diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml
index d65ef640655..79779decf62 100644
--- a/plugins/hypervisors/vmware/pom.xml
+++ b/plugins/hypervisors/vmware/pom.xml
@@ -58,5 +58,15 @@
wsdl4j
1.4
+
+ junit
+ junit
+ 4.10
+
+
+ org.mockito
+ mockito-all
+ 1.9.5
+
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index d87da64040b..6d7e0e7289c 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -111,6 +111,8 @@ import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.RebootRouterCommand;
import com.cloud.agent.api.RevertToVMSnapshotAnswer;
import com.cloud.agent.api.RevertToVMSnapshotCommand;
+import com.cloud.agent.api.ScaleVmCommand;
+import com.cloud.agent.api.ScaleVmAnswer;
import com.cloud.agent.api.SetupAnswer;
import com.cloud.agent.api.SetupCommand;
import com.cloud.agent.api.SetupGuestNetworkAnswer;
@@ -485,6 +487,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
return execute((ResizeVolumeCommand) cmd);
} else if (clz == UnregisterVMCommand.class) {
return execute((UnregisterVMCommand) cmd);
+ } else if (clz == ScaleVmCommand.class) {
+ return execute((ScaleVmCommand) cmd);
} else {
answer = Answer.createUnsupportedCommandAnswer(cmd);
}
@@ -2088,6 +2092,28 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
return validatedDisks.toArray(new VolumeTO[0]);
}
+ protected ScaleVmAnswer execute(ScaleVmCommand cmd) {
+
+ VmwareContext context = getServiceContext();
+ VirtualMachineTO vmSpec = cmd.getVirtualMachine();
+ try{
+ VmwareHypervisorHost hyperHost = getHyperHost(context);
+ VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
+ VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+ int ramMb = (int) (vmSpec.getMinRam());
+
+ VmwareHelper.setVmScaleUpConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getSpeed(), vmSpec.getSpeed(),(int) (vmSpec.getMaxRam()), ramMb, vmSpec.getLimitCpuUse());
+
+ if(!vmMo.configureVm(vmConfigSpec)) {
+ throw new Exception("Unable to execute ScaleVmCommand");
+ }
+ }catch(Exception e) {
+ s_logger.error("Unexpected exception: ", e);
+ return new ScaleVmAnswer(cmd, false, "Unable to execute ScaleVmCommand due to " + e.toString());
+ }
+ return new ScaleVmAnswer(cmd, true, null);
+ }
+
protected StartAnswer execute(StartCommand cmd) {
if (s_logger.isInfoEnabled()) {
@@ -2191,7 +2217,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(),
vmSpec.getMinSpeed(),(int) (vmSpec.getMaxRam()/(1024*1024)), ramMb,
translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), vmSpec.getLimitCpuUse());
-
+
+ vmConfigSpec.setMemoryHotAddEnabled(true);
+ vmConfigSpec.setCpuHotAddEnabled(true);
+
if ("true".equals(vmSpec.getDetails().get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG))) {
s_logger.debug("Nested Virtualization enabled in configuration, checking hypervisor capability");
ManagedObjectReference hostMor = vmMo.getRunningHost().getMor();
diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
new file mode 100644
index 00000000000..3ca0b600e36
--- /dev/null
+++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
@@ -0,0 +1,82 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.hypervisor.vmware.resource;
+
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ScaleVmAnswer;
+import com.cloud.agent.api.ScaleVmCommand;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
+import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
+import com.cloud.hypervisor.vmware.util.VmwareContext;
+import com.cloud.hypervisor.vmware.util.VmwareHelper;
+import com.vmware.vim25.VirtualMachineConfigSpec;
+import org.junit.Test;
+import org.junit.Before;
+
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.MockitoAnnotations;
+import static org.mockito.Mockito.*;
+
+
+public class VmwareResourceTest {
+
+ @Spy VmwareResource _resource = new VmwareResource() {
+
+ @Override
+ public ScaleVmAnswer execute(ScaleVmCommand cmd) {
+ return super.execute(cmd);
+ }
+ @Override
+ public VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd) {
+ return hyperHost;
+ }
+ };
+
+ @Mock VmwareContext context;
+ @Mock ScaleVmCommand cmd;
+ @Mock VirtualMachineTO vmSpec;
+ @Mock
+ VmwareHypervisorHost hyperHost;
+ @Mock VirtualMachineMO vmMo;
+ @Mock VirtualMachineConfigSpec vmConfigSpec;
+
+ @Before
+ public void setup(){
+ MockitoAnnotations.initMocks(this);
+ doReturn(context).when(_resource).getServiceContext(null);
+ when(cmd.getVirtualMachine()).thenReturn(vmSpec);
+ }
+ //Test successful scaling up the vm
+ @Test
+ public void testScaleVMF1() throws Exception {
+ when(_resource.getHyperHost(context, null)).thenReturn(hyperHost);
+ doReturn("i-2-3-VM").when(cmd).getVmName();
+ when(hyperHost.findVmOnHyperHost("i-2-3-VM")).thenReturn(vmMo);
+ doReturn(1024L).when(vmSpec).getMinRam();
+ doReturn(1).when(vmSpec).getCpus();
+ doReturn(1000).when(vmSpec).getSpeed();
+ doReturn(1024L).when(vmSpec).getMaxRam();
+ doReturn(false).when(vmSpec).getLimitCpuUse();
+ when(vmMo.configureVm(vmConfigSpec)).thenReturn(true);
+
+ ScaleVmAnswer answer = _resource.execute(cmd);
+ verify(_resource).execute(cmd);
+ }
+
+}
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index eee8503b3f5..9fbc5099374 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -1064,7 +1064,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
// Verify input parameters
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
- if(vmInstance.getHypervisorType() != HypervisorType.XenServer){
+ if(vmInstance.getHypervisorType() != HypervisorType.XenServer && vmInstance.getHypervisorType() != HypervisorType.VMware){
throw new InvalidParameterValueException("This operation not permitted for this hypervisor of the vm");
}
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java
index 9c467dc8b6b..4a6a135a5b8 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java
@@ -524,7 +524,31 @@ public class VmwareHelper {
return options;
}
- public static void setBasicVmConfig(VirtualMachineConfigSpec vmConfig, int cpuCount, int cpuSpeedMHz, int cpuReservedMhz,
+ public static void setVmScaleUpConfig(VirtualMachineConfigSpec vmConfig, int cpuCount, int cpuSpeedMHz, int cpuReservedMhz,
+ int memoryMB, int memoryReserveMB, boolean limitCpuUse) {
+
+ // VM config for scaling up
+ vmConfig.setMemoryMB((long)memoryMB);
+ vmConfig.setNumCPUs(cpuCount);
+
+ ResourceAllocationInfo cpuInfo = new ResourceAllocationInfo();
+ if (limitCpuUse) {
+ cpuInfo.setLimit((long)(cpuSpeedMHz * cpuCount));
+ } else {
+ cpuInfo.setLimit(-1L);
+ }
+
+ cpuInfo.setReservation((long)cpuReservedMhz);
+ vmConfig.setCpuAllocation(cpuInfo);
+
+ ResourceAllocationInfo memInfo = new ResourceAllocationInfo();
+ memInfo.setLimit((long)memoryMB);
+ memInfo.setReservation((long)memoryReserveMB);
+ vmConfig.setMemoryAllocation(memInfo);
+
+ }
+
+ public static void setBasicVmConfig(VirtualMachineConfigSpec vmConfig, int cpuCount, int cpuSpeedMHz, int cpuReservedMhz,
int memoryMB, int memoryReserveMB, String guestOsIdentifier, boolean limitCpuUse) {
// VM config basics