Skip to content

Commit

Permalink
api, vmware: allow VM setting/detail for disk controller (root/data) …
Browse files Browse the repository at this point in the history
…to override template details (apache#6276)

This PR allows VM details wrt root & data disk controller passed via details parameter of deployVMCmd to take precedence over template settings, i.e., the order of precedence for determining VM disk controller is : VM details passed during deployment > template settings > global setting vmware.root.disk.controller.
  • Loading branch information
Pearl1594 authored and neogismm committed Sep 5, 2022
1 parent 4e962e2 commit 49e33d8
Showing 1 changed file with 47 additions and 31 deletions.
78 changes: 47 additions & 31 deletions server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
Expand Up @@ -4304,6 +4304,15 @@ public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCap
if (!isImport && isIso) {
vm.setIsoId(template.getId());
}

long guestOSId = template.getGuestOSId();
GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
long guestOSCategoryId = guestOS.getCategoryId();
GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId);
if (hypervisorType.equals(HypervisorType.VMware)) {
updateVMDiskController(vm, customParameters, guestOS);
}

Long rootDiskSize = null;
// custom root disk size, resizes base template to larger size
if (customParameters.containsKey(VmDetailConstants.ROOT_DISK_SIZE)) {
Expand All @@ -4324,36 +4333,6 @@ public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCap
vm.setDisplayVm(true);
}

long guestOSId = template.getGuestOSId();
GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
long guestOSCategoryId = guestOS.getCategoryId();
GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId);

// If hypervisor is vSphere and OS is OS X, set special settings.
if (hypervisorType.equals(HypervisorType.VMware)) {
if (guestOS.getDisplayName().toLowerCase().contains("apple mac os")) {
vm.setDetail(VmDetailConstants.SMC_PRESENT, "TRUE");
vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, "scsi");
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "scsi");
vm.setDetail(VmDetailConstants.FIRMWARE, "efi");
s_logger.info("guestOS is OSX : overwrite root disk controller to scsi, use smc and efi");
} else {
String controllerSetting = StringUtils.defaultIfEmpty(_configDao.getValue(Config.VmwareRootDiskControllerType.key()),
Config.VmwareRootDiskControllerType.getDefaultValue());
// Don't override if VM already has root/data disk controller detail
if (vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER) == null) {
vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, controllerSetting);
}
if (vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER) == null) {
if (controllerSetting.equalsIgnoreCase("scsi")) {
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "scsi");
} else {
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "osdefault");
}
}
}
}

if (isImport) {
vm.setDataCenterId(zone.getId());
vm.setHostId(host.getId());
Expand Down Expand Up @@ -4443,6 +4422,42 @@ public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCap
});
}

private void updateVMDiskController(UserVmVO vm, Map<String, String> customParameters, GuestOSVO guestOS) {
// If hypervisor is vSphere and OS is OS X, set special settings.
if (guestOS.getDisplayName().toLowerCase().contains("apple mac os")) {
vm.setDetail(VmDetailConstants.SMC_PRESENT, "TRUE");
vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, "scsi");
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "scsi");
vm.setDetail(VmDetailConstants.FIRMWARE, "efi");
s_logger.info("guestOS is OSX : overwrite root disk controller to scsi, use smc and efi");
} else {
String rootDiskControllerSetting = customParameters.get(VmDetailConstants.ROOT_DISK_CONTROLLER);
String dataDiskControllerSetting = customParameters.get(VmDetailConstants.DATA_DISK_CONTROLLER);
if (StringUtils.isNotEmpty(rootDiskControllerSetting)) {
vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, rootDiskControllerSetting);
}

if (StringUtils.isNotEmpty(dataDiskControllerSetting)) {
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, dataDiskControllerSetting);
}

String controllerSetting = StringUtils.defaultIfEmpty(_configDao.getValue(Config.VmwareRootDiskControllerType.key()),
Config.VmwareRootDiskControllerType.getDefaultValue());

// Don't override if VM already has root/data disk controller detail
if (vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER) == null) {
vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, controllerSetting);
}
if (vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER) == null) {
if (controllerSetting.equalsIgnoreCase("scsi")) {
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "scsi");
} else {
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "osdefault");
}
}
}
}

/**
* take the properties and set them on the vm.
* consider should we be complete, and make sure all default values are copied as well if known?
Expand Down Expand Up @@ -4495,14 +4510,15 @@ private UserVmVO commitUserVm(final DataCenter zone, final VirtualMachineTemplat
public void validateRootDiskResize(final HypervisorType hypervisorType, Long rootDiskSize, VMTemplateVO templateVO, UserVmVO vm, final Map<String, String> customParameters) throws InvalidParameterValueException
{
// rootdisksize must be larger than template.
boolean isIso = ImageFormat.ISO == templateVO.getFormat();
if ((rootDiskSize << 30) < templateVO.getSize()) {
String error = "Unsupported: rootdisksize override is smaller than template size " + toHumanReadableSize(templateVO.getSize());
s_logger.error(error);
throw new InvalidParameterValueException(error);
} else if ((rootDiskSize << 30) > templateVO.getSize()) {
if (hypervisorType == HypervisorType.VMware && (vm.getDetails() == null || vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER) == null)) {
s_logger.warn("If Root disk controller parameter is not overridden, then Root disk resize may fail because current Root disk controller value is NULL.");
} else if (hypervisorType == HypervisorType.VMware && vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER).toLowerCase().contains("ide")) {
} else if (hypervisorType == HypervisorType.VMware && vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER).toLowerCase().contains("ide") && !isIso) {
String error = String.format("Found unsupported root disk controller [%s].", vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER));
s_logger.error(error);
throw new InvalidParameterValueException(error);
Expand Down

0 comments on commit 49e33d8

Please sign in to comment.