diff --git a/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java index f7e17f7bc14..6cd27b16cc1 100644 --- a/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -64,6 +64,7 @@ public class VolumeObjectTO implements DataTO { private boolean directDownload; private boolean deployAsIs; private String updatedDataStoreUUID; + private String vSphereStoragePolicyId; public VolumeObjectTO() { @@ -105,6 +106,7 @@ public class VolumeObjectTO implements DataTO { this.migrationOptions = volume.getMigrationOptions(); this.directDownload = volume.isDirectDownload(); this.deployAsIs = volume.isDeployAsIs(); + this.vSphereStoragePolicyId = volume.getvSphereStoragePolicyId(); } public String getUuid() { @@ -329,4 +331,11 @@ public class VolumeObjectTO implements DataTO { this.updatedDataStoreUUID = updatedDataStoreUUID; } + public String getvSphereStoragePolicyId() { + return vSphereStoragePolicyId; + } + + public void setvSphereStoragePolicyId(String vSphereStoragePolicyId) { + this.vSphereStoragePolicyId = vSphereStoragePolicyId; + } } diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java index 06bda51a092..b1381228265 100644 --- a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java +++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java @@ -87,4 +87,6 @@ public interface VolumeInfo extends DataObject, Volume { boolean isDeployAsIs(); String getDeployAsIsConfiguration(); + + public String getvSphereStoragePolicyId(); } 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 45509c51c43..6d76aba9051 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 @@ -20,12 +20,18 @@ import java.util.Date; import javax.inject.Inject; +import com.cloud.dc.VsphereStoragePolicyVO; +import com.cloud.dc.dao.VsphereStoragePolicyDao; +import com.cloud.service.dao.ServiceOfferingDetailsDao; import com.cloud.storage.MigrationOptions; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VolumeDetailVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDetailsDao; import com.cloud.vm.VmDetailConstants; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; @@ -81,9 +87,17 @@ public class VolumeObject implements VolumeInfo { VMTemplateDao templateDao; @Inject VolumeDetailsDao volumeDetailsDao; + @Inject + ServiceOfferingDetailsDao serviceOfferingDetailsDao; + @Inject + DiskOfferingDetailsDao diskOfferingDetailsDao; + @Inject + VsphereStoragePolicyDao vsphereStoragePolicyDao; + private Object payload; private MigrationOptions migrationOptions; private boolean directDownload; + private String vSphereStoragePolicyId; public VolumeObject() { _volStateMachine = Volume.State.getStateMachine(); @@ -780,6 +794,29 @@ public class VolumeObject implements VolumeInfo { } + public String getvSphereStoragePolicyId() { + if (StringUtils.isEmpty(vSphereStoragePolicyId)) { + if (Volume.Type.ROOT == getVolumeType()) { + Long vmId = volumeVO.getInstanceId(); + if (vmId != null) { + VMInstanceVO vm = vmInstanceDao.findByIdIncludingRemoved(vmId); + String 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(), + ApiConstants.STORAGE_POLICY); + VsphereStoragePolicyVO vsphereStoragePolicyVO = vsphereStoragePolicyDao.findById(Long.parseLong(storagePolicyVOid)); + vSphereStoragePolicyId = vsphereStoragePolicyVO.getPolicyId(); + + } + } + return vSphereStoragePolicyId; + } + @Override public ImageFormat getFormat() { return volumeVO.getFormat(); diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 4a810c664e7..3e515d7b5cd 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -219,6 +219,7 @@ import com.cloud.hypervisor.vmware.mo.HostMO; import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO; import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper; import com.cloud.hypervisor.vmware.mo.NetworkDetails; +import com.cloud.hypervisor.vmware.mo.PbmProfileManagerMO; import com.cloud.hypervisor.vmware.mo.TaskMO; import com.cloud.hypervisor.vmware.mo.StoragepodMO; import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType; @@ -289,6 +290,7 @@ import com.vmware.vim25.HostInternetScsiHba; import com.vmware.vim25.HostPortGroupSpec; import com.vmware.vim25.ManagedObjectReference; import com.vmware.vim25.NasDatastoreInfo; +import com.vmware.vim25.VirtualMachineDefinedProfileSpec; import com.vmware.vim25.ObjectContent; import com.vmware.vim25.OptionValue; import com.vmware.vim25.PerfCounterInfo; @@ -1798,6 +1800,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa VirtualMachineFileInfo existingVmFileInfo = null; VirtualMachineFileLayoutEx existingVmFileLayout = null; List existingDatastores = new ArrayList(); + String diskStoragePolicyId = null; + String vmStoragePolicyId = null; + VirtualMachineDefinedProfileSpec diskProfileSpec = null; + VirtualMachineDefinedProfileSpec vmProfileSpec = null; + DeployAsIsInfoTO deployAsIsInfo = vmSpec.getDeployAsIsInfo(); boolean deployAsIs = deployAsIsInfo != null; @@ -2218,8 +2225,20 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa VirtualDevice device = VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, volumeDsDetails.first(), deviceNumber, i + 1); - if (vol.getType() == Volume.Type.ROOT) + diskStoragePolicyId = volumeTO.getvSphereStoragePolicyId(); + if (!StringUtils.isEmpty(diskStoragePolicyId)) { + PbmProfileManagerMO profMgrMo = new PbmProfileManagerMO(context); + diskProfileSpec = profMgrMo.getProfileSpec(diskStoragePolicyId); + deviceConfigSpecArray[i].getProfile().add(diskProfileSpec); + if (s_logger.isDebugEnabled()) { + s_logger.debug(String.format("Adding vSphere storage profile: %s to virtual disk [%s]", diskStoragePolicyId, _gson.toJson(device))); + } + } + if (vol.getType() == Volume.Type.ROOT) { rootDiskTO = vol; + vmStoragePolicyId = diskStoragePolicyId; + vmProfileSpec = diskProfileSpec; + } deviceConfigSpecArray[i].setDevice(device); deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD); @@ -2393,6 +2412,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa setBootOptions(vmSpec, bootMode, vmConfigSpec); } + if (!StringUtils.isEmpty(vmStoragePolicyId)) { + vmConfigSpec.getVmProfile().add(vmProfileSpec); + if (s_logger.isTraceEnabled()) { + s_logger.trace(String.format("Configuring the VM %s with storage policy: %s", vmInternalCSName, vmStoragePolicyId)); + } + } // // Configure VM // 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 bc2639235a9..cf7d933e5c7 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 @@ -2052,6 +2052,7 @@ public class VmwareStorageProcessor implements StorageProcessor { VolumeObjectTO volumeTO = (VolumeObjectTO)disk.getData(); DataStoreTO primaryStore = volumeTO.getDataStore(); String volumePath = volumeTO.getPath(); + String storagePolicyId = volumeTO.getvSphereStoragePolicyId(); String vmdkPath = isManaged ? resource.getVmdkPath(volumePath) : null; @@ -2193,7 +2194,7 @@ public class VmwareStorageProcessor implements StorageProcessor { diskController = vmMo.getRecommendedDiskController(null); } - vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs, diskController); + vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs, diskController, storagePolicyId); VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder(); VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(volumePath, dsMo.getName()); chainInfo = _gson.toJson(diskInfo); diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PbmProfileManagerMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PbmProfileManagerMO.java index a4142ecde8a..38f18d7e830 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PbmProfileManagerMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PbmProfileManagerMO.java @@ -27,6 +27,7 @@ import com.vmware.pbm.PbmProfileResourceType; import com.vmware.pbm.PbmProfileResourceTypeEnum; import com.vmware.vim25.ManagedObjectReference; +import com.vmware.vim25.VirtualMachineDefinedProfileSpec; import org.apache.log4j.Logger; import java.util.Collections; @@ -89,6 +90,15 @@ public class PbmProfileManagerMO extends BaseMO { resourceType.setResourceType(PbmProfileResourceTypeEnum.STORAGE.value()); return resourceType; } + + + public VirtualMachineDefinedProfileSpec getProfileSpec(String profileId) throws Exception { + VirtualMachineDefinedProfileSpec profileSpec = new VirtualMachineDefinedProfileSpec(); + PbmProfile profile = getStorageProfile(profileId); + profileSpec.setProfileId(profile.getProfileId().getUniqueId()); + return profileSpec; + } + } 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 01bbf02a7b0..9565ac6ff0b 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 @@ -105,6 +105,7 @@ import com.vmware.vim25.VirtualMachineSnapshotInfo; import com.vmware.vim25.VirtualMachineSnapshotTree; import com.vmware.vim25.VirtualSCSIController; import com.vmware.vim25.VirtualSCSISharing; +import com.vmware.vim25.VirtualMachineDefinedProfileSpec; import com.cloud.hypervisor.vmware.mo.SnapshotDescriptor.SnapshotInfo; import com.cloud.hypervisor.vmware.util.VmwareContext; @@ -1293,10 +1294,10 @@ public class VirtualMachineMO extends BaseMO { } public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs) throws Exception { - attachDisk(vmdkDatastorePathChain, morDs, null); + attachDisk(vmdkDatastorePathChain, morDs, null, null); } - public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController) throws Exception { + public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController, String storagePolicyId) throws Exception { if(s_logger.isTraceEnabled()) s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " @@ -1337,7 +1338,14 @@ public class VirtualMachineMO extends BaseMO { deviceConfigSpec.setDevice(newDisk); deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); - + if (!StringUtils.isEmpty(storagePolicyId)) { + PbmProfileManagerMO profMgrMo = new PbmProfileManagerMO(getContext()); + VirtualMachineDefinedProfileSpec diskProfileSpec = profMgrMo.getProfileSpec(storagePolicyId); + deviceConfigSpec.getProfile().add(diskProfileSpec); + if (s_logger.isDebugEnabled()) { + s_logger.debug(String.format("Adding vSphere storage profile: %s to volume [%s]", storagePolicyId, vmdkDatastorePathChain[0])); + } + } reConfigSpec.getDeviceChange().add(deviceConfigSpec); ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);