From 26bbc1ad2896475cc1189a0f300ce7006f675201 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Mon, 15 Mar 2021 17:18:10 +0530 Subject: [PATCH 1/8] resize root disk + Hide override root disk size during deployment of VM for deploy as it --- .../hypervisor/vmware/resource/VmwareResource.java | 2 ++ ui/public/locales/en.json | 2 ++ ui/src/config/section/offering.js | 4 ++++ ui/src/views/compute/DeployVM.vue | 12 +++++++++++- 4 files changed, 19 insertions(+), 1 deletion(-) 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 56d08a4e088e..d3646288ae3f 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 @@ -2072,6 +2072,8 @@ protected StartAnswer execute(StartCommand cmd) { // for (DiskTO vol : sortedDisks) { if (vol.getType() == Volume.Type.ISO || deployAsIs && vol.getType() == Volume.Type.ROOT) { + rootDiskTO = vol; + resizeRootDiskOnVMStart(vmMo, rootDiskTO, hyperHost, context); continue; } diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 5b1cc6a95178..42299042c378 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -1807,6 +1807,7 @@ "label.rolename": "Role", "label.roles": "Roles", "label.roletype": "Role Type", +"label.rootdisksize": "Root disk size (GB)", "label.root.certificate": "Root certificate", "label.root.disk.offering": "Root Disk Offering", "label.root.disk.size": "Root disk size (GB)", @@ -1986,6 +1987,7 @@ "label.start.rolling.maintenance": "Start Rolling Maintenance", "label.start.rolling.maintenance.payload": "Payload", "label.start.vlan": "Start VLAN", +"label.start.vm": "Start VM", "label.start.vxlan": "Start VXLAN", "label.startdate": "By date (start)", "label.startip": "Start IP", diff --git a/ui/src/config/section/offering.js b/ui/src/config/section/offering.js index 085d85989f6f..1ec2d40d181a 100644 --- a/ui/src/config/section/offering.js +++ b/ui/src/config/section/offering.js @@ -36,6 +36,10 @@ export default { store.getters.apis.createServiceOffering.params.filter(x => x.name === 'storagepolicy').length > 0) { fields.splice(6, 0, 'vspherestoragepolicy') } + if (store.getters.apis.createServiceOffering && + store.getters.apis.createServiceOffering.params.filter(x => x.name === 'rootdisksize').length > 0) { + fields.splice(12, 0, 'rootdisksize') + } return fields }, related: [{ diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index b2a5fee8bcb9..0e63e362995d 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -105,7 +105,9 @@ @update-template-iso="updateFieldValue" /> {{ $t('label.override.rootdisk.size') }} - + +
To resize the root disk(s) either create a VM in stopped state and resize the volumes before starting the VM or + Deploy the VM, Stop it and then resize the respective volumes
+ + {{ $t('label.start.vm') }} + + 0) { deployVmData.hypervisor = values.hypervisor } + + deployVmData.startvm = this.startvm + // step 3: select service offering deployVmData.serviceofferingid = values.computeofferingid if (this.serviceOffering && this.serviceOffering.iscustomized) { From 8b93bb206c19eead624865b4fa016ebaf24be3e0 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Tue, 16 Mar 2021 18:14:16 +0530 Subject: [PATCH 2/8] resize volume: Fix issue with volume resize on VMWare (deploy as-is templates) --- ui/public/locales/en.json | 1 + ui/src/config/section/offering.js | 4 ---- ui/src/views/compute/DeployVM.vue | 13 ++++++++----- .../compute/wizard/ComputeOfferingSelection.vue | 10 ++++++++++ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 42299042c378..1af4cbde1c5c 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -2678,6 +2678,7 @@ "message.delete.vpn.customer.gateway": "Please confirm that you want to delete this VPN Customer Gateway", "message.delete.vpn.gateway": "Please confirm that you want to delete this VPN Gateway", "message.deleting.vm": "Deleting VM", +"message.deployasis": "Selected template is Deploy As-Is i.e., the VM is deployed by importing an OVA with vApps directly into vCenter. Root disk(s) resize is allowed only on stopped VMs for such templates.", "message.desc.add.new.lb.sticky.rule": "Add new LB sticky rule", "message.desc.advanced.zone": "For more sophisticated network topologies. This network model provides the most flexibility in defining guest networks and providing custom network offerings such as firewall, VPN, or load balancer support.", "message.desc.basic.zone": "Provide a single network where each VM instance is assigned an IP directly from the network. Guest isolation can be provided through layer-3 means such as security groups (IP address source filtering).", diff --git a/ui/src/config/section/offering.js b/ui/src/config/section/offering.js index 1ec2d40d181a..085d85989f6f 100644 --- a/ui/src/config/section/offering.js +++ b/ui/src/config/section/offering.js @@ -36,10 +36,6 @@ export default { store.getters.apis.createServiceOffering.params.filter(x => x.name === 'storagepolicy').length > 0) { fields.splice(6, 0, 'vspherestoragepolicy') } - if (store.getters.apis.createServiceOffering && - store.getters.apis.createServiceOffering.params.filter(x => x.name === 'rootdisksize').length > 0) { - fields.splice(12, 0, 'rootdisksize') - } return fields }, related: [{ diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index 0e63e362995d..b75551f2a930 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -106,8 +106,7 @@ {{ $t('label.override.rootdisk.size') }} -
To resize the root disk(s) either create a VM in stopped state and resize the volumes before starting the VM or - Deploy the VM, Stop it and then resize the respective volumes
+
{{ this.$t('message.deployasis') }}
+ + + - +
[] }, + selectedTemplate: { + type: Object, + default: () => {} + }, rowCount: { type: Number, default: () => 0 @@ -161,6 +165,9 @@ export default { (item.iscustomized === true && maxMemory < this.minimumMemory))) { disabled = true } + if (this.selectedTemplate && this.selectedTemplate.hypervisor === 'VMware' && this.selectedTemplate.deployasis && item.rootdisksize) { + disabled = true + } return { key: item.id, name: item.name, @@ -238,6 +245,9 @@ export default { return { on: { click: () => { + if (record.disabled) { + return + } this.selectedRowKeys = [record.key] this.$emit('select-compute-item', record.key) } From 5169c0c1e6c3334029b666d4c9136d347a0819cc Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Tue, 16 Mar 2021 20:06:55 +0530 Subject: [PATCH 3/8] Cleanup --- ui/src/views/compute/DeployVM.vue | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index b75551f2a930..5c0606e8fae7 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -549,10 +549,6 @@ - Date: Wed, 17 Mar 2021 16:07:49 +0530 Subject: [PATCH 4/8] Add exceptions when svc offering with root disk size used with deploy as is template --- .../hypervisor/vmware/resource/VmwareResource.java | 6 +++++- .../main/java/com/cloud/vm/UserVmManagerImpl.java | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) 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 d3646288ae3f..e59c7578b061 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 @@ -2071,7 +2071,11 @@ protected StartAnswer execute(StartCommand cmd) { // Setup ROOT/DATA disk devices // for (DiskTO vol : sortedDisks) { - if (vol.getType() == Volume.Type.ISO || deployAsIs && vol.getType() == Volume.Type.ROOT) { + if (vol.getType() == Volume.Type.ISO) { + continue; + } + + if (deployAsIs && vol.getType() == Volume.Type.ROOT) { rootDiskTO = vol; resizeRootDiskOnVMStart(vmMo, rootDiskTO, hyperHost, context); continue; diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index d94c00c23911..31d9b1aeeb2b 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -49,6 +49,8 @@ import javax.xml.parsers.ParserConfigurationException; import com.cloud.agent.api.to.deployasis.OVFPropertyTO; +import com.cloud.api.query.dao.ServiceOfferingJoinDao; +import com.cloud.api.query.vo.ServiceOfferingJoinVO; import com.cloud.deployasis.UserVmDeployAsIsDetailVO; import com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDao; import com.cloud.exception.UnsupportedServiceException; @@ -514,6 +516,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao; @Inject private StorageManager storageMgr; + @Inject + private ServiceOfferingJoinDao serviceOfferingJoinDao; private ScheduledExecutorService _executor = null; private ScheduledExecutorService _vmIpFetchExecutor = null; @@ -5266,6 +5270,16 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE throw new InvalidParameterValueException("Unable to use template " + templateId); } + ServiceOfferingJoinVO svcOffering = serviceOfferingJoinDao.findById(serviceOfferingId); + + if (template.isDeployAsIs() && svcOffering != null && svcOffering.getRootDiskSize() != null && svcOffering.getRootDiskSize() > 0) { + throw new InvalidParameterValueException("Failed to deploy Virtual Machine as a service offering with root disk size specified cannot be used with a deploy as-is template"); + } + + if (template.isDeployAsIs() && cmd.getDetails().get("rootdisksize") != null) { + throw new InvalidParameterValueException("Overriding root disk size isn't supported for VMs deployed from defploy as-is templates"); + } + // Bootmode and boottype are not supported on VMWare dpeloy-as-is templates (since 4.15) if (template.isDeployAsIs() && (cmd.getBootMode() != null || cmd.getBootType() != null)) { throw new InvalidParameterValueException("Boot type and boot mode are not supported on VMware, as we honour what is defined in the template."); From 1c3fc3c57621f003aaefbabae73d8f43fa0ee523 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Wed, 17 Mar 2021 18:24:56 +0530 Subject: [PATCH 5/8] Allow resize of root disk for volume of a VM deployed from an ISO --- .../java/com/cloud/storage/VolumeApiServiceImpl.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index 0adeb836c7c6..dc3bf04396d3 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -916,8 +916,15 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep } // if we are to use the existing disk offering + ImageFormat format = null; if (newDiskOffering == null) { - if (volume.getVolumeType().equals(Volume.Type.ROOT) && diskOffering.getDiskSize() > 0) { + Long templateId = volume.getTemplateId(); + if (templateId != null) { + VMTemplateVO template = _templateDao.findById(templateId); + format = template.getFormat(); + } + + if (volume.getVolumeType().equals(Volume.Type.ROOT) && diskOffering.getDiskSize() > 0 && format != null && format != ImageFormat.ISO) { throw new InvalidParameterValueException( "Failed to resize Root volume. The service offering of this Volume has been configured with a root disk size; " + "on such case a Root Volume can only be resized when changing to another Service Offering with a Root disk size. " From 8480cde874ea28590c369538037e0f6f3eea9aab Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Mon, 22 Mar 2021 11:23:28 +0530 Subject: [PATCH 6/8] refactor code --- .../java/com/cloud/vm/UserVmManagerImpl.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 31d9b1aeeb2b..737beb5274cd 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5272,17 +5272,19 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE ServiceOfferingJoinVO svcOffering = serviceOfferingJoinDao.findById(serviceOfferingId); - if (template.isDeployAsIs() && svcOffering != null && svcOffering.getRootDiskSize() != null && svcOffering.getRootDiskSize() > 0) { - throw new InvalidParameterValueException("Failed to deploy Virtual Machine as a service offering with root disk size specified cannot be used with a deploy as-is template"); - } + if (template.isDeployAsIs()) { + if (svcOffering != null && svcOffering.getRootDiskSize() != null && svcOffering.getRootDiskSize() > 0) { + throw new InvalidParameterValueException("Failed to deploy Virtual Machine as a service offering with root disk size specified cannot be used with a deploy as-is template"); + } - if (template.isDeployAsIs() && cmd.getDetails().get("rootdisksize") != null) { - throw new InvalidParameterValueException("Overriding root disk size isn't supported for VMs deployed from defploy as-is templates"); - } + if (cmd.getDetails().get("rootdisksize") != null) { + throw new InvalidParameterValueException("Overriding root disk size isn't supported for VMs deployed from defploy as-is templates"); + } - // Bootmode and boottype are not supported on VMWare dpeloy-as-is templates (since 4.15) - if (template.isDeployAsIs() && (cmd.getBootMode() != null || cmd.getBootType() != null)) { - throw new InvalidParameterValueException("Boot type and boot mode are not supported on VMware, as we honour what is defined in the template."); + // Bootmode and boottype are not supported on VMWare dpeloy-as-is templates (since 4.15) + if ((cmd.getBootMode() != null || cmd.getBootType() != null)) { + throw new InvalidParameterValueException("Boot type and boot mode are not supported on VMware, as we honour what is defined in the template."); + } } Long diskOfferingId = cmd.getDiskOfferingId(); From 4eda67ecb4ef245b43e83ee95d2e664ca71bf1bf Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Tue, 23 Mar 2021 17:48:11 +0530 Subject: [PATCH 7/8] cleanup --- ui/public/locales/en.json | 2 -- ui/src/views/compute/DeployVM.vue | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 1af4cbde1c5c..d2cff96f87cd 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -1807,7 +1807,6 @@ "label.rolename": "Role", "label.roles": "Roles", "label.roletype": "Role Type", -"label.rootdisksize": "Root disk size (GB)", "label.root.certificate": "Root certificate", "label.root.disk.offering": "Root Disk Offering", "label.root.disk.size": "Root disk size (GB)", @@ -1987,7 +1986,6 @@ "label.start.rolling.maintenance": "Start Rolling Maintenance", "label.start.rolling.maintenance.payload": "Payload", "label.start.vlan": "Start VLAN", -"label.start.vm": "Start VM", "label.start.vxlan": "Start VXLAN", "label.startdate": "By date (start)", "label.startip": "Start IP", diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index 5c0606e8fae7..c4c20dee0392 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -545,7 +545,7 @@ :options="keyboardSelectOptions" > - + From 08faa0462f02377b4cf5788b2780602497e8d7cd Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Fri, 26 Mar 2021 18:03:08 +0530 Subject: [PATCH 8/8] Support for volume resize for CKS --- ...esClusterResourceModifierActionWorker.java | 34 +++++++++++++++++++ .../KubernetesClusterStartWorker.java | 2 ++ 2 files changed, 36 insertions(+) diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java index b715f09d7b88..c771cf345617 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java @@ -31,6 +31,7 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.command.user.firewall.CreateFirewallRuleCmd; import org.apache.cloudstack.api.command.user.vm.StartVMCmd; +import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; import org.apache.commons.codec.binary.Base64; import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Level; @@ -70,6 +71,10 @@ import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.offering.ServiceOffering; import com.cloud.resource.ResourceManager; +import com.cloud.storage.Volume; +import com.cloud.storage.VolumeApiService; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.SSHKeyPairVO; import com.cloud.uservm.UserVm; @@ -118,6 +123,10 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu protected VMInstanceDao vmInstanceDao; @Inject protected UserVmManager userVmManager; + @Inject + protected VolumeApiService volumeService; + @Inject + protected VolumeDao volumeDao; protected String kubernetesClusterNodeNamePrefix; @@ -268,6 +277,29 @@ protected DeployDestination plan() throws InsufficientServerCapacityException { return plan(kubernetesCluster.getTotalNodeCount(), zone, offering); } + protected void resizeNodeVolume(final UserVm vm) throws ManagementServerException { + try { + if (vm.getHypervisorType() == Hypervisor.HypervisorType.VMware && templateDao.findById(vm.getTemplateId()).isDeployAsIs()) { + List vmVols = volumeDao.findByInstance(vm.getId()); + for (VolumeVO volumeVO : vmVols) { + if (volumeVO.getVolumeType() == Volume.Type.ROOT) { + ResizeVolumeCmd resizeVolumeCmd = new ResizeVolumeCmd(); + resizeVolumeCmd = ComponentContext.inject(resizeVolumeCmd); + Field f = resizeVolumeCmd.getClass().getDeclaredField("size"); + Field f1 = resizeVolumeCmd.getClass().getDeclaredField("id"); + f.setAccessible(true); + f1.setAccessible(true); + f1.set(resizeVolumeCmd, volumeVO.getId()); + f.set(resizeVolumeCmd, kubernetesCluster.getNodeRootDiskSize()); + volumeService.resizeVolume(resizeVolumeCmd); + } + } + } + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new ManagementServerException(String.format("Failed to resize volume of VM in the Kubernetes cluster : %s", kubernetesCluster.getName()), e); + } + } + protected void startKubernetesVM(final UserVm vm) throws ManagementServerException { try { StartVMCmd startVm = new StartVMCmd(); @@ -275,6 +307,7 @@ protected void startKubernetesVM(final UserVm vm) throws ManagementServerExcepti Field f = startVm.getClass().getDeclaredField("id"); f.setAccessible(true); f.set(startVm, vm.getId()); + resizeNodeVolume(vm); userVmService.startVirtualMachine(startVm); if (LOGGER.isInfoEnabled()) { LOGGER.info(String.format("Started VM : %s in the Kubernetes cluster : %s", vm.getDisplayName(), kubernetesCluster.getName())); @@ -296,6 +329,7 @@ protected List provisionKubernetesClusterNodeVms(final long nodeCount, f for (int i = offset + 1; i <= nodeCount; i++) { UserVm vm = createKubernetesNode(publicIpAddress, i); addKubernetesClusterVm(kubernetesCluster.getId(), vm.getId()); + resizeNodeVolume(vm); startKubernetesVM(vm); vm = userVmDao.findById(vm.getId()); if (vm == null) { diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java index 855c264d6906..5855319ae67c 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java @@ -277,6 +277,7 @@ private UserVm provisionKubernetesClusterMasterVm(final Network network, final S UserVm k8sMasterVM = null; k8sMasterVM = createKubernetesMaster(network, publicIpAddress); addKubernetesClusterVm(kubernetesCluster.getId(), k8sMasterVM.getId()); + resizeNodeVolume(k8sMasterVM); startKubernetesVM(k8sMasterVM); k8sMasterVM = userVmDao.findById(k8sMasterVM.getId()); if (k8sMasterVM == null) { @@ -296,6 +297,7 @@ private List provisionKubernetesClusterAdditionalMasterVms(final String UserVm vm = null; vm = createKubernetesAdditionalMaster(publicIpAddress, i); addKubernetesClusterVm(kubernetesCluster.getId(), vm.getId()); + resizeNodeVolume(vm); startKubernetesVM(vm); vm = userVmDao.findById(vm.getId()); if (vm == null) {