Updated Branches: refs/heads/add_remove_nics ed12b2304 -> bdbbbc36e
Summary: Allow adding of more than one nic on the same network Detail: Cloudstack allows you to launch a VM with two or more nics on the same network, so this allows you to add more than one nic on the same network after deployment Submitted-by: Brian Angus <[email protected]> Signed-off-by: Marcus Sorensen <[email protected]> 1359063744 -0700 Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/bdbbbc36 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/bdbbbc36 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/bdbbbc36 Branch: refs/heads/add_remove_nics Commit: bdbbbc36e7407ac2e2847d590d1f861e92f42c8e Parents: ed12b23 Author: Marcus Sorensen <[email protected]> Authored: Thu Jan 24 14:42:24 2013 -0700 Committer: Marcus Sorensen <[email protected]> Committed: Thu Jan 24 14:42:24 2013 -0700 ---------------------------------------------------------------------- .../org/apache/cloudstack/api/ApiConstants.java | 1 + .../api/command/user/vm/RemoveNicFromVMCmd.java | 14 +- .../command/user/vm/UpdateDefaultNicForVMCmd.java | 18 ++-- .../cloudstack/api/response/NicResponse.java | 3 + server/src/com/cloud/network/NetworkManager.java | 2 +- .../src/com/cloud/network/NetworkManagerImpl.java | 4 +- server/src/com/cloud/vm/UserVmManagerImpl.java | 103 ++++++--------- server/src/com/cloud/vm/VirtualMachineManager.java | 9 ++ .../com/cloud/vm/VirtualMachineManagerImpl.java | 64 ++++++++- .../com/cloud/network/MockNetworkManagerImpl.java | 2 +- .../cloud/vm/MockVirtualMachineManagerImpl.java | 9 ++ .../test/com/cloud/vpc/MockNetworkManagerImpl.java | 4 +- 12 files changed, 146 insertions(+), 87 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bdbbbc36/api/src/org/apache/cloudstack/api/ApiConstants.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 58a7831..abcab05 100644 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -224,6 +224,7 @@ public class ApiConstants { public static final String NETWORK_OFFERING_ID = "networkofferingid"; public static final String NETWORK_IDS = "networkids"; public static final String NETWORK_ID = "networkid"; + public static final String NIC_ID = "nicid"; public static final String SPECIFY_VLAN = "specifyvlan"; public static final String IS_DEFAULT = "isdefault"; public static final String IS_SYSTEM = "issystem"; http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bdbbbc36/api/src/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java index aea953a..b728f91 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java @@ -24,7 +24,7 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.*; import org.apache.cloudstack.api.ApiConstants.VMDetails; import org.apache.cloudstack.api.response.UserVmResponse; -import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.api.response.NicResponse; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -48,9 +48,9 @@ public class RemoveNicFromVMCmd extends BaseCmd { required=true, description="Virtual Machine ID") private Long vmId; - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType=NetworkResponse.class, - required=true, description="Network ID") - private Long netId; + @Parameter(name=ApiConstants.NIC_ID, type=CommandType.UUID, entityType=NicResponse.class, + required=true, description="NIC ID") + private Long nicId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -60,8 +60,8 @@ public class RemoveNicFromVMCmd extends BaseCmd { return vmId; } - public Long getNetworkId() { - return netId; + public Long getNicId() { + return nicId; } ///////////////////////////////////////////////////// @@ -88,7 +88,7 @@ public class RemoveNicFromVMCmd extends BaseCmd { @Override public void execute(){ - UserContext.current().setEventDetails("Vm Id: "+getVmId()); + UserContext.current().setEventDetails("Vm Id: "+getVmId() + " Nic Id: " + getNicId()); UserVm result = _userVmService.removeNicFromVirtualMachine(this); ArrayList<VMDetails> dc = new ArrayList<VMDetails>(); dc.add(VMDetails.valueOf("nics")); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bdbbbc36/api/src/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java index 19d3bdb..f7a8a0b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java @@ -24,7 +24,7 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.*; import org.apache.cloudstack.api.ApiConstants.VMDetails; import org.apache.cloudstack.api.response.UserVmResponse; -import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.api.response.NicResponse; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -48,9 +48,9 @@ public class UpdateDefaultNicForVMCmd extends BaseCmd { required=true, description="Virtual Machine ID") private Long vmId; - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType=NetworkResponse.class, - required=true, description="Network ID") - private Long netId; + @Parameter(name=ApiConstants.NIC_ID, type=CommandType.UUID, entityType=NicResponse.class, + required=true, description="NIC ID") + private Long nicId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -59,11 +59,11 @@ public class UpdateDefaultNicForVMCmd extends BaseCmd { public Long getVmId() { return vmId; } - - public Long getNetworkId() { - return netId; - } + public Long getNicId() { + return nicId; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -88,7 +88,7 @@ public class UpdateDefaultNicForVMCmd extends BaseCmd { @Override public void execute(){ - UserContext.current().setEventDetails("Vm Id: "+getVmId()); + UserContext.current().setEventDetails("Vm Id: "+getVmId() + " Nic Id: " + getNicId()); UserVm result = _userVmService.updateDefaultNicForVirtualMachine(this); ArrayList<VMDetails> dc = new ArrayList<VMDetails>(); dc.add(VMDetails.valueOf("nics")); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bdbbbc36/api/src/org/apache/cloudstack/api/response/NicResponse.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/response/NicResponse.java b/api/src/org/apache/cloudstack/api/response/NicResponse.java index a6ca5b8..7e200ae 100644 --- a/api/src/org/apache/cloudstack/api/response/NicResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NicResponse.java @@ -17,11 +17,14 @@ package org.apache.cloudstack.api.response; import org.apache.cloudstack.api.ApiConstants; +import com.cloud.vm.Nic; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; @SuppressWarnings("unused") +@EntityReference(value=Nic.class) public class NicResponse extends BaseResponse { @SerializedName("id") @Param(description="the ID of the nic") http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bdbbbc36/server/src/com/cloud/network/NetworkManager.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index c0065dd..695a8f0 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -262,7 +262,7 @@ public interface NetworkManager { * @throws InsufficientCapacityException * @throws ResourceUnavailableException */ - NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare) throws InsufficientVirtualNetworkCapcityException, + NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare, boolean alwayscreate) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException; http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bdbbbc36/server/src/com/cloud/network/NetworkManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 241c07f..d1c3181 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -3355,7 +3355,7 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { } @Override - public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare) + public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare, boolean alwayscreate) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { @@ -3367,7 +3367,7 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { NicProfile nic = getNicProfileForVm(network, requested, vm); //1) allocate nic (if needed) - if (nic == null) { + if (nic == null || alwayscreate) { int deviceId = _nicDao.countNics(vm.getId()); nic = allocateNic(requested, network, false, http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bdbbbc36/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 b1fa323..d2e85a0 100644 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -929,20 +929,17 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager Account caller = UserContext.current().getCaller(); UserVmVO vmInstance = _vmDao.findById(vmId); - NetworkVO network = _networkDao.findById(networkId); - - NicProfile profile = new NicProfile(null); - if(ipAddress != null) { - profile = new NicProfile(ipAddress); - } - if(vmInstance == null) { throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); } - + NetworkVO network = _networkDao.findById(networkId); if(network == null) { throw new InvalidParameterValueException("unable to find a network with id " + networkId); } + NicProfile profile = new NicProfile(null); + if(ipAddress != null) { + profile = new NicProfile(ipAddress); + } // Perform permission check on VM _accountMgr.checkAccess(caller, null, true, vmInstance); @@ -952,7 +949,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager // Check account permissions List<NetworkVO> networkMap = _networkDao.listBy(caller.getId(), network.getId()); if (networkMap == null || networkMap.isEmpty()) { - throw new PermissionDeniedException("Unable to create a vm using network with id " + network.getId() + ", permission denied"); + throw new PermissionDeniedException("Unable to modify a vm using network with id " + network.getId() + ", permission denied"); } } @@ -961,11 +958,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager //todo: check other nics for VPC networks (can only belong to one?) //todo: verify unique hostname in network domain? - //verify that there isn't a NIC attached to network - if(_networkModel.getNicInNetwork(vmInstance.getId(),network.getId()) != null){ - throw new CloudRuntimeException("Unable to add NIC to " + vmInstance + " because it already has a NIC attached to " + network); - } - NicProfile guestNic = null; try { @@ -988,29 +980,36 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager @Override public UserVm removeNicFromVirtualMachine(RemoveNicFromVMCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, CloudRuntimeException { Long vmId = cmd.getVmId(); - Long networkId = cmd.getNetworkId(); + Long nicId = cmd.getNicId(); Account caller = UserContext.current().getCaller(); UserVmVO vmInstance = _vmDao.findById(vmId); - NetworkVO network = _networkDao.findById(networkId); - if(vmInstance == null) { throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); } - + NicVO nic = _nicDao.findById(nicId); + if (nic == null){ + throw new InvalidParameterValueException("unable to find a nic with id " + nicId); + } + NetworkVO network = _networkDao.findById(nic.getNetworkId()); if(network == null) { - throw new InvalidParameterValueException("unable to find a network with id " + networkId); + throw new InvalidParameterValueException("unable to find a network with id " + nic.getNetworkId()); } // Perform permission check on VM _accountMgr.checkAccess(caller, null, true, vmInstance); + //check to see if nic is attached to VM + if (nic.getInstanceId() != vmId) { + throw new InvalidParameterValueException(nic + " is not a nic on " + vmInstance); + } + // Perform account permission check on network if (network.getGuestType() != Network.GuestType.Shared) { // Check account permissions List<NetworkVO> networkMap = _networkDao.listBy(caller.getId(), network.getId()); if (networkMap == null || networkMap.isEmpty()) { - throw new PermissionDeniedException("Unable to create a vm using network with id " + network.getId() + ", permission denied"); + throw new PermissionDeniedException("Unable to modify a vm using network with id " + network.getId() + ", permission denied"); } } @@ -1021,7 +1020,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager boolean nicremoved = false; try { - nicremoved = _itMgr.removeVmFromNetwork(vmInstance, network, null); + nicremoved = _itMgr.removeNicFromVm(vmInstance, nic); } catch (ResourceUnavailableException e) { throw new CloudRuntimeException("Unable to remove " + network + " from " + vmInstance +": " + e); @@ -1042,19 +1041,20 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager @Override public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) throws InvalidParameterValueException, CloudRuntimeException { Long vmId = cmd.getVmId(); - Long networkId = cmd.getNetworkId(); + Long nicId = cmd.getNicId(); Account caller = UserContext.current().getCaller(); UserVmVO vmInstance = _vmDao.findById(vmId); - NetworkVO network = _networkDao.findById(networkId); - - if (vmInstance == null){ throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); } - + NicVO nic = _nicDao.findById(nicId); + if (nic == null){ + throw new InvalidParameterValueException("unable to find a nic with id " + nicId); + } + NetworkVO network = _networkDao.findById(nic.getNetworkId()); if (network == null){ - throw new InvalidParameterValueException("unable to find a network with id " + networkId); + throw new InvalidParameterValueException("unable to find a network with id " + nic.getNetworkId()); } // Perform permission check on VM @@ -1063,74 +1063,57 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager // no need to check permissions for network, we'll enumerate the ones they already have access to Network existingdefaultnet = _networkModel.getDefaultNetworkForVm(vmId); - // if current default equals chosen new default, return and do nothing - if (existingdefaultnet == network){ - s_logger.warn("Skipping updateDefaultNicForVirtualMachine, selected network matches existing default"); - return _vmDao.findById(vmInstance.getId()); + //check to see if nic is attached to VM + if (nic.getInstanceId() != vmId) { + throw new InvalidParameterValueException(nic + " is not a nic on " + vmInstance); } - else { - s_logger.debug("looks like we want to change from " + existingdefaultnet + " to " + network); + // if current default equals chosen new default, Throw an exception + if (nic.isDefaultNic()){ + throw new CloudRuntimeException("refusing to set default nic because chosen nic is already the default"); } - NicProfile chosen = _networkModel.getNicProfile(vmInstance, network.getId(), null); NicProfile existing = _networkModel.getNicProfile(vmInstance, existingdefaultnet.getId(), null); - // if we can't find the chosen nic, fail! - if (chosen == null){ - throw new CloudRuntimeException("Failed to find an existing nic for " + vmInstance +" on " + network); - } - else if (chosen.id == existing.id){ - throw new CloudRuntimeException("refusing to set default nic because chosen network is already the default"); - } - else { - s_logger.debug("chosen nic profile found was "+chosen+" with dev id "+chosen.deviceId+" and nic id "+chosen.id); - } if (existing == null){ s_logger.warn("Failed to update default nic, no nic profile found for existing default network"); throw new CloudRuntimeException("Failed to find a nic profile for the existing default network. This is bad and probably means some sort of configuration corruption"); } - NicVO chosenVO = _nicDao.findById(chosen.id); NicVO existingVO = _nicDao.findById(existing.id); - Integer chosenID = chosen.getDeviceId(); + Integer chosenID = nic.getDeviceId(); Integer existingID = existing.getDeviceId(); - chosenVO.setDefaultNic(true); - chosenVO.setDeviceId(existingID); + nic.setDefaultNic(true); + nic.setDeviceId(existingID); existingVO.setDefaultNic(false); existingVO.setDeviceId(chosenID); - chosenVO = _nicDao.persist(chosenVO); + nic = _nicDao.persist(nic); existingVO = _nicDao.persist(existingVO); Network newdefault = null; newdefault = _networkModel.getDefaultNetworkForVm(vmId); if (newdefault == null){ - chosenVO.setDefaultNic(false); - chosenVO.setDeviceId(chosenID); + nic.setDefaultNic(false); + nic.setDeviceId(chosenID); existingVO.setDefaultNic(true); existingVO.setDeviceId(existingID); - chosenVO = _nicDao.persist(chosenVO); + nic = _nicDao.persist(nic); existingVO = _nicDao.persist(existingVO); newdefault = _networkModel.getDefaultNetworkForVm(vmId); if (newdefault.getId() == existingdefaultnet.getId()) { throw new CloudRuntimeException("Setting a default nic failed, and we had no default nic, but we were able to set it back to the original"); } - throw new CloudRuntimeException("Failed to change default nic to " + network + " and now we have no default"); - } else if (newdefault.getId() != networkId){ - if(newdefault.getId() == existingdefaultnet.getId()) { - throw new CloudRuntimeException("Default nic did not change from previous setting"); - } - throw new CloudRuntimeException("Failed to change default nic to " + network + " with id "+ networkId + ", current default is " + newdefault+ " id " + newdefault.getId()); - } else if (newdefault.getId() == networkId ) { + throw new CloudRuntimeException("Failed to change default nic to " + nic + " and now we have no default"); + } else if (newdefault.getId() == nic.getNetworkId()) { s_logger.debug("successfully set default network to " + network + " for " + vmInstance); return _vmDao.findById(vmInstance.getId()); } - throw new CloudRuntimeException("something strange happened, new default net is not null, not equal to chosen network, not NOT equal to chosen net"); + throw new CloudRuntimeException("something strange happened, new default network(" + newdefault.getId() + ") is not null, and is not equal to the network(" + nic.getNetworkId() + ") of the chosen nic"); } @Override http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bdbbbc36/server/src/com/cloud/vm/VirtualMachineManager.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/VirtualMachineManager.java b/server/src/com/cloud/vm/VirtualMachineManager.java index a9c161e..2d70166 100644 --- a/server/src/com/cloud/vm/VirtualMachineManager.java +++ b/server/src/com/cloud/vm/VirtualMachineManager.java @@ -166,6 +166,15 @@ public interface VirtualMachineManager extends Manager { /** * @param vm + * @param nic + * @return + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + boolean removeNicFromVm(VirtualMachine vm, NicVO nic) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param vm * @param network * @param broadcastUri TODO * @return http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bdbbbc36/server/src/com/cloud/vm/VirtualMachineManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 8546467..7ab9309 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -2476,7 +2476,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene //check vm state if (vm.getState() == State.Running) { //1) allocate and prepare nic - NicProfile nic = _networkMgr.createNicForVm(network, requested, context, vmProfile, true); + NicProfile nic = _networkMgr.createNicForVm(network, requested, context, vmProfile, true, false); //2) Convert vmProfile to vmTO HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType()); @@ -2498,7 +2498,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } } else if (vm.getState() == State.Stopped) { //1) allocate nic - return _networkMgr.createNicForVm(network, requested, context, vmProfile, false); + return _networkMgr.createNicForVm(network, requested, context, vmProfile, false, false); } else { s_logger.warn("Unable to add vm " + vm + " to network " + network); throw new ResourceUnavailableException("Unable to add vm " + vm + " to network, is not in the right state", @@ -2524,7 +2524,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene //check vm state if (vm.getState() == State.Running) { //1) allocate and prepare nic - NicProfile nic = _networkMgr.createNicForVm(network, requested, context, vmProfile, true); + NicProfile nic = _networkMgr.createNicForVm(network, requested, context, vmProfile, true, true); //2) Convert vmProfile to vmTO HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType()); @@ -2546,7 +2546,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } } else if (vm.getState() == State.Stopped) { //1) allocate nic - return _networkMgr.createNicForVm(network, requested, context, vmProfile, false); + return _networkMgr.createNicForVm(network, requested, context, vmProfile, false, true); } else { s_logger.warn("Unable to add vm " + vm + " to network " + network); throw new ResourceUnavailableException("Unable to add vm " + vm + " to network, is not in the right state", @@ -2563,6 +2563,61 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } @Override + public boolean removeNicFromVm(VirtualMachine vm, NicVO nic) throws ConcurrentOperationException, ResourceUnavailableException { + VMInstanceVO vmVO = _vmDao.findById(vm.getId()); + NetworkVO network = _networkDao.findById(nic.getNetworkId()); + ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM), + _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)); + + VirtualMachineProfileImpl<VMInstanceVO> vmProfile = new VirtualMachineProfileImpl<VMInstanceVO>(vmVO, null, + null, null, null); + + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + Host host = _hostDao.findById(vm.getHostId()); + DeployDestination dest = new DeployDestination(dc, null, null, host); + VirtualMachineGuru<VMInstanceVO> vmGuru = getVmGuru(vmVO); + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType()); + VirtualMachineTO vmTO = hvGuru.implement(vmProfile); + + // don't delete default NIC on a user VM + if (nic.isDefaultNic() && vm.getType() == VirtualMachine.Type.User ) { + s_logger.warn("Failed to remove nic from " + vm + " in " + network + ", nic is default."); + throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network + ", nic is default."); + } + + NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), + _networkModel.getNetworkRate(network.getId(), vm.getId()), + _networkModel.isSecurityGroupSupportedInNetwork(network), + _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); + + //1) Unplug the nic + if (vm.getState() == State.Running) { + NicTO nicTO = toNicTO(nicProfile, vmProfile.getVirtualMachine().getHypervisorType()); + s_logger.debug("Un-plugging nic " + nic + " for vm " + vm + " from network " + network); + boolean result = vmGuru.unplugNic(network, nicTO, vmTO, context, dest); + if (result) { + s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network ); + } else { + s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network); + return false; + } + } else if (vm.getState() != State.Stopped) { + s_logger.warn("Unable to remove vm " + vm + " from network " + network); + throw new ResourceUnavailableException("Unable to remove vm " + vm + " from network, is not in the right state", + DataCenter.class, vm.getDataCenterIdToDeployIn()); + } + + //2) Release the nic + _networkMgr.releaseNic(vmProfile, nic); + s_logger.debug("Successfully released nic " + nic + "for vm " + vm); + + //3) Remove the nic + _networkMgr.removeNic(vmProfile, nic); + _nicsDao.expunge(nic.getId()); + return true; + } + + @Override public boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException { VMInstanceVO vmVO = _vmDao.findById(vm.getId()); ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM), @@ -2625,7 +2680,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene //3) Remove the nic _networkMgr.removeNic(vmProfile, nic); - _nicsDao.expunge(nic.getId()); return true; } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bdbbbc36/server/test/com/cloud/network/MockNetworkManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index c9446bb..850d92a 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -733,7 +733,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS */ @Override public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, - VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare) + VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare, boolean alwayscreate) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { // TODO Auto-generated method stub http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bdbbbc36/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java index 6ff0a53..403055b 100755 --- a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java +++ b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java @@ -283,6 +283,15 @@ public class MockVirtualMachineManagerImpl implements VirtualMachineManager { * @see com.cloud.vm.VirtualMachineManager#removeVmFromNetwork(com.cloud.vm.VirtualMachine, com.cloud.network.Network, java.net.URI) */ @Override + public boolean removeNicFromVm(VirtualMachine vm, NicVO nic) throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see com.cloud.vm.VirtualMachineManager#removeVmFromNetwork(com.cloud.vm.VirtualMachine, com.cloud.network.Network, java.net.URI) + */ + @Override public boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException { // TODO Auto-generated method stub return false; http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bdbbbc36/server/test/com/cloud/vpc/MockNetworkManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index 63bc752..c55b4c0 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -1123,11 +1123,11 @@ public class MockNetworkManagerImpl implements NetworkManager, NetworkService, M /* (non-Javadoc) - * @see com.cloud.network.NetworkManager#createNicForVm(com.cloud.network.Network, com.cloud.vm.NicProfile, com.cloud.vm.ReservationContext, com.cloud.vm.VirtualMachineProfileImpl, boolean) + * @see com.cloud.network.NetworkManager#createNicForVm(com.cloud.network.Network, com.cloud.vm.NicProfile, com.cloud.vm.ReservationContext, com.cloud.vm.VirtualMachineProfileImpl, boolean, boolean) */ @Override public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, - VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare) + VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare, boolean alwayscreate) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { // TODO Auto-generated method stub
