You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by GitBox <gi...@apache.org> on 2022/04/22 17:16:39 UTC
[GitHub] [cloudstack] DaanHoogland opened a new pull request, #6307: fix pseudo random behaviour in pool selection
DaanHoogland opened a new pull request, #6307:
URL: https://github.com/apache/cloudstack/pull/6307
### Description
This PR fixes the issue where the same pool is selected when multiple volumes are attached to a VM when only two pools are available. The list is shuffled but due to a bug in Random this does not result to a different one being selected each time. By using SecureRandom with a seed. this is fixed.
<!--- Describe your changes in DETAIL - And how has behaviour functionally changed. -->
<!-- For new features, provide link to FS, dev ML discussion etc. -->
<!-- In case of bug fix, the expected and actual behaviours, steps to reproduce. -->
<!-- When "Fixes: #<id>" is specified, the issue/PR will automatically be closed when this PR gets merged -->
<!-- For addressing multiple issues/PRs, use multiple "Fixes: #<id>" -->
<!-- Fixes: # -->
<!--- ********************************************************************************* -->
<!--- NOTE: AUTOMATATION USES THE DESCRIPTIONS TO SET LABELS AND PRODUCE DOCUMENTATION. -->
<!--- PLEASE PUT AN 'X' in only **ONE** box -->
<!--- ********************************************************************************* -->
### Types of changes
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] New feature (non-breaking change which adds functionality)
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] Enhancement (improves an existing feature and functionality)
- [ ] Cleanup (Code refactoring and cleanup, that may add test cases)
### Feature/Enhancement Scale or Bug Severity
#### Feature/Enhancement Scale
- [ ] Major
- [x] Minor
#### Bug Severity
- [ ] BLOCKER
- [ ] Critical
- [x] Major
- [ ] Minor
- [ ] Trivial
### Screenshots (if appropriate):
### How Has This Been Tested?
<!-- Please describe in detail how you tested your changes. -->
<!-- Include details of your testing environment, and the tests you ran to -->
<!-- see how your change affects other areas of the code, etc. -->
<!-- Please read the [CONTRIBUTING](https://github.com/apache/cloudstack/blob/main/CONTRIBUTING.md) document -->
manually tested.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1144817078
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1144901476
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r857527748
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ }
- StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ // if target VM has backups
+ if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ }
+ }
- // managed storage can be used for different types of hypervisors
- // only perform this check if the volume's storage pool is not null and not managed
- if (volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged()) {
- if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
- throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ /**
+ * If local storage is disabled then attaching a volume with a local diskoffering is not allowed
+ */
+ private void excludeLocalStorageIfNeeded(VolumeInfo volumeToAttach) {
+ DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
+ if (!dataCenter.isLocalStorageEnabled()) {
+ DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
+ if (diskOffering.isUseLocalStorage()) {
+ throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
}
}
+ }
- AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-
- if (asyncExecutionContext != null) {
- AsyncJob job = asyncExecutionContext.getJob();
+ /**
+ * Check that the number of data volumes attached to VM is less than the number that are supported by the hypervisor
+ */
+ private void checkNumberOfAttachedVolumes(Long deviceId, UserVmVO vm) {
+ if (deviceId == null || deviceId.longValue() != 0) {
+ List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.DATADISK);
+ int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
+ if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
+ throw new InvalidParameterValueException(
+ "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
+ }
+ }
+ }
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
+ private void checkDeviceId(Long deviceId, VolumeInfo volumeToAttach, UserVmVO vm) {
+ if (deviceId != null) {
+ // validate ROOT volume type
+ if (deviceId.longValue() == 0) {
Review Comment:
extra return statements ar a code smell I don´t want to introduce.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123938765
@blueorangutan test
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1124624618
@acs-robot a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1124628877
UI build: :heavy_check_mark:
Live QA URL: http://qa.cloudstack.cloud:8080/client/pr/6307 (SL-JID-1563)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] nvazquez commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
nvazquez commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1106592293
@blueorangutan test
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1107072194
<b>Trillian test result (tid-3998)</b>
Environment: kvm-centos7 (x2), Advanced Networking with Mgmt server 7
Total time taken: 33608 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr6307-t3998-kvm-centos7.zip
Intermittent failure detected: /marvin/tests/smoke/test_kubernetes_clusters.py
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1106552676
@nvazquez a Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r857529284
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
Review Comment:
note that this didn´t change, but you are right, I might add some information to the exception message.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] nvazquez merged pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
nvazquez merged PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1124442108
<b>Trillian test result (tid-4163)</b>
Environment: kvm-centos7 (x2), Advanced Networking with Mgmt server 7
Total time taken: 34643 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr6307-t4163-kvm-centos7.zip
Smoke tests completed. 88 look OK, 1 have errors
Only failed tests results shown below:
Test | Result | Time (s) | Test File
--- | --- | --- | ---
test_01_add_primary_storage_disabled_host | `Error` | 34.44 | test_primary_storage.py
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] sonarcloud[bot] commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1144965358
SonarCloud Quality Gate failed. [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=apache_cloudstack&pullRequest=6307)
[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [![C](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/C-16px.png 'C')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [1 Bug](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG)
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY)
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT)
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL)
[![17.5%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '17.5%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list) [17.5% Coverage](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1148315941
UI build: :heavy_check_mark:
Live QA URL: http://qa.cloudstack.cloud:8080/client/pr/6307 (SL-JID-1686)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1109485661
## PR Coverage Report
|**CLASS**|**INSTRUCTION MISSED**|**INSTRUCTION COVERED**|**BRANCH MISSED**|**BRANCH COVERED**|**LINE MISSED**|**LINE COVERED**|
|-----|-----|-----|-----|-----|-----|-----|
||
||
||
||
||
||
||
||
||
||
|Network|554|0|42|0|107|0|
||
||
||
||
||
||
||
||
||
|Volume|109|0|2|0|44|0|
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
|VirtualMachineGuru|78|0|4|0|15|0|
|NetworkOrchestrationService|0|101|0|0|0|10|
||
||
||
|AlertManager|79|0|0|0|7|0|
||
||
|StorageUtil|203|0|44|0|56|0|
|ClusteredAgentManagerImpl|2361|0|242|0|536|0|
|ConnectedAgentAttache|149|0|20|0|40|0|
|VirtualMachineManagerImpl|15659|0|1500|0|3079|0|
|NetworkOrchestrator|9910|0|1224|0|1945|0|
|VolumeOrchestrator|5236|0|566|0|984|0|
|CapacityVO|261|0|0|0|80|0|
|DataCenterVnetVO|58|0|0|0|24|0|
|VlanVO|186|0|2|0|72|0|
||
|VlanDaoImpl|1307|0|54|0|218|0|
|EventVO|140|0|0|0|58|0|
||
|HostDaoImpl|4983|0|180|0|803|0|
|AccountGuestVlanMapVO|46|0|0|0|19|0|
||
|NetworkDetailsDaoImpl|30|0|4|0|5|0|
|NetworkVO|396|159|19|1|140|44|
||
|VpcOfferingDaoImpl|137|0|0|0|25|0|
||
|VpcOfferingDetailsDaoImpl|173|0|10|0|31|0|
|NetworkOfferingVO|414|31|0|0|126|12|
||
|NetworkOfferingDaoImpl|691|0|22|0|114|0|
|VolumeVO|529|133|4|0|179|39|
|SystemVmTemplateRegistration|1773|0|86|0|376|0|
|Upgrade41520to41600|262|17|16|0|62|5|
|Upgrade41610to41700|159|7|6|0|43|2|
|DomainRouterVO|116|50|0|0|41|14|
|ConsoleProxyDaoImpl|635|0|20|0|144|0|
||
|DomainRouterDaoImpl|1600|0|22|0|228|0|
||
|NicDaoImpl|1392|0|12|0|193|0|
||
|SnapshotObject|748|30|64|0|151|11|
|DefaultVMSnapshotStrategy|486|677|52|30|100|140|
|AbstractStoragePoolAllocator|784|0|150|0|163|0|
|VolumeObject|773|665|77|39|178|117|
||
||
||
||
||
||
||
|CloudStackContextLoaderListener|77|0|2|0|21|0|
|LibvirtComputingResource|8888|1988|1087|147|1983|451|
|LibvirtVMDef|37|114|6|4|11|36|
|LibvirtStartCommandWrapper|75|295|16|22|15|72|
||
||
|MockNetworkManagerImpl|510|0|24|0|88|0|
|SimulatorManagerImpl|1394|0|214|0|309|0|
|VmwareManagerImpl|2613|528|296|38|615|117|
|VmwareResource|20395|0|2274|0|4397|0|
|VmwareStorageProcessor|9892|9|940|0|2122|2|
|CitrixResourceBase|14658|557|1456|34|3169|122|
|CitrixCheckSshCommandWrapper|15|51|3|3|3|14|
|CitrixNetworkElementCommandWrapper|0|14|0|0|0|4|
|CitrixRebootRouterCommandWrapper|28|25|3|1|5|7|
|CitrixStartCommandWrapper|690|62|81|1|116|16|
|KubernetesClusterManagerImpl|4724|0|480|0|760|0|
|KubernetesClusterActionWorker|1540|0|114|0|281|0|
|KubernetesClusterResourceModifierActionWorker|1843|0|140|0|325|0|
|CreateKubernetesClusterCmd|215|0|18|0|61|0|
||
|MetricsServiceImpl|2130|0|134|0|446|0|
|ClusterMetricsResponse|523|0|132|0|60|0|
|VmMetricsResponse|142|0|22|0|25|0|
|VolumeMetricsResponse|69|0|8|0|10|0|
|ZoneMetricsResponse|501|0|126|0|56|0|
||
|BigSwitchBcfGuestNetworkGuru|662|0|62|0|145|0|
|CreateServiceInstanceCmd|201|0|16|0|45|0|
|ContrailManagerImpl|2218|0|234|0|497|0|
|StopNetScalerVMCmd|114|0|12|0|26|0|
|NetScalerControlCenterResource|1943|0|144|0|468|0|
|NetscalerResource|6882|0|806|0|1623|0|
|OvsGuestNetworkGuru|409|0|48|0|90|0|
|VxlanGuestNetworkGuru|89|180|11|21|16|39|
||
|DateraPrimaryDataStoreDriver|3195|0|283|0|748|0|
|CloudStackPrimaryDataStoreDriverImpl|903|0|114|0|229|0|
|LinstorPrimaryDataStoreDriverImpl|1442|0|91|0|348|0|
||
||
|ScaleIOPrimaryDataStoreDriver|2537|0|246|0|537|0|
|SolidFirePrimaryDataStoreDriver|3347|0|284|0|697|0|
|LinkAccountToLdapCmd|77|105|6|4|18|23|
|ListAndSwitchSAMLAccountCmd|182|205|30|22|38|34|
|SAMLUtils|202|465|41|11|53|108|
||
||
|DomainChecker|1206|0|300|0|238|0|
|AlertManagerImpl|2133|0|183|0|418|0|
|ApiAsyncJobDispatcher|212|0|12|0|53|0|
|ApiDBUtils|2374|0|210|0|592|0|
|ApiDispatcher|231|0|42|0|55|0|
|ApiResponseHelper|12400|0|1292|0|2837|0|
|ApiServer|2868|112|346|0|672|14|
|ResponseObjectTypeAdapter|161|8|14|0|37|2|
|ParamProcessWorker|1050|0|155|0|241|0|
|QueryManagerImpl|14429|0|1270|0|2439|0|
|DomainRouterJoinDaoImpl|801|0|80|0|195|0|
|NetworkOfferingJoinDaoImpl|278|0|12|0|57|0|
|VolumeJoinDaoImpl|770|0|94|0|171|0|
|VpcOfferingJoinDaoImpl|172|0|6|0|36|0|
|AsyncJobJoinVO|86|0|0|0|31|0|
|DomainRouterJoinVO|237|0|0|0|80|0|
|EventJoinVO|100|0|0|0|35|0|
|NetworkOfferingJoinVO|219|0|0|0|79|0|
|VolumeJoinVO|267|0|0|0|93|0|
|VpcOfferingJoinVO|120|0|0|0|37|0|
|ConfigurationManagerImpl|18652|0|3092|0|3639|0|
|ConsoleProxyManagerImpl|3717|0|423|0|726|0|
|ActionEventInterceptor|398|19|44|2|90|7|
|ActionEventUtils|929|0|90|0|198|0|
|EventJoinDaoImpl|329|0|18|0|58|0|
|HypervisorGuruBase|669|38|52|0|133|5|
|LibvirtServerDiscoverer|994|0|116|0|218|0|
|ExternalFirewallDeviceManagerImpl|1885|0|198|0|381|0|
|ExternalLoadBalancerDeviceManagerImpl|2591|0|288|0|593|0|
|IpAddressManagerImpl|4084|0|463|0|814|0|
|Ipv6AddressManagerImpl|371|0|32|0|70|0|
|NetworkMigrationManagerImpl|1706|0|90|0|355|0|
|NetworkModelImpl|6182|0|838|0|1300|0|
|NetworkServiceImpl|13648|0|1902|0|2613|0|
|FirewallManagerImpl|2600|0|399|0|466|0|
|ExternalGuestNetworkGuru|849|0|92|0|158|0|
|GuestNetworkGuru|702|298|114|34|142|64|
|PrivateNetworkGuru|394|0|46|0|88|0|
|PublicNetworkGuru|341|0|42|0|77|0|
|LoadBalancingRulesManagerImpl|6024|0|666|0|1254|0|
|CommandSetupHelper|4088|0|300|0|771|0|
||
|NetworkHelperImpl|2092|0|278|0|445|0|
|VirtualNetworkApplianceManagerImpl|7767|0|792|0|1544|0|
|RulesManagerImpl|4074|0|492|0|790|0|
|NetworkACLManagerImpl|861|0|118|0|182|0|
|NetworkACLServiceImpl|2701|0|304|0|520|0|
|VpcManagerImpl|6936|0|770|0|1321|0|
|Site2SiteVpnManagerImpl|2298|0|214|0|468|0|
|ResourceManagerImpl|8524|0|982|0|1659|0|
|RollingMaintenanceManagerImpl|2041|0|192|0|363|0|
|ResourceIconManagerImpl|328|0|36|0|70|0|
|ConfigurationServerImpl|2061|0|176|0|495|0|
||
|ManagementServerImpl|12197|0|1076|0|2428|0|
|StatsCollector|2178|0|124|0|359|0|
|StorageManagerImpl|8580|0|976|0|1710|0|
|VolumeApiServiceImpl|11163|0|1516|0|2078|0|
|SnapshotManagerImpl|4195|0|410|0|753|0|
|SnapshotSchedulerImpl|871|0|81|0|197|0|
|ResourceManagerUtilImpl|356|0|24|0|71|0|
|TaggedResourceManagerImpl|473|0|58|0|96|0|
|TemplateManagerImpl|5011|0|696|0|1045|0|
|AccountManagerImpl|6460|0|906|0|1352|0|
|UserVmManagerImpl|20798|0|2566|0|3869|0|
|VMSnapshotManagerImpl|3151|0|296|0|628|0|
|RoleManagerImpl|737|0|114|0|147|0|
|AffinityGroupServiceImpl|791|0|112|0|172|0|
|AnnotationManagerImpl|1401|0|167|0|284|0|
|BackupManagerImpl|2779|0|224|0|489|0|
|CAManagerImpl|633|0|80|0|129|0|
|DirectDownloadManagerImpl|1684|0|186|0|361|0|
|HAManagerImpl|1391|0|194|0|231|0|
|BasicNetworkVisitor|535|0|28|0|112|0|
|OutOfBandManagementServiceImpl|1182|0|130|0|237|0|
|PowerOperationTask|109|0|0|0|17|0|
||
||
||
||
||
||
||
||
||
||
||
||
||
||
|MockNetworkManagerImpl|510|0|24|0|88|0|
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
|PremiumSecondaryStorageManagerImpl|775|0|64|0|116|0|
|SecondaryStorageManagerImpl|3544|149|343|11|629|32|
||
||
||
||
||
||
||
||
||
||
|VirtualMachineMO|8953|135|1063|17|1982|31|
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1115829550
UI build: :heavy_check_mark:
Live QA URL: http://qa.cloudstack.cloud:8080/client/pr/6307 (SL-JID-1511)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1149821647
@nvazquez a Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1113190394
@acs-robot a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1106833076
This is it. Why not merge as it. It contains no other functionality
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r857528719
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ }
- StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ // if target VM has backups
+ if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
Review Comment:
yes, this is code moved in a refactor, but Iĺl have a look at improving the exception messages.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1108653297
UI build: :heavy_check_mark:
Live QA URL: http://qa.cloudstack.cloud:8080/client/pr/6307 (SL-JID-1466)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r857525628
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ }
- StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ // if target VM has backups
+ if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ }
+ }
- // managed storage can be used for different types of hypervisors
- // only perform this check if the volume's storage pool is not null and not managed
- if (volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged()) {
- if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
- throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ /**
+ * If local storage is disabled then attaching a volume with a local diskoffering is not allowed
+ */
+ private void excludeLocalStorageIfNeeded(VolumeInfo volumeToAttach) {
+ DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
+ if (!dataCenter.isLocalStorageEnabled()) {
+ DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
+ if (diskOffering.isUseLocalStorage()) {
+ throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
}
}
+ }
- AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-
- if (asyncExecutionContext != null) {
- AsyncJob job = asyncExecutionContext.getJob();
+ /**
+ * Check that the number of data volumes attached to VM is less than the number that are supported by the hypervisor
+ */
+ private void checkNumberOfAttachedVolumes(Long deviceId, UserVmVO vm) {
+ if (deviceId == null || deviceId.longValue() != 0) {
+ List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.DATADISK);
+ int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
+ if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
+ throw new InvalidParameterValueException(
+ "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
+ }
+ }
+ }
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
+ private void checkDeviceId(Long deviceId, VolumeInfo volumeToAttach, UserVmVO vm) {
+ if (deviceId != null) {
Review Comment:
extra return statements ar a code smell I don´t want to introduce.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] nvazquez commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
nvazquez commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1117149575
@blueorangutan package
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] nvazquez commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
nvazquez commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1117180857
@blueorangutan test
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123662124
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1145773186
@DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] sonarcloud[bot] commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1144743410
SonarCloud Quality Gate failed. [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=apache_cloudstack&pullRequest=6307)
[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [![C](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/C-16px.png 'C')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [1 Bug](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG)
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY)
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT)
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1146342840
<b>Trillian test result (tid-4295)</b>
Environment: kvm-centos7 (x2), Advanced Networking with Mgmt server 7
Total time taken: 39155 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr6307-t4295-kvm-centos7.zip
Smoke tests completed. 94 look OK, 4 have errors
Only failed tests results shown below:
Test | Result | Time (s) | Test File
--- | --- | --- | ---
test_01_add_primary_storage_disabled_host | `Error` | 0.80 | test_primary_storage.py
test_01_primary_storage_nfs | `Error` | 0.10 | test_primary_storage.py
ContextSuite context=TestStorageTags>:setup | `Error` | 0.18 | test_primary_storage.py
test_03_deploy_and_scale_kubernetes_cluster | `Failure` | 30.81 | test_kubernetes_clusters.py
test_07_deploy_kubernetes_ha_cluster | `Failure` | 57.35 | test_kubernetes_clusters.py
test_08_upgrade_kubernetes_ha_cluster | `Failure` | 37.95 | test_kubernetes_clusters.py
test_09_delete_kubernetes_ha_cluster | `Failure` | 0.04 | test_kubernetes_clusters.py
ContextSuite context=TestKubernetesCluster>:teardown | `Error` | 71.70 | test_kubernetes_clusters.py
test_01_secure_vm_migration | `Error` | 148.94 | test_vm_life_cycle.py
test_02_unsecure_vm_migration | `Error` | 266.14 | test_vm_life_cycle.py
test_03_secured_to_nonsecured_vm_migration | `Error` | 140.68 | test_vm_life_cycle.py
test_08_migrate_vm | `Error` | 43.91 | test_vm_life_cycle.py
test_hostha_enable_ha_when_host_in_maintenance | `Error` | 301.73 | test_hostha_kvm.py
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] GutoVeronezi commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
GutoVeronezi commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r870590382
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2497,7 +2573,7 @@ public Volume detachVolumeFromVM(DetachVolumeCmd cmmd) {
AsyncJob job = asyncExecutionContext.getJob();
if (s_logger.isInfoEnabled()) {
- s_logger.info("Trying to attaching volume " + volumeId + "to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
+ s_logger.info(String.format("Trying to attach volume [%s/%s] to VM instance [%s/%s], update async job-%s progress status", volume.getName(), volume.getUuid(), vm.getName(), vm.getUuid(), job.getId()));
Review Comment:
We could use `ReflectionToStringBuilderUtils#reflectOnlySelectedFields` here.
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2146,170 +2165,227 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
+ excludeLocalStorageIfNeeded(volumeToAttach);
+
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForMatchingHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info(String.format("Trying to attach volume [%s/%s] to VM instance [%s/%s], update async job-%s progress status",
+ volumeToAttach.getName(),
+ volumeToAttach.getUuid(),
+ vm.getName(),
+ vm.getUuid(),
+ job.getId()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
- }
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
+
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return safelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException | ExecutionException e) {
+ throw new RuntimeException(String.format("Could not get attach volume job result for VM [%s], volume[%s] and device [%s], due to [%s].", vmId, volumeId, deviceId, e.getMessage()), e);
}
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume safelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchingHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
Review Comment:
We could turn this comment into a javadoc.
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2146,170 +2165,227 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
+ excludeLocalStorageIfNeeded(volumeToAttach);
+
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForMatchingHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info(String.format("Trying to attach volume [%s/%s] to VM instance [%s/%s], update async job-%s progress status",
+ volumeToAttach.getName(),
+ volumeToAttach.getUuid(),
+ vm.getName(),
+ vm.getUuid(),
+ job.getId()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
- }
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
+
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return safelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException | ExecutionException e) {
+ throw new RuntimeException(String.format("Could not get attach volume job result for VM [%s], volume[%s] and device [%s], due to [%s].", vmId, volumeId, deviceId, e.getMessage()), e);
}
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume safelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchingHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded && volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException(String.format("Unable to attach volume to VM %s/%s, please specify a VM that does not have VM snapshots", vm.getName(), vm.getUuid()));
+ }
- StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ // if target VM has backups
+ if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
+ throw new InvalidParameterValueException(String.format("Unable to attach volume to VM %s/%s, please specify a VM that does not have any backups", vm.getName(), vm.getUuid()));
+ }
+ }
- // managed storage can be used for different types of hypervisors
- // only perform this check if the volume's storage pool is not null and not managed
- if (volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged()) {
- if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
- throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ /**
+ * If local storage is disabled then attaching a volume with a local diskoffering is not allowed
+ */
+ private void excludeLocalStorageIfNeeded(VolumeInfo volumeToAttach) {
+ DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
+ if (!dataCenter.isLocalStorageEnabled()) {
+ DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
+ if (diskOffering.isUseLocalStorage()) {
+ throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
}
}
+ }
- AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-
- if (asyncExecutionContext != null) {
- AsyncJob job = asyncExecutionContext.getJob();
+ /**
+ * Check that the number of data volumes attached to VM is less than the number that are supported by the hypervisor
+ */
+ private void checkNumberOfAttachedVolumes(Long deviceId, UserVmVO vm) {
+ if (deviceId == null || deviceId.longValue() != 0) {
+ List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.DATADISK);
+ int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
+ if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
+ throw new InvalidParameterValueException(
+ "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
+ }
+ }
+ }
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
+ /**
+ * validate ROOT volume type;
+ * 1. vm shouldn't have any volume with deviceId 0
+ * 2. volume can't be in Uploaded state
+ *
+ * @param deviceId requested device number to attach as
+ * @param volumeToAttach
+ * @param vm
+ */
+ private void checkDeviceId(Long deviceId, VolumeInfo volumeToAttach, UserVmVO vm) {
+ if (deviceId != null && deviceId.longValue() == 0) {
+ validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
+ 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);
}
+ }
+ }
- _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
+ /**
+ * Check that the virtual machine ID is valid and it's a user vm
+ *
+ * @return the user vm vo object correcponding to the vmId to attach to
+ */
+ @NotNull private UserVmVO getAndCheckUserVmVO(Long vmId, VolumeInfo volumeToAttach) {
+ UserVmVO vm = _userVmDao.findById(vmId);
+ if (vm == null || vm.getType() != VirtualMachine.Type.User) {
+ throw new InvalidParameterValueException("Please specify a valid User VM.");
}
- AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
- if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
- // avoid re-entrance
+ // Check that the VM is in the correct state
+ if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
+ throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
+ }
- VmWorkJobVO placeHolder = null;
- placeHolder = createPlaceHolderWork(vmId);
- try {
- return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
- } finally {
- _workJobDao.expunge(placeHolder.getId());
- }
+ // Check that the VM and the volume are in the same zone
+ if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
+ throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ }
+ return vm;
+ }
- } else {
- Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+ /**
+ * Check that the volume ID is valid
+ * Check that the volume is a data volume
+ * Check that the volume is not currently attached to any VM
+ * Check that the volume is not destroyed
+ *
+ * @param volumeId the id of the volume to attach
+ * @return the volume info object representing the volume to attach
+ */
+ @NotNull private VolumeInfo getAndCheckVolumeInfo(Long volumeId) {
+ VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
+ if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
+ throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
+ }
- Volume vol = null;
- try {
- outcome.get();
- } catch (InterruptedException e) {
- throw new RuntimeException("Operation is interrupted", e);
- } catch (java.util.concurrent.ExecutionException e) {
- throw new RuntimeException("Execution excetion", e);
- }
+ if (volumeToAttach.getInstanceId() != null) {
+ throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
+ }
- Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
- if (jobResult != null) {
- if (jobResult instanceof ConcurrentOperationException) {
- throw (ConcurrentOperationException)jobResult;
- } else if (jobResult instanceof InvalidParameterValueException) {
- throw (InvalidParameterValueException)jobResult;
- } else if (jobResult instanceof RuntimeException) {
- throw (RuntimeException)jobResult;
- } else if (jobResult instanceof Throwable) {
- throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
- } else if (jobResult instanceof Long) {
- vol = _volsDao.findById((Long)jobResult);
- }
- }
- return vol;
+ if (volumeToAttach.getState() == Volume.State.Destroy) {
+ throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
}
+
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready, Volume.State.Uploaded).contains(volumeToAttach.getState())) {
Review Comment:
@DaanHoogland, can we extract this list `Array.asList...` to a `final` attribute of the class? This way we avoid it to be created every time.
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ }
- StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ // if target VM has backups
+ if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
Review Comment:
My bad, didn't see it correctly.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r870218542
##########
engine/components-api/src/main/java/com/cloud/storage/StorageUtil.java:
##########
@@ -33,13 +33,27 @@
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.VMInstanceDao;
+import org.apache.log4j.Logger;
+
public class StorageUtil {
@Inject private ClusterDao clusterDao;
@Inject private HostDao hostDao;
@Inject private PrimaryDataStoreDao storagePoolDao;
@Inject private VMInstanceDao vmInstanceDao;
@Inject private VolumeDao volumeDao;
+ public static void traceLogStoragePools(List<StoragePool> poolList, Logger logger, String initialMessage) {
+ if (logger.isTraceEnabled()) {
Review Comment:
extra return statement is a bad smell
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1149936583
Packaging result: :heavy_multiplication_x: el7 :heavy_check_mark: el8 :heavy_check_mark: debian :heavy_multiplication_x: suse15. SL-JID 3543
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1150046053
@nvazquez a Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1108646871
@acs-robot a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1109451335
@acs-robot a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] nvazquez commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
nvazquez commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1149821117
@blueorangutan package
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1113245980
## PR Analysis
https://sonarcloud.io/summary/new_code?id=apachecloudstack&pullRequest=6307
## PR Coverage Report
|**CLASS**|**INSTRUCTION MISSED**|**INSTRUCTION COVERED**|**BRANCH MISSED**|**BRANCH COVERED**|**LINE MISSED**|**LINE COVERED**|
|-----|-----|-----|-----|-----|-----|-----|
|Network|554|0|42|0|107|0|
|Volume|109|0|2|0|44|0|
|VirtualMachineGuru|78|0|4|0|15|0|
|NetworkOrchestrationService|0|101|0|0|0|10|
|AlertManager|79|0|0|0|7|0|
|StorageUtil|203|0|44|0|56|0|
|ClusteredAgentManagerImpl|2361|0|242|0|536|0|
|ConnectedAgentAttache|149|0|20|0|40|0|
|VirtualMachineManagerImpl|15659|0|1500|0|3079|0|
|NetworkOrchestrator|9910|0|1224|0|1945|0|
|VolumeOrchestrator|5236|0|566|0|984|0|
|CapacityVO|261|0|0|0|80|0|
|DataCenterVnetVO|58|0|0|0|24|0|
|VlanVO|186|0|2|0|72|0|
|VlanDaoImpl|1307|0|54|0|218|0|
|EventVO|140|0|0|0|58|0|
|HostDaoImpl|4983|0|180|0|803|0|
|AccountGuestVlanMapVO|46|0|0|0|19|0|
|NetworkDetailsDaoImpl|30|0|4|0|5|0|
|NetworkVO|396|159|19|1|140|44|
|VpcOfferingDaoImpl|137|0|0|0|25|0|
|VpcOfferingDetailsDaoImpl|173|0|10|0|31|0|
|NetworkOfferingVO|414|31|0|0|126|12|
|NetworkOfferingDaoImpl|701|0|24|0|118|0|
|VolumeVO|529|133|4|0|179|39|
|SystemVmTemplateRegistration|1773|0|86|0|376|0|
|Upgrade41520to41600|262|17|16|0|62|5|
|Upgrade41610to41700|159|7|6|0|43|2|
|DomainRouterVO|116|50|0|0|41|14|
|ConsoleProxyDaoImpl|635|0|20|0|144|0|
|DomainRouterDaoImpl|1600|0|22|0|228|0|
|NicDaoImpl|1392|0|12|0|193|0|
|SnapshotObject|748|30|64|0|151|11|
|DefaultVMSnapshotStrategy|486|677|52|30|100|140|
|AbstractStoragePoolAllocator|784|0|150|0|163|0|
|VolumeObject|773|665|77|39|178|117|
|CloudStackContextLoaderListener|77|0|2|0|21|0|
|LibvirtComputingResource|8888|1988|1087|147|1983|451|
|LibvirtVMDef|37|114|6|4|11|36|
|LibvirtStartCommandWrapper|75|295|16|22|15|72|
|MockNetworkManagerImpl|510|0|24|0|88|0|
|SimulatorManagerImpl|1394|0|214|0|309|0|
|VmwareManagerImpl|2613|528|296|38|615|117|
|VmwareResource|20395|0|2274|0|4397|0|
|VmwareStorageLayoutHelper|1297|0|118|0|201|0|
|VmwareStorageProcessor|9892|9|940|0|2122|2|
|CitrixResourceBase|14658|557|1456|34|3169|122|
|CitrixCheckSshCommandWrapper|15|51|3|3|3|14|
|CitrixNetworkElementCommandWrapper|0|14|0|0|0|4|
|CitrixRebootRouterCommandWrapper|28|25|3|1|5|7|
|CitrixStartCommandWrapper|690|62|81|1|116|16|
|KubernetesClusterManagerImpl|4724|0|480|0|760|0|
|KubernetesClusterActionWorker|1540|0|114|0|281|0|
|KubernetesClusterResourceModifierActionWorker|1843|0|140|0|325|0|
|CreateKubernetesClusterCmd|215|0|18|0|61|0|
|MetricsServiceImpl|2130|0|134|0|446|0|
|ClusterMetricsResponse|523|0|132|0|60|0|
|VmMetricsResponse|142|0|22|0|25|0|
|VolumeMetricsResponse|69|0|8|0|10|0|
|ZoneMetricsResponse|501|0|126|0|56|0|
|BigSwitchBcfGuestNetworkGuru|662|0|62|0|145|0|
|CreateServiceInstanceCmd|201|0|16|0|45|0|
|ContrailManagerImpl|2218|0|234|0|497|0|
|StopNetScalerVMCmd|114|0|12|0|26|0|
|NetScalerControlCenterResource|1943|0|144|0|468|0|
|NetscalerResource|6882|0|806|0|1623|0|
|OvsGuestNetworkGuru|409|0|48|0|90|0|
|VxlanGuestNetworkGuru|89|180|11|21|16|39|
|DateraPrimaryDataStoreDriver|3195|0|283|0|748|0|
|CloudStackPrimaryDataStoreDriverImpl|903|0|114|0|229|0|
|LinstorPrimaryDataStoreDriverImpl|1442|0|91|0|348|0|
|ScaleIOPrimaryDataStoreDriver|2537|0|246|0|537|0|
|SolidFirePrimaryDataStoreDriver|3347|0|284|0|697|0|
|LinkAccountToLdapCmd|77|105|6|4|18|23|
|ListAndSwitchSAMLAccountCmd|182|205|30|22|38|34|
|SAMLUtils|202|465|41|11|53|108|
|DomainChecker|1206|0|300|0|238|0|
|AlertManagerImpl|2133|0|183|0|418|0|
|ApiAsyncJobDispatcher|212|0|12|0|53|0|
|ApiDBUtils|2374|0|210|0|592|0|
|ApiDispatcher|231|0|42|0|55|0|
|ApiResponseHelper|12401|0|1292|0|2837|0|
|ApiServer|2868|112|346|0|672|14|
|ResponseObjectTypeAdapter|161|8|14|0|37|2|
|ParamProcessWorker|1050|0|155|0|241|0|
|QueryManagerImpl|14429|0|1270|0|2439|0|
|DomainRouterJoinDaoImpl|801|0|80|0|195|0|
|NetworkOfferingJoinDaoImpl|286|0|14|0|60|0|
|VolumeJoinDaoImpl|770|0|94|0|171|0|
|VpcOfferingJoinDaoImpl|180|0|8|0|39|0|
|AsyncJobJoinVO|86|0|0|0|31|0|
|DomainRouterJoinVO|237|0|0|0|80|0|
|EventJoinVO|100|0|0|0|35|0|
|NetworkOfferingJoinVO|219|0|0|0|79|0|
|VolumeJoinVO|267|0|0|0|93|0|
|VpcOfferingJoinVO|120|0|0|0|37|0|
|ConfigurationManagerImpl|18652|0|3092|0|3639|0|
|ConsoleProxyManagerImpl|3717|0|423|0|726|0|
|ActionEventInterceptor|398|19|44|2|90|7|
|ActionEventUtils|929|0|90|0|198|0|
|EventJoinDaoImpl|333|0|18|0|58|0|
|HypervisorGuruBase|669|38|52|0|133|5|
|LibvirtServerDiscoverer|994|0|116|0|218|0|
|ExternalFirewallDeviceManagerImpl|1885|0|198|0|381|0|
|ExternalLoadBalancerDeviceManagerImpl|2591|0|288|0|593|0|
|IpAddressManagerImpl|4084|0|463|0|814|0|
|Ipv6AddressManagerImpl|371|0|32|0|70|0|
|NetworkMigrationManagerImpl|1706|0|90|0|355|0|
|NetworkModelImpl|6182|0|838|0|1300|0|
|NetworkServiceImpl|13648|0|1902|0|2613|0|
|FirewallManagerImpl|2600|0|399|0|466|0|
|ExternalGuestNetworkGuru|849|0|92|0|158|0|
|GuestNetworkGuru|702|298|114|34|142|64|
|PrivateNetworkGuru|394|0|46|0|88|0|
|PublicNetworkGuru|341|0|42|0|77|0|
|LoadBalancingRulesManagerImpl|6024|0|666|0|1254|0|
|CommandSetupHelper|4086|0|300|0|769|0|
|NetworkHelperImpl|2092|0|278|0|445|0|
|VirtualNetworkApplianceManagerImpl|7767|0|792|0|1544|0|
|RulesManagerImpl|4074|0|492|0|790|0|
|NetworkACLManagerImpl|861|0|118|0|182|0|
|NetworkACLServiceImpl|2701|0|304|0|520|0|
|VpcManagerImpl|6936|0|770|0|1321|0|
|Site2SiteVpnManagerImpl|2298|0|214|0|468|0|
|ResourceManagerImpl|8524|0|982|0|1659|0|
|RollingMaintenanceManagerImpl|2041|0|192|0|363|0|
|ResourceIconManagerImpl|328|0|36|0|70|0|
|ConfigurationServerImpl|2061|0|176|0|495|0|
|ManagementServerImpl|12197|0|1076|0|2428|0|
|StatsCollector|2178|0|124|0|359|0|
|StorageManagerImpl|8580|0|976|0|1710|0|
|VolumeApiServiceImpl|11155|0|1516|0|2077|0|
|SnapshotManagerImpl|4195|0|410|0|753|0|
|SnapshotSchedulerImpl|871|0|81|0|197|0|
|ResourceManagerUtilImpl|356|0|24|0|71|0|
|TaggedResourceManagerImpl|473|0|58|0|96|0|
|TemplateManagerImpl|5011|0|696|0|1045|0|
|AccountManagerImpl|6460|0|906|0|1352|0|
|UserVmManagerImpl|20798|0|2566|0|3869|0|
|VMSnapshotManagerImpl|3151|0|296|0|628|0|
|RoleManagerImpl|737|0|114|0|147|0|
|AffinityGroupServiceImpl|791|0|112|0|172|0|
|AnnotationManagerImpl|1401|0|167|0|284|0|
|BackupManagerImpl|2779|0|224|0|489|0|
|CAManagerImpl|633|0|80|0|129|0|
|DirectDownloadManagerImpl|1684|0|186|0|361|0|
|HAManagerImpl|1391|0|194|0|231|0|
|BasicNetworkVisitor|535|0|28|0|112|0|
|OutOfBandManagementServiceImpl|1182|0|130|0|237|0|
|PowerOperationTask|109|0|0|0|17|0|
|MockNetworkManagerImpl|510|0|24|0|88|0|
|PremiumSecondaryStorageManagerImpl|775|0|64|0|116|0|
|SecondaryStorageManagerImpl|3544|149|343|11|629|32|
|VirtualMachineMO|8953|135|1063|17|1982|31|
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1106589911
Packaging result: :heavy_check_mark: el7 :heavy_check_mark: el8 :heavy_check_mark: debian :heavy_check_mark: suse15. SL-JID 3279
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] sonarcloud[bot] commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123591847
SonarCloud Quality Gate failed. [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=apache_cloudstack&pullRequest=6307)
[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [![C](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/C-16px.png 'C')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [1 Bug](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG)
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY)
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT)
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [3 Code Smells](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1109447628
@acs-robot a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1109445175
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1109452479
UI build: :heavy_check_mark:
Live QA URL: http://qa.cloudstack.cloud:8080/client/pr/6307 (SL-JID-1471)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1108645471
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1109450599
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] nvazquez commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
nvazquez commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1150123033
@blueorangutan package
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1151742816
<b>Trillian test result (tid-4317)</b>
Environment: kvm-centos7 (x2), Advanced Networking with Mgmt server 7
Total time taken: 36288 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr6307-t4317-kvm-centos7.zip
Smoke tests completed. 98 look OK, 0 have errors
Only failed tests results shown below:
Test | Result | Time (s) | Test File
--- | --- | --- | ---
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1117151834
@nvazquez a Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1106813866
Yes @weizhouapache , there rest is refactoring and traces to make the code more understandable. And there is a little fix to remove a redundant variable as well.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] GutoVeronezi commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
GutoVeronezi commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r856512085
##########
engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java:
##########
@@ -169,25 +175,57 @@ protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, L
@Override
public List<StoragePool> reorderPools(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan, DiskProfile dskCh) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("reordering pools");
+ }
if (pools == null) {
return null;
}
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering %d pools", pools.size()));
+ }
Account account = null;
if (vmProfile.getVirtualMachine() != null) {
account = vmProfile.getOwner();
}
if (allocationAlgorithm.equals("random") || allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) {
- // Shuffle this so that we don't check the pools in the same order.
- Collections.shuffle(pools);
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("Shuffle this so that we don't check the pools in the same order. Algorithm == '%s' (or no account?)",allocationAlgorithm));
+ StringBuilder pooltable = new StringBuilder();
+ pooltable.append("pools to choose from: ");
+ int i = 1;
+ for (StoragePool pool : pools) {
+ pooltable.append("\nno ").append(i).append(": ").append(pool.getName()).append("/").append(pool.getUuid());
+ }
+ s_logger.trace(pooltable.toString());
+ }
+ Collections.shuffle(pools, secureRandom);
+ if (s_logger.isTraceEnabled()) {
+ StringBuilder pooltable = new StringBuilder();
+ pooltable.append("shuffled list of pools to choose from: ");
+ int i = 1;
+ for (StoragePool pool : pools) {
+ pooltable.append("\nno ").append(i).append(": ").append(pool.getName()).append("/").append(pool.getUuid());
+ }
+ s_logger.trace(pooltable.toString());
+ }
} else if (allocationAlgorithm.equals("userdispersing")) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering: Algorithm == '%s'",allocationAlgorithm));
+ }
pools = reorderPoolsByNumberOfVolumes(plan, pools, account);
} else if(allocationAlgorithm.equals("firstfitleastconsumed")){
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering: Algorithm == '%s'",allocationAlgorithm));
+ }
pools = reorderPoolsByCapacity(plan, pools);
Review Comment:
These two blocks could be unified.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123663760
@acs-robot a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123529796
@acs-robot a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123528770
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1109492357
## PR Coverage Report
|**CLASS**|**INSTRUCTION MISSED**|**INSTRUCTION COVERED**|**BRANCH MISSED**|**BRANCH COVERED**|**LINE MISSED**|**LINE COVERED**|
|-----|-----|-----|-----|-----|-----|-----|
||
||
||
||
||
||
||
||
||
||
|Network|554|0|42|0|107|0|
||
||
||
||
||
||
||
||
||
|Volume|109|0|2|0|44|0|
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
|VirtualMachineGuru|78|0|4|0|15|0|
|NetworkOrchestrationService|0|101|0|0|0|10|
||
||
||
|AlertManager|79|0|0|0|7|0|
||
||
|StorageUtil|203|0|44|0|56|0|
|ClusteredAgentManagerImpl|2361|0|242|0|536|0|
|ConnectedAgentAttache|149|0|20|0|40|0|
|VirtualMachineManagerImpl|15659|0|1500|0|3079|0|
|NetworkOrchestrator|9910|0|1224|0|1945|0|
|VolumeOrchestrator|5236|0|566|0|984|0|
|CapacityVO|261|0|0|0|80|0|
|DataCenterVnetVO|58|0|0|0|24|0|
|VlanVO|186|0|2|0|72|0|
||
|VlanDaoImpl|1307|0|54|0|218|0|
|EventVO|140|0|0|0|58|0|
||
|HostDaoImpl|4983|0|180|0|803|0|
|AccountGuestVlanMapVO|46|0|0|0|19|0|
||
|NetworkDetailsDaoImpl|30|0|4|0|5|0|
|NetworkVO|396|159|19|1|140|44|
||
|VpcOfferingDaoImpl|137|0|0|0|25|0|
||
|VpcOfferingDetailsDaoImpl|173|0|10|0|31|0|
|NetworkOfferingVO|414|31|0|0|126|12|
||
|NetworkOfferingDaoImpl|691|0|22|0|114|0|
|VolumeVO|529|133|4|0|179|39|
|SystemVmTemplateRegistration|1773|0|86|0|376|0|
|Upgrade41520to41600|262|17|16|0|62|5|
|Upgrade41610to41700|159|7|6|0|43|2|
|DomainRouterVO|116|50|0|0|41|14|
|ConsoleProxyDaoImpl|635|0|20|0|144|0|
||
|DomainRouterDaoImpl|1600|0|22|0|228|0|
||
|NicDaoImpl|1392|0|12|0|193|0|
||
|SnapshotObject|748|30|64|0|151|11|
|DefaultVMSnapshotStrategy|486|677|52|30|100|140|
|AbstractStoragePoolAllocator|784|0|150|0|163|0|
|VolumeObject|773|665|77|39|178|117|
||
||
||
||
||
||
||
|CloudStackContextLoaderListener|77|0|2|0|21|0|
|LibvirtComputingResource|8888|1988|1087|147|1983|451|
|LibvirtVMDef|37|114|6|4|11|36|
|LibvirtStartCommandWrapper|75|295|16|22|15|72|
||
||
|MockNetworkManagerImpl|510|0|24|0|88|0|
|SimulatorManagerImpl|1394|0|214|0|309|0|
|VmwareManagerImpl|2613|528|296|38|615|117|
|VmwareResource|20395|0|2274|0|4397|0|
|VmwareStorageProcessor|9892|9|940|0|2122|2|
|CitrixResourceBase|14658|557|1456|34|3169|122|
|CitrixCheckSshCommandWrapper|15|51|3|3|3|14|
|CitrixNetworkElementCommandWrapper|0|14|0|0|0|4|
|CitrixRebootRouterCommandWrapper|28|25|3|1|5|7|
|CitrixStartCommandWrapper|690|62|81|1|116|16|
|KubernetesClusterManagerImpl|4724|0|480|0|760|0|
|KubernetesClusterActionWorker|1540|0|114|0|281|0|
|KubernetesClusterResourceModifierActionWorker|1843|0|140|0|325|0|
|CreateKubernetesClusterCmd|215|0|18|0|61|0|
||
|MetricsServiceImpl|2130|0|134|0|446|0|
|ClusterMetricsResponse|523|0|132|0|60|0|
|VmMetricsResponse|142|0|22|0|25|0|
|VolumeMetricsResponse|69|0|8|0|10|0|
|ZoneMetricsResponse|501|0|126|0|56|0|
||
|BigSwitchBcfGuestNetworkGuru|662|0|62|0|145|0|
|CreateServiceInstanceCmd|201|0|16|0|45|0|
|ContrailManagerImpl|2218|0|234|0|497|0|
|StopNetScalerVMCmd|114|0|12|0|26|0|
|NetScalerControlCenterResource|1943|0|144|0|468|0|
|NetscalerResource|6882|0|806|0|1623|0|
|OvsGuestNetworkGuru|409|0|48|0|90|0|
|VxlanGuestNetworkGuru|89|180|11|21|16|39|
||
|DateraPrimaryDataStoreDriver|3195|0|283|0|748|0|
|CloudStackPrimaryDataStoreDriverImpl|903|0|114|0|229|0|
|LinstorPrimaryDataStoreDriverImpl|1442|0|91|0|348|0|
||
||
|ScaleIOPrimaryDataStoreDriver|2537|0|246|0|537|0|
|SolidFirePrimaryDataStoreDriver|3347|0|284|0|697|0|
|LinkAccountToLdapCmd|77|105|6|4|18|23|
|ListAndSwitchSAMLAccountCmd|182|205|30|22|38|34|
|SAMLUtils|202|465|41|11|53|108|
||
||
|DomainChecker|1206|0|300|0|238|0|
|AlertManagerImpl|2133|0|183|0|418|0|
|ApiAsyncJobDispatcher|212|0|12|0|53|0|
|ApiDBUtils|2374|0|210|0|592|0|
|ApiDispatcher|231|0|42|0|55|0|
|ApiResponseHelper|12400|0|1292|0|2837|0|
|ApiServer|2868|112|346|0|672|14|
|ResponseObjectTypeAdapter|161|8|14|0|37|2|
|ParamProcessWorker|1050|0|155|0|241|0|
|QueryManagerImpl|14429|0|1270|0|2439|0|
|DomainRouterJoinDaoImpl|801|0|80|0|195|0|
|NetworkOfferingJoinDaoImpl|278|0|12|0|57|0|
|VolumeJoinDaoImpl|770|0|94|0|171|0|
|VpcOfferingJoinDaoImpl|172|0|6|0|36|0|
|AsyncJobJoinVO|86|0|0|0|31|0|
|DomainRouterJoinVO|237|0|0|0|80|0|
|EventJoinVO|100|0|0|0|35|0|
|NetworkOfferingJoinVO|219|0|0|0|79|0|
|VolumeJoinVO|267|0|0|0|93|0|
|VpcOfferingJoinVO|120|0|0|0|37|0|
|ConfigurationManagerImpl|18652|0|3092|0|3639|0|
|ConsoleProxyManagerImpl|3717|0|423|0|726|0|
|ActionEventInterceptor|398|19|44|2|90|7|
|ActionEventUtils|929|0|90|0|198|0|
|EventJoinDaoImpl|329|0|18|0|58|0|
|HypervisorGuruBase|669|38|52|0|133|5|
|LibvirtServerDiscoverer|994|0|116|0|218|0|
|ExternalFirewallDeviceManagerImpl|1885|0|198|0|381|0|
|ExternalLoadBalancerDeviceManagerImpl|2591|0|288|0|593|0|
|IpAddressManagerImpl|4084|0|463|0|814|0|
|Ipv6AddressManagerImpl|371|0|32|0|70|0|
|NetworkMigrationManagerImpl|1706|0|90|0|355|0|
|NetworkModelImpl|6182|0|838|0|1300|0|
|NetworkServiceImpl|13648|0|1902|0|2613|0|
|FirewallManagerImpl|2600|0|399|0|466|0|
|ExternalGuestNetworkGuru|849|0|92|0|158|0|
|GuestNetworkGuru|702|298|114|34|142|64|
|PrivateNetworkGuru|394|0|46|0|88|0|
|PublicNetworkGuru|341|0|42|0|77|0|
|LoadBalancingRulesManagerImpl|6024|0|666|0|1254|0|
|CommandSetupHelper|4088|0|300|0|771|0|
||
|NetworkHelperImpl|2092|0|278|0|445|0|
|VirtualNetworkApplianceManagerImpl|7767|0|792|0|1544|0|
|RulesManagerImpl|4074|0|492|0|790|0|
|NetworkACLManagerImpl|861|0|118|0|182|0|
|NetworkACLServiceImpl|2701|0|304|0|520|0|
|VpcManagerImpl|6936|0|770|0|1321|0|
|Site2SiteVpnManagerImpl|2298|0|214|0|468|0|
|ResourceManagerImpl|8524|0|982|0|1659|0|
|RollingMaintenanceManagerImpl|2041|0|192|0|363|0|
|ResourceIconManagerImpl|328|0|36|0|70|0|
|ConfigurationServerImpl|2061|0|176|0|495|0|
||
|ManagementServerImpl|12197|0|1076|0|2428|0|
|StatsCollector|2178|0|124|0|359|0|
|StorageManagerImpl|8580|0|976|0|1710|0|
|VolumeApiServiceImpl|11155|0|1516|0|2077|0|
|SnapshotManagerImpl|4195|0|410|0|753|0|
|SnapshotSchedulerImpl|871|0|81|0|197|0|
|ResourceManagerUtilImpl|356|0|24|0|71|0|
|TaggedResourceManagerImpl|473|0|58|0|96|0|
|TemplateManagerImpl|5011|0|696|0|1045|0|
|AccountManagerImpl|6460|0|906|0|1352|0|
|UserVmManagerImpl|20798|0|2566|0|3869|0|
|VMSnapshotManagerImpl|3151|0|296|0|628|0|
|RoleManagerImpl|737|0|114|0|147|0|
|AffinityGroupServiceImpl|791|0|112|0|172|0|
|AnnotationManagerImpl|1401|0|167|0|284|0|
|BackupManagerImpl|2779|0|224|0|489|0|
|CAManagerImpl|633|0|80|0|129|0|
|DirectDownloadManagerImpl|1684|0|186|0|361|0|
|HAManagerImpl|1391|0|194|0|231|0|
|BasicNetworkVisitor|535|0|28|0|112|0|
|OutOfBandManagementServiceImpl|1182|0|130|0|237|0|
|PowerOperationTask|109|0|0|0|17|0|
||
||
||
||
||
||
||
||
||
||
||
||
||
||
|MockNetworkManagerImpl|510|0|24|0|88|0|
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
|PremiumSecondaryStorageManagerImpl|775|0|64|0|116|0|
|SecondaryStorageManagerImpl|3544|149|343|11|629|32|
||
||
||
||
||
||
||
||
||
||
|VirtualMachineMO|8953|135|1063|17|1982|31|
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1108659051
UI build: :heavy_check_mark:
Live QA URL: http://qa.cloudstack.cloud:8080/client/pr/6307 (SL-JID-1467)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1109456319
UI build: :heavy_check_mark:
Live QA URL: http://qa.cloudstack.cloud:8080/client/pr/6307 (SL-JID-1472)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1144698773
@acs-robot a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1148307676
@blueorangutan package
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1148457507
Packaging result: :heavy_check_mark: el7 :heavy_check_mark: el8 :heavy_check_mark: debian :heavy_check_mark: suse15. SL-JID 3536
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] weizhouapache commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
weizhouapache commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1106811822
@DaanHoogland
from what I understand, the issue can be fixed by https://github.com/apache/cloudstack/pull/6307/commits/65d557ed62a2520d376ce8410e247257d331dcd6
in another word, by following change, right ?
```
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
index 41a8325558..237d016e97 100644
--- a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
@@ -17,6 +17,7 @@
package org.apache.cloudstack.storage.allocator;
import java.math.BigDecimal;
+import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -74,6 +75,11 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
@Inject private StorageUtil storageUtil;
@Inject private StoragePoolDetailsDao storagePoolDetailsDao;
+ /**
+ * make sure shuffled lists of Pools are really shuffled
+ */
+ private SecureRandom secureRandom = new SecureRandom();
+
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
super.configure(name, params);
@@ -179,7 +185,7 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
if (allocationAlgorithm.equals("random") || allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) {
// Shuffle this so that we don't check the pools in the same order.
- Collections.shuffle(pools);
+ Collections.shuffle(pools, secureRandom);
} else if (allocationAlgorithm.equals("userdispersing")) {
pools = reorderPoolsByNumberOfVolumes(plan, pools, account);
} else if(allocationAlgorithm.equals("firstfitleastconsumed")){
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1106593985
@nvazquez a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1144894664
@DaanHoogland a Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1150121879
Packaging result: :heavy_check_mark: el7 :heavy_check_mark: el8 :heavy_check_mark: debian :heavy_multiplication_x: suse15. SL-JID 3546
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] nvazquez commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
nvazquez commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1150045540
@blueorangutan package
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1148379862
@blueorangutan package
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123540060
UI build: :heavy_check_mark:
Live QA URL: http://qa.cloudstack.cloud:8080/client/pr/6307 (SL-JID-1549)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] sonarcloud[bot] commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123745436
SonarCloud Quality Gate failed. [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=apache_cloudstack&pullRequest=6307)
[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [![C](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/C-16px.png 'C')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [1 Bug](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG)
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY)
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT)
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [3 Code Smells](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123671132
UI build: :heavy_check_mark:
Live QA URL: http://qa.cloudstack.cloud:8080/client/pr/6307 (SL-JID-1550)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123939625
@DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r857528186
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ }
- StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ // if target VM has backups
+ if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ }
+ }
- // managed storage can be used for different types of hypervisors
- // only perform this check if the volume's storage pool is not null and not managed
- if (volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged()) {
- if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
- throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ /**
+ * If local storage is disabled then attaching a volume with a local diskoffering is not allowed
+ */
+ private void excludeLocalStorageIfNeeded(VolumeInfo volumeToAttach) {
+ DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
+ if (!dataCenter.isLocalStorageEnabled()) {
+ DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
+ if (diskOffering.isUseLocalStorage()) {
+ throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
}
}
+ }
- AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-
- if (asyncExecutionContext != null) {
- AsyncJob job = asyncExecutionContext.getJob();
+ /**
+ * Check that the number of data volumes attached to VM is less than the number that are supported by the hypervisor
+ */
+ private void checkNumberOfAttachedVolumes(Long deviceId, UserVmVO vm) {
+ if (deviceId == null || deviceId.longValue() != 0) {
Review Comment:
extra return statements ar a code smell I don´t want to introduce.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] nvazquez commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
nvazquez commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1106550519
@blueorangutan package
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1115825895
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1115865131
## PR Analysis
https://sonarcloud.io/summary/new_code?id=apachecloudstack&pullRequest=6307
## PR Coverage Report
|**CLASS**|**INSTRUCTION MISSED**|**INSTRUCTION COVERED**|**BRANCH MISSED**|**BRANCH COVERED**|**LINE MISSED**|**LINE COVERED**|
|-----|-----|-----|-----|-----|-----|-----|
|Network|554|0|42|0|107|0|
|Volume|109|0|2|0|44|0|
|VirtualMachineGuru|78|0|4|0|15|0|
|NetworkOrchestrationService|0|101|0|0|0|10|
|AlertManager|79|0|0|0|7|0|
|StorageUtil|203|0|44|0|56|0|
|ClusteredAgentManagerImpl|2361|0|242|0|536|0|
|ConnectedAgentAttache|149|0|20|0|40|0|
|VirtualMachineManagerImpl|15659|0|1500|0|3079|0|
|NetworkOrchestrator|9910|0|1224|0|1945|0|
|VolumeOrchestrator|5236|0|566|0|984|0|
|CapacityVO|261|0|0|0|80|0|
|DataCenterVnetVO|58|0|0|0|24|0|
|VlanVO|186|0|2|0|72|0|
|VlanDaoImpl|1307|0|54|0|218|0|
|EventVO|140|0|0|0|58|0|
|HostDaoImpl|4983|0|180|0|803|0|
|AccountGuestVlanMapVO|46|0|0|0|19|0|
|NetworkDetailsDaoImpl|30|0|4|0|5|0|
|NetworkVO|396|159|19|1|140|44|
|VpcOfferingDaoImpl|137|0|0|0|25|0|
|VpcOfferingDetailsDaoImpl|173|0|10|0|31|0|
|NetworkOfferingVO|414|31|0|0|126|12|
|NetworkOfferingDaoImpl|701|0|24|0|118|0|
|VolumeVO|529|133|4|0|179|39|
|SystemVmTemplateRegistration|1773|0|86|0|376|0|
|Upgrade41520to41600|262|17|16|0|62|5|
|Upgrade41610to41700|159|7|6|0|43|2|
|DomainRouterVO|116|50|0|0|41|14|
|ConsoleProxyDaoImpl|635|0|20|0|144|0|
|DomainRouterDaoImpl|1600|0|22|0|228|0|
|NicDaoImpl|1392|0|12|0|193|0|
|SnapshotObject|748|30|64|0|151|11|
|DefaultVMSnapshotStrategy|486|677|52|30|100|140|
|AbstractStoragePoolAllocator|784|0|150|0|163|0|
|VolumeObject|773|665|77|39|178|117|
|CloudStackContextLoaderListener|77|0|2|0|21|0|
|LibvirtComputingResource|8888|1988|1087|147|1983|451|
|LibvirtVMDef|37|114|6|4|11|36|
|LibvirtStartCommandWrapper|75|295|16|22|15|72|
|MockNetworkManagerImpl|510|0|24|0|88|0|
|SimulatorManagerImpl|1394|0|214|0|309|0|
|VmwareManagerImpl|2613|528|296|38|615|117|
|VmwareResource|20395|0|2274|0|4397|0|
|VmwareStorageLayoutHelper|1297|0|118|0|201|0|
|VmwareStorageProcessor|9892|9|940|0|2122|2|
|CitrixResourceBase|14658|557|1456|34|3169|122|
|CitrixCheckSshCommandWrapper|15|51|3|3|3|14|
|CitrixNetworkElementCommandWrapper|0|14|0|0|0|4|
|CitrixRebootRouterCommandWrapper|28|25|3|1|5|7|
|CitrixStartCommandWrapper|690|62|81|1|116|16|
|KubernetesClusterManagerImpl|4724|0|480|0|760|0|
|KubernetesClusterActionWorker|1540|0|114|0|281|0|
|KubernetesClusterResourceModifierActionWorker|1843|0|140|0|325|0|
|CreateKubernetesClusterCmd|215|0|18|0|61|0|
|MetricsServiceImpl|2130|0|134|0|446|0|
|ClusterMetricsResponse|523|0|132|0|60|0|
|VmMetricsResponse|142|0|22|0|25|0|
|VolumeMetricsResponse|69|0|8|0|10|0|
|ZoneMetricsResponse|501|0|126|0|56|0|
|BigSwitchBcfGuestNetworkGuru|662|0|62|0|145|0|
|CreateServiceInstanceCmd|201|0|16|0|45|0|
|ContrailManagerImpl|2218|0|234|0|497|0|
|StopNetScalerVMCmd|114|0|12|0|26|0|
|NetScalerControlCenterResource|1943|0|144|0|468|0|
|NetscalerResource|6882|0|806|0|1623|0|
|OvsGuestNetworkGuru|409|0|48|0|90|0|
|VxlanGuestNetworkGuru|89|180|11|21|16|39|
|DateraPrimaryDataStoreDriver|3195|0|283|0|748|0|
|CloudStackPrimaryDataStoreDriverImpl|903|0|114|0|229|0|
|LinstorPrimaryDataStoreDriverImpl|1442|0|91|0|348|0|
|ScaleIOPrimaryDataStoreDriver|2537|0|246|0|537|0|
|SolidFirePrimaryDataStoreDriver|3347|0|284|0|697|0|
|LinkAccountToLdapCmd|77|105|6|4|18|23|
|ListAndSwitchSAMLAccountCmd|182|205|30|22|38|34|
|SAMLUtils|202|465|41|11|53|108|
|DomainChecker|1206|0|300|0|238|0|
|AlertManagerImpl|2133|0|183|0|418|0|
|ApiAsyncJobDispatcher|212|0|12|0|53|0|
|ApiDBUtils|2374|0|210|0|592|0|
|ApiDispatcher|231|0|42|0|55|0|
|ApiResponseHelper|12401|0|1292|0|2837|0|
|ApiServer|2868|112|346|0|672|14|
|ResponseObjectTypeAdapter|161|8|14|0|37|2|
|ParamProcessWorker|1050|0|155|0|241|0|
|QueryManagerImpl|14429|0|1270|0|2439|0|
|DomainRouterJoinDaoImpl|801|0|80|0|195|0|
|NetworkOfferingJoinDaoImpl|286|0|14|0|60|0|
|VolumeJoinDaoImpl|770|0|94|0|171|0|
|VpcOfferingJoinDaoImpl|180|0|8|0|39|0|
|AsyncJobJoinVO|86|0|0|0|31|0|
|DomainRouterJoinVO|237|0|0|0|80|0|
|EventJoinVO|100|0|0|0|35|0|
|NetworkOfferingJoinVO|219|0|0|0|79|0|
|VolumeJoinVO|267|0|0|0|93|0|
|VpcOfferingJoinVO|120|0|0|0|37|0|
|ConfigurationManagerImpl|18652|0|3092|0|3639|0|
|ConsoleProxyManagerImpl|3717|0|423|0|726|0|
|ActionEventInterceptor|398|19|44|2|90|7|
|ActionEventUtils|929|0|90|0|198|0|
|EventJoinDaoImpl|333|0|18|0|58|0|
|HypervisorGuruBase|669|38|52|0|133|5|
|LibvirtServerDiscoverer|994|0|116|0|218|0|
|ExternalFirewallDeviceManagerImpl|1885|0|198|0|381|0|
|ExternalLoadBalancerDeviceManagerImpl|2591|0|288|0|593|0|
|IpAddressManagerImpl|4084|0|463|0|814|0|
|Ipv6AddressManagerImpl|371|0|32|0|70|0|
|NetworkMigrationManagerImpl|1706|0|90|0|355|0|
|NetworkModelImpl|6182|0|838|0|1300|0|
|NetworkServiceImpl|13648|0|1902|0|2613|0|
|FirewallManagerImpl|2600|0|399|0|466|0|
|ExternalGuestNetworkGuru|849|0|92|0|158|0|
|GuestNetworkGuru|702|298|114|34|142|64|
|PrivateNetworkGuru|394|0|46|0|88|0|
|PublicNetworkGuru|341|0|42|0|77|0|
|LoadBalancingRulesManagerImpl|6024|0|666|0|1254|0|
|CommandSetupHelper|4086|0|300|0|769|0|
|NetworkHelperImpl|2092|0|278|0|445|0|
|VirtualNetworkApplianceManagerImpl|7767|0|792|0|1544|0|
|RulesManagerImpl|4074|0|492|0|790|0|
|NetworkACLManagerImpl|861|0|118|0|182|0|
|NetworkACLServiceImpl|2701|0|304|0|520|0|
|VpcManagerImpl|6936|0|770|0|1321|0|
|Site2SiteVpnManagerImpl|2298|0|214|0|468|0|
|ResourceManagerImpl|8524|0|982|0|1659|0|
|RollingMaintenanceManagerImpl|2041|0|192|0|363|0|
|ResourceIconManagerImpl|328|0|36|0|70|0|
|ConfigurationServerImpl|2061|0|176|0|495|0|
|ManagementServerImpl|12197|0|1076|0|2428|0|
|StatsCollector|2178|0|124|0|359|0|
|StorageManagerImpl|8580|0|976|0|1710|0|
|VolumeApiServiceImpl|11155|0|1516|0|2077|0|
|SnapshotManagerImpl|4195|0|410|0|753|0|
|SnapshotSchedulerImpl|871|0|81|0|197|0|
|ResourceManagerUtilImpl|356|0|24|0|71|0|
|TaggedResourceManagerImpl|473|0|58|0|96|0|
|TemplateManagerImpl|5011|0|696|0|1045|0|
|AccountManagerImpl|6460|0|906|0|1352|0|
|UserVmManagerImpl|20798|0|2566|0|3869|0|
|VMSnapshotManagerImpl|3151|0|296|0|628|0|
|RoleManagerImpl|737|0|114|0|147|0|
|AffinityGroupServiceImpl|791|0|112|0|172|0|
|AnnotationManagerImpl|1401|0|167|0|284|0|
|BackupManagerImpl|2779|0|224|0|489|0|
|CAManagerImpl|633|0|80|0|129|0|
|DirectDownloadManagerImpl|1684|0|186|0|361|0|
|HAManagerImpl|1391|0|194|0|231|0|
|BasicNetworkVisitor|535|0|28|0|112|0|
|OutOfBandManagementServiceImpl|1182|0|130|0|237|0|
|PowerOperationTask|109|0|0|0|17|0|
|MockNetworkManagerImpl|510|0|24|0|88|0|
|PremiumSecondaryStorageManagerImpl|775|0|64|0|116|0|
|SecondaryStorageManagerImpl|3544|149|343|11|629|32|
|VirtualMachineMO|8953|135|1063|17|1982|31|
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r857545840
##########
engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java:
##########
@@ -169,25 +175,57 @@ protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, L
@Override
public List<StoragePool> reorderPools(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan, DiskProfile dskCh) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("reordering pools");
+ }
if (pools == null) {
return null;
}
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering %d pools", pools.size()));
+ }
Account account = null;
if (vmProfile.getVirtualMachine() != null) {
account = vmProfile.getOwner();
}
if (allocationAlgorithm.equals("random") || allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) {
- // Shuffle this so that we don't check the pools in the same order.
- Collections.shuffle(pools);
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("Shuffle this so that we don't check the pools in the same order. Algorithm == '%s' (or no account?)",allocationAlgorithm));
+ StringBuilder pooltable = new StringBuilder();
+ pooltable.append("pools to choose from: ");
+ int i = 1;
+ for (StoragePool pool : pools) {
+ pooltable.append("\nno ").append(i).append(": ").append(pool.getName()).append("/").append(pool.getUuid());
+ }
+ s_logger.trace(pooltable.toString());
Review Comment:
moving it to StorageUtil
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1108701740
## PR Coverage Report
|**CLASS**|**INSTRUCTION MISSED**|**INSTRUCTION COVERED**|**BRANCH MISSED**|**BRANCH COVERED**|**LINE MISSED**|**LINE COVERED**|
|-----|-----|-----|-----|-----|-----|-----|
||
||
||
||
||
||
|Network|554|0|42|0|107|0|
||
||
||
||
||
||
||
|Volume|109|0|2|0|44|0|
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
|VirtualMachineGuru|78|0|4|0|15|0|
|NetworkOrchestrationService|0|101|0|0|0|10|
||
||
||
|StorageUtil|203|0|44|0|56|0|
|ClusteredAgentManagerImpl|2361|0|242|0|536|0|
|ConnectedAgentAttache|149|0|20|0|40|0|
|VirtualMachineManagerImpl|15659|0|1500|0|3079|0|
|NetworkOrchestrator|9806|0|1206|0|1928|0|
|VolumeOrchestrator|5236|0|566|0|984|0|
|DataCenterVnetVO|58|0|0|0|24|0|
|VlanVO|186|0|2|0|72|0|
|EventVO|140|0|0|0|58|0|
||
|HostDaoImpl|4983|0|180|0|803|0|
|AccountGuestVlanMapVO|46|0|0|0|19|0|
|NetworkOfferingVO|414|31|0|0|126|12|
|VolumeVO|529|133|4|0|179|39|
|SystemVmTemplateRegistration|1773|0|86|0|376|0|
|Upgrade41520to41600|262|17|16|0|62|5|
|Upgrade41610to41700|159|7|6|0|43|2|
|DomainRouterVO|116|50|0|0|41|14|
|ConsoleProxyDaoImpl|635|0|20|0|144|0|
||
|DomainRouterDaoImpl|1600|0|22|0|228|0|
||
|SnapshotObject|748|30|64|0|151|11|
|DefaultVMSnapshotStrategy|486|677|52|30|100|140|
|AbstractStoragePoolAllocator|784|0|150|0|163|0|
|VolumeObject|773|665|77|39|178|117|
||
||
||
||
||
||
||
|CloudStackContextLoaderListener|77|0|2|0|21|0|
|LibvirtComputingResource|8888|1988|1087|147|1983|451|
|LibvirtVMDef|37|114|6|4|11|36|
|LibvirtStartCommandWrapper|75|295|16|22|15|72|
||
|VmwareManagerImpl|2613|528|296|38|615|117|
|VmwareResource|20395|0|2274|0|4397|0|
|VmwareStorageProcessor|9892|9|940|0|2122|2|
|CitrixResourceBase|14658|557|1456|34|3169|122|
|CitrixCheckSshCommandWrapper|15|51|3|3|3|14|
|CitrixNetworkElementCommandWrapper|0|14|0|0|0|4|
|CitrixRebootRouterCommandWrapper|28|25|3|1|5|7|
|CitrixStartCommandWrapper|690|62|81|1|116|16|
|KubernetesClusterManagerImpl|4724|0|480|0|760|0|
|KubernetesClusterActionWorker|1540|0|114|0|281|0|
|KubernetesClusterResourceModifierActionWorker|1843|0|140|0|325|0|
|CreateKubernetesClusterCmd|215|0|18|0|61|0|
||
|MetricsServiceImpl|2130|0|134|0|446|0|
|ClusterMetricsResponse|523|0|132|0|60|0|
|VmMetricsResponse|142|0|22|0|25|0|
|VolumeMetricsResponse|69|0|8|0|10|0|
|ZoneMetricsResponse|501|0|126|0|56|0|
||
|BigSwitchBcfGuestNetworkGuru|662|0|62|0|145|0|
|CreateServiceInstanceCmd|201|0|16|0|45|0|
|StopNetScalerVMCmd|114|0|12|0|26|0|
|NetScalerControlCenterResource|1943|0|144|0|468|0|
|NetscalerResource|6882|0|806|0|1623|0|
|OvsGuestNetworkGuru|409|0|48|0|90|0|
|VxlanGuestNetworkGuru|89|180|11|21|16|39|
||
|DateraPrimaryDataStoreDriver|3195|0|283|0|748|0|
|CloudStackPrimaryDataStoreDriverImpl|903|0|114|0|229|0|
|LinstorPrimaryDataStoreDriverImpl|1442|0|91|0|348|0|
||
||
|ScaleIOPrimaryDataStoreDriver|2537|0|246|0|537|0|
|SolidFirePrimaryDataStoreDriver|3347|0|284|0|697|0|
|LinkAccountToLdapCmd|77|105|6|4|18|23|
|ListAndSwitchSAMLAccountCmd|182|205|30|22|38|34|
|SAMLUtils|202|465|41|11|53|108|
||
||
|DomainChecker|1206|0|300|0|238|0|
|ApiAsyncJobDispatcher|212|0|12|0|53|0|
|ApiDBUtils|2374|0|210|0|592|0|
|ApiDispatcher|231|0|42|0|55|0|
|ApiResponseHelper|12147|0|1276|0|2779|0|
|ApiServer|2868|112|346|0|672|14|
|ResponseObjectTypeAdapter|161|8|14|0|37|2|
|ParamProcessWorker|1050|0|155|0|241|0|
|QueryManagerImpl|14429|0|1270|0|2439|0|
|DomainRouterJoinDaoImpl|801|0|80|0|195|0|
|VolumeJoinDaoImpl|770|0|94|0|171|0|
|AsyncJobJoinVO|86|0|0|0|31|0|
|DomainRouterJoinVO|237|0|0|0|80|0|
|EventJoinVO|100|0|0|0|35|0|
|VolumeJoinVO|267|0|0|0|93|0|
|ConfigurationManagerImpl|18122|0|3032|0|3573|0|
|ConsoleProxyManagerImpl|3717|0|423|0|726|0|
|ActionEventInterceptor|398|19|44|2|90|7|
|ActionEventUtils|929|0|90|0|198|0|
|EventJoinDaoImpl|329|0|18|0|58|0|
|LibvirtServerDiscoverer|994|0|116|0|218|0|
|IpAddressManagerImpl|4049|0|461|0|807|0|
|NetworkModelImpl|6182|0|838|0|1300|0|
|NetworkServiceImpl|13401|0|1868|0|2557|0|
|FirewallManagerImpl|2522|0|391|0|455|0|
|ExternalGuestNetworkGuru|810|0|78|0|148|0|
|GuestNetworkGuru|632|298|98|34|125|64|
|PrivateNetworkGuru|394|0|46|0|88|0|
|LoadBalancingRulesManagerImpl|6024|0|666|0|1254|0|
||
|NetworkHelperImpl|2080|0|276|0|443|0|
|VirtualNetworkApplianceManagerImpl|7600|0|780|0|1521|0|
|RulesManagerImpl|4074|0|492|0|790|0|
|NetworkACLManagerImpl|841|0|114|0|176|0|
|VpcManagerImpl|6893|0|762|0|1316|0|
|Site2SiteVpnManagerImpl|2298|0|214|0|468|0|
|ResourceManagerImpl|8524|0|982|0|1659|0|
|RollingMaintenanceManagerImpl|2041|0|192|0|363|0|
|ResourceIconManagerImpl|328|0|36|0|70|0|
|ConfigurationServerImpl|2061|0|176|0|495|0|
||
|ManagementServerImpl|12197|0|1076|0|2428|0|
|StatsCollector|2178|0|124|0|359|0|
|StorageManagerImpl|8580|0|976|0|1710|0|
|VolumeApiServiceImpl|11092|0|1516|0|2076|0|
|SnapshotManagerImpl|4195|0|410|0|753|0|
|SnapshotSchedulerImpl|871|0|81|0|197|0|
|ResourceManagerUtilImpl|356|0|24|0|71|0|
|TaggedResourceManagerImpl|473|0|58|0|96|0|
|TemplateManagerImpl|5011|0|696|0|1045|0|
|AccountManagerImpl|6460|0|906|0|1352|0|
|UserVmManagerImpl|20798|0|2566|0|3869|0|
|VMSnapshotManagerImpl|3151|0|296|0|628|0|
|RoleManagerImpl|737|0|114|0|147|0|
|AffinityGroupServiceImpl|791|0|112|0|172|0|
|AnnotationManagerImpl|1401|0|167|0|284|0|
|BackupManagerImpl|2779|0|224|0|489|0|
|CAManagerImpl|633|0|80|0|129|0|
|DirectDownloadManagerImpl|1684|0|186|0|361|0|
|HAManagerImpl|1391|0|194|0|231|0|
|OutOfBandManagementServiceImpl|1182|0|130|0|237|0|
|PowerOperationTask|109|0|0|0|17|0|
||
||
||
||
||
||
||
||
||
||
||
||
|MockNetworkManagerImpl|485|0|22|0|83|0|
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
|PremiumSecondaryStorageManagerImpl|775|0|64|0|116|0|
|SecondaryStorageManagerImpl|3544|149|343|11|629|32|
||
||
||
||
||
||
||
||
||
|VirtualMachineMO|8953|135|1063|17|1982|31|
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1144908505
@DaanHoogland a Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1144907648
@blueorangutan package
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1144704495
UI build: :heavy_check_mark:
Live QA URL: http://qa.cloudstack.cloud:8080/client/pr/6307 (SL-JID-1663)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1148308751
@acs-robot a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] sonarcloud[bot] commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1148379623
SonarCloud Quality Gate failed. [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=apache_cloudstack&pullRequest=6307)
[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [![B](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/B-16px.png 'B')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [1 Bug](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG)
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY)
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT)
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL)
[![17.5%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '17.5%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list) [17.5% Coverage](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r871112941
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2497,7 +2573,7 @@ public Volume detachVolumeFromVM(DetachVolumeCmd cmmd) {
AsyncJob job = asyncExecutionContext.getJob();
if (s_logger.isInfoEnabled()) {
- s_logger.info("Trying to attaching volume " + volumeId + "to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
+ s_logger.info(String.format("Trying to attach volume [%s/%s] to VM instance [%s/%s], update async job-%s progress status", volume.getName(), volume.getUuid(), vm.getName(), vm.getUuid(), job.getId()));
Review Comment:
changed it, please have a look if this is what you mean, @GutoVeronezi ?
it seems a bit over the top to me, if I may say so myself.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] rohityadavcloud closed pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
rohityadavcloud closed pull request #6307: fix pseudo random behaviour in pool selection
URL: https://github.com/apache/cloudstack/pull/6307
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] sonarcloud[bot] commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1117430421
SonarCloud Quality Gate failed. [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=apache_cloudstack&pullRequest=6307)
[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [![C](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/C-16px.png 'C')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [1 Bug](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG)
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY)
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT)
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [3 Code Smells](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1113190158
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] sureshanaparti commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r870139824
##########
engine/components-api/src/main/java/com/cloud/storage/StorageUtil.java:
##########
@@ -33,13 +33,27 @@
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.VMInstanceDao;
+import org.apache.log4j.Logger;
+
public class StorageUtil {
@Inject private ClusterDao clusterDao;
@Inject private HostDao hostDao;
@Inject private PrimaryDataStoreDao storagePoolDao;
@Inject private VMInstanceDao vmInstanceDao;
@Inject private VolumeDao volumeDao;
+ public static void traceLogStoragePools(List<StoragePool> poolList, Logger logger, String initialMessage) {
+ if (logger.isTraceEnabled()) {
Review Comment:
```suggestion
if (!logger.isTraceEnabled()) {
return
}
```
##########
engine/components-api/src/main/java/com/cloud/storage/StorageUtil.java:
##########
@@ -33,13 +33,27 @@
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.VMInstanceDao;
+import org.apache.log4j.Logger;
+
public class StorageUtil {
@Inject private ClusterDao clusterDao;
@Inject private HostDao hostDao;
@Inject private PrimaryDataStoreDao storagePoolDao;
@Inject private VMInstanceDao vmInstanceDao;
@Inject private VolumeDao volumeDao;
+ public static void traceLogStoragePools(List<StoragePool> poolList, Logger logger, String initialMessage) {
+ if (logger.isTraceEnabled()) {
Review Comment:
```suggestion
if (!logger.isTraceEnabled()) {
return;
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123679470
@DaanHoogland a Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123678378
@blueorangutan package
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] sonarcloud[bot] commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1124681881
SonarCloud Quality Gate failed. [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=apache_cloudstack&pullRequest=6307)
[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [![C](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/C-16px.png 'C')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [1 Bug](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG)
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY)
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT)
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [3 Code Smells](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1108652919
@acs-robot a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] GutoVeronezi commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
GutoVeronezi commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r856508992
##########
engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java:
##########
@@ -169,25 +175,57 @@ protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, L
@Override
public List<StoragePool> reorderPools(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan, DiskProfile dskCh) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("reordering pools");
+ }
if (pools == null) {
return null;
}
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering %d pools", pools.size()));
+ }
Account account = null;
if (vmProfile.getVirtualMachine() != null) {
account = vmProfile.getOwner();
}
if (allocationAlgorithm.equals("random") || allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) {
- // Shuffle this so that we don't check the pools in the same order.
- Collections.shuffle(pools);
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("Shuffle this so that we don't check the pools in the same order. Algorithm == '%s' (or no account?)",allocationAlgorithm));
+ StringBuilder pooltable = new StringBuilder();
+ pooltable.append("pools to choose from: ");
+ int i = 1;
+ for (StoragePool pool : pools) {
+ pooltable.append("\nno ").append(i).append(": ").append(pool.getName()).append("/").append(pool.getUuid());
+ }
+ s_logger.trace(pooltable.toString());
Review Comment:
This code is repeated twice in this class and once in VolumeOrchestrator. We could extract it to a method in a helper, for example.
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
Review Comment:
```suggestion
s_logger.info(String.format("Trying to attach volume [%s] to VM instance [%s], update async job-%s progress status", volumeId, vm.getId(), job.getId()));
```
We can log the UUID (and maybe the name) of the volume and VM instead of the ID to facilitate the troubleshooting by the operator.
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
Review Comment:
It would be interesting to add some context to the log, like which volume could not be attached and which VM has VM snapshots.
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ }
- StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ // if target VM has backups
+ if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ }
+ }
- // managed storage can be used for different types of hypervisors
- // only perform this check if the volume's storage pool is not null and not managed
- if (volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged()) {
- if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
- throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ /**
+ * If local storage is disabled then attaching a volume with a local diskoffering is not allowed
+ */
+ private void excludeLocalStorageIfNeeded(VolumeInfo volumeToAttach) {
+ DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
+ if (!dataCenter.isLocalStorageEnabled()) {
+ DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
+ if (diskOffering.isUseLocalStorage()) {
+ throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
}
}
+ }
- AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-
- if (asyncExecutionContext != null) {
- AsyncJob job = asyncExecutionContext.getJob();
+ /**
+ * Check that the number of data volumes attached to VM is less than the number that are supported by the hypervisor
+ */
+ private void checkNumberOfAttachedVolumes(Long deviceId, UserVmVO vm) {
+ if (deviceId == null || deviceId.longValue() != 0) {
Review Comment:
We can invert this if and add a return statement to reduce code indentation.
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ }
- StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ // if target VM has backups
+ if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ }
+ }
- // managed storage can be used for different types of hypervisors
- // only perform this check if the volume's storage pool is not null and not managed
- if (volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged()) {
- if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
- throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ /**
+ * If local storage is disabled then attaching a volume with a local diskoffering is not allowed
+ */
+ private void excludeLocalStorageIfNeeded(VolumeInfo volumeToAttach) {
+ DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
+ if (!dataCenter.isLocalStorageEnabled()) {
+ DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
+ if (diskOffering.isUseLocalStorage()) {
+ throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
}
}
+ }
- AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-
- if (asyncExecutionContext != null) {
- AsyncJob job = asyncExecutionContext.getJob();
+ /**
+ * Check that the number of data volumes attached to VM is less than the number that are supported by the hypervisor
+ */
+ private void checkNumberOfAttachedVolumes(Long deviceId, UserVmVO vm) {
+ if (deviceId == null || deviceId.longValue() != 0) {
+ List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.DATADISK);
+ int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
+ if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
+ throw new InvalidParameterValueException(
+ "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
+ }
+ }
+ }
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
+ private void checkDeviceId(Long deviceId, VolumeInfo volumeToAttach, UserVmVO vm) {
+ if (deviceId != null) {
+ // validate ROOT volume type
+ if (deviceId.longValue() == 0) {
Review Comment:
We can invert this if and add a return statement to reduce code indentation.
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ }
- StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ // if target VM has backups
+ if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
Review Comment:
It would be interesting to add some context to the log, like which volume could not be attached and which VM has backups.
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
Review Comment:
```suggestion
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(String.format("Could not get attach volume job result for VM [%s], volume[%s] and device [%s], due to [%s].", vmId, volumeId deviceId, e.getMessage()), e);
}
```
##########
engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java:
##########
@@ -169,25 +175,57 @@ protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, L
@Override
public List<StoragePool> reorderPools(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan, DiskProfile dskCh) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("reordering pools");
+ }
if (pools == null) {
return null;
}
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering %d pools", pools.size()));
+ }
Account account = null;
if (vmProfile.getVirtualMachine() != null) {
account = vmProfile.getOwner();
}
if (allocationAlgorithm.equals("random") || allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) {
- // Shuffle this so that we don't check the pools in the same order.
- Collections.shuffle(pools);
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("Shuffle this so that we don't check the pools in the same order. Algorithm == '%s' (or no account?)",allocationAlgorithm));
+ StringBuilder pooltable = new StringBuilder();
+ pooltable.append("pools to choose from: ");
+ int i = 1;
+ for (StoragePool pool : pools) {
+ pooltable.append("\nno ").append(i).append(": ").append(pool.getName()).append("/").append(pool.getUuid());
+ }
+ s_logger.trace(pooltable.toString());
+ }
+ Collections.shuffle(pools, secureRandom);
+ if (s_logger.isTraceEnabled()) {
+ StringBuilder pooltable = new StringBuilder();
+ pooltable.append("shuffled list of pools to choose from: ");
+ int i = 1;
+ for (StoragePool pool : pools) {
+ pooltable.append("\nno ").append(i).append(": ").append(pool.getName()).append("/").append(pool.getUuid());
+ }
+ s_logger.trace(pooltable.toString());
+ }
} else if (allocationAlgorithm.equals("userdispersing")) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering: Algorithm == '%s'",allocationAlgorithm));
+ }
pools = reorderPoolsByNumberOfVolumes(plan, pools, account);
} else if(allocationAlgorithm.equals("firstfitleastconsumed")){
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering: Algorithm == '%s'",allocationAlgorithm));
+ }
pools = reorderPoolsByCapacity(plan, pools);
Review Comment:
This two blocks could be unified.
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
Review Comment:
```suggestion
if (checkNeeded && volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
}
```
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ }
- StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ // if target VM has backups
+ if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
Review Comment:
We can use `CollectionUtils#isNotEmpty` here.
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ }
- StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ // if target VM has backups
+ if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ }
+ }
- // managed storage can be used for different types of hypervisors
- // only perform this check if the volume's storage pool is not null and not managed
- if (volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged()) {
- if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
- throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ /**
+ * If local storage is disabled then attaching a volume with a local diskoffering is not allowed
+ */
+ private void excludeLocalStorageIfNeeded(VolumeInfo volumeToAttach) {
+ DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
+ if (!dataCenter.isLocalStorageEnabled()) {
+ DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
+ if (diskOffering.isUseLocalStorage()) {
+ throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
}
}
+ }
- AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-
- if (asyncExecutionContext != null) {
- AsyncJob job = asyncExecutionContext.getJob();
+ /**
+ * Check that the number of data volumes attached to VM is less than the number that are supported by the hypervisor
+ */
+ private void checkNumberOfAttachedVolumes(Long deviceId, UserVmVO vm) {
+ if (deviceId == null || deviceId.longValue() != 0) {
+ List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.DATADISK);
+ int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
+ if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
+ throw new InvalidParameterValueException(
+ "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
+ }
+ }
+ }
- if (s_logger.isInfoEnabled()) {
- s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
+ private void checkDeviceId(Long deviceId, VolumeInfo volumeToAttach, UserVmVO vm) {
+ if (deviceId != null) {
Review Comment:
We can invert this if and add a return statement to reduce code indentation.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland closed pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland closed pull request #6307: fix pseudo random behaviour in pool selection
URL: https://github.com/apache/cloudstack/pull/6307
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] weizhouapache commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
weizhouapache commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1106832378
> Yes @weizhouapache , there rest is refactoring and traces to make the code more understandable. And there is a little fix to remove a redundant variable as well.
@DaanHoogland can you create a PR for the change, so we can merge next Monday (4.17.0.0 code freeze date) ?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1145772716
@blueorangutan test
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1144894351
@blueorangutan package
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1148459020
@blueorangutan test
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1151156088
@nvazquez a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1150177002
Packaging result: :heavy_check_mark: el7 :heavy_check_mark: el8 :heavy_check_mark: debian :heavy_check_mark: suse15. SL-JID 3547
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1113194115
UI build: :heavy_check_mark:
Live QA URL: http://qa.cloudstack.cloud:8080/client/pr/6307 (SL-JID-1497)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] sonarcloud[bot] commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
sonarcloud[bot] commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1117152880
SonarCloud Quality Gate failed. [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=apache_cloudstack&pullRequest=6307)
[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [![C](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/C-16px.png 'C')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG) [2 Bugs](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=BUG)
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=VULNERABILITY)
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_cloudstack&pullRequest=6307&resolved=false&types=SECURITY_HOTSPOT)
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL) [3 Code Smells](https://sonarcloud.io/project/issues?id=apache_cloudstack&pullRequest=6307&resolved=false&types=CODE_SMELL)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_coverage&view=list)
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=apache_cloudstack&pullRequest=6307&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1117179625
Packaging result: :heavy_check_mark: el7 :heavy_check_mark: el8 :heavy_check_mark: debian :heavy_check_mark: suse15. SL-JID 3349
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r857398503
##########
engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java:
##########
@@ -169,25 +175,57 @@ protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, L
@Override
public List<StoragePool> reorderPools(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan, DiskProfile dskCh) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("reordering pools");
+ }
if (pools == null) {
return null;
}
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering %d pools", pools.size()));
+ }
Account account = null;
if (vmProfile.getVirtualMachine() != null) {
account = vmProfile.getOwner();
}
if (allocationAlgorithm.equals("random") || allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) {
- // Shuffle this so that we don't check the pools in the same order.
- Collections.shuffle(pools);
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("Shuffle this so that we don't check the pools in the same order. Algorithm == '%s' (or no account?)",allocationAlgorithm));
+ StringBuilder pooltable = new StringBuilder();
+ pooltable.append("pools to choose from: ");
+ int i = 1;
+ for (StoragePool pool : pools) {
+ pooltable.append("\nno ").append(i).append(": ").append(pool.getName()).append("/").append(pool.getUuid());
+ }
+ s_logger.trace(pooltable.toString());
+ }
+ Collections.shuffle(pools, secureRandom);
+ if (s_logger.isTraceEnabled()) {
+ StringBuilder pooltable = new StringBuilder();
+ pooltable.append("shuffled list of pools to choose from: ");
+ int i = 1;
+ for (StoragePool pool : pools) {
+ pooltable.append("\nno ").append(i).append(": ").append(pool.getName()).append("/").append(pool.getUuid());
+ }
+ s_logger.trace(pooltable.toString());
+ }
} else if (allocationAlgorithm.equals("userdispersing")) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering: Algorithm == '%s'",allocationAlgorithm));
+ }
pools = reorderPoolsByNumberOfVolumes(plan, pools, account);
} else if(allocationAlgorithm.equals("firstfitleastconsumed")){
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering: Algorithm == '%s'",allocationAlgorithm));
+ }
pools = reorderPoolsByCapacity(plan, pools);
Review Comment:
I don´t see how, @GutoVeronezi . let me remove the unnecessary `String.format()`. Is this what you mean?
```suggestion
} else if (allocationAlgorithm.equals("userdispersing")) {
if (s_logger.isTraceEnabled()) {
s_logger.trace("reordering: Algorithm == ´userdispersing´");
}
pools = reorderPoolsByNumberOfVolumes(plan, pools, account);
} else if(allocationAlgorithm.equals("firstfitleastconsumed")){
if (s_logger.isTraceEnabled()) {
s_logger.trace("reordering: Algorithm == 'firstfitleastconsumed'"));
}
pools = reorderPoolsByCapacity(plan, pools);
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] GutoVeronezi commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
GutoVeronezi commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r862784314
##########
engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java:
##########
@@ -169,25 +175,57 @@ protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, L
@Override
public List<StoragePool> reorderPools(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan, DiskProfile dskCh) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("reordering pools");
+ }
if (pools == null) {
return null;
}
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering %d pools", pools.size()));
+ }
Account account = null;
if (vmProfile.getVirtualMachine() != null) {
account = vmProfile.getOwner();
}
if (allocationAlgorithm.equals("random") || allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) {
- // Shuffle this so that we don't check the pools in the same order.
- Collections.shuffle(pools);
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("Shuffle this so that we don't check the pools in the same order. Algorithm == '%s' (or no account?)",allocationAlgorithm));
+ StringBuilder pooltable = new StringBuilder();
+ pooltable.append("pools to choose from: ");
+ int i = 1;
+ for (StoragePool pool : pools) {
+ pooltable.append("\nno ").append(i).append(": ").append(pool.getName()).append("/").append(pool.getUuid());
+ }
+ s_logger.trace(pooltable.toString());
+ }
+ Collections.shuffle(pools, secureRandom);
+ if (s_logger.isTraceEnabled()) {
+ StringBuilder pooltable = new StringBuilder();
+ pooltable.append("shuffled list of pools to choose from: ");
+ int i = 1;
+ for (StoragePool pool : pools) {
+ pooltable.append("\nno ").append(i).append(": ").append(pool.getName()).append("/").append(pool.getUuid());
+ }
+ s_logger.trace(pooltable.toString());
+ }
} else if (allocationAlgorithm.equals("userdispersing")) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering: Algorithm == '%s'",allocationAlgorithm));
+ }
pools = reorderPoolsByNumberOfVolumes(plan, pools, account);
} else if(allocationAlgorithm.equals("firstfitleastconsumed")){
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace(String.format("reordering: Algorithm == '%s'",allocationAlgorithm));
+ }
pools = reorderPoolsByCapacity(plan, pools);
Review Comment:
@DaanHoogland, I mean something like this, to avoid multiple blocks repeating the same log:
```java
} else if (StringUtils.equalsAny(allocationAlgorithm, "userdispersing", "firstfitleastconsumed")) {
if (s_logger.isTraceEnabled()) {
s_logger.trace(String.format("Using reordering algorithm [%s]", allocationAlgorithm));
}
if (allocationAlgorithm.equals("userdispersing")) {
pools = reorderPoolsByNumberOfVolumes(plan, pools, account);
} else {
pools = reorderPoolsByCapacity(plan, pools);
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1115826171
@acs-robot a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1123730072
Packaging result: :heavy_check_mark: el7 :heavy_check_mark: el8 :heavy_check_mark: debian :heavy_check_mark: suse15. SL-JID 3387
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1145002401
Packaging result: :heavy_check_mark: el7 :heavy_check_mark: el8 :heavy_check_mark: debian :heavy_check_mark: suse15. SL-JID 3520
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1144698252
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1148308529
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1148459313
@DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1148380804
@DaanHoogland a Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] nvazquez commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
nvazquez commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1151155369
@blueorangutan test
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] blueorangutan commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
blueorangutan commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1150123606
@nvazquez a Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] DaanHoogland commented on a diff in pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on code in PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#discussion_r857524058
##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -2113,170 +2132,224 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
Account caller = CallContext.current().getCallingAccount();
- // Check that the volume ID is valid
- VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
- // Check that the volume is a data volume
- if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
- throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
- }
+ VolumeInfo volumeToAttach = getAndCheckVolumeInfo(volumeId);
- // Check that the volume is not currently attached to any VM
- if (volumeToAttach.getInstanceId() != null) {
- throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
- }
+ UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach);
- // Check that the volume is not destroyed
- if (volumeToAttach.getState() == Volume.State.Destroy) {
- throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
- }
+ checkDeviceId(deviceId, volumeToAttach, vm);
- // Check that the virtual machine ID is valid and it's a user vm
- UserVmVO vm = _userVmDao.findById(vmId);
- if (vm == null || vm.getType() != VirtualMachine.Type.User) {
- throw new InvalidParameterValueException("Please specify a valid User VM.");
- }
+ checkNumberOfAttachedVolumes(deviceId, vm);
- // Check that the VM is in the correct state
- if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
- throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
- }
+ excludeLocalStorageIfNeeded(volumeToAttach);
- // Check that the VM and the volume are in the same zone
- if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
- throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+ checkForDevicesInCopies(vmId, vm);
+
+ checkRightsToAttach(caller, volumeToAttach, vm);
+
+ HypervisorType rootDiskHyperType = vm.getHypervisorType();
+ HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+ StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ if (s_logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
+ s_logger.trace(String.format("volume to attach (%s/%s) has a primary storage assigned to begin with (%s/%s)",
+ volumeToAttach.getName(), volumeToAttach.getUuid(), volumeToAttachStoragePool.getName(), volumeToAttachStoragePool.getUuid()));
}
- // Check that the device ID is valid
- if (deviceId != null) {
- // validate ROOT volume type
- if (deviceId.longValue() == 0) {
- validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
- // vm shouldn't have any volume with deviceId 0
- if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
- throw new InvalidParameterValueException("Vm already has root volume attached to it");
- }
- // volume can't be in Uploaded state
- if (volumeToAttach.getState() == Volume.State.Uploaded) {
- throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
- }
+ checkForMatchinHypervisorTypesIf(volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged(), rootDiskHyperType, volumeToAttachHyperType);
+
+ AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+ if (asyncExecutionContext != null) {
+ AsyncJob job = asyncExecutionContext.getJob();
+
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
}
+
+ _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
}
- // Check that the number of data volumes attached to VM is less than
- // that supported by hypervisor
- if (deviceId == null || deviceId.longValue() != 0) {
- List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
- int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
- if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
- throw new InvalidParameterValueException(
- "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
- }
+ if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+ return savelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
+ } else {
+ return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
+ }
- // If local storage is disabled then attaching a volume with local disk
- // offering not allowed
- DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
- if (!dataCenter.isLocalStorageEnabled()) {
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
- if (diskOffering.isUseLocalStorage()) {
- throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+ @Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
+ Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+ Volume vol = null;
+ try {
+ outcome.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Operation is interrupted", e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Execution excetion", e);
+ }
+
+ Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+ if (jobResult != null) {
+ if (jobResult instanceof ConcurrentOperationException) {
+ throw (ConcurrentOperationException)jobResult;
+ } else if (jobResult instanceof InvalidParameterValueException) {
+ throw (InvalidParameterValueException)jobResult;
+ } else if (jobResult instanceof RuntimeException) {
+ throw (RuntimeException)jobResult;
+ } else if (jobResult instanceof Throwable) {
+ throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+ } else if (jobResult instanceof Long) {
+ vol = _volsDao.findById((Long)jobResult);
}
}
+ return vol;
+ }
- // if target VM has associated VM snapshots
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (vmSnapshots.size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ private Volume savelyOrchestrateAttachVolume(Long vmId, Long volumeId, Long deviceId) {
+ // avoid re-entrance
+
+ VmWorkJobVO placeHolder = null;
+ placeHolder = createPlaceHolderWork(vmId);
+ try {
+ return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+ } finally {
+ _workJobDao.expunge(placeHolder.getId());
}
+ }
- // if target VM has backups
- if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
- throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
+ private void checkForMatchinHypervisorTypesIf(boolean checkNeeded, HypervisorType rootDiskHyperType, HypervisorType volumeToAttachHyperType) {
+ // managed storage can be used for different types of hypervisors
+ // only perform this check if the volume's storage pool is not null and not managed
+ if (checkNeeded) {
+ if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+ throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+ }
}
+ }
+ private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
// permission check
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
- if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
- throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
- }
-
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
- if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+ if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
} catch (ResourceAllocationException e) {
s_logger.error("primary storage resource limit check failed", e);
throw new InvalidParameterValueException(e.getMessage());
}
}
+ }
- HypervisorType rootDiskHyperType = vm.getHypervisorType();
- HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+ private void checkForDevicesInCopies(Long vmId, UserVmVO vm) {
+ // if target VM has associated VM snapshots
+ List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+ if (vmSnapshots.size() > 0) {
+ throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+ }
- StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+ // if target VM has backups
+ if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
Review Comment:
```suggestion
if (CollectionUtils.isNotEmpty(vm.getBackupOfferingId())) {
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1108652243
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [cloudstack] acs-robot commented on pull request #6307: fix pseudo random behaviour in pool selection
Posted by GitBox <gi...@apache.org>.
acs-robot commented on PR #6307:
URL: https://github.com/apache/cloudstack/pull/6307#issuecomment-1124623587
Found UI changes, kicking a new UI QA build
@blueorangutan ui
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org