Bug 11522 - New agent manager

implements ResourceStateAdapter in a couple of components
This commit is contained in:
frank 2011-09-23 11:28:02 -07:00
parent b5e3639263
commit e0e5491c42
14 changed files with 647 additions and 16 deletions

View File

@ -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<String, String> details,
List<String> 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;
}
}

View File

@ -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<? extends ServerResource, Map<String, String>> find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List<String> 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<String, String> details,
List<String> 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<VMInstanceVO> 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);
}
}

View File

@ -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<String, String> details,
List<String> 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;
}
}

View File

@ -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<String, String> details,
List<String> 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;
}
}

View File

@ -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<ConsoleProxyVO>, SystemVmLoadScanHandler<Long> {
public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProxyService, Manager, AgentHook, VirtualMachineGuru<ConsoleProxyVO>, SystemVmLoadScanHandler<Long>, 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<String, String> details,
List<String> 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;
}
}

View File

@ -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<HostVO> 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<String, String> details,
List<String> 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);
}
}

View File

@ -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<? extends ServerResource, Map<String, String>> 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<String, String> details,
List<String> 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;
}
}

View File

@ -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<String, String> details,
List<String> 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;
}
}

View File

@ -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<String, String> details,
List<String> 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;
}
}

View File

@ -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<String, String> details,
List<String> 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;
}
}

View File

@ -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<String, String> 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<String, String> details, List<String> hostTags);
public void deleteRoutingHost(HostVO host, boolean isForced, boolean forceDestroyStorage) throws UnableDeleteHostException;
}

View File

@ -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<? extends Discoverer> _discoverers;
@ -1008,12 +1034,12 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
Map.Entry<String, Pair<ResourceStateAdapter, List<String>>> item = (Map.Entry<String, Pair<ResourceStateAdapter, List<String>>>)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<String, String>)args[3], (List<String>)args[4]);
result = adapter.createHostVOForDirectConnectAgent((HostVO)args[0], (StartupCommand[])args[1], (ServerResource)args[2], (Map<String, String>)args[3], (List<String>)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<DataCenterIpAddressVO> 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<IPAddressVO> 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<String, String> details, List<String> 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<String, String> 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<VMInstanceVO> 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<VMInstanceVO> 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");
}
}
}
}
}

View File

@ -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<String, String> details, List<String> hostTags);
public HostVO createHostVOForDirectConnectAgent(HostVO host, final StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags);
public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException;
}

View File

@ -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<SecondaryStorageVmVO>, SystemVmLoadScanHandler<Long> {
public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, VirtualMachineGuru<SecondaryStorageVmVO>, SystemVmLoadScanHandler<Long>, 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<String, String> details,
List<String> 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<String, String> 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;
}
}