Skip to content

Commit d9a4e03

Browse files
author
Alena Prokharchyk
committed
Enhanced updateVirtualMachine API with optional parameter "name" - to allow update hostName for the virtual machine
1 parent c93b2fa commit d9a4e03

6 files changed

Lines changed: 72 additions & 34 deletions

File tree

api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ public class UpdateVMCmd extends BaseCustomIdCmd {
7777
description = "true if VM contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
7878
protected Boolean isDynamicallyScalable;
7979

80+
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "new host name of the vm. The VM has to be stopped/started for this update to take affect", since = "4.4")
81+
private String name;
82+
8083
/////////////////////////////////////////////////////
8184
/////////////////// Accessors ///////////////////////
8285
/////////////////////////////////////////////////////
@@ -109,6 +112,10 @@ public Boolean isDynamicallyScalable() {
109112
return isDynamicallyScalable;
110113
}
111114

115+
public String getHostName() {
116+
return name;
117+
}
118+
112119
/////////////////////////////////////////////////////
113120
/////////////// API Implementation///////////////////
114121
/////////////////////////////////////////////////////

engine/schema/src/com/cloud/vm/VMInstanceVO.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
5353
@Column(name = "id", updatable = false, nullable = false)
5454
protected long id;
5555

56-
@Column(name = "name", updatable = false, nullable = false, length = 255)
56+
@Column(name = "name", nullable = false, length = 255)
5757
protected String hostName = null;
5858

5959
@Encrypt
@@ -272,6 +272,10 @@ public String getHostName() {
272272
return hostName;
273273
}
274274

275+
public void setHostName(String hostName) {
276+
this.hostName = hostName;
277+
}
278+
275279
@Override
276280
public String getInstanceName() {
277281
return instanceName;

engine/schema/src/com/cloud/vm/dao/UserVmDao.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ public interface UserVmDao extends GenericDao<UserVmVO, Long> {
4343
* @param userData updates the userData of the vm
4444
* @param displayVm updates the displayvm attribute signifying whether it has to be displayed to the end user or not.
4545
* @param customId
46+
* @param hostName TODO
4647
*/
47-
void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable, String customId);
48+
void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable, String customId, String hostName);
4849

4950
List<UserVmVO> findDestroyedVms(Date date);
5051

engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,14 +216,17 @@ public List<UserVmVO> listByAccountAndDataCenter(long accountId, long dcId) {
216216
}
217217

218218
@Override
219-
public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable, String customId) {
219+
public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable, String customId, String hostName) {
220220
UserVmVO vo = createForUpdate();
221221
vo.setDisplayName(displayName);
222222
vo.setHaEnabled(enable);
223223
vo.setGuestOSId(osTypeId);
224224
vo.setUserData(userData);
225225
vo.setDisplayVm(displayVm);
226226
vo.setDynamicallyScalable(isDynamicallyScalable);
227+
if (hostName != null) {
228+
vo.setHostName(hostName);
229+
}
227230
if (customId != null) {
228231
vo.setUuid(customId);
229232
}

server/src/com/cloud/vm/UserVmManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import com.cloud.offering.ServiceOffering;
2424
import com.cloud.service.ServiceOfferingVO;
25+
2526
import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
2627
import org.apache.cloudstack.framework.config.ConfigKey;
2728

@@ -119,7 +120,7 @@ boolean upgradeVirtualMachine(Long id, Long serviceOfferingId, Map<String, Strin
119120
void collectVmDiskStatistics(UserVmVO userVm);
120121

121122
UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData,
122-
Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId) throws ResourceUnavailableException, InsufficientCapacityException;
123+
Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName) throws ResourceUnavailableException, InsufficientCapacityException;
123124

124125
//the validateCustomParameters, save and remove CustomOfferingDetils functions can be removed from the interface once we can
125126
//find a common place for all the scaling and upgrading code of both user and systemvms.

server/src/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1831,7 +1831,7 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx
18311831
Long osTypeId = cmd.getOsTypeId();
18321832
String userData = cmd.getUserData();
18331833
Boolean isDynamicallyScalable = cmd.isDynamicallyScalable();
1834-
Account caller = CallContext.current().getCallingAccount();
1834+
String hostName = cmd.getHostName();
18351835

18361836
// Input validation and permission checks
18371837
UserVmVO vmInstance = _vmDao.findById(id.longValue());
@@ -1849,12 +1849,12 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx
18491849
_resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.memory, isDisplayVm, new Long(offering.getRamSize()));
18501850
}
18511851

1852-
return updateVirtualMachine(id, displayName, group, ha, isDisplayVm, osTypeId, userData, isDynamicallyScalable, cmd.getHttpMethod(), cmd.getCustomId());
1852+
return updateVirtualMachine(id, displayName, group, ha, isDisplayVm, osTypeId, userData, isDynamicallyScalable, cmd.getHttpMethod(), cmd.getCustomId(), hostName);
18531853
}
18541854

