Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert test of #10267 #10323

Open
wants to merge 1 commit into
base: 4.19
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 42 additions & 81 deletions server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,7 @@
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.Pod;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.domain.Domain;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
Expand All @@ -155,7 +153,6 @@
import com.cloud.hypervisor.HypervisorCapabilitiesVO;
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
import com.cloud.offering.DiskOffering;
import com.cloud.org.Cluster;
import com.cloud.org.Grouping;
import com.cloud.projects.Project;
import com.cloud.projects.ProjectManager;
Expand Down Expand Up @@ -326,8 +323,6 @@
@Inject
private VmWorkJobDao _workJobDao;
@Inject
ClusterDao clusterDao;
@Inject
private ClusterDetailsDao _clusterDetailsDao;
@Inject
private StorageManager storageMgr;
Expand All @@ -351,8 +346,6 @@
protected ProjectManager projectManager;
@Inject
protected StoragePoolDetailsDao storagePoolDetailsDao;
@Inject
HostPodDao podDao;


protected Gson _gson;
Expand Down Expand Up @@ -2387,18 +2380,25 @@
return attachVolumeToVM(command.getVirtualMachineId(), command.getId(), command.getDeviceId());
}

protected VolumeVO getVmExistingVolumeForVolumeAttach(UserVmVO vm, VolumeInfo volumeToAttach) {
private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);

Check warning on line 2384 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2383-L2384

Added lines #L2383 - L2384 were not covered by tests

if (volumeToAttach.isAttachedVM()) {
throw new CloudRuntimeException("This volume is already attached to a VM.");

Check warning on line 2387 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2387

Added line #L2387 was not covered by tests
}

UserVmVO vm = _userVmDao.findById(vmId);

Check warning on line 2390 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2390

Added line #L2390 was not covered by tests
VolumeVO existingVolumeOfVm = null;
VMTemplateVO template = _templateDao.findById(vm.getTemplateId());
List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT);
List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT);

Check warning on line 2393 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2393

Added line #L2393 was not covered by tests
if (rootVolumesOfVm.size() > 1 && template != null && !template.isDeployAsIs()) {
throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state.");
} else {
if (!rootVolumesOfVm.isEmpty()) {
existingVolumeOfVm = rootVolumesOfVm.get(0);
} else {
// locate data volume of the vm
List<VolumeVO> diskVolumesOfVm = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.DATADISK);
List<VolumeVO> diskVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);

Check warning on line 2401 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2401

Added line #L2401 was not covered by tests
for (VolumeVO diskVolume : diskVolumesOfVm) {
if (diskVolume.getState() != Volume.State.Allocated) {
existingVolumeOfVm = diskVolume;
Expand All @@ -2407,89 +2407,45 @@
}
}
}
if (existingVolumeOfVm == null) {
if (s_logger.isTraceEnabled()) {
s_logger.trace(String.format("No existing volume found for VM (%s/%s) to attach volume %s/%s",
if (s_logger.isTraceEnabled()) {
String msg = "attaching volume %s/%s to a VM (%s/%s) with an existing volume %s/%s on primary storage %s";

Check warning on line 2411 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2411

Added line #L2411 was not covered by tests
if (existingVolumeOfVm != null) {
s_logger.trace(String.format(msg,
volumeToAttach.getName(), volumeToAttach.getUuid(),

Check warning on line 2414 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2413-L2414

Added lines #L2413 - L2414 were not covered by tests
vm.getName(), vm.getUuid(),
volumeToAttach.getName(), volumeToAttach.getUuid()));
existingVolumeOfVm.getName(), existingVolumeOfVm.getUuid(),
existingVolumeOfVm.getPoolId()));

Check warning on line 2417 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2416-L2417

Added lines #L2416 - L2417 were not covered by tests
}
return null;
}
if (s_logger.isTraceEnabled()) {
String msg = "attaching volume %s/%s to a VM (%s/%s) with an existing volume %s/%s on primary storage %s";
s_logger.trace(String.format(msg,
volumeToAttach.getName(), volumeToAttach.getUuid(),
vm.getName(), vm.getUuid(),
existingVolumeOfVm.getName(), existingVolumeOfVm.getUuid(),
existingVolumeOfVm.getPoolId()));
}
return existingVolumeOfVm;
}

protected StoragePool getPoolForAllocatedOrUploadedVolumeForAttach(final VolumeInfo volumeToAttach, final UserVmVO vm) {
DataCenter zone = _dcDao.findById(vm.getDataCenterId());
Pair<Long, Long> clusterHostId = virtualMachineManager.findClusterAndHostIdForVm(vm, false);
long podId = vm.getPodIdToDeployIn();
if (clusterHostId.first() != null) {
Cluster cluster = clusterDao.findById(clusterHostId.first());
podId = cluster.getPodId();
}
Pod pod = podDao.findById(podId);
DiskOfferingVO offering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
DiskProfile diskProfile = new DiskProfile(volumeToAttach.getId(), volumeToAttach.getVolumeType(),
volumeToAttach.getName(), volumeToAttach.getId(), volumeToAttach.getSize(), offering.getTagsArray(),
offering.isUseLocalStorage(), offering.isRecreatable(),
volumeToAttach.getTemplateId());
diskProfile.setHyperType(vm.getHypervisorType());
StoragePool pool = _volumeMgr.findStoragePool(diskProfile, zone, pod, clusterHostId.first(),
clusterHostId.second(), vm, Collections.emptySet());
if (pool == null) {
throw new CloudRuntimeException(String.format("Failed to find a primary storage for volume in state: %s", volumeToAttach.getState()));
}
return pool;
}

protected VolumeInfo createVolumeOnPrimaryForAttachIfNeeded(final VolumeInfo volumeToAttach, final UserVmVO vm, VolumeVO existingVolumeOfVm) {

HypervisorType rootDiskHyperType = vm.getHypervisorType();
HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());

Check warning on line 2422 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2421-L2422

Added lines #L2421 - L2422 were not covered by tests

VolumeInfo newVolumeOnPrimaryStorage = volumeToAttach;
boolean volumeOnSecondary = volumeToAttach.getState() == Volume.State.Uploaded;
if (!Arrays.asList(Volume.State.Allocated, Volume.State.Uploaded).contains(volumeToAttach.getState())) {
return newVolumeOnPrimaryStorage;
}

//don't create volume on primary storage if its being attached to the vm which Root's volume hasn't been created yet
StoragePool destPrimaryStorage = null;
StoragePoolVO destPrimaryStorage = null;

Check warning on line 2427 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2427

Added line #L2427 was not covered by tests
if (existingVolumeOfVm != null && !existingVolumeOfVm.getState().equals(Volume.State.Allocated)) {
destPrimaryStorage = _storagePoolDao.findById(existingVolumeOfVm.getPoolId());
if (s_logger.isTraceEnabled() && destPrimaryStorage != null) {
s_logger.trace(String.format("decided on target storage: %s/%s", destPrimaryStorage.getName(), destPrimaryStorage.getUuid()));
}
}
if (destPrimaryStorage == null) {
destPrimaryStorage = getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
}
try {
if (volumeOnSecondary && Storage.StoragePoolType.PowerFlex.equals(destPrimaryStorage.getPoolType())) {
throw new InvalidParameterValueException("Cannot attach uploaded volume, this operation is unsupported on storage pool type " + destPrimaryStorage.getPoolType());
}
newVolumeOnPrimaryStorage = _volumeMgr.createVolumeOnPrimaryStorage(vm, volumeToAttach,
vm.getHypervisorType(), destPrimaryStorage);
} catch (NoTransitionException e) {
s_logger.debug("Failed to create volume on primary storage", e);
throw new CloudRuntimeException("Failed to create volume on primary storage", e);
}
return newVolumeOnPrimaryStorage;
}

