Repository: cloudstack Updated Branches: refs/heads/master c93b2fa60 -> d9a4e038a
Enhanced updateVirtualMachine API with optional parameter "name" - to allow update hostName for the virtual machine Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/d9a4e038 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/d9a4e038 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/d9a4e038 Branch: refs/heads/master Commit: d9a4e038a0d38bfcd4b15154e0cd796414204b14 Parents: c93b2fa Author: Alena Prokharchyk <[email protected]> Authored: Fri Feb 28 14:25:32 2014 -0800 Committer: Alena Prokharchyk <[email protected]> Committed: Fri Feb 28 14:35:37 2014 -0800 ---------------------------------------------------------------------- .../api/command/user/vm/UpdateVMCmd.java | 7 ++ .../schema/src/com/cloud/vm/VMInstanceVO.java | 6 +- .../schema/src/com/cloud/vm/dao/UserVmDao.java | 3 +- .../src/com/cloud/vm/dao/UserVmDaoImpl.java | 5 +- server/src/com/cloud/vm/UserVmManager.java | 3 +- server/src/com/cloud/vm/UserVmManagerImpl.java | 82 +++++++++++++------- 6 files changed, 72 insertions(+), 34 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d9a4e038/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java index fc3be33..9e16f01 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java @@ -77,6 +77,9 @@ public class UpdateVMCmd extends BaseCustomIdCmd { description = "true if VM contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory") protected Boolean isDynamicallyScalable; + @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") + private String name; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -109,6 +112,10 @@ public class UpdateVMCmd extends BaseCustomIdCmd { return isDynamicallyScalable; } + public String getHostName() { + return name; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d9a4e038/engine/schema/src/com/cloud/vm/VMInstanceVO.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/vm/VMInstanceVO.java b/engine/schema/src/com/cloud/vm/VMInstanceVO.java index 48229b8..30ef60f 100644 --- a/engine/schema/src/com/cloud/vm/VMInstanceVO.java +++ b/engine/schema/src/com/cloud/vm/VMInstanceVO.java @@ -53,7 +53,7 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi @Column(name = "id", updatable = false, nullable = false) protected long id; - @Column(name = "name", updatable = false, nullable = false, length = 255) + @Column(name = "name", nullable = false, length = 255) protected String hostName = null; @Encrypt @@ -272,6 +272,10 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi return hostName; } + public void setHostName(String hostName) { + this.hostName = hostName; + } + @Override public String getInstanceName() { return instanceName; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d9a4e038/engine/schema/src/com/cloud/vm/dao/UserVmDao.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDao.java b/engine/schema/src/com/cloud/vm/dao/UserVmDao.java index 0a4acbb..884d0a3 100755 --- a/engine/schema/src/com/cloud/vm/dao/UserVmDao.java +++ b/engine/schema/src/com/cloud/vm/dao/UserVmDao.java @@ -43,8 +43,9 @@ public interface UserVmDao extends GenericDao<UserVmVO, Long> { * @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. * @param customId + * @param hostName TODO */ - void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable, String customId); + void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable, String customId, String hostName); List<UserVmVO> findDestroyedVms(Date date); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d9a4e038/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java index feacee7..7a05be8 100755 --- a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java @@ -216,7 +216,7 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use } @Override - public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable, String customId) { + public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable, String customId, String hostName) { UserVmVO vo = createForUpdate(); vo.setDisplayName(displayName); vo.setHaEnabled(enable); @@ -224,6 +224,9 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use vo.setUserData(userData); vo.setDisplayVm(displayVm); vo.setDynamicallyScalable(isDynamicallyScalable); + if (hostName != null) { + vo.setHostName(hostName); + } if (customId != null) { vo.setUuid(customId); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d9a4e038/server/src/com/cloud/vm/UserVmManager.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index 950e7e3..7371692 100755 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -22,6 +22,7 @@ import java.util.Map; import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; + import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.framework.config.ConfigKey; @@ -119,7 +120,7 @@ public interface UserVmManager extends UserVmService { void collectVmDiskStatistics(UserVmVO userVm); UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData, - Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId) throws ResourceUnavailableException, InsufficientCapacityException; + Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName) throws ResourceUnavailableException, InsufficientCapacityException; //the validateCustomParameters, save and remove CustomOfferingDetils functions can be removed from the interface once we can //find a common place for all the scaling and upgrading code of both user and systemvms. http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d9a4e038/server/src/com/cloud/vm/UserVmManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 97e3ae7..2f686be 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1831,7 +1831,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir Long osTypeId = cmd.getOsTypeId(); String userData = cmd.getUserData(); Boolean isDynamicallyScalable = cmd.isDynamicallyScalable(); - Account caller = CallContext.current().getCallingAccount(); + String hostName = cmd.getHostName(); // Input validation and permission checks UserVmVO vmInstance = _vmDao.findById(id.longValue()); @@ -1849,12 +1849,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.memory, isDisplayVm, new Long(offering.getRamSize())); } - return updateVirtualMachine(id, displayName, group, ha, isDisplayVm, osTypeId, userData, isDynamicallyScalable, cmd.getHttpMethod(), cmd.getCustomId()); + return updateVirtualMachine(id, displayName, group, ha, isDisplayVm, osTypeId, userData, isDynamicallyScalable, cmd.getHttpMethod(), cmd.getCustomId(), hostName); } @Override public UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData, - Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId) throws ResourceUnavailableException, InsufficientCapacityException { + Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName) throws ResourceUnavailableException, InsufficientCapacityException { UserVmVO vm = _vmDao.findById(id); if (vm == null) { throw new CloudRuntimeException("Unable to find virual machine with id " + id); @@ -1909,7 +1909,25 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir isDynamicallyScalable = vm.isDynamicallyScalable(); } - _vmDao.updateVM(id, displayName, ha, osTypeId, userData, isDisplayVmEnabled, isDynamicallyScalable, customId); + if (hostName != null) { + // Check is hostName is RFC compliant + checkNameForRFCCompliance(hostName); + + if (vm.getHostName().equalsIgnoreCase(hostName)) { + s_logger.debug("Vm " + vm + " is already set with the hostName specified: " + hostName); + hostName = null; + } + + // Verify that vm's hostName is unique + List<NetworkVO> vmNtwks = new ArrayList<NetworkVO>(); + List<? extends Nic> nics = _nicDao.listByVmId(vm.getId()); + for (Nic nic : nics) { + vmNtwks.add(_networkDao.findById(nic.getNetworkId())); + } + checkIfHostNameUniqueInNtwkDomain(hostName, vmNtwks); + } + + _vmDao.updateVM(id, displayName, ha, osTypeId, userData, isDisplayVmEnabled, isDynamicallyScalable, customId, hostName); if (updateUserdata) { boolean result = updateUserDataInternal(_vmDao.findById(id)); @@ -2728,32 +2746,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir throw new InvalidParameterValueException("There already exists a VM by the display name supplied"); } - // Check that hostName is unique in the network domain - Map<String, List<Long>> ntwkDomains = new HashMap<String, List<Long>>(); - for (NetworkVO network : networkList) { - String ntwkDomain = network.getNetworkDomain(); - if (!ntwkDomains.containsKey(ntwkDomain)) { - List<Long> ntwkIds = new ArrayList<Long>(); - ntwkIds.add(network.getId()); - ntwkDomains.put(ntwkDomain, ntwkIds); - } else { - List<Long> ntwkIds = ntwkDomains.get(ntwkDomain); - ntwkIds.add(network.getId()); - ntwkDomains.put(ntwkDomain, ntwkIds); - } - } - - for (Entry<String, List<Long>> ntwkDomain : ntwkDomains.entrySet()) { - for (Long ntwkId : ntwkDomain.getValue()) { - // * get all vms hostNames in the network - List<String> hostNames = _vmInstanceDao.listDistinctHostNames(ntwkId); - // * verify that there are no duplicates - if (hostNames.contains(hostName)) { - throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the network domain: " + ntwkDomain.getKey() + "; network=" - + _networkModel.getNetwork(ntwkId)); - } - } - } + checkIfHostNameUniqueInNtwkDomain(hostName, networkList); HypervisorType hypervisorType = null; if (template.getHypervisorType() == null || template.getHypervisorType() == HypervisorType.None) { @@ -2786,6 +2779,35 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir return vm; } + private void checkIfHostNameUniqueInNtwkDomain(String hostName, List<? extends Network> networkList) { + // Check that hostName is unique in the network domain + Map<String, List<Long>> ntwkDomains = new HashMap<String, List<Long>>(); + for (Network network : networkList) { + String ntwkDomain = network.getNetworkDomain(); + if (!ntwkDomains.containsKey(ntwkDomain)) { + List<Long> ntwkIds = new ArrayList<Long>(); + ntwkIds.add(network.getId()); + ntwkDomains.put(ntwkDomain, ntwkIds); + } else { + List<Long> ntwkIds = ntwkDomains.get(ntwkDomain); + ntwkIds.add(network.getId()); + ntwkDomains.put(ntwkDomain, ntwkIds); + } + } + + for (Entry<String, List<Long>> ntwkDomain : ntwkDomains.entrySet()) { + for (Long ntwkId : ntwkDomain.getValue()) { + // * get all vms hostNames in the network + List<String> hostNames = _vmInstanceDao.listDistinctHostNames(ntwkId); + // * verify that there are no duplicates + if (hostNames.contains(hostName)) { + throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the network domain: " + ntwkDomain.getKey() + "; network=" + + _networkModel.getNetwork(ntwkId)); + } + } + } + } + private String generateHostName(String uuidName) { return _instance + "-" + uuidName; }
