From 0d4f67ad8c3e7c3a7cc7e067b7b20c227be7ff0c Mon Sep 17 00:00:00 2001 From: harikrishna-patnala Date: Thu, 18 Jun 2020 09:19:19 +0530 Subject: [PATCH] server: NPE occured when dynamic scaling tried on VM and as part of this when VM tries to migrate if current host does not have capacity. (#3998) Repro Steps: 1. Create a VM on host1 2. Make host1 capacity full by deploying multiple VMs 3. Try Dynamic scaling on VM on host1 4. NPE occurs when MS tries to find host to migrate the VM and then scale. Root cause: VM profile is not initiated properly with serviceoffering before planning for deployment Solution: Iniate VM profile with serviceoffering and also make sure custom compute parameters are handled --- .../main/java/com/cloud/vm/VirtualMachineManager.java | 2 +- .../java/com/cloud/vm/VirtualMachineManagerImpl.java | 10 +++++++--- .../com/cloud/vm/VirtualMachineManagerImplTest.java | 2 +- .../src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java index 3b9358a3682..e3afbf40a00 100644 --- a/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java @@ -207,7 +207,7 @@ public interface VirtualMachineManager extends Manager { VirtualMachine reConfigureVm(String vmUuid, ServiceOffering oldServiceOffering, ServiceOffering newServiceOffering, Map customParameters, boolean sameHost) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientServerCapacityException; - void findHostAndMigrate(String vmUuid, Long newSvcOfferingId, DeploymentPlanner.ExcludeList excludeHostList) throws InsufficientCapacityException, + void findHostAndMigrate(String vmUuid, Long newSvcOfferingId, Map customParameters, DeploymentPlanner.ExcludeList excludeHostList) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException; void migrateForScale(String vmUuid, long srcHostId, DeployDestination dest, Long newSvcOfferingId) throws ResourceUnavailableException, ConcurrentOperationException; diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index 20750b33f7e..5ccb80d8a7d 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -3869,15 +3869,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } @Override - public void findHostAndMigrate(final String vmUuid, final Long newSvcOfferingId, final ExcludeList excludes) throws InsufficientCapacityException, ConcurrentOperationException, + public void findHostAndMigrate(final String vmUuid, final Long newSvcOfferingId, final Map customParameters, final ExcludeList excludes) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { final VMInstanceVO vm = _vmDao.findByUuid(vmUuid); if (vm == null) { throw new CloudRuntimeException("Unable to find " + vmUuid); } - - final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); + ServiceOfferingVO newServiceOffering = _offeringDao.findById(newSvcOfferingId); + if (newServiceOffering.isDynamic()) { + newServiceOffering.setDynamicFlag(true); + newServiceOffering = _offeringDao.getComputeOffering(newServiceOffering, customParameters); + } + final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, null, newServiceOffering, null, null); final Long srcHostId = vm.getHostId(); final Long oldSvcOfferingId = vm.getServiceOfferingId(); diff --git a/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java index 0e7579ea5fd..1725a413145 100644 --- a/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java +++ b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java @@ -150,7 +150,7 @@ public class VirtualMachineManagerImplTest { when(vmInstanceDaoMock.findById(anyLong())).thenReturn(vmInstanceMock); when(vmInstanceDaoMock.findByUuid(any(String.class))).thenReturn(vmInstanceMock); DeploymentPlanner.ExcludeList excludeHostList = new DeploymentPlanner.ExcludeList(); - virtualMachineManagerImpl.findHostAndMigrate(vmInstanceMock.getUuid(), 2l, excludeHostList); + virtualMachineManagerImpl.findHostAndMigrate(vmInstanceMock.getUuid(), 2l, null, excludeHostList); } @Test diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index da493e7c1cf..60e82e35a36 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -1859,7 +1859,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir // #2 migrate the vm if host doesn't have capacity or is in avoid set if (!existingHostHasCapacity) { - _itMgr.findHostAndMigrate(vmInstance.getUuid(), newServiceOfferingId, excludes); + _itMgr.findHostAndMigrate(vmInstance.getUuid(), newServiceOfferingId, customParameters, excludes); } // #3 scale the vm now