diff --git a/api/src/com/cloud/network/element/NetworkElement.java b/api/src/com/cloud/network/element/NetworkElement.java
index fb620a7babf..7b6763fbdcd 100644
--- a/api/src/com/cloud/network/element/NetworkElement.java
+++ b/api/src/com/cloud/network/element/NetworkElement.java
@@ -94,4 +94,5 @@ public interface NetworkElement extends Adapter {
* @throws ResourceUnavailableException
*/
boolean applyRules(Network network, List extends FirewallRule> rules) throws ResourceUnavailableException;
+
}
diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in
index 7036dc4ebde..e7095585d93 100755
--- a/client/tomcatconf/components.xml.in
+++ b/client/tomcatconf/components.xml.in
@@ -76,6 +76,7 @@
+
diff --git a/server/src/com/cloud/network/element/DhcpElement.java b/server/src/com/cloud/network/element/DhcpElement.java
new file mode 100644
index 00000000000..8203b1d1205
--- /dev/null
+++ b/server/src/com/cloud/network/element/DhcpElement.java
@@ -0,0 +1,151 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.cloud.network.element;
+
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientNetworkCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkManager;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.router.DomainRouterManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.service.Providers;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.GuestIpType;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.net.Ip;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.UserVmManager;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.UserVmDao;
+
+
+@Local(value=NetworkElement.class)
+public class DhcpElement extends AdapterBase implements NetworkElement {
+ private static final Logger s_logger = Logger.getLogger(DhcpElement.class);
+
+ @Inject NetworkDao _networkConfigDao;
+ @Inject NetworkManager _networkMgr;
+ @Inject DomainRouterManager _routerMgr;
+ @Inject UserVmManager _userVmMgr;
+ @Inject UserVmDao _userVmDao;
+ @Inject DomainRouterDao _routerDao;
+
+ private boolean canHandle(GuestIpType ipType, DeployDestination dest) {
+ DataCenter dc = dest.getDataCenter();
+ String provider = dc.getGatewayProvider();
+ if (!dc.getDhcpProvider().equals(Providers.VirtualRouter)) {
+ return false;
+ }
+ return ((ipType == GuestIpType.Virtual && !provider.equals(Providers.VirtualRouter)) || (ipType == GuestIpType.Direct || ipType == GuestIpType.DirectPodBased));
+ }
+
+ @Override
+ public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException {
+ if (canHandle(offering.getGuestIpType(), dest)) {
+ DomainRouterVO router = _routerMgr.deployDhcp(guestConfig, dest, context.getAccount());
+ if (router == null) {
+ throw new ResourceUnavailableException("Unable to deploy the router for " + guestConfig);
+ }
+ return true;
+
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile extends VirtualMachine> vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException {
+ if (canHandle(config.getGuestType(), dest)) {
+ if (config.getTrafficType() != TrafficType.Guest || vm.getType() != Type.User) {
+ s_logger.trace("DHCP only cares about guest network and User VMs");
+ return false;
+ }
+
+ if (vm.getType() != VirtualMachine.Type.User) {
+ return false;
+ }
+
+ @SuppressWarnings("unchecked")
+ VirtualMachineProfile uservm = (VirtualMachineProfile)vm;
+
+ return _routerMgr.addVirtualMachineIntoNetwork(config, nic, uservm, dest, context, true) != null;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean release(Network config, NicProfile nic, VirtualMachineProfile extends VirtualMachine> vm, ReservationContext context) {
+ if (config.getTrafficType() != TrafficType.Guest || vm.getType() != Type.User) {
+ s_logger.trace("DHCP only cares about guest network and User VMs");
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean shutdown(Network config, ReservationContext context) throws ConcurrentOperationException {
+ if (config.getTrafficType() != TrafficType.Guest) {
+ s_logger.trace("DHCP only cares about guet network.");
+ return false;
+ }
+ DomainRouterVO router = _routerDao.findByNetworkConfiguration(config.getId());
+ if (router == null) {
+ return true;
+ }
+ return _routerMgr.stopRouter(router.getId(), 1);
+ }
+
+ protected DhcpElement() {
+ super();
+ }
+
+ @Override
+ public boolean applyRules(Network config, List extends FirewallRule> rules) throws ResourceUnavailableException {
+ return true;
+ }
+
+ @Override
+ public boolean associate(Network network, Ip ipAddress) throws ResourceUnavailableException {
+ return true;
+ }
+
+ @Override
+ public boolean disassociate(Network network, Ip ipAddress) throws ResourceUnavailableException {
+ return true;
+ }
+}
diff --git a/server/src/com/cloud/network/element/DomainRouterElement.java b/server/src/com/cloud/network/element/DomainRouterElement.java
index aa462f6564a..3f632a184f5 100644
--- a/server/src/com/cloud/network/element/DomainRouterElement.java
+++ b/server/src/com/cloud/network/element/DomainRouterElement.java
@@ -23,6 +23,7 @@ import javax.ejb.Local;
import org.apache.log4j.Logger;
+import com.cloud.dc.DataCenter;
import com.cloud.deploy.DeployDestination;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
@@ -34,8 +35,11 @@ import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.router.DomainRouterManager;
import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.service.Providers;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.GuestIpType;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.uservm.UserVm;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.Inject;
@@ -57,41 +61,52 @@ public class DomainRouterElement extends AdapterBase implements NetworkElement {
@Inject NetworkDao _networkConfigDao;
@Inject NetworkManager _networkMgr;
+ @Inject NetworkOfferingDao _networkOfferingDao;
@Inject DomainRouterManager _routerMgr;
@Inject UserVmManager _userVmMgr;
@Inject UserVmDao _userVmDao;
@Inject DomainRouterDao _routerDao;
+
+ private boolean canHandle(GuestIpType ipType, DeployDestination dest) {
+ DataCenter dc = dest.getDataCenter();
+ String provider = dc.getGatewayProvider();
+ return (ipType == GuestIpType.Virtual && provider.equals(Providers.VirtualRouter));
+ }
@Override
public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException {
- if (offering.getGuestIpType() != GuestIpType.Virtual) {
- s_logger.trace("Not handling guest ip type = " + offering.getGuestIpType());
+ if (canHandle(offering.getGuestIpType(), dest)) {
+ DomainRouterVO router = _routerMgr.deployVirtualRouter(guestConfig, dest, context.getAccount());
+ if (router == null) {
+ throw new ResourceUnavailableException("Unable to deploy the router for " + guestConfig);
+ }
+
+ return true;
+ } else {
return false;
}
-
- DomainRouterVO router = _routerMgr.deploy(guestConfig, dest, context.getAccount());
- if (router == null) {
- throw new ResourceUnavailableException("Unable to deploy the router for " + guestConfig);
- }
-
- return true;
}
@Override
public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile extends VirtualMachine> vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException {
- if (config.getTrafficType() != TrafficType.Guest || vm.getType() != Type.User) {
- s_logger.trace("Domain Router only cares about guest network and User VMs");
+ if (canHandle(config.getGuestType(), dest)) {
+ if (config.getTrafficType() != TrafficType.Guest || vm.getType() != Type.User) {
+ s_logger.trace("Domain Router only cares about guest network and User VMs");
+ return false;
+ }
+
+ if (vm.getType() != VirtualMachine.Type.User) {
+ return false;
+ }
+
+ @SuppressWarnings("unchecked")
+ VirtualMachineProfile uservm = (VirtualMachineProfile)vm;
+
+ return _routerMgr.addVirtualMachineIntoNetwork(config, nic, uservm, dest, context, false) != null;
+ } else {
return false;
}
-
- if (vm.getType() != VirtualMachine.Type.User) {
- return false;
- }
-
- @SuppressWarnings("unchecked")
- VirtualMachineProfile uservm = (VirtualMachineProfile)vm;
-
- return _routerMgr.addVirtualMachineIntoNetwork(config, nic, uservm, dest, context) != null;
+
}
@Override
@@ -100,8 +115,6 @@ public class DomainRouterElement extends AdapterBase implements NetworkElement {
s_logger.trace("Domain Router only cares about guest network and User VMs");
return false;
}
-
-
return true;
}
diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java
index f604b40bc01..ae8f0556e39 100644
--- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java
+++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java
@@ -169,8 +169,10 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
if (nic == null) {
nic = new NicProfile(ReservationStrategy.Start, null, null, null, null);
- } else {
+ } else if (nic.getIp4Address() != null){
nic.setStrategy(ReservationStrategy.Create);
+ } else {
+ nic.setStrategy(ReservationStrategy.Start);
}
if (nic.getMacAddress() == null) {
diff --git a/server/src/com/cloud/network/router/DomainRouterManager.java b/server/src/com/cloud/network/router/DomainRouterManager.java
index bb0cd05a426..38758f696fb 100644
--- a/server/src/com/cloud/network/router/DomainRouterManager.java
+++ b/server/src/com/cloud/network/router/DomainRouterManager.java
@@ -147,13 +147,15 @@ public interface DomainRouterManager extends Manager {
DomainRouterVO getRouter(long accountId, long zoneId);
DomainRouterVO getRouter(String publicIpAddress);
- DomainRouterVO deploy(Network guestConfig, DeployDestination dest, Account owner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException;
-
+ DomainRouterVO deployVirtualRouter(Network guestConfig, DeployDestination dest, Account owner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException;
+
+ DomainRouterVO deployDhcp(Network guestConfig, DeployDestination dest, Account owner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException;
+
RemoteAccessVpnVO startRemoteAccessVpn(RemoteAccessVpnVO vpnVO) throws ResourceUnavailableException;
boolean addRemoveVpnUsers(RemoteAccessVpnVO vpnVO, List addUsers, List removeUsers);
boolean deleteRemoteAccessVpn(RemoteAccessVpnVO vpnVO);
- DomainRouterVO addVirtualMachineIntoNetwork(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException;
+ DomainRouterVO addVirtualMachineIntoNetwork(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context, Boolean startDhcp) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException;
}
diff --git a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java
index f10a99ae2b2..34ba73972e7 100644
--- a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java
+++ b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java
@@ -2069,7 +2069,7 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
}
@Override
- public DomainRouterVO deploy(Network guestConfig, DeployDestination dest, Account owner) throws InsufficientCapacityException, StorageUnavailableException, ConcurrentOperationException, ResourceUnavailableException {
+ public DomainRouterVO deployVirtualRouter(Network guestConfig, DeployDestination dest, Account owner) throws InsufficientCapacityException, StorageUnavailableException, ConcurrentOperationException, ResourceUnavailableException {
long dcId = dest.getDataCenter().getId();
if (s_logger.isDebugEnabled()) {
@@ -2123,6 +2123,49 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
return _itMgr.start(router, null, _accountService.getSystemUser(), _accountService.getSystemAccount());
}
+
+ @Override
+ public DomainRouterVO deployDhcp(Network guestConfig, DeployDestination dest, Account owner) throws InsufficientCapacityException, StorageUnavailableException, ConcurrentOperationException, ResourceUnavailableException {
+ long dcId = dest.getDataCenter().getId();
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Starting a dhcp for network configurations: dhcp=" + guestConfig + " in " + dest);
+ }
+ assert guestConfig.getState() == Network.State.Implemented || guestConfig.getState() == Network.State.Setup : "Network is not yet fully implemented: " + guestConfig;
+ assert guestConfig.getTrafficType() == TrafficType.Guest;
+
+ DataCenterDeployment plan = new DataCenterDeployment(dcId);
+
+ guestConfig = _networkConfigurationDao.lockRow(guestConfig.getId(), true);
+ if (guestConfig == null) {
+ throw new ConcurrentOperationException("Unable to get the lock on " + guestConfig);
+ }
+
+ DomainRouterVO router = _routerDao.findByNetworkConfiguration(guestConfig.getId());
+ if (router == null) {
+ long id = _routerDao.getNextInSequence(Long.class, "id");
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Creating the router " + id);
+ }
+
+ List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmControlNetwork);
+ NetworkOfferingVO controlOffering = offerings.get(0);
+ NetworkVO controlConfig = _networkMgr.setupNetworkConfiguration(_systemAcct, controlOffering, plan, null, null, false).get(0);
+
+ List> networks = new ArrayList>(3);
+ NicProfile gatewayNic = new NicProfile();
+ gatewayNic.setDefaultNic(true);
+ networks.add(new Pair((NetworkVO)guestConfig, gatewayNic));
+ networks.add(new Pair(controlConfig, null));
+
+ router = new DomainRouterVO(id, _offering.getId(), VirtualMachineName.getRouterName(id, _instance), _template.getId(), _template.getGuestOSId(), owner.getDomainId(), owner.getId(), guestConfig.getId(), _offering.getOfferHA());
+ router.setRole(Role.DHCP_USERDATA);
+ router = _itMgr.allocate(router, _template, _offering, networks, plan, owner);
+ }
+
+ return _itMgr.start(router, null, _accountService.getSystemUser(), _accountService.getSystemAccount());
+ }
+
@Override
public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
StringBuilder buf = profile.getBootArgsBuilder();
@@ -2277,10 +2320,15 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
}
@Override
- public DomainRouterVO addVirtualMachineIntoNetwork(Network config, NicProfile nic, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException {
+ public DomainRouterVO addVirtualMachineIntoNetwork(Network config, NicProfile nic, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context, Boolean startDhcp) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException {
DomainRouterVO router = _routerDao.findByNetworkConfiguration(config.getId());
try {
- router = this.deploy(config, dest, profile.getOwner());
+ if (startDhcp) {
+ router = this.deployDhcp(config, dest, profile.getOwner());
+ } else {
+ router = this.deployVirtualRouter(config, dest, profile.getOwner());
+ }
+
} catch (InsufficientNetworkCapacityException e) {
throw e;
} catch (InsufficientCapacityException e) {
diff --git a/vmops.log.2010-12-06.gz b/vmops.log.2010-12-06.gz
new file mode 100644
index 00000000000..d3a44dae78e
Binary files /dev/null and b/vmops.log.2010-12-06.gz differ