From 5fdabc1cb00d40f3277147599e4a894cf68d59f9 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Mon, 12 Oct 2020 00:38:47 +0530 Subject: [PATCH] Added storage policy details to disk while creating disk and restricted migration of volumes to storage pools which are not storage policy compliance --- .../storage/volume/VolumeObject.java | 11 ++++----- .../resource/VmwareStorageProcessor.java | 7 +++--- .../com/cloud/storage/StorageManagerImpl.java | 2 +- .../cloud/storage/VolumeApiServiceImpl.java | 14 +++++++++++ .../vmware/mo/VirtualMachineMO.java | 23 ++++++++++++------- 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java index 6d76aba9051..da759f84a7c 100644 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -796,22 +796,21 @@ public class VolumeObject implements VolumeInfo { public String getvSphereStoragePolicyId() { if (StringUtils.isEmpty(vSphereStoragePolicyId)) { + String storagePolicyVOid = null; if (Volume.Type.ROOT == getVolumeType()) { Long vmId = volumeVO.getInstanceId(); if (vmId != null) { VMInstanceVO vm = vmInstanceDao.findByIdIncludingRemoved(vmId); - String storagePolicyVOid = serviceOfferingDetailsDao.getDetail(vm.getServiceOfferingId(), + storagePolicyVOid = serviceOfferingDetailsDao.getDetail(vm.getServiceOfferingId(), ApiConstants.STORAGE_POLICY); - VsphereStoragePolicyVO vsphereStoragePolicyVO = vsphereStoragePolicyDao.findById(Long.parseLong(storagePolicyVOid)); - vSphereStoragePolicyId = vsphereStoragePolicyVO.getPolicyId(); - } } else { - String storagePolicyVOid = diskOfferingDetailsDao.getDetail(volumeVO.getDiskOfferingId(), + storagePolicyVOid = diskOfferingDetailsDao.getDetail(volumeVO.getDiskOfferingId(), ApiConstants.STORAGE_POLICY); + } + if (storagePolicyVOid != null) { VsphereStoragePolicyVO vsphereStoragePolicyVO = vsphereStoragePolicyDao.findById(Long.parseLong(storagePolicyVOid)); vSphereStoragePolicyId = vsphereStoragePolicyVO.getPolicyId(); - } } return vSphereStoragePolicyId; diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java index cf7d933e5c7..e7349ee49ba 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -831,7 +831,7 @@ public class VmwareStorageProcessor implements StorageProcessor { synchronized (this) { s_logger.info("Delete file if exists in datastore to clear the way for creating the volume. file: " + volumeDatastorePath); VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vmdkName, dcMo, searchExcludedFolders); - vmMo.createDisk(volumeDatastorePath, (long)(volume.getSize() / (1024L * 1024L)), morDatastore, -1); + vmMo.createDisk(volumeDatastorePath, (long)(volume.getSize() / (1024L * 1024L)), morDatastore, -1, null); vmMo.detachDisk(volumeDatastorePath, false); } } finally { @@ -2497,6 +2497,7 @@ public class VmwareStorageProcessor implements StorageProcessor { VolumeObjectTO volume = (VolumeObjectTO)cmd.getData(); DataStoreTO primaryStore = volume.getDataStore(); + String vSphereStoragePolicyId = volume.getvSphereStoragePolicyId(); try { VmwareContext context = hostService.getServiceContext(null); @@ -2534,7 +2535,7 @@ public class VmwareStorageProcessor implements StorageProcessor { synchronized (this) { try { - vmMo.createDisk(volumeDatastorePath, (int)(volume.getSize() / (1024L * 1024L)), morDatastore, vmMo.getScsiDeviceControllerKey()); + vmMo.createDisk(volumeDatastorePath, (int)(volume.getSize() / (1024L * 1024L)), morDatastore, vmMo.getScsiDeviceControllerKey(), vSphereStoragePolicyId); vmMo.detachDisk(volumeDatastorePath, false); } catch (Exception e1) { @@ -3243,7 +3244,7 @@ public class VmwareStorageProcessor implements StorageProcessor { Long volumeSizeToUse = volumeSize < dsMo.getDatastoreSummary().getFreeSpace() ? volumeSize : dsMo.getDatastoreSummary().getFreeSpace(); - vmMo.createDisk(vmdkDatastorePath, getMBsFromBytes(volumeSizeToUse), dsMo.getMor(), vmMo.getScsiDeviceControllerKey()); + vmMo.createDisk(vmdkDatastorePath, getMBsFromBytes(volumeSizeToUse), dsMo.getMor(), vmMo.getScsiDeviceControllerKey(), null); vmMo.detachDisk(vmdkDatastorePath, false); vmMo.destroy(); } diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java index 212f6938e65..2ef88e44350 100644 --- a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java @@ -2038,7 +2038,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C // check cummilative result for all volumes for (Pair answer : answers) { if (!answer.second().getResult()) { - s_logger.debug(String.format("Storage pool %s is not complaince with storage policy for volume %s", pool.getName(), answer.first().getName())); + s_logger.debug(String.format("Storage pool %s is not compliance with storage policy for volume %s", pool.getUuid(), answer.first().getName())); return false; } } diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index 75847bde637..58e1bffaf37 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -2232,6 +2232,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic throw new InvalidParameterValueException("Cannot migrate volume " + vol + "to the destination storage pool " + destPool.getName() + " as the storage pool is in maintenance mode."); } + String poolUuid = destPool.getUuid(); if (destPool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) { DataCenter dc = _entityMgr.findById(DataCenter.class, vol.getDataCenterId()); Pod destPoolPod = _entityMgr.findById(Pod.class, destPool.getPodId()); @@ -2277,6 +2278,19 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic updateMissingRootDiskController(vm, vol.getChainInfo()); } } + + HypervisorType hypervisorType = _volsDao.getHypervisorType(volumeId); + if (hypervisorType.equals(HypervisorType.VMware)) { + try { + boolean isStoragePoolStoragepolicyComplaince = storageMgr.isStoragePoolComplaintWithStoragePolicy(Arrays.asList(vol), destPool); + if (!isStoragePoolStoragepolicyComplaince) { + throw new CloudRuntimeException(String.format("Storage pool %s is not storage policy compliance with the volume %s", poolUuid, vol.getUuid())); + } + } catch (StorageUnavailableException e) { + throw new CloudRuntimeException(String.format("Could not verify storage policy compliance against storage pool %s due to exception %s", destPool.getUuid(), e.getMessage())); + } + } + DiskOfferingVO newDiskOffering = retrieveAndValidateNewDiskOffering(cmd); validateConditionsToReplaceDiskOfferingOfVolume(vol, newDiskOffering, destPool); if (vm != null) { diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index 9565ac6ff0b..5f61b31171c 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -1148,13 +1148,13 @@ public class VirtualMachineMO extends BaseMO { } // vmdkDatastorePath: [datastore name] vmdkFilePath - public void createDisk(String vmdkDatastorePath, long sizeInMb, ManagedObjectReference morDs, int controllerKey) throws Exception { - createDisk(vmdkDatastorePath, VirtualDiskType.THIN, VirtualDiskMode.PERSISTENT, null, sizeInMb, morDs, controllerKey); + public void createDisk(String vmdkDatastorePath, long sizeInMb, ManagedObjectReference morDs, int controllerKey, String vSphereStoragePolicyId) throws Exception { + createDisk(vmdkDatastorePath, VirtualDiskType.THIN, VirtualDiskMode.PERSISTENT, null, sizeInMb, morDs, controllerKey, vSphereStoragePolicyId); } // vmdkDatastorePath: [datastore name] vmdkFilePath public void createDisk(String vmdkDatastorePath, VirtualDiskType diskType, VirtualDiskMode diskMode, String rdmDeviceName, long sizeInMb, - ManagedObjectReference morDs, int controllerKey) throws Exception { + ManagedObjectReference morDs, int controllerKey, String vSphereStoragePolicyId) throws Exception { if (s_logger.isTraceEnabled()) s_logger.trace("vCenter API trace - createDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + vmdkDatastorePath + ", sizeInMb: " + sizeInMb + @@ -1219,7 +1219,14 @@ public class VirtualMachineMO extends BaseMO { deviceConfigSpec.setDevice(newDisk); deviceConfigSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.CREATE); deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); - + if (!StringUtils.isEmpty(vSphereStoragePolicyId)) { + PbmProfileManagerMO profMgrMo = new PbmProfileManagerMO(getContext()); + VirtualMachineDefinedProfileSpec diskProfileSpec = profMgrMo.getProfileSpec(vSphereStoragePolicyId); + deviceConfigSpec.getProfile().add(diskProfileSpec); + if (s_logger.isDebugEnabled()) { + s_logger.debug(String.format("Adding vSphere storage profile: %s to volume [%s]", vSphereStoragePolicyId, vmdkDatastorePath)); + } + } reConfigSpec.getDeviceChange().add(deviceConfigSpec); ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec); @@ -1297,7 +1304,7 @@ public class VirtualMachineMO extends BaseMO { attachDisk(vmdkDatastorePathChain, morDs, null, null); } - public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController, String storagePolicyId) throws Exception { + public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController, String vSphereStoragePolicyId) throws Exception { if(s_logger.isTraceEnabled()) s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " @@ -1338,12 +1345,12 @@ public class VirtualMachineMO extends BaseMO { deviceConfigSpec.setDevice(newDisk); deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); - if (!StringUtils.isEmpty(storagePolicyId)) { + if (!StringUtils.isEmpty(vSphereStoragePolicyId)) { PbmProfileManagerMO profMgrMo = new PbmProfileManagerMO(getContext()); - VirtualMachineDefinedProfileSpec diskProfileSpec = profMgrMo.getProfileSpec(storagePolicyId); + VirtualMachineDefinedProfileSpec diskProfileSpec = profMgrMo.getProfileSpec(vSphereStoragePolicyId); deviceConfigSpec.getProfile().add(diskProfileSpec); if (s_logger.isDebugEnabled()) { - s_logger.debug(String.format("Adding vSphere storage profile: %s to volume [%s]", storagePolicyId, vmdkDatastorePathChain[0])); + s_logger.debug(String.format("Adding vSphere storage profile: %s to volume [%s]", vSphereStoragePolicyId, vmdkDatastorePathChain[0])); } } reConfigSpec.getDeviceChange().add(deviceConfigSpec);