18551855
@Override
18561856
public UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData,
1857-
Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId) throws ResourceUnavailableException, InsufficientCapacityException {
1857+
Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName) throws ResourceUnavailableException, InsufficientCapacityException {
18581858
UserVmVO vm = _vmDao.findById(id);
18591859
if (vm == null) {
18601860
throw new CloudRuntimeException("Unable to find virual machine with id " + id);
@@ -1909,7 +1909,25 @@ public UserVm updateVirtualMachine(long id, String displayName, String group, Bo
19091909
isDynamicallyScalable = vm.isDynamicallyScalable();
19101910
}
19111911

1912-
_vmDao.updateVM(id, displayName, ha, osTypeId, userData, isDisplayVmEnabled, isDynamicallyScalable, customId);
1912+
if (hostName != null) {
1913+
// Check is hostName is RFC compliant
1914+
checkNameForRFCCompliance(hostName);
1915+
1916+
if (vm.getHostName().equalsIgnoreCase(hostName)) {
1917+
s_logger.debug("Vm " + vm + " is already set with the hostName specified: " + hostName);
1918+
hostName = null;
1919+
}
1920+
1921+
// Verify that vm's hostName is unique
1922+
List<NetworkVO> vmNtwks = new ArrayList<NetworkVO>();
1923+
List<? extends Nic> nics = _nicDao.listByVmId(vm.getId());
1924+
for (Nic nic : nics) {
1925+
vmNtwks.add(_networkDao.findById(nic.getNetworkId()));
1926+
}
1927+
checkIfHostNameUniqueInNtwkDomain(hostName, vmNtwks);
1928+
}
1929+
1930+
_vmDao.updateVM(id, displayName, ha, osTypeId, userData, isDisplayVmEnabled, isDynamicallyScalable, customId, hostName);
19131931

19141932
if (updateUserdata) {
19151933
boolean result = updateUserDataInternal(_vmDao.findById(id));
@@ -2728,32 +2746,7 @@ protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOf
27282746
throw new InvalidParameterValueException("There already exists a VM by the display name supplied");
27292747
}
27302748

2731-
// Check that hostName is unique in the network domain
2732-
Map<String, List<Long>> ntwkDomains = new HashMap<String, List<Long>>();
2733-
for (NetworkVO network : networkList) {
2734-
String ntwkDomain = network.getNetworkDomain();
2735-
if (!ntwkDomains.containsKey(ntwkDomain)) {
2736-
List<Long> ntwkIds = new ArrayList<Long>();
2737-
ntwkIds.add(network.getId());
2738-
ntwkDomains.put(ntwkDomain, ntwkIds);
2739-
} else {
2740-
List<Long> ntwkIds = ntwkDomains.get(ntwkDomain);
2741-
ntwkIds.add(network.getId());
2742-
ntwkDomains.put(ntwkDomain, ntwkIds);
2743-
}
2744-
}
2745-
2746-
for (Entry<String, List<Long>> ntwkDomain : ntwkDomains.entrySet()) {
2747-
for (Long ntwkId : ntwkDomain.getValue()) {
2748-
// * get all vms hostNames in the network
2749-
List<String> hostNames = _vmInstanceDao.listDistinctHostNames(ntwkId);
2750-
// * verify that there are no duplicates
2751-
if (hostNames.contains(hostName)) {
2752-
throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the network domain: " + ntwkDomain.getKey() + "; network="
2753-
+ _networkModel.getNetwork(ntwkId));
2754-
}
2755-
}
2756-
}
2749+
checkIfHostNameUniqueInNtwkDomain(hostName, networkList);
27572750

27582751
HypervisorType hypervisorType = null;
27592752
if (template.getHypervisorType() == null || template.getHypervisorType() == HypervisorType.None) {
@@ -2786,6 +2779,35 @@ protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOf
27862779
return vm;
27872780
}
27882781

2782+
private void checkIfHostNameUniqueInNtwkDomain(String hostName, List<? extends Network> networkList) {
2783+
// Check that hostName is unique in the network domain
2784+
Map<String, List<Long>> ntwkDomains = new HashMap<String, List<Long>>();
2785+
for (Network network : networkList) {
2786+
String ntwkDomain = network.getNetworkDomain();
2787+
if (!ntwkDomains.containsKey(ntwkDomain)) {
2788+
List<Long> ntwkIds = new ArrayList<Long>();
2789+
ntwkIds.add(network.getId());
2790+
ntwkDomains.put(ntwkDomain, ntwkIds);
2791+
} else {
2792+
List<Long> ntwkIds = ntwkDomains.get(ntwkDomain);
2793+
ntwkIds.add(network.getId());
2794+
ntwkDomains.put(ntwkDomain, ntwkIds);
2795+
}
2796+
}
2797+
2798+
for (Entry<String, List<Long>> ntwkDomain : ntwkDomains.entrySet()) {
2799+
for (Long ntwkId : ntwkDomain.getValue()) {
2800+
// * get all vms hostNames in the network
2801+
List<String> hostNames = _vmInstanceDao.listDistinctHostNames(ntwkId);
2802+
// * verify that there are no duplicates
2803+
if (hostNames.contains(hostName)) {
2804+
throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the network domain: " + ntwkDomain.getKey() + "; network="
2805+
+ _networkModel.getNetwork(ntwkId));
2806+
}
2807+
}
2808+
}
2809+
}
2810+
27892811
private String generateHostName(String uuidName) {
27902812
return _instance + "-" + uuidName;
27912813
}

0 commit comments

Comments
 (0)