PVLAN: CLOUDSTACK-2401: VM Migration support
diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java
index 8021e6f..1916678 100755
--- a/server/src/com/cloud/network/element/VirtualRouterElement.java
+++ b/server/src/com/cloud/network/element/VirtualRouterElement.java
@@ -47,7 +47,9 @@
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkMigrationResponder;
import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.PhysicalNetworkServiceProvider;
@@ -85,9 +87,13 @@
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
import com.cloud.vm.ReservationContext;
+import com.cloud.vm.UserVmManager;
+import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.UserVmDao;
@@ -108,10 +114,12 @@
@Local(value = {NetworkElement.class, FirewallServiceProvider.class,
DhcpServiceProvider.class, UserDataServiceProvider.class,
StaticNatServiceProvider.class, LoadBalancingServiceProvider.class,
- PortForwardingServiceProvider.class, IpDeployer.class, RemoteAccessVPNServiceProvider.class} )
+ PortForwardingServiceProvider.class, IpDeployer.class,
+ RemoteAccessVPNServiceProvider.class, NetworkMigrationResponder.class} )
public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider,
UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider,
- LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer {
+ LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer,
+ NetworkMigrationResponder {
private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class);
protected static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
@@ -130,6 +138,8 @@
ConfigurationManager _configMgr;
@Inject
RulesManager _rulesMgr;
+ @Inject
+ UserVmManager _userVmMgr;
@Inject
UserVmDao _userVmDao;
@@ -1024,7 +1034,6 @@
// TODO Auto-generated method stub
return null;
}
-
private boolean canHandleLbRules(List<LoadBalancingRule> rules) {
Map<Capability, String> lbCaps = this.getCapabilities().get(Service.Lb);
if (!lbCaps.isEmpty()) {
@@ -1039,5 +1048,60 @@
}
}
return true;
+ }
+
+ @Override
+ public boolean prepareMigration(NicProfile nic, Network network,
+ VirtualMachineProfile<? extends VirtualMachine> vm,
+ DeployDestination dest, ReservationContext context) {
+ if (nic.getBroadcastType() != Networks.BroadcastDomainType.Pvlan) {
+ return true;
+ }
+ if (vm.getType() == Type.DomainRouter) {
+ assert vm instanceof DomainRouterVO;
+ DomainRouterVO router = (DomainRouterVO)vm.getVirtualMachine();
+ _routerMgr.setupDhcpForPvlan(false, router, router.getHostId(), nic);
+ } else if (vm.getType() == Type.User){
+ assert vm instanceof UserVmVO;
+ UserVmVO userVm = (UserVmVO)vm.getVirtualMachine();
+ _userVmMgr.setupVmForPvlan(false, userVm.getHostId(), nic);
+ }
+ return true;
+ }
+
+ @Override
+ public void rollbackMigration(NicProfile nic, Network network,
+ VirtualMachineProfile<? extends VirtualMachine> vm,
+ ReservationContext src, ReservationContext dst) {
+ if (nic.getBroadcastType() != Networks.BroadcastDomainType.Pvlan) {
+ return;
+ }
+ if (vm.getType() == Type.DomainRouter) {
+ assert vm instanceof DomainRouterVO;
+ DomainRouterVO router = (DomainRouterVO)vm.getVirtualMachine();
+ _routerMgr.setupDhcpForPvlan(true, router, router.getHostId(), nic);
+ } else if (vm.getType() == Type.User){
+ assert vm instanceof UserVmVO;
+ UserVmVO userVm = (UserVmVO)vm.getVirtualMachine();
+ _userVmMgr.setupVmForPvlan(true, userVm.getHostId(), nic);
+ }
+ }
+
+ @Override
+ public void commitMigration(NicProfile nic, Network network,
+ VirtualMachineProfile<? extends VirtualMachine> vm,
+ ReservationContext src, ReservationContext dst) {
+ if (nic.getBroadcastType() != Networks.BroadcastDomainType.Pvlan) {
+ return;
+ }
+ if (vm.getType() == Type.DomainRouter) {
+ assert vm instanceof DomainRouterVO;
+ DomainRouterVO router = (DomainRouterVO)vm.getVirtualMachine();
+ _routerMgr.setupDhcpForPvlan(true, router, router.getHostId(), nic);
+ } else if (vm.getType() == Type.User){
+ assert vm instanceof UserVmVO;
+ UserVmVO userVm = (UserVmVO)vm.getVirtualMachine();
+ _userVmMgr.setupVmForPvlan(true, userVm.getHostId(), nic);
+ }
}
}
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
index 9852c47..72fddf4 100644
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
@@ -33,7 +33,6 @@
import com.cloud.uservm.UserVm;
import com.cloud.utils.component.Manager;
import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
import com.cloud.vm.VirtualMachineProfile;
@@ -113,4 +112,5 @@
boolean removeDhcpSupportForSubnet(Network network, List<DomainRouterVO> routers) throws ResourceUnavailableException;
+ boolean setupDhcpForPvlan(boolean add, DomainRouterVO router, Long hostId, NicProfile nic);
}
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 50ae4c1..64e412a 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -2223,8 +2223,9 @@
return dhcpRange;
}
- private boolean setupDhcpForPvlan(boolean add, DomainRouterVO router, Nic nic) {
- if (!nic.getBroadcastUri().getScheme().equals("pvlan")) {
+ @Override
+ public boolean setupDhcpForPvlan(boolean add, DomainRouterVO router, Long hostId, NicProfile nic) {
+ if (!nic.getBroadCastUri().getScheme().equals("pvlan")) {
return false;
}
String op = "add";
@@ -2233,15 +2234,22 @@
}
Network network = _networkDao.findById(nic.getNetworkId());
String networkTag = _networkModel.getNetworkTag(router.getHypervisorType(), network);
- PvlanSetupCommand cmd = PvlanSetupCommand.createDhcpSetup(op, nic.getBroadcastUri(), networkTag, router.getInstanceName(), nic.getMacAddress(), nic.getIp4Address());
- Commands cmds = new Commands(cmd);
+ PvlanSetupCommand cmd = PvlanSetupCommand.createDhcpSetup(op, nic.getBroadCastUri(), networkTag, router.getInstanceName(), nic.getMacAddress(), nic.getIp4Address());
// In fact we send command to the host of router, we're not programming router but the host
- try {
- sendCommandsToRouter(router, cmds);
- } catch (AgentUnavailableException e) {
+ Answer answer = null;
+ try {
+ answer = _agentMgr.send(hostId, cmd);
+ } catch (OperationTimedoutException e) {
+ s_logger.warn("Timed Out", e);
+ return false;
+ } catch (AgentUnavailableException e) {
s_logger.warn("Agent Unavailable ", e);
- return false;
- }
+ return false;
+ }
+
+ if (answer == null || !answer.getResult()) {
+ return false;
+ }
return true;
}
@@ -2563,7 +2571,8 @@
if (network.getTrafficType() == TrafficType.Guest) {
guestNetworks.add(network);
if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
- result = setupDhcpForPvlan(true, router, nic);
+ NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
+ result = setupDhcpForPvlan(true, router, router.getHostId(), nicProfile);
}
}
}
@@ -2601,7 +2610,8 @@
for (Nic nic : routerNics) {
Network network = _networkModel.getNetwork(nic.getNetworkId());
if (network.getTrafficType() == TrafficType.Guest && nic.getBroadcastUri().getScheme().equals("pvlan")) {
- setupDhcpForPvlan(false, domR, nic);
+ NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
+ setupDhcpForPvlan(false, domR, domR.getHostId(), nicProfile);
}
}
diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java
index 0f8e368..4dcfb73 100755
--- a/server/src/com/cloud/vm/UserVmManager.java
+++ b/server/src/com/cloud/vm/UserVmManager.java
@@ -94,4 +94,5 @@
boolean upgradeVirtualMachine(Long id, Long serviceOfferingId) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException;
+ boolean setupVmForPvlan(boolean add, Long hostId, NicProfile nic);
}
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 86150a2..71b4e3f 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -2821,8 +2821,9 @@
return true;
}
- private boolean setupVmForPvlan(boolean add, Long hostId, NicVO nic) {
- if (!nic.getBroadcastUri().getScheme().equals("pvlan")) {
+ @Override
+ public boolean setupVmForPvlan(boolean add, Long hostId, NicProfile nic) {
+ if (!nic.getBroadCastUri().getScheme().equals("pvlan")) {
return false;
}
String op = "add";
@@ -2833,7 +2834,7 @@
Network network = _networkDao.findById(nic.getNetworkId());
Host host = _hostDao.findById(hostId);
String networkTag = _networkModel.getNetworkTag(host.getHypervisorType(), network);
- PvlanSetupCommand cmd = PvlanSetupCommand.createVmSetup(op, nic.getBroadcastUri(), networkTag, nic.getMacAddress());
+ PvlanSetupCommand cmd = PvlanSetupCommand.createVmSetup(op, nic.getBroadCastUri(), networkTag, nic.getMacAddress());
Answer answer = null;
try {
answer = _agentMgr.send(hostId, cmd);
@@ -2916,7 +2917,8 @@
// In vmware, we will be effecting pvlan settings in portgroups in StartCommand.
if (profile.getHypervisorType() != HypervisorType.VMware) {
if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
- if (!setupVmForPvlan(true, hostId, nic)) {
+ NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
+ if (!setupVmForPvlan(true, hostId, nicProfile)) {
return false;
}
}
@@ -3058,7 +3060,8 @@
NetworkVO network = _networkDao.findById(nic.getNetworkId());
if (network.getTrafficType() == TrafficType.Guest) {
if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
- setupVmForPvlan(false, vm.getHostId(), nic);
+ NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
+ setupVmForPvlan(false, vm.getHostId(), nicProfile);
}
}
}
diff --git a/server/test/com/cloud/vm/MockUserVmManagerImpl.java b/server/test/com/cloud/vm/MockUserVmManagerImpl.java
index 50a90f2..448a5dd 100644
--- a/server/test/com/cloud/vm/MockUserVmManagerImpl.java
+++ b/server/test/com/cloud/vm/MockUserVmManagerImpl.java
@@ -455,4 +455,10 @@
// TODO Auto-generated method stub
return null;
}
+
+ @Override
+ public boolean setupVmForPvlan(boolean add, Long hostId, NicProfile nic) {
+ // TODO Auto-generated method stub
+ return false;
+ }
}
diff --git a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
index 8d50211..f325c4a 100644
--- a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
+++ b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
@@ -420,4 +420,10 @@
return null;
}
+ @Override
+ public boolean setupDhcpForPvlan(boolean add, DomainRouterVO router, Long hostId,
+ NicProfile nic) {
+ // TODO Auto-generated method stub
+ return false;
+ }
}