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);