From 2f369973e22441dbebabf8d0683ddec866bef72f Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Mon, 29 Jul 2013 15:24:59 +0530 Subject: [PATCH] CLOUDSTACK-3779: Support System vm scaling on VMWare Marked the system template new system template as dynamicallyScalable - handled upgrade case - moved "dynamicallyScalable" flag to vm_instance table from user_vm_details to support dynamic scaling of system vm Signed off by : Nitin Mehta --- .../cloud/upgrade/dao/Upgrade410to420.java | 9 +++++++- .../schema/src/com/cloud/vm/VMInstanceVO.java | 10 +++++++++ .../src/com/cloud/vm/dao/UserVmDao.java | 2 +- .../src/com/cloud/vm/dao/UserVmDaoImpl.java | 3 ++- .../xen/resource/XenServer56FP1Resource.java | 4 ++-- .../cloud/hypervisor/HypervisorGuruBase.java | 9 +++----- .../cloud/server/ManagementServerImpl.java | 4 ++++ .../src/com/cloud/vm/UserVmManagerImpl.java | 21 ++++++------------- .../vm/VirtualMachineManagerImplTest.java | 2 -- setup/db/db/schema-410to420.sql | 9 ++++---- 10 files changed, 40 insertions(+), 33 deletions(-) diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java index d4b7b6d353b..61e678198f2 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java @@ -265,7 +265,14 @@ public class Upgrade410to420 implements DbUpgrade { throw new CloudRuntimeException("Error while updating "+ hypervisorAndTemplateName.getKey() +" systemVm template", e); } } - + try { + pstmt = conn.prepareStatement("UPDATE `cloud`.`vm_template` set dynamically_scalable = 1 where name = ? and type = 'SYSTEM'"); + pstmt.setString(1, NewTemplateNameList.get(HypervisorType.VMware)); + pstmt.executeUpdate(); + pstmt.close(); + } catch (SQLException e) { + throw new CloudRuntimeException("Error while updating dynamically_scalable flag to 1 for SYSTEM template systemvm-vmware-4.2"); + } s_logger.debug("Updating System Vm Template IDs Complete"); } finally { diff --git a/engine/schema/src/com/cloud/vm/VMInstanceVO.java b/engine/schema/src/com/cloud/vm/VMInstanceVO.java index e1d289206a9..8cf7fd0dd87 100644 --- a/engine/schema/src/com/cloud/vm/VMInstanceVO.java +++ b/engine/schema/src/com/cloud/vm/VMInstanceVO.java @@ -146,6 +146,8 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject { * @param userData updates the userData of the vm * @param displayVm updates the displayvm attribute signifying whether it has to be displayed to the end user or not. */ - void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm); + void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable); List findDestroyedVms(Date date); diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java index 1c11563b270..8afce099394 100755 --- a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java @@ -224,13 +224,14 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use } @Override - public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm) { + public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable) { UserVmVO vo = createForUpdate(); vo.setDisplayName(displayName); vo.setHaEnabled(enable); vo.setGuestOSId(osTypeId); vo.setUserData(userData); vo.setDisplayVm(displayVm); + vo.setDynamicallyScalable(isDynamicallyScalable); update(id, vo); } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java index 11a7b42b81a..d230be10155 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java @@ -178,8 +178,8 @@ public class XenServer56FP1Resource extends XenServer56Resource { vmr.memoryDynamicMax = vmSpec.getMaxRam(); } else { //scaling disallowed, set static memory target - if (s_logger.isDebugEnabled()) { - s_logger.warn("Host "+ host.getHostname(conn) +" does not support dynamic scaling"); + if (vmSpec.isEnableDynamicallyScaleVm() && !isDmcEnabled(conn, host)) { + s_logger.warn("Host "+ host.getHostname(conn) +" does not support dynamic scaling, so the vm " + vmSpec.getName() + " is not dynamically scalable"); } vmr.memoryStaticMin = vmSpec.getMinRam(); vmr.memoryStaticMax = vmSpec.getMaxRam(); diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index 6d368bd61c2..8a9df03015d 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -120,15 +120,12 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis if(detailsInVm != null) { details.putAll(detailsInVm); } - if (details.get(VirtualMachine.IsDynamicScalingEnabled) == null || details.get(VirtualMachine.IsDynamicScalingEnabled).isEmpty()) { - to.setEnableDynamicallyScaleVm(false); - } else { - // check if XStools/VMWare tools are present in the VM and dynamic scaling feature is enabled (per zone/global) - to.setEnableDynamicallyScaleVm(details.get(VirtualMachine.IsDynamicScalingEnabled).equals("true") && Boolean.parseBoolean(_configServer.getConfigValue(Config.EnableDynamicallyScaleVm.key(), Config.ConfigurationParameterScope.zone.toString(), vm.getDataCenterId()))); - } to.setDetails(details); // Workaround to make sure the TO has the UUID we need for Niciri integration VMInstanceVO vmInstance = _virtualMachineDao.findById(to.getId()); + // check if XStools/VMWare tools are present in the VM and dynamic scaling feature is enabled (per zone/global) + Boolean isDynamicallyScalable = vmInstance.isDynamicallyScalable() && Boolean.parseBoolean(_configServer.getConfigValue(Config.EnableDynamicallyScaleVm.key(), Config.ConfigurationParameterScope.zone.toString(), vm.getDataCenterId())); + to.setEnableDynamicallyScaleVm(isDynamicallyScalable); to.setUuid(vmInstance.getUuid()); // diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index e0abe0146fb..8e29bb834c7 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -3736,6 +3736,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Override public VirtualMachine upgradeSystemVM(ScaleSystemVMCmd cmd) throws ResourceUnavailableException, ManagementServerException, VirtualMachineMigrationException, ConcurrentOperationException { + VMInstanceVO vmInstance = _vmInstanceDao.findById(cmd.getId()); + if (vmInstance.getHypervisorType() == HypervisorType.XenServer && vmInstance.getState().equals(State.Running)) { + throw new InvalidParameterValueException("Dynamic Scaling operation is not permitted for this hypervisor on system vm"); + } boolean result = _userVmMgr.upgradeVirtualMachine(cmd.getId(), cmd.getServiceOfferingId()); if(result){ VirtualMachine vm = _vmInstanceDao.findById(cmd.getId()); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index c950b4b5f9a..2def783667d 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1189,9 +1189,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if(!enableDynamicallyScaleVm){ throw new PermissionDeniedException("Dynamically scaling virtual machines is disabled for this zone, please contact your admin"); } - UserVmDetailVO vmDetailVO = _vmDetailsDao.findDetail(vmId, VirtualMachine.IsDynamicScalingEnabled); - if (vmDetailVO == null || !Boolean.parseBoolean(vmDetailVO.getValue())) { - throw new CloudRuntimeException("Unable to Scale the vm: " + vmInstance.getUuid() + " as vm does not have xs tools to support dynamic scaling"); + if (!vmInstance.isDynamicallyScalable()) { + throw new CloudRuntimeException("Unable to Scale the vm: " + vmInstance.getUuid() + " as vm does not have tools to support dynamic scaling"); } while (retry-- != 0) { // It's != so that it can match -1. @@ -1803,18 +1802,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } - if (isDynamicallyScalable != null) { - UserVmDetailVO vmDetailVO = _vmDetailsDao.findDetail(vm.getId(), VirtualMachine.IsDynamicScalingEnabled); - if (vmDetailVO == null) { - vmDetailVO = new UserVmDetailVO(vm.getId(), VirtualMachine.IsDynamicScalingEnabled, isDynamicallyScalable.toString()); - _vmDetailsDao.persist(vmDetailVO); - } else { - vmDetailVO.setValue(isDynamicallyScalable.toString()); - _vmDetailsDao.update(vmDetailVO.getId(), vmDetailVO); - } + if (isDynamicallyScalable == null) { + isDynamicallyScalable = vmInstance.isDynamicallyScalable(); } - _vmDao.updateVM(id, displayName, ha, osTypeId, userData, isDisplayVmEnabled); + _vmDao.updateVM(id, displayName, ha, osTypeId, userData, isDisplayVmEnabled, isDynamicallyScalable); if (updateUserdata) { boolean result = updateUserDataInternal(_vmDao.findById(id)); @@ -2716,8 +2708,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir owner.getDomainId(), owner.getId(), offering.getId(), userData, hostName, diskOfferingId); vm.setUuid(uuidName); - vm.setDetail(VirtualMachine.IsDynamicScalingEnabled, template.isDynamicallyScalable().toString()); - + vm.setDynamicallyScalable(template.isDynamicallyScalable()); if (sshPublicKey != null) { vm.setDetail("SSH.PublicKey", sshPublicKey); } diff --git a/server/test/com/cloud/vm/VirtualMachineManagerImplTest.java b/server/test/com/cloud/vm/VirtualMachineManagerImplTest.java index 7882b197d99..9f36450c67e 100644 --- a/server/test/com/cloud/vm/VirtualMachineManagerImplTest.java +++ b/server/test/com/cloud/vm/VirtualMachineManagerImplTest.java @@ -265,8 +265,6 @@ public class VirtualMachineManagerImplTest { long l = 1L; doReturn(3L).when(_vmInstance).getId(); - when(_vmDetailsDao.findDetail(3L, VirtualMachine.IsDynamicScalingEnabled)).thenReturn(_vmDetailVO); - doReturn("true").when(_vmDetailVO).getValue(); when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance); ServiceOfferingVO newServiceOffering = getSvcoffering(512); doReturn(1L).when(_vmInstance).getHostId(); diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 530608edc70..3ed2fd25350 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -43,7 +43,9 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'manage ALTER TABLE `cloud`.`load_balancer_vm_map` ADD state VARCHAR(40) NULL COMMENT 'service status updated by LB healthcheck manager'; ALTER TABLE `cloud`.`vm_template` ADD COLUMN `dynamically_scalable` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory'; +ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `dynamically_scalable` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if VM contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory'; UPDATE `cloud`.`vm_template` SET dynamically_scalable = 1 WHERE name = "CentOS 5.6(64-bit) no GUI (XenServer)" AND type = "BUILTIN"; +UPDATE `cloud`.`vm_template` SET dynamically_scalable = 1 WHERE name = "SystemVM Template (vSphere)" AND type = "SYSTEM"; alter table storage_pool add hypervisor varchar(32); alter table storage_pool change storage_provider_id storage_provider_name varchar(255); @@ -1620,7 +1622,7 @@ CREATE VIEW `cloud`.`user_vm_view` AS affinity_group.uuid affinity_group_uuid, affinity_group.name affinity_group_name, affinity_group.description affinity_group_description, - vm_details.value dynamically_scalable + vm_instance.dynamically_scalable dynamically_scalable from `cloud`.`user_vm` @@ -1684,10 +1686,7 @@ CREATE VIEW `cloud`.`user_vm_view` AS left join `cloud`.`affinity_group_vm_map` ON vm_instance.id = affinity_group_vm_map.instance_id left join - `cloud`.`affinity_group` ON affinity_group_vm_map.affinity_group_id = affinity_group.id - left join - `cloud`.`user_vm_details` vm_details ON vm_details.vm_id = vm_instance.id - and vm_details.name = 'enable.dynamic.scaling'; + `cloud`.`affinity_group` ON affinity_group_vm_map.affinity_group_id = affinity_group.id; DROP VIEW IF EXISTS `cloud`.`volume_view`; CREATE VIEW `cloud`.`volume_view` AS