Skip to content

Commit 3e4430d

Browse files
committed
CLOUDSTACK-658 - Scaleup vm support for Xenserver
Added the framweork so that it can be extended for vmware and kvm as well. Added unitests and marvin tests.
1 parent f8b8f60 commit 3e4430d

24 files changed

Lines changed: 1545 additions & 79 deletions

File tree

api/src/com/cloud/agent/api/ScaleVmCommand.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ public int getCpus() {
4040
}
4141

4242
public ScaleVmCommand(String vmName, int cpus,
43-
Integer speed, long minRam, long maxRam) {
43+
Integer speed, long minRam, long maxRam, boolean limitCpuUse) {
4444
super();
4545
this.vmName = vmName;
4646
this.cpus = cpus;
47-
//this.speed = speed;
47+
this.speed = speed;
4848
this.minRam = minRam;
4949
this.maxRam = maxRam;
50-
this.vm = new VirtualMachineTO(1L, vmName, null, cpus, null, minRam, maxRam, null, null, false, false, null);
50+
this.vm = new VirtualMachineTO(1L, vmName, null, cpus, speed, minRam, maxRam, null, null, false, false, null);
5151
/*vm.setName(vmName);
5252
vm.setCpus(cpus);
5353
vm.setRam(minRam, maxRam);*/

api/src/com/cloud/event/EventTypes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public class EventTypes {
5959
public static final String EVENT_VM_REBOOT = "VM.REBOOT";
6060
public static final String EVENT_VM_UPDATE = "VM.UPDATE";
6161
public static final String EVENT_VM_UPGRADE = "VM.UPGRADE";
62+
public static final String EVENT_VM_SCALE = "VM.SCALE";
6263
public static final String EVENT_VM_RESETPASSWORD = "VM.RESETPASSWORD";
6364
public static final String EVENT_VM_RESETSSHKEY = "VM.RESETSSHKEY";
6465
public static final String EVENT_VM_MIGRATE = "VM.MIGRATE";

api/src/com/cloud/vm/UserVmService.java

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,7 @@
2323

2424
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
2525
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
26-
import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
27-
import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
28-
import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
29-
import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
30-
import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
31-
import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
32-
import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
33-
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
34-
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
35-
import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
36-
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
37-
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
26+
import org.apache.cloudstack.api.command.user.vm.*;
3827
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
3928
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
4029
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
@@ -402,4 +391,7 @@ UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityExceptio
402391
VirtualMachine vmStorageMigration(Long vmId, StoragePool destPool);
403392

404393
UserVm restoreVM(RestoreVMCmd cmd);
394+
395+
UserVm upgradeVirtualMachine(ScaleVMCmd scaleVMCmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException;
396+
405397
}

api/src/com/cloud/vm/VirtualMachine.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ public enum Event {
176176
AgentReportShutdowned,
177177
AgentReportMigrated,
178178
RevertRequested,
179-
SnapshotRequested
179+
SnapshotRequested,
180180
};
181181

182182
public enum Type {
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.api.command.user.vm;
18+
19+
import com.cloud.exception.*;
20+
import com.cloud.user.Account;
21+
import com.cloud.user.UserContext;
22+
import com.cloud.uservm.UserVm;
23+
import org.apache.cloudstack.api.*;
24+
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
25+
import org.apache.cloudstack.api.response.UserVmResponse;
26+
import org.apache.log4j.Logger;
27+
28+
29+
@APICommand(name = "scaleVirtualMachine", description="Scales the virtual machine to a new service offering.", responseObject=UserVmResponse.class)
30+
public class ScaleVMCmd extends BaseCmd {
31+
public static final Logger s_logger = Logger.getLogger(ScaleVMCmd.class.getName());
32+
private static final String s_name = "scalevirtualmachineresponse";
33+
34+
/////////////////////////////////////////////////////
35+
//////////////// API parameters /////////////////////
36+
/////////////////////////////////////////////////////
37+
38+
@ACL
39+
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
40+
required=true, description="The ID of the virtual machine")
41+
private Long id;
42+
43+
@ACL
44+
@Parameter(name=ApiConstants.SERVICE_OFFERING_ID, type=CommandType.UUID, entityType=ServiceOfferingResponse.class,
45+
required=true, description="the ID of the service offering for the virtual machine")
46+
private Long serviceOfferingId;
47+
48+
/////////////////////////////////////////////////////
49+
/////////////////// Accessors ///////////////////////
50+
/////////////////////////////////////////////////////
51+
52+
public Long getId() {
53+
return id;
54+
}
55+
56+
public Long getServiceOfferingId() {
57+
return serviceOfferingId;
58+
}
59+
60+
/////////////////////////////////////////////////////
61+
/////////////// API Implementation///////////////////
62+
/////////////////////////////////////////////////////
63+
64+
@Override
65+
public String getCommandName() {
66+
return s_name;
67+
}
68+
69+
public static String getResultObjectName() {
70+
return "virtualmachine";
71+
}
72+
73+
@Override
74+
public long getEntityOwnerId() {
75+
UserVm userVm = _entityMgr.findById(UserVm.class, getId());
76+
if (userVm != null) {
77+
return userVm.getAccountId();
78+
}
79+
80+
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
81+
}
82+
83+
@Override
84+
public void execute(){
85+
//UserContext.current().setEventDetails("Vm Id: "+getId());
86+
UserVm result = null;
87+
try {
88+
result = _userVmService.upgradeVirtualMachine(this);
89+
} catch (ResourceUnavailableException ex) {
90+
s_logger.warn("Exception: ", ex);
91+
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
92+
} catch (ConcurrentOperationException ex) {
93+
s_logger.warn("Exception: ", ex);
94+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
95+
} catch (ManagementServerException ex) {
96+
s_logger.warn("Exception: ", ex);
97+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
98+
} catch (VirtualMachineMigrationException ex) {
99+
s_logger.warn("Exception: ", ex);
100+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
101+
}
102+
if (result != null){
103+
UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
104+
response.setResponseName(getCommandName());
105+
this.setResponseObject(response);
106+
} else {
107+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to scale vm");
108+
}
109+
}
110+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.api.command.test;
18+
19+
import com.cloud.user.Account;
20+
import com.cloud.user.UserContext;
21+
import com.cloud.uservm.UserVm;
22+
import com.cloud.vm.UserVmService;
23+
import junit.framework.Assert;
24+
import junit.framework.TestCase;
25+
import org.apache.cloudstack.api.ResponseGenerator;
26+
import org.apache.cloudstack.api.ServerApiException;
27+
import org.apache.cloudstack.api.command.admin.region.AddRegionCmd;
28+
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
29+
import org.apache.cloudstack.api.response.RegionResponse;
30+
import org.apache.cloudstack.api.response.UserVmResponse;
31+
import org.apache.cloudstack.region.Region;
32+
import org.apache.cloudstack.region.RegionService;
33+
import org.junit.Before;
34+
import org.junit.Rule;
35+
import org.junit.Test;
36+
import org.junit.rules.ExpectedException;
37+
import org.mockito.Mockito;
38+
39+
import java.util.ArrayList;
40+
import java.util.List;
41+
import java.util.UUID;
42+
43+
44+
public class ScaleVMCmdTest extends TestCase{
45+
46+
private ScaleVMCmd scaleVMCmd;
47+
private ResponseGenerator responseGenerator;
48+
49+
@Rule
50+
public ExpectedException expectedException = ExpectedException.none();
51+
52+
@Before
53+
public void setUp() {
54+
55+
scaleVMCmd = new ScaleVMCmd(){
56+
@Override
57+
public Long getId() {
58+
return 2L;
59+
}
60+
};
61+
62+
//Account account = new AccountVO("testaccount", 1L, "networkdomain", (short) 0, "uuid");
63+
//UserContext.registerContext(1, account, null, true);
64+
65+
66+
}
67+
68+
69+
@Test
70+
public void testCreateSuccess() {
71+
72+
UserVmService userVmService = Mockito.mock(UserVmService.class);
73+
74+
UserVm uservm = Mockito.mock(UserVm.class);
75+
try {
76+
Mockito.when(
77+
userVmService.upgradeVirtualMachine(scaleVMCmd))
78+
.thenReturn(uservm);
79+
}catch (Exception e){
80+
Assert.fail("Received exception when success expected " +e.getMessage());
81+
}
82+
83+
scaleVMCmd._userVmService = userVmService;
84+
responseGenerator = Mockito.mock(ResponseGenerator.class);
85+
86+
UserVmResponse userVmResponse = Mockito.mock(UserVmResponse.class);
87+
List<UserVmResponse> responseList = new ArrayList<UserVmResponse>();
88+
responseList.add(userVmResponse);
89+
90+
Mockito.when(responseGenerator.createUserVmResponse("virtualmachine",uservm))
91+
.thenReturn(responseList);
92+
93+
scaleVMCmd._responseGenerator = responseGenerator;
94+
scaleVMCmd.execute();
95+
96+
}
97+
98+
@Test
99+
public void testCreateFailure() {
100+
101+
UserVmService userVmService = Mockito.mock(UserVmService.class);
102+
103+
try {
104+
UserVm uservm = Mockito.mock(UserVm.class);
105+
Mockito.when(
106+
userVmService.upgradeVirtualMachine(scaleVMCmd))
107+
.thenReturn(null);
108+
}catch (Exception e){
109+
Assert.fail("Received exception when success expected " +e.getMessage());
110+
}
111+
112+
scaleVMCmd._userVmService = userVmService;
113+
114+
try {
115+
scaleVMCmd.execute();
116+
} catch (ServerApiException exception) {
117+
Assert.assertEquals("Failed to scale vm",
118+
exception.getDescription());
119+
}
120+
121+
}
122+
}

client/tomcatconf/commands.properties.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ listVirtualMachines=15
6666
getVMPassword=15
6767
restoreVirtualMachine=15
6868
changeServiceForVirtualMachine=15
69+
scaleVirtualMachine=15
6970
assignVirtualMachine=1
7071
migrateVirtualMachine=1
7172
recoverVirtualMachine=7

core/src/com/cloud/vm/VMInstanceVO.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,4 +480,4 @@ public Long getDiskOfferingId() {
480480
return diskOfferingId;
481481
}
482482

483-
}
483+
}

0 commit comments

Comments
 (0)