diff --git a/ovm/src/com/cloud/ovm/hypervisor/OvmDiscoverer.java b/ovm/src/com/cloud/ovm/hypervisor/OvmDiscoverer.java index e505dfdba40..f7830e43cbb 100755 --- a/ovm/src/com/cloud/ovm/hypervisor/OvmDiscoverer.java +++ b/ovm/src/com/cloud/ovm/hypervisor/OvmDiscoverer.java @@ -14,6 +14,8 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.dc.ClusterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.exception.DiscoveryException; @@ -24,16 +26,20 @@ import com.cloud.ovm.object.Connection; import com.cloud.ovm.object.OvmHost; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; import com.cloud.utils.component.Inject; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.ssh.SSHCmdHelper; @Local(value=Discoverer.class) -public class OvmDiscoverer extends DiscovererBase implements Discoverer { +public class OvmDiscoverer extends DiscovererBase implements Discoverer, ResourceStateAdapter { private static final Logger s_logger = Logger.getLogger(OvmDiscoverer.class); @Inject ClusterDao _clusterDao; + @Inject ResourceManager _resourceMgr; protected OvmDiscoverer() { @@ -163,4 +169,32 @@ public class OvmDiscoverer extends DiscovererBase implements Discoverer { return HypervisorType.Ovm; } + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, + List hostTags) { + StartupCommand firstCmd = startup[0]; + if (!(firstCmd instanceof StartupRoutingCommand)) { + return null; + } + + StartupRoutingCommand ssCmd = ((StartupRoutingCommand) firstCmd); + if (ssCmd.getHypervisorType() != HypervisorType.Ovm) { + return null; + } + + return _resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.Ovm, details, hostTags); + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + // TODO Auto-generated method stub + return null; + } + } diff --git a/server/src/com/cloud/baremetal/BareMetalDiscoverer.java b/server/src/com/cloud/baremetal/BareMetalDiscoverer.java index cf6e38d343a..860149192e0 100755 --- a/server/src/com/cloud/baremetal/BareMetalDiscoverer.java +++ b/server/src/com/cloud/baremetal/BareMetalDiscoverer.java @@ -30,11 +30,13 @@ import javax.ejb.Local; import org.apache.log4j.Logger; +import com.cloud.agent.api.StartupCommand; import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.DiscoveryException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; @@ -42,17 +44,23 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; +import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; import com.cloud.utils.component.Inject; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.dao.VMInstanceDao; @Local(value=Discoverer.class) -public class BareMetalDiscoverer extends DiscovererBase implements Discoverer { +public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, ResourceStateAdapter { private static final Logger s_logger = Logger.getLogger(BareMetalDiscoverer.class); @Inject ClusterDao _clusterDao; @Inject protected HostDao _hostDao; @Inject DataCenterDao _dcDao; + @Inject VMInstanceDao _vmDao = null; @Override public Map> find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List hostTags) @@ -179,4 +187,34 @@ public class BareMetalDiscoverer extends DiscovererBase implements Discoverer { return Hypervisor.HypervisorType.BareMetal; } + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, + List hostTags) { + // TODO Auto-generated method stub + return null; + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + if (host.getType() != Host.Type.Routing || host.getHypervisorType() != HypervisorType.BareMetal) { + return null; + } + + List deadVms = _vmDao.listByLastHostId(host.getId()); + for (VMInstanceVO vm : deadVms) { + if (vm.getState() == State.Running || vm.getHostId() != null) { + throw new CloudRuntimeException("VM " + vm.getId() + "is still running on host " + host.getId()); + } + _vmDao.remove(vm.getId()); + } + + return new DeleteHostAnswer(true); + } + } diff --git a/server/src/com/cloud/baremetal/ExternalDhcpManagerImpl.java b/server/src/com/cloud/baremetal/ExternalDhcpManagerImpl.java index 5ba62fce8e2..b882547551b 100755 --- a/server/src/com/cloud/baremetal/ExternalDhcpManagerImpl.java +++ b/server/src/com/cloud/baremetal/ExternalDhcpManagerImpl.java @@ -39,6 +39,7 @@ import com.cloud.agent.api.AgentControlCommand; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupExternalDhcpCommand; import com.cloud.agent.api.routing.DhcpEntryCommand; import com.cloud.agent.manager.Commands; import com.cloud.baremetal.ExternalDhcpEntryListener.DhcpEntryState; @@ -60,7 +61,9 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network; import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; import com.cloud.utils.component.Inject; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; @@ -74,7 +77,7 @@ import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.UserVmDao; @Local(value = {ExternalDhcpManager.class}) -public class ExternalDhcpManagerImpl implements ExternalDhcpManager { +public class ExternalDhcpManagerImpl implements ExternalDhcpManager, ResourceStateAdapter { private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalDhcpManagerImpl.class); protected String _name; @Inject DataCenterDao _dcDao; @@ -237,4 +240,27 @@ public class ExternalDhcpManagerImpl implements ExternalDhcpManager { throw new ResourceUnavailableException(errMsg + e.getMessage(), DataCenter.class, zoneId); } } + + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, + List hostTags) { + if (!(startup[0] instanceof StartupExternalDhcpCommand)) { + return null; + } + + host.setType(Host.Type.ExternalDhcp); + return host; + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + // TODO Auto-generated method stub + return null; + } } diff --git a/server/src/com/cloud/baremetal/PxeServerManagerImpl.java b/server/src/com/cloud/baremetal/PxeServerManagerImpl.java old mode 100644 new mode 100755 index 397fda13344..80a58a5f52d --- a/server/src/com/cloud/baremetal/PxeServerManagerImpl.java +++ b/server/src/com/cloud/baremetal/PxeServerManagerImpl.java @@ -20,6 +20,7 @@ package com.cloud.baremetal; +import java.util.List; import java.util.Map; import javax.ejb.Local; @@ -27,12 +28,17 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupPxeServerCommand; import com.cloud.baremetal.PxeServerManager.PxeServerType; import com.cloud.dc.dao.DataCenterDao; import com.cloud.deploy.DeployDestination; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; +import com.cloud.resource.ResourceStateAdapter; +import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; import com.cloud.uservm.UserVm; import com.cloud.utils.component.Adapters; import com.cloud.utils.component.Inject; @@ -43,7 +49,7 @@ import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile.Param; @Local(value = {PxeServerManager.class}) -public class PxeServerManagerImpl implements PxeServerManager { +public class PxeServerManagerImpl implements PxeServerManager, ResourceStateAdapter { private static final org.apache.log4j.Logger s_logger = Logger.getLogger(PxeServerManagerImpl.class); protected String _name; @Inject DataCenterDao _dcDao; @@ -115,4 +121,27 @@ public class PxeServerManagerImpl implements PxeServerManager { throw new CloudRuntimeException("Unkown PXE server resource " + host.getResource()); } } + + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, + List hostTags) { + if (!(startup[0] instanceof StartupPxeServerCommand)) { + return null; + } + + host.setType(Host.Type.PxeServer); + return host; + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + // TODO Auto-generated method stub + return null; + } } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java old mode 100644 new mode 100755 index b155abf42b3..dc099c07654 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -88,6 +88,9 @@ import com.cloud.network.NetworkVO; import com.cloud.network.Networks.TrafficType; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.resource.ResourceStateAdapter; +import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.servlet.ConsoleProxyServlet; @@ -149,7 +152,7 @@ import com.google.gson.GsonBuilder; // because sooner or later, it will be driven into Running state // @Local(value = { ConsoleProxyManager.class, ConsoleProxyService.class }) -public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProxyService, Manager, AgentHook, VirtualMachineGuru, SystemVmLoadScanHandler { +public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProxyService, Manager, AgentHook, VirtualMachineGuru, SystemVmLoadScanHandler, ResourceStateAdapter { private static final Logger s_logger = Logger.getLogger(ConsoleProxyManagerImpl.class); private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30 seconds @@ -1657,4 +1660,27 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx @Override public void onScanEnd() { } + + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + if (!(cmd[0] instanceof StartupProxyCommand)) { + return null; + } + + host.setType(com.cloud.host.Host.Type.ConsoleProxy); + return host; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, + List hostTags) { + // TODO Auto-generated method stub + return null; + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + // TODO Auto-generated method stub + return null; + } } diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java index 289d215d20f..756c8bb4c7a 100755 --- a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java @@ -30,18 +30,23 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; +import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; import com.cloud.agent.api.AgentControlCommand; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.ShutdownCommand; import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterVO; import com.cloud.dc.dao.ClusterDao; +import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.DiscoveredWithErrorException; import com.cloud.exception.DiscoveryException; +import com.cloud.exception.OperationTimedoutException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; @@ -51,7 +56,10 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.kvm.resource.KvmDummyResourceBase; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.script.Script; @@ -62,7 +70,7 @@ import com.trilead.ssh2.Session; @Local(value=Discoverer.class) public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, - Listener { + Listener, ResourceStateAdapter { private static final Logger s_logger = Logger.getLogger(KvmServerDiscoverer.class); private String _setupAgentPath; private ConfigurationDao _configDao; @@ -73,6 +81,8 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, private String _kvmGuestNic; @Inject HostDao _hostDao = null; @Inject ClusterDao _clusterDao; + @Inject ResourceManager _resourceMgr; + @Inject AgentManager _agentMgr; @Override public boolean processAnswers(long agentId, long seq, Answer[] answers) { @@ -289,5 +299,60 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, return Hypervisor.HypervisorType.KVM.toString().equalsIgnoreCase(hypervisor); } + + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + StartupCommand firstCmd = cmd[0]; + if (!(firstCmd instanceof StartupRoutingCommand)) { + return null; + } + + StartupRoutingCommand ssCmd = ((StartupRoutingCommand) firstCmd); + if (ssCmd.getHypervisorType() != HypervisorType.KVM) { + return null; + } + + /* KVM requires host are the same in cluster */ + ClusterVO clusterVO = _clusterDao.findById(host.getClusterId()); + List hostsInCluster = _hostDao.listByCluster(clusterVO.getId()); + if (!hostsInCluster.isEmpty()) { + HostVO oneHost = hostsInCluster.get(0); + _hostDao.loadDetails(oneHost); + String hostOsInCluster = oneHost.getDetail("Host.OS"); + String hostOs = ssCmd.getHostDetails().get("Host.OS"); + if (!hostOsInCluster.equalsIgnoreCase(hostOs)) { + throw new IllegalArgumentException("Can't add host: " + firstCmd.getPrivateIpAddress() + " with hostOS: " + hostOs + " into a cluster," + + "in which there are " + hostOsInCluster + " hosts added"); + } + } + + return _resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.KVM, null, null); + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, + List hostTags) { + // TODO Auto-generated method stub + return null; + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + if (host.getType() != Host.Type.Routing || host.getHypervisorType() != HypervisorType.KVM) { + return null; + } + + _resourceMgr.deleteRoutingHost(host, isForced, isForceDeleteStorage); + try { + ShutdownCommand cmd = new ShutdownCommand(ShutdownCommand.DeleteHost, null); + _agentMgr.send(host.getId(), cmd); + } catch (AgentUnavailableException e) { + s_logger.warn("Sending ShutdownCommand failed: ", e); + } catch (OperationTimedoutException e) { + s_logger.warn("Sending ShutdownCommand failed: ", e); + } + + return new DeleteHostAnswer(true); + } } diff --git a/server/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/server/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index 2b692ee571c..ac6cd2727de 100755 --- a/server/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -16,6 +16,8 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.alert.AlertManager; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterDetailsDao; @@ -35,7 +37,10 @@ import com.cloud.hypervisor.vmware.resource.VmwareResource; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.VMTemplateVO; @@ -48,7 +53,7 @@ import com.vmware.vim25.ClusterDasConfigInfo; import com.vmware.vim25.ManagedObjectReference; @Local(value=Discoverer.class) -public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer { +public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer, ResourceStateAdapter { private static final Logger s_logger = Logger.getLogger(VmwareServerDiscoverer.class); @Inject ClusterDao _clusterDao; @@ -57,6 +62,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer @Inject VMTemplateDao _tmpltDao; @Inject ClusterDetailsDao _clusterDetailsDao; @Inject HostDao _hostDao; + @Inject ResourceManager _resourceMgr; @Override public Map> find(long dcId, Long podId, Long clusterId, URI url, @@ -245,6 +251,34 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer tmplt.setUrl(null); _tmpltDao.update(id, tmplt); } + } + + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, + List hostTags) { + StartupCommand firstCmd = startup[0]; + if (!(firstCmd instanceof StartupRoutingCommand)) { + return null; + } + + StartupRoutingCommand ssCmd = ((StartupRoutingCommand) firstCmd); + if (ssCmd.getHypervisorType() != HypervisorType.VMware) { + return null; + } + + return _resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.VMware, details, hostTags); + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + // TODO Auto-generated method stub + return null; } } diff --git a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index 9e86ea93ead..9f6407dc95b 100755 --- a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -47,7 +47,11 @@ import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConnectionException; import com.cloud.exception.DiscoveredWithErrorException; @@ -69,7 +73,10 @@ import com.cloud.hypervisor.xen.resource.XenServer60Resource; import com.cloud.hypervisor.xen.resource.XenServerConnectionPool; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.VMTemplateVO; @@ -88,7 +95,7 @@ import com.xensource.xenapi.Types.SessionAuthenticationFailed; import com.xensource.xenapi.Types.XenAPIException; @Local(value=Discoverer.class) -public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, Listener { +public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, Listener, ResourceStateAdapter { private static final Logger s_logger = Logger.getLogger(XcpServerDiscoverer.class); protected String _publicNic; protected String _privateNic; @@ -108,6 +115,9 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L @Inject VMTemplateHostDao _vmTemplateHostDao; @Inject ClusterDao _clusterDao; @Inject protected ConfigurationDao _configDao; + @Inject ResourceManager _resourceMgr; + @Inject HostPodDao _podDao; + @Inject DataCenterDao _dcDao; protected XcpServerDiscoverer() { } @@ -609,5 +619,37 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L @Override public boolean processTimeout(long agentId, long seq) { return false; + } + + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, + List hostTags) { + StartupCommand firstCmd = startup[0]; + if (!(firstCmd instanceof StartupRoutingCommand)) { + return null; + } + + StartupRoutingCommand ssCmd = ((StartupRoutingCommand) firstCmd); + if (ssCmd.getHypervisorType() != HypervisorType.XenServer) { + return null; + } + + HostPodVO pod = _podDao.findById(host.getPodId()); + DataCenterVO dc = _dcDao.findById(host.getDataCenterId()); + s_logger.info("Host: " + host.getName() + " connected with hypervisor type: " + HypervisorType.XenServer + ". Checking CIDR..."); + _resourceMgr.checkCIDR(pod, dc, ssCmd.getPrivateIpAddress(), ssCmd.getPrivateNetmask()); + return _resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.XenServer, details, hostTags); + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + // TODO Auto-generated method stub + return null; } } diff --git a/server/src/com/cloud/network/ExternalNetworkManagerImpl.java b/server/src/com/cloud/network/ExternalNetworkManagerImpl.java index c43718c708f..eac69de7299 100755 --- a/server/src/com/cloud/network/ExternalNetworkManagerImpl.java +++ b/server/src/com/cloud/network/ExternalNetworkManagerImpl.java @@ -37,6 +37,9 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer; import com.cloud.agent.api.ExternalNetworkResourceUsageCommand; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupExternalFirewallCommand; +import com.cloud.agent.api.StartupExternalLoadBalancerCommand; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; @@ -94,7 +97,9 @@ import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; import com.cloud.server.api.response.ExternalFirewallResponse; import com.cloud.server.api.response.ExternalLoadBalancerResponse; import com.cloud.user.Account; @@ -122,7 +127,7 @@ import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; @Local(value = {ExternalNetworkManager.class}) -public class ExternalNetworkManagerImpl implements ExternalNetworkManager { +public class ExternalNetworkManagerImpl implements ExternalNetworkManager, ResourceStateAdapter { public enum ExternalNetworkResourceName { JuniperSrx, F5BigIp, @@ -1287,4 +1292,30 @@ public class ExternalNetworkManagerImpl implements ExternalNetworkManager { } } } + + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, + List hostTags) { + if (startup[0] instanceof StartupExternalFirewallCommand) { + host.setType(Host.Type.ExternalFirewall); + return host; + } else if (startup[0] instanceof StartupExternalLoadBalancerCommand) { + host.setType(Host.Type.ExternalLoadBalancer); + return host; + } else { + return null; + } + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + // TODO Auto-generated method stub + return null; + } } diff --git a/server/src/com/cloud/network/NetworkUsageManagerImpl.java b/server/src/com/cloud/network/NetworkUsageManagerImpl.java index e5172e5a838..8647ed5b47c 100755 --- a/server/src/com/cloud/network/NetworkUsageManagerImpl.java +++ b/server/src/com/cloud/network/NetworkUsageManagerImpl.java @@ -67,6 +67,9 @@ import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.resource.TrafficSentinelResource; import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceStateAdapter; +import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; import com.cloud.server.api.response.TrafficMonitorResponse; import com.cloud.usage.UsageIPAddressVO; import com.cloud.user.AccountManager; @@ -88,7 +91,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.MacAddress; @Local(value = {NetworkUsageManager.class}) -public class NetworkUsageManagerImpl implements NetworkUsageManager { +public class NetworkUsageManagerImpl implements NetworkUsageManager, ResourceStateAdapter { public enum NetworkUsageResourceName { TrafficSentinel; } @@ -501,4 +504,27 @@ public class NetworkUsageManagerImpl implements NetworkUsageManager { } + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, + List hostTags) { + if (!(startup[0] instanceof StartupTrafficMonitorCommand)) { + return null; + } + + host.setType(Host.Type.TrafficMonitor); + return host; + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + // TODO Auto-generated method stub + return null; + } + } diff --git a/server/src/com/cloud/resource/ResourceManager.java b/server/src/com/cloud/resource/ResourceManager.java index 86205d346d2..5b6d791a83d 100755 --- a/server/src/com/cloud/resource/ResourceManager.java +++ b/server/src/com/cloud/resource/ResourceManager.java @@ -21,9 +21,13 @@ import java.util.List; import java.util.Map; import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupRoutingCommand; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.host.HostVO; +import com.cloud.hypervisor.Hypervisor.HypervisorType; /** * ResourceManager manages how physical resources are organized within the @@ -58,4 +62,10 @@ public interface ResourceManager { public Host addHost(long zoneId, ServerResource resource, Type hostType, Map hostDetails); public HostVO createHostVOForConnectedAgent(StartupCommand[] cmds); + + public void checkCIDR(HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask); + + public HostVO fillRoutingHostVO(HostVO host, StartupRoutingCommand ssCmd, HypervisorType hyType, Map details, List hostTags); + + public void deleteRoutingHost(HostVO host, boolean isForced, boolean forceDestroyStorage) throws UnableDeleteHostException; } diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index 18bbe0b506b..1350fadcb1b 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -35,6 +35,7 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager.TapAgentsAction; import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.manager.AgentAttache; import com.cloud.agent.transport.Request; import com.cloud.api.commands.AddClusterCmd; @@ -49,15 +50,18 @@ import com.cloud.api.commands.UpdateHostPasswordCmd; import com.cloud.cluster.ManagementServerNode; import com.cloud.dc.ClusterDetailsDao; import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenterIpAddressVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.DataCenterIpAddressDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.DiscoveryException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; +import com.cloud.ha.HighAvailabilityManager; import com.cloud.host.Host; import com.cloud.host.Host.HostAllocationState; import com.cloud.host.Host.Type; @@ -69,11 +73,16 @@ import com.cloud.host.dao.HostTagsDao; import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.kvm.resource.KvmDummyResourceBase; +import com.cloud.network.IPAddressVO; +import com.cloud.network.dao.IPAddressDao; import com.cloud.org.Cluster; import com.cloud.org.Grouping; import com.cloud.org.Managed; import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePool; +import com.cloud.storage.StoragePoolStatus; +import com.cloud.storage.StorageService; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.user.Account; @@ -88,7 +97,12 @@ import com.cloud.utils.component.Manager; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.dao.VMInstanceDao; @Local({ ResourceManager.class, ResourceService.class }) public class ResourceManagerImpl implements ResourceManager, ResourceService, Manager { @@ -121,7 +135,19 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma protected HostTagsDao _hostTagsDao; @Inject protected GuestOSCategoryDao _guestOSCategoryDao; - + @Inject + protected DataCenterIpAddressDao _privateIPAddressDao; + @Inject + protected IPAddressDao _publicIPAddressDao; + @Inject + protected VirtualMachineManager _vmMgr; + @Inject + protected VMInstanceDao _vmDao; + @Inject + protected HighAvailabilityManager _haMgr; + @Inject + protected StorageService _storageSvr; + @Inject(adapter = Discoverer.class) protected Adapters _discoverers; @@ -1008,12 +1034,12 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma Map.Entry>> item = (Map.Entry>>)it.next(); ResourceStateAdapter adapter = item.getValue().first(); if (event == ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED) { - result = adapter.createHostVO((HostVO)args[0], (StartupCommand[])args[1]); + result = adapter.createHostVOForConnectedAgent((HostVO)args[0], (StartupCommand[])args[1]); if (result != null && singleTaker) { break; } } else if (event == ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT) { - result = adapter.createHostVO((HostVO)args[0], (StartupCommand[])args[1], (ServerResource)args[2], (Map)args[3], (List)args[4]); + result = adapter.createHostVOForDirectConnectAgent((HostVO)args[0], (StartupCommand[])args[1], (ServerResource)args[2], (Map)args[3], (List)args[4]); if (result != null && singleTaker) { break; } @@ -1036,6 +1062,38 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma } } + @Override + public void checkCIDR(HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask) throws IllegalArgumentException { + if (serverPrivateIP == null) { + return; + } + // Get the CIDR address and CIDR size + String cidrAddress = pod.getCidrAddress(); + long cidrSize = pod.getCidrSize(); + + // If the server's private IP address is not in the same subnet as the + // pod's CIDR, return false + String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize); + String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask); + if (!cidrSubnet.equals(serverSubnet)) { + s_logger.warn("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + pod.getName() + + " and zone: " + dc.getName()); + throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + + pod.getName() + " and zone: " + dc.getName()); + } + + // If the server's private netmask is less inclusive than the pod's CIDR + // netmask, return false + String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize); + long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask); + long serverNetmaskNumeric = NetUtils.ip2Long(serverPrivateNetmask); + if (serverNetmaskNumeric > cidrNetmaskNumeric) { + throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + + pod.getName() + " and zone: " + dc.getName()); + } + + } + private boolean checkCIDR(HostPodVO pod, String serverPrivateIP, String serverPrivateNetmask) { if (serverPrivateIP == null) { return true; @@ -1252,5 +1310,151 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma public HostVO createHostVOForConnectedAgent(StartupCommand[] cmds) { return createHostVO(cmds, null, null, null, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED); } + + private void checkIPConflicts(HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask, String serverPublicIP, String serverPublicNetmask) { + // If the server's private IP is the same as is public IP, this host has + // a host-only private network. Don't check for conflicts with the + // private IP address table. + if (serverPrivateIP != serverPublicIP) { + if (!_privateIPAddressDao.mark(dc.getId(), pod.getId(), serverPrivateIP)) { + // If the server's private IP address is already in the + // database, return false + List existingPrivateIPs = _privateIPAddressDao.listByPodIdDcIdIpAddress(pod.getId(), dc.getId(), serverPrivateIP); + + assert existingPrivateIPs.size() <= 1 : " How can we get more than one ip address with " + serverPrivateIP; + if (existingPrivateIPs.size() > 1) { + throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() + " and zone: " + dc.getName()); + } + if (existingPrivateIPs.size() == 1) { + DataCenterIpAddressVO vo = existingPrivateIPs.get(0); + if (vo.getInstanceId() != null) { + throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() + " and zone: " + dc.getName()); + } + } + } + } + + if (serverPublicIP != null && !_publicIPAddressDao.mark(dc.getId(), new Ip(serverPublicIP))) { + // If the server's public IP address is already in the database, + // return false + List existingPublicIPs = _publicIPAddressDao.listByDcIdIpAddress(dc.getId(), serverPublicIP); + if (existingPublicIPs.size() > 0) { + throw new IllegalArgumentException("The public ip address of the server (" + serverPublicIP + ") is already in use in zone: " + dc.getName()); + } + } + } + + @Override + public HostVO fillRoutingHostVO(HostVO host, StartupRoutingCommand ssCmd, HypervisorType hyType, Map details, List hostTags) { + if (host.getPodId() == null) { + s_logger.error("Host " + ssCmd.getPrivateIpAddress() + " sent incorrect pod, pod id is null"); + throw new IllegalArgumentException("Host " + ssCmd.getPrivateIpAddress() + " sent incorrect pod, pod id is null"); + } + + ClusterVO clusterVO = _clusterDao.findById(host.getClusterId()); + if (clusterVO.getHypervisorType() != hyType) { + throw new IllegalArgumentException("Can't add host whose hypervisor type is: " + hyType + " into cluster: " + clusterVO.getId() + " whose hypervisor type is: " + + clusterVO.getHypervisorType()); + } + + final Map hostDetails = ssCmd.getHostDetails(); + if (hostDetails != null) { + if (details != null) { + details.putAll(hostDetails); + } else { + details = hostDetails; + } + } + + HostPodVO pod = _podDao.findById(host.getPodId()); + DataCenterVO dc = _dcDao.findById(host.getDataCenterId()); + checkIPConflicts(pod, dc, ssCmd.getPrivateIpAddress(), ssCmd.getPublicIpAddress(), ssCmd.getPublicIpAddress(), ssCmd.getPublicNetmask()); + host.setType(com.cloud.host.Host.Type.Routing); + host.setDetails(details); + host.setCaps(ssCmd.getCapabilities()); + host.setCpus(ssCmd.getCpus()); + host.setTotalMemory(ssCmd.getMemory()); + host.setSpeed(ssCmd.getSpeed()); + host.setHypervisorType(hyType); + return host; + } + + @Override + public void deleteRoutingHost(HostVO host, boolean isForced, boolean forceDestroyStorage) throws UnableDeleteHostException { + if (host.getType() != Host.Type.Routing) { + throw new CloudRuntimeException("Non-Routing host gets in deleteRoutingHost, id is " + host.getId()); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Deleting Host: " + host.getId() + " Guid:" + host.getGuid()); + } + + User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); + if (forceDestroyStorage) { + // put local storage into mainenance mode, will set all the VMs on + // this local storage into stopped state + StoragePool storagePool = _storageMgr.findLocalStorageOnHost(host.getId()); + if (storagePool != null) { + if (storagePool.getStatus() == StoragePoolStatus.Up || storagePool.getStatus() == StoragePoolStatus.ErrorInMaintenance) { + try { + storagePool = _storageSvr.preparePrimaryStorageForMaintenance(storagePool.getId()); + if (storagePool == null) { + s_logger.debug("Failed to set primary storage into maintenance mode"); + throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode"); + } + } catch (Exception e) { + s_logger.debug("Failed to set primary storage into maintenance mode, due to: " + e.toString()); + throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode, due to: " + e.toString()); + } + } + + List vmsOnLocalStorage = _storageMgr.listByStoragePool(storagePool.getId()); + for (VMInstanceVO vm : vmsOnLocalStorage) { + try { + if (!_vmMgr.destroy(vm, caller, _accountMgr.getAccount(vm.getAccountId()))) { + String errorMsg = "There was an error Destory the vm: " + vm + " as a part of hostDelete id=" + host.getId(); + s_logger.warn(errorMsg); + throw new UnableDeleteHostException(errorMsg); + } + } catch (Exception e) { + String errorMsg = "There was an error Destory the vm: " + vm + " as a part of hostDelete id=" + host.getId(); + s_logger.debug(errorMsg, e); + throw new UnableDeleteHostException(errorMsg + "," + e.getMessage()); + } + } + } + } else { + // Check if there are vms running/starting/stopping on this host + List vms = _vmDao.listByHostId(host.getId()); + if (!vms.isEmpty()) { + if (isForced) { + // Stop HA disabled vms and HA enabled vms in Stopping state + // Restart HA enabled vms + for (VMInstanceVO vm : vms) { + if (!vm.isHaEnabled() || vm.getState() == State.Stopping) { + s_logger.debug("Stopping vm: " + vm + " as a part of deleteHost id=" + host.getId()); + try { + if (!_vmMgr.advanceStop(vm, true, caller, _accountMgr.getAccount(vm.getAccountId()))) { + String errorMsg = "There was an error stopping the vm: " + vm + " as a part of hostDelete id=" + host.getId(); + s_logger.warn(errorMsg); + throw new UnableDeleteHostException(errorMsg); + } + } catch (Exception e) { + String errorMsg = "There was an error stopping the vm: " + vm + " as a part of hostDelete id=" + host.getId(); + s_logger.debug(errorMsg, e); + throw new UnableDeleteHostException(errorMsg + "," + e.getMessage()); + } + } else if (vm.isHaEnabled() && (vm.getState() == State.Running || vm.getState() == State.Starting)) { + s_logger.debug("Scheduling restart for vm: " + vm + " " + vm.getState() + " on the host id=" + host.getId()); + _haMgr.scheduleRestart(vm, false); + } + } + } else { + throw new UnableDeleteHostException("Unable to delete the host as there are vms in " + vms.get(0).getState() + + " state using this host and isForced=false specified"); + } + } + } + } } diff --git a/server/src/com/cloud/resource/ResourceStateAdapter.java b/server/src/com/cloud/resource/ResourceStateAdapter.java index 83ce0ebc02d..18e044f9716 100755 --- a/server/src/com/cloud/resource/ResourceStateAdapter.java +++ b/server/src/com/cloud/resource/ResourceStateAdapter.java @@ -39,9 +39,9 @@ public interface ResourceStateAdapter extends Adapter { } } - public HostVO createHostVO(HostVO host, StartupCommand[] cmd); + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd); - public HostVO createHostVO(HostVO host, final StartupCommand[] startup, ServerResource resource, Map details, List hostTags); + public HostVO createHostVOForDirectConnectAgent(HostVO host, final StartupCommand[] startup, ServerResource resource, Map details, List hostTags); public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException; } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java old mode 100644 new mode 100755 index d18aecf8c28..af079260011 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -18,6 +18,7 @@ package com.cloud.storage.secondary; import java.util.ArrayList; + import java.util.Date; import java.util.Enumeration; import java.util.HashMap; @@ -38,6 +39,8 @@ import com.cloud.agent.api.SecStorageSetupAnswer; import com.cloud.agent.api.SecStorageSetupCommand; import com.cloud.agent.api.SecStorageVMSetupCommand; import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupSecondaryStorageCommand; +import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; @@ -69,6 +72,9 @@ import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; import com.cloud.network.Networks.TrafficType; import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.resource.ResourceStateAdapter; +import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.SnapshotVO; @@ -79,6 +85,7 @@ import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateHostDao; +import com.cloud.storage.resource.DummySecondaryStorageResource; import com.cloud.storage.template.TemplateConstants; import com.cloud.user.Account; import com.cloud.user.AccountService; @@ -110,6 +117,7 @@ import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDetailsDao; import com.cloud.vm.dao.VMInstanceDao; +import com.cloud.storage.Storage; // // Possible secondary storage vm state transition cases @@ -130,7 +138,7 @@ import com.cloud.vm.dao.VMInstanceDao; // because sooner or later, it will be driven into Running state // @Local(value = { SecondaryStorageVmManager.class }) -public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, VirtualMachineGuru, SystemVmLoadScanHandler { +public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, VirtualMachineGuru, SystemVmLoadScanHandler, ResourceStateAdapter { private static final Logger s_logger = Logger.getLogger(SecondaryStorageManagerImpl.class); private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30 @@ -1180,4 +1188,62 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V public void onScanEnd() { } + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, + List hostTags) { + StartupCommand firstCmd = startup[0]; + if (!(firstCmd instanceof StartupSecondaryStorageCommand) && !(firstCmd instanceof StartupSecondaryStorageCommand)) { + return null; + } + + com.cloud.host.Host.Type type = null; + if (firstCmd instanceof StartupSecondaryStorageCommand) { + type = com.cloud.host.Host.Type.SecondaryStorageVM; + } else if (firstCmd instanceof StartupSecondaryStorageCommand) { + StartupStorageCommand ssCmd = ((StartupStorageCommand) firstCmd); + if (ssCmd.getHostType() == Host.Type.SecondaryStorageCmdExecutor) { + type = ssCmd.getHostType(); + } else { + if (ssCmd.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE) { + type = Host.Type.SecondaryStorage; + if (resource != null && resource instanceof DummySecondaryStorageResource) { + host.setResource(null); + } + } else if (ssCmd.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE) { + type = Host.Type.LocalSecondaryStorage; + } else { + type = Host.Type.Storage; + } + + final Map hostDetails = ssCmd.getHostDetails(); + if (hostDetails != null) { + if (details != null) { + details.putAll(hostDetails); + } else { + details = hostDetails; + } + } + + host.setDetails(details); + } + } + + host.setType(type); + return host; + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + if (host.getType() == Host.Type.SecondaryStorage) { + deleteHost(host.getId()); + return new DeleteHostAnswer(false); + } + return null; + } }