diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java
index 4a1cc9538f1..d2e0ebaf59d 100644
--- a/api/src/com/cloud/network/Network.java
+++ b/api/src/com/cloud/network/Network.java
@@ -73,6 +73,8 @@ public interface Network extends ControlledEntity {
public static final Provider DhcpServer = new Provider("DhcpServer");
public static final Provider JuniperSRX = new Provider("JuniperSRX");
public static final Provider F5BigIp = new Provider("F5BigIp");
+ public static final Provider ExternalDhcpServer = new Provider("ExternalDhcpServer");
+ public static final Provider ExternalGateWay = new Provider("ExternalGateWay");
private String name;
diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java
index a5449faef97..cbf64da9483 100755
--- a/api/src/com/cloud/vm/VirtualMachine.java
+++ b/api/src/com/cloud/vm/VirtualMachine.java
@@ -145,7 +145,13 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, StateObject
User,
DomainRouter,
ConsoleProxy,
- SecondaryStorageVm
+ SecondaryStorageVm,
+
+ /*
+ * UserBareMetal is only used for selecting VirtualMachineGuru, there is no
+ * VM with this type. UserBareMetal should treat exactly as User.
+ */
+ UserBareMetal,
}
public String getInstanceName();
diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in
index 0b8886962de..1d45a537924 100755
--- a/client/tomcatconf/components.xml.in
+++ b/client/tomcatconf/components.xml.in
@@ -69,6 +69,7 @@
+
diff --git a/server/src/com/cloud/hypervisor/BareMetalGuru.java b/server/src/com/cloud/hypervisor/BareMetalGuru.java
new file mode 100644
index 00000000000..3c400cb4613
--- /dev/null
+++ b/server/src/com/cloud/hypervisor/BareMetalGuru.java
@@ -0,0 +1,37 @@
+package com.cloud.hypervisor;
+
+import javax.ejb.Local;
+
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.utils.component.Inject;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value=HypervisorGuru.class)
+public class BareMetalGuru extends HypervisorGuruBase implements HypervisorGuru {
+ @Inject GuestOSDao _guestOsDao;
+
+ protected BareMetalGuru() {
+ super();
+ }
+
+ @Override
+ public HypervisorType getHypervisorType() {
+ return HypervisorType.BareMetal;
+ }
+
+ @Override
+ public VirtualMachineTO implement(VirtualMachineProfile vm) {
+ VirtualMachineTO to = toVirtualMachineTO(vm);
+
+ // Determine the VM's OS description
+ GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId());
+ to.setOs(guestOS.getDisplayName());
+
+ return to;
+ }
+
+}
diff --git a/server/src/com/cloud/network/element/DhcpElement.java b/server/src/com/cloud/network/element/DhcpElement.java
index e51304ee0e2..849bebb63dc 100644
--- a/server/src/com/cloud/network/element/DhcpElement.java
+++ b/server/src/com/cloud/network/element/DhcpElement.java
@@ -80,6 +80,8 @@ public class DhcpElement extends AdapterBase implements NetworkElement, Password
if (provider.equalsIgnoreCase(Provider.JuniperSRX.getName()) && ipType == GuestIpType.Virtual) {
return true;
+ } else if (dc.getDhcpProvider().equalsIgnoreCase(Provider.ExternalDhcpServer.getName())){
+ return false;
} else {
if (dc.getNetworkType() == NetworkType.Basic) {
return (ipType == GuestIpType.Direct && trafficType == TrafficType.Guest);
diff --git a/server/src/com/cloud/vm/BareMetalVmManagerImpl.java b/server/src/com/cloud/vm/BareMetalVmManagerImpl.java
index 3238e573947..59a71cb7caa 100644
--- a/server/src/com/cloud/vm/BareMetalVmManagerImpl.java
+++ b/server/src/com/cloud/vm/BareMetalVmManagerImpl.java
@@ -2,20 +2,26 @@ package com.cloud.vm;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
import javax.ejb.Local;
+import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
+import com.cloud.agent.manager.Commands;
import com.cloud.api.commands.AttachVolumeCmd;
import com.cloud.api.commands.CreateTemplateCmd;
import com.cloud.api.commands.DeployVMCmd;
import com.cloud.api.commands.DetachVolumeCmd;
import com.cloud.api.commands.UpgradeVMCmd;
import com.cloud.configuration.ResourceCount.ResourceType;
+import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
import com.cloud.domain.DomainVO;
import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventVO;
@@ -39,15 +45,20 @@ import com.cloud.user.Account;
import com.cloud.user.SSHKeyPair;
import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
+import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
+import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Manager;
+import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.VirtualMachine.Type;
@Local(value={BareMetalVmManager.class, BareMetalVmService.class})
public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMetalVmManager, BareMetalVmService, Manager {
private static final Logger s_logger = Logger.getLogger(BareMetalVmManagerImpl.class);
+ private ConfigurationDao _configDao;
@Override
public boolean attachISOToVM(long vmId, long isoId, boolean attach) {
@@ -275,6 +286,87 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet
}
public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
- return null;
+ return super.startVirtualMachine(cmd);
+ }
+
+ @Override
+ public boolean configure(String name, Map params) throws ConfigurationException {
+ _name = name;
+
+ ComponentLocator locator = ComponentLocator.getCurrentLocator();
+ _configDao = locator.getDao(ConfigurationDao.class);
+ if (_configDao == null) {
+ throw new ConfigurationException("Unable to get the configuration dao.");
+ }
+
+ Map configs = _configDao.getConfiguration("AgentManager", params);
+
+ _instance = configs.get("instance.name");
+ if (_instance == null) {
+ _instance = "DEFAULT";
+ }
+
+ String workers = configs.get("expunge.workers");
+ int wrks = NumbersUtil.parseInt(workers, 10);
+
+ String time = configs.get("expunge.interval");
+ _expungeInterval = NumbersUtil.parseInt(time, 86400);
+
+ time = configs.get("expunge.delay");
+ _expungeDelay = NumbersUtil.parseInt(time, _expungeInterval);
+
+ _executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("UserVm-Scavenger"));
+
+ _itMgr.registerGuru(Type.UserBareMetal, this);
+
+ s_logger.info("User VM Manager is configured.");
+
+ return true;
+ }
+
+ @Override
+ public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+ UserVmVO vm = profile.getVirtualMachine();
+ Account owner = _accountDao.findById(vm.getAccountId());
+
+ if (owner == null || owner.getState() == Account.State.disabled) {
+ throw new PermissionDeniedException("The owner of " + vm + " either does not exist or is disabled: " + vm.getAccountId());
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+ UserVmVO userVm = profile.getVirtualMachine();
+ List nics = _nicDao.listByVmId(userVm.getId());
+ for (NicVO nic : nics) {
+ NetworkVO network = _networkDao.findById(nic.getNetworkId());
+ if (network.getTrafficType() == TrafficType.Guest) {
+ userVm.setPrivateIpAddress(nic.getIp4Address());
+ userVm.setPrivateMacAddress(nic.getMacAddress());
+ }
+ }
+ _vmDao.update(userVm.getId(), userVm);
+ return true;
+ }
+
+ @Override
+ public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
+ UserVmVO vm = profile.getVirtualMachine();
+ UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_START, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(),
+ vm.getServiceOfferingId(), vm.getTemplateId(), null);
+ _usageEventDao.persist(usageEvent);
+
+ List nics = _nicDao.listByVmId(vm.getId());
+ for (NicVO nic : nics) {
+ NetworkVO network = _networkDao.findById(nic.getNetworkId());
+ long isDefault = (nic.isDefaultNic()) ? 1 : 0;
+ usageEvent = new UsageEventVO(EventTypes.EVENT_NETWORK_OFFERING_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(),
+ network.getNetworkOfferingId(), null, isDefault);
+ _usageEventDao.persist(usageEvent);
+ }
+
+ return true;
}
}
diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
index f5de5cccd1f..a61d9411145 100755
--- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -130,6 +130,7 @@ import com.cloud.utils.fsm.StateMachine2;
import com.cloud.vm.ItWorkVO.Step;
import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.dao.ConsoleProxyDao;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
@@ -296,6 +297,11 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
return (VirtualMachineGuru)_vmGurus.get(vm.getType());
}
+ @SuppressWarnings("unchecked")
+ private VirtualMachineGuru getBareMetalVmGuru(T vm) {
+ return (VirtualMachineGuru)_vmGurus.get(Type.UserBareMetal);
+ }
+
@Override
public boolean expunge(T vm, User caller, Account account) throws ResourceUnavailableException {
try {
@@ -521,7 +527,13 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
public T advanceStart(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
long vmId = vm.getId();
- VirtualMachineGuru vmGuru = getVmGuru(vm);
+ VirtualMachineGuru vmGuru;
+ if (vm.getHypervisorType() == HypervisorType.BareMetal) {
+ vmGuru = getBareMetalVmGuru(vm);
+ } else {
+ vmGuru = getVmGuru(vm);
+ }
+
vm = vmGuru.findById(vm.getId());
Ternary start = changeToStartState(vmGuru, vm, caller, account);
if (start == null) {
@@ -569,7 +581,9 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
try {
- _storageMgr.prepare(vmProfile, dest);
+ if (vm.getHypervisorType() != HypervisorType.BareMetal) {
+ _storageMgr.prepare(vmProfile, dest);
+ }
_networkMgr.prepare(vmProfile, dest, ctx);
vmGuru.finalizeVirtualMachineProfile(vmProfile, dest, ctx);