private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
boolean volumeOnSecondary = volumeToAttach.getState() == Volume.State.Uploaded;

if (volumeToAttach.isAttachedVM()) {
throw new CloudRuntimeException("This volume is already attached to a VM.");
if (destPrimaryStorage != null && (volumeToAttach.getState() == Volume.State.Allocated || volumeOnSecondary)) {
try {

Check warning on line 2438 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2438

Added line #L2438 was not covered by tests
if (volumeOnSecondary && destPrimaryStorage.getPoolType() == Storage.StoragePoolType.PowerFlex) {
throw new InvalidParameterValueException("Cannot attach uploaded volume, this operation is unsupported on storage pool type " + destPrimaryStorage.getPoolType());

Check warning on line 2440 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2440

Added line #L2440 was not covered by tests
}
newVolumeOnPrimaryStorage = _volumeMgr.createVolumeOnPrimaryStorage(vm, volumeToAttach, rootDiskHyperType, destPrimaryStorage);
} catch (NoTransitionException e) {
s_logger.debug("Failed to create volume on primary storage", e);
throw new CloudRuntimeException("Failed to create volume on primary storage", e);
}

Check warning on line 2446 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2442-L2446

Added lines #L2442 - L2446 were not covered by tests
}

UserVmVO vm = _userVmDao.findById(vmId);
VolumeVO existingVolumeOfVm = getVmExistingVolumeForVolumeAttach(vm, volumeToAttach);
VolumeInfo newVolumeOnPrimaryStorage = createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm, existingVolumeOfVm);

// reload the volume from db
newVolumeOnPrimaryStorage = volFactory.getVolume(newVolumeOnPrimaryStorage.getId());
boolean moveVolumeNeeded = needMoveVolume(existingVolumeOfVm, newVolumeOnPrimaryStorage);
Expand All @@ -2507,17 +2463,19 @@
StoragePoolVO vmRootVolumePool = _storagePoolDao.findById(existingVolumeOfVm.getPoolId());

try {
HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
newVolumeOnPrimaryStorage = _volumeMgr.moveVolume(newVolumeOnPrimaryStorage, vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(), vmRootVolumePool.getClusterId(),
volumeToAttachHyperType);
} catch (ConcurrentOperationException | StorageUnavailableException e) {
} catch (ConcurrentOperationException e) {
s_logger.debug("move volume failed", e);
throw new CloudRuntimeException("move volume failed", e);
} catch (StorageUnavailableException e) {

Check warning on line 2471 in server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java#L2468-L2471

Added lines #L2468 - L2471 were not covered by tests
s_logger.debug("move volume failed", e);
throw new CloudRuntimeException("move volume failed", e);
}
}
VolumeVO newVol = _volsDao.findById(newVolumeOnPrimaryStorage.getId());
// Getting the fresh vm object in case of volume migration to check the current state of VM
if (moveVolumeNeeded) {
if (moveVolumeNeeded || volumeOnSecondary) {
vm = _userVmDao.findById(vmId);
if (vm == null) {
throw new InvalidParameterValueException("VM not found.");
Expand Down Expand Up @@ -2701,6 +2659,9 @@
if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
throw new InvalidParameterValueException("Vm already has root volume attached to it");
}
if (volumeToAttach.getState() == Volume.State.Uploaded) {
throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
}
}
}

Expand Down
Loading
Loading