From 5ce631e9d700784b23ca68e969102cda95f2e9cf Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Mon, 16 May 2011 10:03:32 -0700 Subject: [PATCH] Separated resource management and agent management code. It's not all done but at least we make a first step --- server/src/com/cloud/agent/AgentManager.java | 21 +- .../cloud/agent/manager/AgentManagerImpl.java | 676 +--------------- .../manager/ClusteredAgentManagerImpl.java | 45 +- .../allocator/impl/FirstFitAllocator.java | 4 +- .../DefaultComponentLibrary.java | 24 +- .../src/com/cloud/deploy/FirstFitPlanner.java | 4 +- .../src/com/cloud/host/dao/HostDaoImpl.java | 2 +- .../{DetailsDao.java => HostDetailsDao.java} | 2 +- ...lsDaoImpl.java => HostDetailsDaoImpl.java} | 6 +- .../cloud/resource/ResourceManagerImpl.java | 737 +++++++++++++++++- .../cloud/server/ManagementServerImpl.java | 6 +- .../com/cloud/storage/StorageManagerImpl.java | 4 +- .../storage/snapshot/SnapshotManagerImpl.java | 4 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 4 +- 14 files changed, 802 insertions(+), 737 deletions(-) rename server/src/com/cloud/host/dao/{DetailsDao.java => HostDetailsDao.java} (94%) rename server/src/com/cloud/host/dao/{DetailsDaoImpl.java => HostDetailsDaoImpl.java} (94%) diff --git a/server/src/com/cloud/agent/AgentManager.java b/server/src/com/cloud/agent/AgentManager.java index 91ade974382..cda55e06791 100755 --- a/server/src/com/cloud/agent/AgentManager.java +++ b/server/src/com/cloud/agent/AgentManager.java @@ -23,18 +23,17 @@ import java.util.Set; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.manager.AgentAttache; import com.cloud.agent.manager.Commands; +import com.cloud.api.commands.UpdateHostPasswordCmd; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.PodCluster; import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.DiscoveryException; -import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.OperationTimedoutException; import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.host.HostStats; -import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.Status.Event; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -137,16 +136,16 @@ public interface AgentManager extends Manager { * @return id to unregister if needed. */ int registerForHostEvents(Listener listener, boolean connections, boolean commands, boolean priority); - - + + /** - * Register to listen for initial agent connections. + * Register to listen for initial agent connections. * @param creator * @param priority in listening for events. * @return id to unregister if needed. */ int registerForInitialConnects(StartupCommandProcessor creator, boolean priority); - + /** * Unregister for listening to host events. * @@ -253,9 +252,6 @@ public interface AgentManager extends Manager { public boolean reconnect(final long hostId) throws AgentUnavailableException; - public List discoverHosts(Long dcId, Long podId, Long clusterId, String clusterName, String url, String username, String password, String hypervisor, List hostTags) - throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException; - Answer easySend(Long hostId, Command cmd, int timeout); boolean isHostNativeHAEnabled(long hostId); @@ -263,4 +259,9 @@ public interface AgentManager extends Manager { Answer sendTo(Long dcId, HypervisorType type, Command cmd); void notifyAnswersToMonitors(long agentId, long seq, Answer[] answers); + + AgentAttache simulateStart(Long id, ServerResource resource, Map details, boolean old, List hostTags, String allocationState) throws IllegalArgumentException; + + boolean updateHostPassword(UpdateHostPasswordCmd upasscmd); + } diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index 3910bf405d9..1550b30b5b4 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -19,9 +19,6 @@ package com.cloud.agent.manager; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URLDecoder; import java.nio.channels.ClosedChannelException; import java.util.ArrayList; import java.util.Enumeration; @@ -78,14 +75,6 @@ import com.cloud.agent.transport.Request; import com.cloud.agent.transport.Response; import com.cloud.alert.AlertManager; import com.cloud.api.ApiConstants; -import com.cloud.api.commands.AddClusterCmd; -import com.cloud.api.commands.AddHostCmd; -import com.cloud.api.commands.AddSecondaryStorageCmd; -import com.cloud.api.commands.CancelMaintenanceCmd; -import com.cloud.api.commands.DeleteClusterCmd; -import com.cloud.api.commands.PrepareForMaintenanceCmd; -import com.cloud.api.commands.ReconnectHostCmd; -import com.cloud.api.commands.UpdateHostCmd; import com.cloud.api.commands.UpdateHostPasswordCmd; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityVO; @@ -107,11 +96,8 @@ import com.cloud.dc.dao.HostPodDao; import com.cloud.event.dao.EventDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConnectionException; -import com.cloud.exception.DiscoveredWithErrorException; -import com.cloud.exception.DiscoveryException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.UnsupportedVersionException; import com.cloud.ha.HighAvailabilityManager; import com.cloud.ha.HighAvailabilityManager.WorkType; @@ -123,22 +109,17 @@ import com.cloud.host.HostStats; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.Status.Event; -import com.cloud.host.dao.DetailsDao; import com.cloud.host.dao.HostDao; +import com.cloud.host.dao.HostDetailsDao; 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.offering.ServiceOffering; -import com.cloud.org.Cluster; -import com.cloud.org.Grouping; import com.cloud.resource.Discoverer; -import com.cloud.resource.ResourceService; import com.cloud.resource.ServerResource; import com.cloud.service.ServiceOfferingVO; -import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.Storage; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolHostVO; @@ -150,16 +131,13 @@ import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.resource.DummySecondaryStorageResource; import com.cloud.template.VirtualMachineTemplate; -import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.User; -import com.cloud.user.UserContext; import com.cloud.uservm.UserVm; import com.cloud.utils.ActionDelegate; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; -import com.cloud.utils.UriUtils; import com.cloud.utils.component.Adapters; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; @@ -194,8 +172,8 @@ import com.cloud.vm.dao.VMInstanceDao; * ping.interval before announcing an agent has timed out | float | 2.0x || || router.stats.interval | interval to * report router statistics | seconds | 300s || * } **/ -@Local(value = { AgentManager.class, ResourceService.class }) -public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceService, Manager { +@Local(value = { AgentManager.class }) +public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager { private static final Logger s_logger = Logger.getLogger(AgentManagerImpl.class); protected ConcurrentHashMap _agents = new ConcurrentHashMap(10007); @@ -209,7 +187,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS @Inject protected HostDao _hostDao = null; @Inject - protected DetailsDao _detailsDao = null; + protected HostDetailsDao _detailsDao = null; @Inject protected DataCenterDao _dcDao = null; @Inject @@ -235,7 +213,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS @Inject protected GuestOSCategoryDao _guestOSCategoryDao = null; @Inject - protected DetailsDao _hostDetailsDao = null; + protected HostDetailsDao _hostDetailsDao = null; @Inject protected ClusterDao _clusterDao = null; @Inject @@ -523,502 +501,6 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS return attache; } - @Override - public List discoverCluster(AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException { - Long dcId = cmd.getZoneId(); - Long podId = cmd.getPodId(); - String clusterName = cmd.getClusterName(); - String url = cmd.getUrl(); - String username = cmd.getUsername(); - String password = cmd.getPassword(); - - if(url != null) { - url = URLDecoder.decode(url); - } - - URI uri = null; - - // Check if the zone exists in the system - DataCenterVO zone = _dcDao.findById(dcId); - if (zone == null) { - throw new InvalidParameterValueException("Can't find zone by id " + dcId); - } - - Account account = UserContext.current().getCaller(); - if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { - throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + dcId); - } - - // Check if the pod exists in the system - if (podId != null) { - if (_podDao.findById(podId) == null) { - throw new InvalidParameterValueException("Can't find pod by id " + podId); - } - // check if pod belongs to the zone - HostPodVO pod = _podDao.findById(podId); - if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) { - throw new InvalidParameterValueException("Pod " + podId + " doesn't belong to the zone " + dcId); - } - } - - // Verify cluster information and create a new cluster if needed - if (clusterName == null || clusterName.isEmpty()) { - throw new InvalidParameterValueException("Please specify cluster name"); - } - - if (cmd.getHypervisor() == null || cmd.getHypervisor().isEmpty()) { - throw new InvalidParameterValueException("Please specify a hypervisor"); - } - - Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(cmd.getHypervisor()); - if (hypervisorType == null) { - s_logger.error("Unable to resolve " + cmd.getHypervisor() + " to a valid supported hypervisor type"); - throw new InvalidParameterValueException("Unable to resolve " + cmd.getHypervisor() + " to a supported "); - } - - Cluster.ClusterType clusterType = null; - if (cmd.getClusterType() != null && !cmd.getClusterType().isEmpty()) { - clusterType = Cluster.ClusterType.valueOf(cmd.getClusterType()); - } - if (clusterType == null) { - clusterType = Cluster.ClusterType.CloudManaged; - } - - Grouping.AllocationState allocationState = null; - if (cmd.getAllocationState() != null && !cmd.getAllocationState().isEmpty()) { - try { - allocationState = Grouping.AllocationState.valueOf(cmd.getAllocationState()); - } catch (IllegalArgumentException ex) { - throw new InvalidParameterValueException("Unable to resolve Allocation State '" + cmd.getAllocationState() + "' to a supported state"); - } - } - if (allocationState == null) { - allocationState = Grouping.AllocationState.Enabled; - } - - Discoverer discoverer = getMatchingDiscover(hypervisorType); - if (discoverer == null) { - - throw new InvalidParameterValueException("Could not find corresponding resource manager for " + cmd.getHypervisor()); - } - - List result = new ArrayList(); - - long clusterId = 0; - ClusterVO cluster = new ClusterVO(dcId, podId, clusterName); - cluster.setHypervisorType(cmd.getHypervisor()); - - cluster.setClusterType(clusterType); - cluster.setAllocationState(allocationState); - try { - cluster = _clusterDao.persist(cluster); - } catch (Exception e) { - // no longer tolerate exception during the cluster creation phase - throw new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod " + podId + " and data center " + dcId, e); - } - clusterId = cluster.getId(); - result.add(cluster); - - if (clusterType == Cluster.ClusterType.CloudManaged) { - return result; - } - - // save cluster details for later cluster/host cross-checking - Map details = new HashMap(); - details.put("url", url); - details.put("username", username); - details.put("password", password); - _clusterDetailsDao.persist(cluster.getId(), details); - - boolean success = false; - try { - try { - uri = new URI(UriUtils.encodeURIComponent(url)); - if (uri.getScheme() == null) { - throw new InvalidParameterValueException("uri.scheme is null " + url + ", add http:// as a prefix"); - } else if (uri.getScheme().equalsIgnoreCase("http")) { - if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) { - throw new InvalidParameterValueException("Your host and/or path is wrong. Make sure it's of the format http://hostname/path"); - } - } - } catch (URISyntaxException e) { - throw new InvalidParameterValueException(url + " is not a valid uri"); - } - - List hosts = new ArrayList(); - Map> resources = null; - - try { - resources = discoverer.find(dcId, podId, clusterId, uri, username, password); - } catch (Exception e) { - s_logger.info("Exception in external cluster discovery process with discoverer: " + discoverer.getName()); - } - if (resources != null) { - for (Map.Entry> entry : resources.entrySet()) { - ServerResource resource = entry.getKey(); - - // For Hyper-V, we are here means agent have already started and connected to management server - if (hypervisorType == Hypervisor.HypervisorType.Hyperv) { - break; - } - - AgentAttache attache = simulateStart(null, resource, entry.getValue(), true, null, null); - if (attache != null) { - hosts.add(_hostDao.findById(attache.getId())); - } - discoverer.postDiscovery(hosts, _nodeId); - } - s_logger.info("External cluster has been successfully discovered by " + discoverer.getName()); - success = true; - return result; - } - - s_logger.warn("Unable to find the server resources at " + url); - throw new DiscoveryException("Unable to add the external cluster"); - } catch (Throwable e) { - s_logger.error("Unexpected exception ", e); - throw new DiscoveryException("Unable to add the external cluster due to unhandled exception"); - } finally { - if (!success) { - _clusterDetailsDao.deleteDetails(clusterId); - _clusterDao.remove(clusterId); - } - } - } - - private Discoverer getMatchingDiscover(Hypervisor.HypervisorType hypervisorType) { - Enumeration en = _discoverers.enumeration(); - while (en.hasMoreElements()) { - Discoverer discoverer = en.nextElement(); - if (discoverer.getHypervisorType() == hypervisorType) { - return discoverer; - } - } - return null; - } - - @Override - public List discoverHosts(AddHostCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { - Long dcId = cmd.getZoneId(); - Long podId = cmd.getPodId(); - Long clusterId = cmd.getClusterId(); - String clusterName = cmd.getClusterName(); - String url = cmd.getUrl(); - String username = cmd.getUsername(); - String password = cmd.getPassword(); - Long memCapacity = cmd.getMemCapacity(); - Long cpuSpeed = cmd.getCpuSpeed(); - Long cpuNum = cmd.getCpuNum(); - String mac = cmd.getMac(); - List hostTags = cmd.getHostTags(); - Map bareMetalParams = new HashMap(); - - dcId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), dcId); - - // this is for standalone option - if (clusterName == null && clusterId == null) { - clusterName = "Standalone-" + url; - } - - if ( clusterId != null ) { - ClusterVO cluster = _clusterDao.findById(clusterId); - if ( cluster == null ) { - throw new InvalidParameterValueException("can not fine cluster for clusterId " + clusterId); - } else { - if ( cluster.getGuid() == null ) { - List hosts = _hostDao.listByCluster(clusterId); - if ( ! hosts.isEmpty() ) { - throw new CloudRuntimeException("Guid is not updated for cluster " + clusterId + " need to wait hosts in this cluster up"); - } - } - } - } - - if (cmd.getHypervisor().equalsIgnoreCase(Hypervisor.HypervisorType.BareMetal.toString())) { - if (memCapacity == null) { - memCapacity = Long.valueOf(0); - } - if (cpuSpeed == null) { - cpuSpeed = Long.valueOf(0); - } - if (cpuNum == null) { - cpuNum = Long.valueOf(0); - } - if (mac == null) { - mac = "unknown"; - } - - bareMetalParams.put("cpuNum", cpuNum.toString()); - bareMetalParams.put("cpuCapacity", cpuSpeed.toString()); - bareMetalParams.put("memCapacity", memCapacity.toString()); - bareMetalParams.put("mac", mac); - if (hostTags != null) { - bareMetalParams.put("hostTag", hostTags.get(0)); - } - } - String allocationState = cmd.getAllocationState(); - if (allocationState == null) { - allocationState = Host.HostAllocationState.Enabled.toString(); - } - - return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, cmd.getHypervisor(), hostTags, bareMetalParams, allocationState); - } - - @Override - public List discoverHosts(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { - Long dcId = cmd.getZoneId(); - String url = cmd.getUrl(); - return discoverHosts(dcId, null, null, null, url, null, null, "SecondaryStorage", null); - } - - @Override - public List discoverHosts(Long dcId, Long podId, Long clusterId, String clusterName, String url, String username, String password, String hypervisorType, List hostTags) - throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { - return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, hypervisorType, hostTags, null, null); - } - - private List discoverHostsFull(Long dcId, Long podId, Long clusterId, String clusterName, String url, String username, String password, String hypervisorType, List hostTags, - Map params, String allocationState) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { - URI uri = null; - - // Check if the zone exists in the system - DataCenterVO zone = _dcDao.findById(dcId); - if (zone == null) { - throw new InvalidParameterValueException("Can't find zone by id " + dcId); - } - - Account account = UserContext.current().getCaller(); - if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { - throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + dcId); - } - - // Check if the pod exists in the system - if (podId != null) { - if (_podDao.findById(podId) == null) { - throw new InvalidParameterValueException("Can't find pod by id " + podId); - } - // check if pod belongs to the zone - HostPodVO pod = _podDao.findById(podId); - if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) { - throw new InvalidParameterValueException("Pod " + podId + " doesn't belong to the zone " + dcId); - } - } - - // Deny to add a secondary storage multiple times for the same zone - if ((username == null) && (_hostDao.findSecondaryStorageHost(dcId) != null)) { - throw new InvalidParameterValueException("A secondary storage host already exists in the specified zone"); - } - - // Verify cluster information and create a new cluster if needed - if (clusterName != null && clusterId != null) { - throw new InvalidParameterValueException("Can't specify cluster by both id and name"); - } - - if (hypervisorType == null || hypervisorType.isEmpty()) { - throw new InvalidParameterValueException("Need to specify Hypervisor Type"); - } - - if ((clusterName != null || clusterId != null) && podId == null) { - throw new InvalidParameterValueException("Can't specify cluster without specifying the pod"); - } - - if (clusterId != null) { - if (_clusterDao.findById(clusterId) == null) { - throw new InvalidParameterValueException("Can't find cluster by id " + clusterId); - } - } - - if (clusterName != null) { - ClusterVO cluster = new ClusterVO(dcId, podId, clusterName); - cluster.setHypervisorType(hypervisorType); - try { - cluster = _clusterDao.persist(cluster); - } catch (Exception e) { - cluster = _clusterDao.findBy(clusterName, podId); - if (cluster == null) { - throw new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod " + podId + " and data center " + dcId, e); - } - } - clusterId = cluster.getId(); - } - - try { - uri = new URI(UriUtils.encodeURIComponent(url)); - if (uri.getScheme() == null) { - throw new InvalidParameterValueException("uri.scheme is null " + url + ", add nfs:// as a prefix"); - } else if (uri.getScheme().equalsIgnoreCase("nfs")) { - if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) { - throw new InvalidParameterValueException("Your host and/or path is wrong. Make sure it's of the format nfs://hostname/path"); - } - } - } catch (URISyntaxException e) { - throw new InvalidParameterValueException(url + " is not a valid uri"); - } - - List hosts = new ArrayList(); - s_logger.info("Trying to add a new host at " + url + " in data center " + dcId); - Enumeration en = _discoverers.enumeration(); - boolean isHypervisorTypeSupported = false; - while (en.hasMoreElements()) { - Discoverer discoverer = en.nextElement(); - if (params != null) { - discoverer.putParam(params); - } - - if (!discoverer.matchHypervisor(hypervisorType)) { - continue; - } - isHypervisorTypeSupported = true; - Map> resources = null; - - try { - resources = discoverer.find(dcId, podId, clusterId, uri, username, password); - } catch (DiscoveredWithErrorException e) { - throw e; - } catch (Exception e) { - s_logger.info("Exception in host discovery process with discoverer: " + discoverer.getName() + ", skip to another discoverer if there is any"); - } - if (resources != null) { - for (Map.Entry> entry : resources.entrySet()) { - ServerResource resource = entry.getKey(); - /* - * For KVM, if we go to here, that means kvm agent is already connected to mgt svr. - */ - if (resource instanceof KvmDummyResourceBase) { - Map details = entry.getValue(); - String guid = details.get("guid"); - List kvmHosts = _hostDao.listBy(Host.Type.Routing, clusterId, podId, dcId); - for (HostVO host : kvmHosts) { - if (host.getGuid().equalsIgnoreCase(guid)) { - hosts.add(host); - return hosts; - } - } - return null; - } - AgentAttache attache = simulateStart(null, resource, entry.getValue(), true, hostTags, allocationState); - if (attache != null) { - hosts.add(_hostDao.findById(attache.getId())); - } - discoverer.postDiscovery(hosts, _nodeId); - - } - s_logger.info("server resources successfully discovered by " + discoverer.getName()); - return hosts; - } - } - if (!isHypervisorTypeSupported) { - String msg = "Do not support HypervisorType " + hypervisorType + " for " + url; - s_logger.warn(msg); - throw new DiscoveryException(msg); - } - s_logger.warn("Unable to find the server resources at " + url); - throw new DiscoveryException("Unable to add the host"); - } - - @Override - @DB - public boolean deleteCluster(DeleteClusterCmd cmd) { - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true); - if (cluster == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Cluster: " + cmd.getId() + " does not even exist. Delete call is ignored."); - } - txn.rollback(); - return true; - } - - List hosts = _hostDao.listByCluster(cmd.getId()); - if (hosts.size() > 0) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Cluster: " + cmd.getId() + " still has hosts"); - } - txn.rollback(); - return false; - } - - _clusterDao.remove(cmd.getId()); - - txn.commit(); - return true; - } catch (Throwable t) { - s_logger.error("Unable to delete cluster: " + cmd.getId(), t); - txn.rollback(); - return false; - } - } - - @Override - @DB - public Cluster updateCluster(Cluster clusterToUpdate, String clusterType, String hypervisor, String allocationState) { - - ClusterVO cluster = (ClusterVO) clusterToUpdate; - // Verify cluster information and update the cluster if needed - boolean doUpdate = false; - - if (hypervisor != null && !hypervisor.isEmpty()) { - Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(hypervisor); - if (hypervisorType == null) { - s_logger.error("Unable to resolve " + hypervisor + " to a valid supported hypervisor type"); - throw new InvalidParameterValueException("Unable to resolve " + hypervisor + " to a supported type"); - } else { - cluster.setHypervisorType(hypervisor); - doUpdate = true; - } - } - - Cluster.ClusterType newClusterType = null; - if (clusterType != null && !clusterType.isEmpty()) { - try { - newClusterType = Cluster.ClusterType.valueOf(clusterType); - } catch (IllegalArgumentException ex) { - throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type"); - } - if (newClusterType == null) { - s_logger.error("Unable to resolve " + clusterType + " to a valid supported cluster type"); - throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type"); - } else { - cluster.setClusterType(newClusterType); - doUpdate = true; - } - } - - Grouping.AllocationState newAllocationState = null; - if (allocationState != null && !allocationState.isEmpty()) { - try { - newAllocationState = Grouping.AllocationState.valueOf(allocationState); - } catch (IllegalArgumentException ex) { - throw new InvalidParameterValueException("Unable to resolve Allocation State '" + allocationState + "' to a supported state"); - } - if (newAllocationState == null) { - s_logger.error("Unable to resolve " + allocationState + " to a valid supported allocation State"); - throw new InvalidParameterValueException("Unable to resolve " + allocationState + " to a supported state"); - } else { - cluster.setAllocationState(newAllocationState); - doUpdate = true; - } - } - if (doUpdate) { - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - _clusterDao.update(cluster.getId(), cluster); - txn.commit(); - } catch (Exception e) { - s_logger.error("Unable to update cluster due to " + e.getMessage(), e); - throw new CloudRuntimeException("Failed to update cluster. Please contact Cloud Support."); - } - } - return cluster; - } - - @Override - public Cluster getCluster(Long clusterId) { - return _clusterDao.findById(clusterId); - } @Override public Answer sendTo(Long dcId, HypervisorType type, Command cmd) { @@ -1200,19 +682,6 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS } } - @Override - public boolean deleteHost(long hostId, boolean isForced) { - User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); - // Verify that host exists - HostVO host = _hostDao.findById(hostId); - if (host == null) { - throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist"); - } - _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), host.getDataCenterId()); - return deleteHost(hostId, isForced, caller); - } - - @Override public boolean updateHostPassword(UpdateHostPasswordCmd upasscmd) { if (upasscmd.getClusterId() == null) { @@ -1227,9 +696,9 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS for (HostVO h : hosts) { AgentAttache agent = this.findAttache(h.getId()); UpdateHostPasswordCommand cmd = new UpdateHostPasswordCommand(upasscmd.getUsername(), upasscmd.getPassword()); - agent.updatePassword(cmd); + agent.updatePassword(cmd); } - } + } return true; } @@ -1757,7 +1226,8 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS _executor.execute(new SimulateStartTask(host.getId(), resource, host.getDetails(), null)); } - protected AgentAttache simulateStart(Long id, ServerResource resource, Map details, boolean old, List hostTags, String allocationState) throws IllegalArgumentException { + @Override + public AgentAttache simulateStart(Long id, ServerResource resource, Map details, boolean old, List hostTags, String allocationState) throws IllegalArgumentException { HostVO host = null; if (id != null) { synchronized (_loadingAgents) { @@ -1993,22 +1463,6 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS return send(hostId, cmds, _wait); } - @Override - public Host reconnectHost(ReconnectHostCmd cmd) throws AgentUnavailableException { - Long hostId = cmd.getId(); - - HostVO host = _hostDao.findById(hostId); - if (host == null) { - throw new InvalidParameterValueException("Host with id " + hostId.toString() + " doesn't exist"); - } - - boolean result = reconnect(hostId); - if (result) { - return host; - } - throw new CloudRuntimeException("Failed to reconnect host with id " + hostId.toString() + ", internal error."); - } - @Override public boolean reconnect(final long hostId) throws AgentUnavailableException { HostVO host; @@ -2060,23 +1514,6 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS return true; } - @Override - public Host cancelMaintenance(CancelMaintenanceCmd cmd) { - Long hostId = cmd.getId(); - - // verify input parameters - HostVO host = _hostDao.findById(hostId); - if (host == null || host.getRemoved() != null) { - throw new InvalidParameterValueException("Host with id " + hostId.toString() + " doesn't exist"); - } - - boolean success = cancelMaintenance(hostId); - if (!success) { - throw new CloudRuntimeException("Internal error cancelling maintenance."); - } - return host; - } - @Override public boolean executeUserRequest(long hostId, Event event) throws AgentUnavailableException { if (event == Event.MaintenanceRequested) { @@ -2099,7 +1536,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS } else if (event == Event.ShutdownRequested) { return reconnect(hostId); } - else if (event == Event.UpdatePassword) { + else if (event == Event.UpdatePassword) { AgentAttache attache = findAttache(hostId); if (attache != null) { DetailVO nv = _detailsDao.findDetail(hostId, ApiConstants.USERNAME); @@ -2173,34 +1610,6 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS return true; } - @Override - public Host maintain(PrepareForMaintenanceCmd cmd) { - Long hostId = cmd.getId(); - HostVO host = _hostDao.findById(hostId); - - if (host == null) { - s_logger.debug("Unable to find host " + hostId); - throw new InvalidParameterValueException("Unable to find host with ID: " + hostId + ". Please specify a valid host ID."); - } - - if (_hostDao.countBy(host.getClusterId(), Status.PrepareForMaintenance, Status.ErrorInMaintenance) > 0) { - throw new InvalidParameterValueException("There are other servers in PrepareForMaintenance OR ErrorInMaintenance STATUS in cluster " + host.getClusterId()); - } - - if (_storageMgr.isLocalStorageActiveOnHost(host)) { - throw new InvalidParameterValueException("There are active VMs using the host's local storage pool. Please stop all VMs on this host that use local storage."); - } - - try { - if (maintain(hostId)) { - return _hostDao.findById(hostId); - } else { - throw new CloudRuntimeException("Unable to prepare for maintenance host " + hostId); - } - } catch (AgentUnavailableException e) { - throw new CloudRuntimeException("Unable to prepare for maintenance host " + hostId); - } - } public boolean checkCIDR(Host.Type type, HostPodVO pod, String serverPrivateIP, String serverPrivateNetmask) { if (serverPrivateIP == null) { @@ -2517,66 +1926,6 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS } } - @Override - public Host updateHost(UpdateHostCmd cmd) { - Long hostId = cmd.getId(); - Long guestOSCategoryId = cmd.getOsCategoryId(); - - if (guestOSCategoryId != null) { - - // Verify that the host exists - HostVO host = _hostDao.findById(hostId); - if (host == null) { - throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist"); - } - - // Verify that the guest OS Category exists - if (guestOSCategoryId > 0) { - if (_guestOSCategoryDao.findById(guestOSCategoryId) == null) { - throw new InvalidParameterValueException("Please specify a valid guest OS category."); - } - } - - GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId); - Map hostDetails = _hostDetailsDao.findDetails(hostId); - - if (guestOSCategory != null) { - // Save a new entry for guest.os.category.id - hostDetails.put("guest.os.category.id", String.valueOf(guestOSCategory.getId())); - } else { - // Delete any existing entry for guest.os.category.id - hostDetails.remove("guest.os.category.id"); - } - _hostDetailsDao.persist(hostId, hostDetails); - } - - String allocationState = cmd.getAllocationState(); - if (allocationState != null) { - // Verify that the host exists - HostVO host = _hostDao.findById(hostId); - if (host == null) { - throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist"); - } - - try { - HostAllocationState newAllocationState = Host.HostAllocationState.valueOf(allocationState); - if (newAllocationState == null) { - s_logger.error("Unable to resolve " + allocationState + " to a valid supported allocation State"); - throw new InvalidParameterValueException("Unable to resolve " + allocationState + " to a supported state"); - } else { - host.setHostAllocationState(newAllocationState); - } - } catch (IllegalArgumentException ex) { - s_logger.error("Unable to resolve " + allocationState + " to a valid supported allocation State"); - throw new InvalidParameterValueException("Unable to resolve " + allocationState + " to a supported state"); - } - - _hostDao.update(hostId, host); - } - - HostVO updatedHost = _hostDao.findById(hostId); - return updatedHost; - } protected void updateHost(final HostVO host, final StartupCommand startup, final Host.Type type, final long msId) throws IllegalArgumentException { s_logger.debug("updateHost() called"); @@ -2747,11 +2096,6 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS } - @Override - public Host getHost(long hostId) { - return _hostDao.findById(hostId); - } - // protected void upgradeAgent(final Link link, final byte[] request, final // String reason) { // diff --git a/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java b/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java index 5402bfc5431..f6a6b0778d8 100644 --- a/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java @@ -41,7 +41,6 @@ import com.cloud.exception.AgentUnavailableException; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.Status.Event; -import com.cloud.resource.ResourceService; import com.cloud.resource.ServerResource; import com.cloud.storage.resource.DummySecondaryStorageResource; import com.cloud.user.User; @@ -55,14 +54,14 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.nio.Link; import com.cloud.utils.nio.Task; -@Local(value = { AgentManager.class, ResourceService.class }) +@Local(value = { AgentManager.class }) public class ClusteredAgentManagerImpl extends AgentManagerImpl implements ClusterManagerListener { - final static Logger s_logger = Logger.getLogger(ClusteredAgentManagerImpl.class); + final static Logger s_logger = Logger.getLogger(ClusteredAgentManagerImpl.class); - public final static long STARTUP_DELAY = 5000; - public final static long SCAN_INTERVAL = 90000; // 90 seconds, it takes 60 sec for xenserver to fail login - public final static int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds - public long _loadSize = 100; + public final static long STARTUP_DELAY = 5000; + public final static long SCAN_INTERVAL = 90000; // 90 seconds, it takes 60 sec for xenserver to fail login + public final static int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds + public long _loadSize = 100; @Inject protected ClusterManager _clusterMgr = null; @@ -76,9 +75,9 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust super(); } - @Override - public boolean configure(String name, Map xmlParams) throws ConfigurationException { - _peers = new HashMap(7); + @Override + public boolean configure(String name, Map xmlParams) throws ConfigurationException { + _peers = new HashMap(7); _nodeId = _clusterMgr.getManagementNodeId(); ConfigurationDao configDao = ComponentLocator.getCurrentLocator().getDao(ConfigurationDao.class); @@ -91,13 +90,13 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust _clusterMgr.registerListener(this); return super.configure(name, xmlParams); - } + } - @Override - public boolean start() { - if (!super.start()) { - return false; - } + @Override + public boolean start() { + if (!super.start()) { + return false; + } _timer.schedule(new DirectAgentScanTimerTask(), STARTUP_DELAY, SCAN_INTERVAL); return true; } @@ -122,12 +121,12 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust s_logger.trace("Begin scanning directly connected hosts"); } - // for agents that are self-managed, threshold to be considered as disconnected is 3 ping intervals - long cutSeconds = (System.currentTimeMillis() >> 10) - (_pingInterval*3); - List hosts = _hostDao.findDirectAgentToLoad(_clusterMgr.getManagementNodeId(), cutSeconds, _loadSize); - if ( hosts != null && hosts.size() == _loadSize ) { - Long clusterId = hosts.get((int)(_loadSize-1)).getClusterId(); - if ( clusterId != null) { + // for agents that are self-managed, threshold to be considered as disconnected is 3 ping intervals + long cutSeconds = (System.currentTimeMillis() >> 10) - (_pingInterval*3); + List hosts = _hostDao.findDirectAgentToLoad(_clusterMgr.getManagementNodeId(), cutSeconds, _loadSize); + if ( hosts != null && hosts.size() == _loadSize ) { + Long clusterId = hosts.get((int)(_loadSize-1)).getClusterId(); + if ( clusterId != null) { for ( int i = (int)(_loadSize-1); i > 0; i-- ) { if ( hosts.get(i).getClusterId() == clusterId ) { hosts.remove(i); @@ -135,7 +134,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust break; } } - } + } } if (hosts != null && hosts.size() > 0) { for (HostVO host : hosts) { diff --git a/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java b/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java index a567ed4b5e6..a6f4915c5bc 100755 --- a/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java +++ b/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java @@ -39,7 +39,7 @@ import com.cloud.host.DetailVO; import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.host.HostVO; -import com.cloud.host.dao.DetailsDao; +import com.cloud.host.dao.HostDetailsDao; import com.cloud.host.dao.HostDao; import com.cloud.offering.ServiceOffering; import com.cloud.service.dao.ServiceOfferingDao; @@ -72,7 +72,7 @@ public class FirstFitAllocator implements HostAllocator { private static final Logger s_logger = Logger.getLogger(FirstFitAllocator.class); private String _name; @Inject HostDao _hostDao = null; - @Inject DetailsDao _hostDetailsDao = null; + @Inject HostDetailsDao _hostDetailsDao = null; @Inject UserVmDao _vmDao = null; @Inject ServiceOfferingDao _offeringDao = null; @Inject DomainRouterDao _routerDao = null; diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index de5f995d134..63146860079 100644 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -64,8 +64,8 @@ import com.cloud.event.dao.EventDaoImpl; import com.cloud.event.dao.UsageEventDaoImpl; import com.cloud.ha.HighAvailabilityManagerImpl; import com.cloud.ha.dao.HighAvailabilityDaoImpl; -import com.cloud.host.dao.DetailsDaoImpl; import com.cloud.host.dao.HostDaoImpl; +import com.cloud.host.dao.HostDetailsDaoImpl; import com.cloud.host.dao.HostTagsDaoImpl; import com.cloud.hypervisor.HypervisorGuruManagerImpl; import com.cloud.keystore.KeystoreDaoImpl; @@ -105,6 +105,7 @@ import com.cloud.network.security.dao.SecurityGroupWorkDaoImpl; import com.cloud.network.security.dao.VmRulesetLogDaoImpl; import com.cloud.network.vpn.RemoteAccessVpnManagerImpl; import com.cloud.offerings.dao.NetworkOfferingDaoImpl; +import com.cloud.resource.ResourceManagerImpl; import com.cloud.service.dao.ServiceOfferingDaoImpl; import com.cloud.storage.StorageManagerImpl; import com.cloud.storage.dao.DiskOfferingDaoImpl; @@ -117,6 +118,7 @@ import com.cloud.storage.dao.SnapshotScheduleDaoImpl; import com.cloud.storage.dao.StoragePoolDaoImpl; import com.cloud.storage.dao.StoragePoolHostDaoImpl; import com.cloud.storage.dao.StoragePoolWorkDaoImpl; +import com.cloud.storage.dao.SwiftDaoImpl; import com.cloud.storage.dao.UploadDaoImpl; import com.cloud.storage.dao.VMTemplateDaoImpl; import com.cloud.storage.dao.VMTemplateHostDaoImpl; @@ -128,11 +130,10 @@ import com.cloud.storage.secondary.SecondaryStorageManagerImpl; import com.cloud.storage.snapshot.SnapshotManagerImpl; import com.cloud.storage.snapshot.SnapshotSchedulerImpl; import com.cloud.storage.upload.UploadMonitorImpl; -import com.cloud.storage.dao.SwiftDaoImpl; import com.cloud.template.HyervisorTemplateAdapter; import com.cloud.template.TemplateAdapter; -import com.cloud.template.TemplateManagerImpl; import com.cloud.template.TemplateAdapter.TemplateAdapterType; +import com.cloud.template.TemplateManagerImpl; import com.cloud.upgrade.DatabaseUpgradeChecker; import com.cloud.user.AccountManagerImpl; import com.cloud.user.dao.AccountDaoImpl; @@ -162,7 +163,7 @@ import com.cloud.vm.dao.UserVmDetailsDaoImpl; import com.cloud.vm.dao.VMInstanceDaoImpl; public class DefaultComponentLibrary extends ComponentLibraryBase implements ComponentLibrary { - + @Override public List getSystemIntegrityCheckers() { ArrayList checkers = new ArrayList(); @@ -242,7 +243,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("GuestOSCategoryDao", GuestOSCategoryDaoImpl.class); addDao("StoragePoolDao", StoragePoolDaoImpl.class); addDao("StoragePoolHostDao", StoragePoolHostDaoImpl.class); - addDao("DetailsDao", DetailsDaoImpl.class); + addDao("DetailsDao", HostDetailsDaoImpl.class); addDao("SnapshotPolicyDao", SnapshotPolicyDaoImpl.class); addDao("SnapshotScheduleDao", SnapshotScheduleDaoImpl.class); addDao("ClusterDao", ClusterDaoImpl.class); @@ -276,7 +277,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("DcDetailsDao", DcDetailsDaoImpl.class); addDao("SwiftDao", SwiftDaoImpl.class); } - + @Override public synchronized Map>> getDaos() { if (_daos.size() == 0) { @@ -323,7 +324,8 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addManager("VirtualMachineManager", ClusteredVirtualMachineManagerImpl.class); addManager("HypervisorGuruManager", HypervisorGuruManagerImpl.class); addManager("ClusterFenceManager", ClusterFenceManagerImpl.class); - + addManager("ResourceManager", ResourceManagerImpl.class); + ComponentInfo info = addManager("ConsoleProxyManager", ConsoleProxyManagerImpl.class); info.addParameter("consoleproxy.sslEnabled", "true"); } @@ -335,9 +337,9 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com } return _managers; } - + protected void populateAdapters() { - addAdapter(TemplateAdapter.class, TemplateAdapterType.Hypervisor.getName(), HyervisorTemplateAdapter.class); + addAdapter(TemplateAdapter.class, TemplateAdapterType.Hypervisor.getName(), HyervisorTemplateAdapter.class); } @Override @@ -347,9 +349,9 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com } return _adapters; } - + @Override - public synchronized Map, Class> getFactories() { + public synchronized Map, Class> getFactories() { HashMap, Class> factories = new HashMap, Class>(); factories.put(EntityManager.class, EntityManagerImpl.class); return factories; diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/com/cloud/deploy/FirstFitPlanner.java index 6ae99cfce4c..47af2f55589 100644 --- a/server/src/com/cloud/deploy/FirstFitPlanner.java +++ b/server/src/com/cloud/deploy/FirstFitPlanner.java @@ -47,7 +47,7 @@ import com.cloud.exception.InsufficientServerCapacityException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; -import com.cloud.host.dao.DetailsDao; +import com.cloud.host.dao.HostDetailsDao; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.offering.ServiceOffering; @@ -83,7 +83,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner { @Inject protected DataCenterDao _dcDao; @Inject protected HostPodDao _podDao; @Inject protected ClusterDao _clusterDao; - @Inject protected DetailsDao _hostDetailsDao = null; + @Inject protected HostDetailsDao _hostDetailsDao = null; @Inject protected GuestOSDao _guestOSDao = null; @Inject protected GuestOSCategoryDao _guestOSCategoryDao = null; @Inject protected DiskOfferingDao _diskOfferingDao; diff --git a/server/src/com/cloud/host/dao/HostDaoImpl.java b/server/src/com/cloud/host/dao/HostDaoImpl.java index a616a542838..569ac3888cd 100644 --- a/server/src/com/cloud/host/dao/HostDaoImpl.java +++ b/server/src/com/cloud/host/dao/HostDaoImpl.java @@ -96,7 +96,7 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao protected final Attribute _msIdAttr; protected final Attribute _pingTimeAttr; - protected final DetailsDaoImpl _detailsDao = ComponentLocator.inject(DetailsDaoImpl.class); + protected final HostDetailsDaoImpl _detailsDao = ComponentLocator.inject(HostDetailsDaoImpl.class); protected final HostTagsDaoImpl _hostTagsDao = ComponentLocator.inject(HostTagsDaoImpl.class); public HostDaoImpl() { diff --git a/server/src/com/cloud/host/dao/DetailsDao.java b/server/src/com/cloud/host/dao/HostDetailsDao.java similarity index 94% rename from server/src/com/cloud/host/dao/DetailsDao.java rename to server/src/com/cloud/host/dao/HostDetailsDao.java index e398f353887..322573019ea 100644 --- a/server/src/com/cloud/host/dao/DetailsDao.java +++ b/server/src/com/cloud/host/dao/HostDetailsDao.java @@ -22,7 +22,7 @@ import java.util.Map; import com.cloud.host.DetailVO; import com.cloud.utils.db.GenericDao; -public interface DetailsDao extends GenericDao { +public interface HostDetailsDao extends GenericDao { Map findDetails(long hostId); void persist(long hostId, Map details); diff --git a/server/src/com/cloud/host/dao/DetailsDaoImpl.java b/server/src/com/cloud/host/dao/HostDetailsDaoImpl.java similarity index 94% rename from server/src/com/cloud/host/dao/DetailsDaoImpl.java rename to server/src/com/cloud/host/dao/HostDetailsDaoImpl.java index d1cfe247d66..a6954fa7314 100644 --- a/server/src/com/cloud/host/dao/DetailsDaoImpl.java +++ b/server/src/com/cloud/host/dao/HostDetailsDaoImpl.java @@ -29,12 +29,12 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; -@Local(value=DetailsDao.class) -public class DetailsDaoImpl extends GenericDaoBase implements DetailsDao { +@Local(value=HostDetailsDao.class) +public class HostDetailsDaoImpl extends GenericDaoBase implements HostDetailsDao { protected final SearchBuilder HostSearch; protected final SearchBuilder DetailSearch; - protected DetailsDaoImpl() { + protected HostDetailsDaoImpl() { HostSearch = createSearchBuilder(); HostSearch.and("hostId", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ); HostSearch.done(); diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index 3719bb46b20..31deec943fe 100644 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -17,38 +17,757 @@ */ package com.cloud.resource; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.ejb.Local; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.manager.AgentAttache; +import com.cloud.api.commands.AddClusterCmd; +import com.cloud.api.commands.AddHostCmd; +import com.cloud.api.commands.AddSecondaryStorageCmd; +import com.cloud.api.commands.CancelMaintenanceCmd; +import com.cloud.api.commands.DeleteClusterCmd; +import com.cloud.api.commands.PrepareForMaintenanceCmd; +import com.cloud.api.commands.ReconnectHostCmd; +import com.cloud.api.commands.UpdateHostCmd; +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.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.DiscoveredWithErrorException; +import com.cloud.exception.DiscoveryException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.host.Host; +import com.cloud.host.Host.HostAllocationState; +import com.cloud.host.HostVO; +import com.cloud.host.Status; +import com.cloud.host.dao.HostDao; +import com.cloud.host.dao.HostDetailsDao; +import com.cloud.hypervisor.Hypervisor; +import com.cloud.hypervisor.kvm.resource.KvmDummyResourceBase; +import com.cloud.org.Cluster; +import com.cloud.org.Grouping; +import com.cloud.storage.GuestOSCategoryVO; +import com.cloud.storage.StorageManager; +import com.cloud.storage.dao.GuestOSCategoryDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.User; +import com.cloud.user.UserContext; +import com.cloud.utils.UriUtils; +import com.cloud.utils.component.Adapters; +import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; @Local({ ResourceManager.class, ResourceService.class }) -public class ResourceManagerImpl implements ResourceManager, Manager { +public class ResourceManagerImpl implements ResourceManager, ResourceService, Manager { + private static final Logger s_logger = Logger.getLogger(ResourceManagerImpl.class); + + private String _name; + + @Inject + AccountManager _accountMgr; + @Inject + AgentManager _agentMgr; + @Inject + StorageManager _storageMgr; + + @Inject + protected DataCenterDao _dcDao; + @Inject + protected HostPodDao _podDao; + @Inject + protected ClusterDetailsDao _clusterDetailsDao; + @Inject + protected ClusterDao _clusterDao; + @Inject + protected HostDao _hostDao; + @Inject + protected HostDetailsDao _hostDetailsDao; + @Inject + protected GuestOSCategoryDao _guestOSCategoryDao; + + @Inject(adapter = Discoverer.class) + protected Adapters _discoverers; + + protected long _nodeId = ManagementServerNode.getManagementServerId(); + + @Override + public boolean updateHostPassword(UpdateHostPasswordCmd cmd) { + return _agentMgr.updateHostPassword(cmd); + } + + @Override + public List discoverCluster(AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException { + Long dcId = cmd.getZoneId(); + Long podId = cmd.getPodId(); + String clusterName = cmd.getClusterName(); + String url = cmd.getUrl(); + String username = cmd.getUsername(); + String password = cmd.getPassword(); + + if (url != null) { + url = URLDecoder.decode(url); + } + + URI uri = null; + + // Check if the zone exists in the system + DataCenterVO zone = _dcDao.findById(dcId); + if (zone == null) { + throw new InvalidParameterValueException("Can't find zone by id " + dcId); + } + + Account account = UserContext.current().getCaller(); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { + throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + dcId); + } + + // Check if the pod exists in the system + if (podId != null) { + if (_podDao.findById(podId) == null) { + throw new InvalidParameterValueException("Can't find pod by id " + podId); + } + // check if pod belongs to the zone + HostPodVO pod = _podDao.findById(podId); + if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) { + throw new InvalidParameterValueException("Pod " + podId + " doesn't belong to the zone " + dcId); + } + } + + // Verify cluster information and create a new cluster if needed + if (clusterName == null || clusterName.isEmpty()) { + throw new InvalidParameterValueException("Please specify cluster name"); + } + + if (cmd.getHypervisor() == null || cmd.getHypervisor().isEmpty()) { + throw new InvalidParameterValueException("Please specify a hypervisor"); + } + + Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(cmd.getHypervisor()); + if (hypervisorType == null) { + s_logger.error("Unable to resolve " + cmd.getHypervisor() + " to a valid supported hypervisor type"); + throw new InvalidParameterValueException("Unable to resolve " + cmd.getHypervisor() + " to a supported "); + } + + Cluster.ClusterType clusterType = null; + if (cmd.getClusterType() != null && !cmd.getClusterType().isEmpty()) { + clusterType = Cluster.ClusterType.valueOf(cmd.getClusterType()); + } + if (clusterType == null) { + clusterType = Cluster.ClusterType.CloudManaged; + } + + Grouping.AllocationState allocationState = null; + if (cmd.getAllocationState() != null && !cmd.getAllocationState().isEmpty()) { + try { + allocationState = Grouping.AllocationState.valueOf(cmd.getAllocationState()); + } catch (IllegalArgumentException ex) { + throw new InvalidParameterValueException("Unable to resolve Allocation State '" + cmd.getAllocationState() + "' to a supported state"); + } + } + if (allocationState == null) { + allocationState = Grouping.AllocationState.Enabled; + } + + Discoverer discoverer = getMatchingDiscover(hypervisorType); + if (discoverer == null) { + + throw new InvalidParameterValueException("Could not find corresponding resource manager for " + cmd.getHypervisor()); + } + + List result = new ArrayList(); + + long clusterId = 0; + ClusterVO cluster = new ClusterVO(dcId, podId, clusterName); + cluster.setHypervisorType(cmd.getHypervisor()); + + cluster.setClusterType(clusterType); + cluster.setAllocationState(allocationState); + try { + cluster = _clusterDao.persist(cluster); + } catch (Exception e) { + // no longer tolerate exception during the cluster creation phase + throw new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod " + podId + " and data center " + dcId, e); + } + clusterId = cluster.getId(); + result.add(cluster); + + if (clusterType == Cluster.ClusterType.CloudManaged) { + return result; + } + + // save cluster details for later cluster/host cross-checking + Map details = new HashMap(); + details.put("url", url); + details.put("username", username); + details.put("password", password); + _clusterDetailsDao.persist(cluster.getId(), details); + + boolean success = false; + try { + try { + uri = new URI(UriUtils.encodeURIComponent(url)); + if (uri.getScheme() == null) { + throw new InvalidParameterValueException("uri.scheme is null " + url + ", add http:// as a prefix"); + } else if (uri.getScheme().equalsIgnoreCase("http")) { + if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) { + throw new InvalidParameterValueException("Your host and/or path is wrong. Make sure it's of the format http://hostname/path"); + } + } + } catch (URISyntaxException e) { + throw new InvalidParameterValueException(url + " is not a valid uri"); + } + + List hosts = new ArrayList(); + Map> resources = null; + + try { + resources = discoverer.find(dcId, podId, clusterId, uri, username, password); + } catch (Exception e) { + s_logger.info("Exception in external cluster discovery process with discoverer: " + discoverer.getName()); + } + if (resources != null) { + for (Map.Entry> entry : resources.entrySet()) { + ServerResource resource = entry.getKey(); + + // For Hyper-V, we are here means agent have already started and connected to management server + if (hypervisorType == Hypervisor.HypervisorType.Hyperv) { + break; + } + + AgentAttache attache = _agentMgr.simulateStart(null, resource, entry.getValue(), true, null, null); + if (attache != null) { + hosts.add(_hostDao.findById(attache.getId())); + } + discoverer.postDiscovery(hosts, _nodeId); + } + s_logger.info("External cluster has been successfully discovered by " + discoverer.getName()); + success = true; + return result; + } + + s_logger.warn("Unable to find the server resources at " + url); + throw new DiscoveryException("Unable to add the external cluster"); + } catch (Throwable e) { + s_logger.error("Unexpected exception ", e); + throw new DiscoveryException("Unable to add the external cluster due to unhandled exception"); + } finally { + if (!success) { + _clusterDetailsDao.deleteDetails(clusterId); + _clusterDao.remove(clusterId); + } + } + } + + private Discoverer getMatchingDiscover(Hypervisor.HypervisorType hypervisorType) { + Enumeration en = _discoverers.enumeration(); + while (en.hasMoreElements()) { + Discoverer discoverer = en.nextElement(); + if (discoverer.getHypervisorType() == hypervisorType) { + return discoverer; + } + } + return null; + } + + @Override + public List discoverHosts(AddHostCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { + Long dcId = cmd.getZoneId(); + Long podId = cmd.getPodId(); + Long clusterId = cmd.getClusterId(); + String clusterName = cmd.getClusterName(); + String url = cmd.getUrl(); + String username = cmd.getUsername(); + String password = cmd.getPassword(); + Long memCapacity = cmd.getMemCapacity(); + Long cpuSpeed = cmd.getCpuSpeed(); + Long cpuNum = cmd.getCpuNum(); + String mac = cmd.getMac(); + List hostTags = cmd.getHostTags(); + Map bareMetalParams = new HashMap(); + + dcId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), dcId); + + // this is for standalone option + if (clusterName == null && clusterId == null) { + clusterName = "Standalone-" + url; + } + + if (clusterId != null) { + ClusterVO cluster = _clusterDao.findById(clusterId); + if (cluster == null) { + throw new InvalidParameterValueException("can not fine cluster for clusterId " + clusterId); + } else { + if (cluster.getGuid() == null) { + List hosts = _hostDao.listByCluster(clusterId); + if (!hosts.isEmpty()) { + throw new CloudRuntimeException("Guid is not updated for cluster " + clusterId + " need to wait hosts in this cluster up"); + } + } + } + } + + if (cmd.getHypervisor().equalsIgnoreCase(Hypervisor.HypervisorType.BareMetal.toString())) { + if (memCapacity == null) { + memCapacity = Long.valueOf(0); + } + if (cpuSpeed == null) { + cpuSpeed = Long.valueOf(0); + } + if (cpuNum == null) { + cpuNum = Long.valueOf(0); + } + if (mac == null) { + mac = "unknown"; + } + + bareMetalParams.put("cpuNum", cpuNum.toString()); + bareMetalParams.put("cpuCapacity", cpuSpeed.toString()); + bareMetalParams.put("memCapacity", memCapacity.toString()); + bareMetalParams.put("mac", mac); + if (hostTags != null) { + bareMetalParams.put("hostTag", hostTags.get(0)); + } + } + String allocationState = cmd.getAllocationState(); + if (allocationState == null) { + allocationState = Host.HostAllocationState.Enabled.toString(); + } + + return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, cmd.getHypervisor(), hostTags, bareMetalParams, allocationState); + } + + @Override + public List discoverHosts(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { + Long dcId = cmd.getZoneId(); + String url = cmd.getUrl(); + return discoverHostsFull(dcId, null, null, null, url, null, null, "SecondaryStorage", null, null, null); + } + + private List discoverHostsFull(Long dcId, Long podId, Long clusterId, String clusterName, String url, String username, String password, String hypervisorType, List hostTags, + Map params, String allocationState) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { + URI uri = null; + + // Check if the zone exists in the system + DataCenterVO zone = _dcDao.findById(dcId); + if (zone == null) { + throw new InvalidParameterValueException("Can't find zone by id " + dcId); + } + + Account account = UserContext.current().getCaller(); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { + throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + dcId); + } + + // Check if the pod exists in the system + if (podId != null) { + if (_podDao.findById(podId) == null) { + throw new InvalidParameterValueException("Can't find pod by id " + podId); + } + // check if pod belongs to the zone + HostPodVO pod = _podDao.findById(podId); + if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) { + throw new InvalidParameterValueException("Pod " + podId + " doesn't belong to the zone " + dcId); + } + } + + // Deny to add a secondary storage multiple times for the same zone + if ((username == null) && (_hostDao.findSecondaryStorageHost(dcId) != null)) { + throw new InvalidParameterValueException("A secondary storage host already exists in the specified zone"); + } + + // Verify cluster information and create a new cluster if needed + if (clusterName != null && clusterId != null) { + throw new InvalidParameterValueException("Can't specify cluster by both id and name"); + } + + if (hypervisorType == null || hypervisorType.isEmpty()) { + throw new InvalidParameterValueException("Need to specify Hypervisor Type"); + } + + if ((clusterName != null || clusterId != null) && podId == null) { + throw new InvalidParameterValueException("Can't specify cluster without specifying the pod"); + } + + if (clusterId != null) { + if (_clusterDao.findById(clusterId) == null) { + throw new InvalidParameterValueException("Can't find cluster by id " + clusterId); + } + } + + if (clusterName != null) { + ClusterVO cluster = new ClusterVO(dcId, podId, clusterName); + cluster.setHypervisorType(hypervisorType); + try { + cluster = _clusterDao.persist(cluster); + } catch (Exception e) { + cluster = _clusterDao.findBy(clusterName, podId); + if (cluster == null) { + throw new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod " + podId + " and data center " + dcId, e); + } + } + clusterId = cluster.getId(); + } + + try { + uri = new URI(UriUtils.encodeURIComponent(url)); + if (uri.getScheme() == null) { + throw new InvalidParameterValueException("uri.scheme is null " + url + ", add nfs:// as a prefix"); + } else if (uri.getScheme().equalsIgnoreCase("nfs")) { + if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) { + throw new InvalidParameterValueException("Your host and/or path is wrong. Make sure it's of the format nfs://hostname/path"); + } + } + } catch (URISyntaxException e) { + throw new InvalidParameterValueException(url + " is not a valid uri"); + } + + List hosts = new ArrayList(); + s_logger.info("Trying to add a new host at " + url + " in data center " + dcId); + Enumeration en = _discoverers.enumeration(); + boolean isHypervisorTypeSupported = false; + while (en.hasMoreElements()) { + Discoverer discoverer = en.nextElement(); + if (params != null) { + discoverer.putParam(params); + } + + if (!discoverer.matchHypervisor(hypervisorType)) { + continue; + } + isHypervisorTypeSupported = true; + Map> resources = null; + + try { + resources = discoverer.find(dcId, podId, clusterId, uri, username, password); + } catch (DiscoveredWithErrorException e) { + throw e; + } catch (Exception e) { + s_logger.info("Exception in host discovery process with discoverer: " + discoverer.getName() + ", skip to another discoverer if there is any"); + } + if (resources != null) { + for (Map.Entry> entry : resources.entrySet()) { + ServerResource resource = entry.getKey(); + /* + * For KVM, if we go to here, that means kvm agent is already connected to mgt svr. + */ + if (resource instanceof KvmDummyResourceBase) { + Map details = entry.getValue(); + String guid = details.get("guid"); + List kvmHosts = _hostDao.listBy(Host.Type.Routing, clusterId, podId, dcId); + for (HostVO host : kvmHosts) { + if (host.getGuid().equalsIgnoreCase(guid)) { + hosts.add(host); + return hosts; + } + } + return null; + } + AgentAttache attache = _agentMgr.simulateStart(null, resource, entry.getValue(), true, hostTags, allocationState); + if (attache != null) { + hosts.add(_hostDao.findById(attache.getId())); + } + discoverer.postDiscovery(hosts, _nodeId); + + } + s_logger.info("server resources successfully discovered by " + discoverer.getName()); + return hosts; + } + } + if (!isHypervisorTypeSupported) { + String msg = "Do not support HypervisorType " + hypervisorType + " for " + url; + s_logger.warn(msg); + throw new DiscoveryException(msg); + } + s_logger.warn("Unable to find the server resources at " + url); + throw new DiscoveryException("Unable to add the host"); + } + + @Override + public Host getHost(long hostId) { + return _hostDao.findById(hostId); + } + + @Override + public boolean deleteHost(long hostId, boolean isForced) { + User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); + // Verify that host exists + HostVO host = _hostDao.findById(hostId); + if (host == null) { + throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist"); + } + _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), host.getDataCenterId()); + return _agentMgr.deleteHost(hostId, isForced, caller); + } + + @Override + @DB + public boolean deleteCluster(DeleteClusterCmd cmd) { + Transaction txn = Transaction.currentTxn(); + try { + txn.start(); + ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true); + if (cluster == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Cluster: " + cmd.getId() + " does not even exist. Delete call is ignored."); + } + txn.rollback(); + return true; + } + + List hosts = _hostDao.listByCluster(cmd.getId()); + if (hosts.size() > 0) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Cluster: " + cmd.getId() + " still has hosts"); + } + txn.rollback(); + return false; + } + + _clusterDao.remove(cmd.getId()); + + txn.commit(); + return true; + } catch (Throwable t) { + s_logger.error("Unable to delete cluster: " + cmd.getId(), t); + txn.rollback(); + return false; + } + } + + @Override + @DB + public Cluster updateCluster(Cluster clusterToUpdate, String clusterType, String hypervisor, String allocationState) { + + ClusterVO cluster = (ClusterVO) clusterToUpdate; + // Verify cluster information and update the cluster if needed + boolean doUpdate = false; + + if (hypervisor != null && !hypervisor.isEmpty()) { + Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(hypervisor); + if (hypervisorType == null) { + s_logger.error("Unable to resolve " + hypervisor + " to a valid supported hypervisor type"); + throw new InvalidParameterValueException("Unable to resolve " + hypervisor + " to a supported type"); + } else { + cluster.setHypervisorType(hypervisor); + doUpdate = true; + } + } + + Cluster.ClusterType newClusterType = null; + if (clusterType != null && !clusterType.isEmpty()) { + try { + newClusterType = Cluster.ClusterType.valueOf(clusterType); + } catch (IllegalArgumentException ex) { + throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type"); + } + if (newClusterType == null) { + s_logger.error("Unable to resolve " + clusterType + " to a valid supported cluster type"); + throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type"); + } else { + cluster.setClusterType(newClusterType); + doUpdate = true; + } + } + + Grouping.AllocationState newAllocationState = null; + if (allocationState != null && !allocationState.isEmpty()) { + try { + newAllocationState = Grouping.AllocationState.valueOf(allocationState); + } catch (IllegalArgumentException ex) { + throw new InvalidParameterValueException("Unable to resolve Allocation State '" + allocationState + "' to a supported state"); + } + if (newAllocationState == null) { + s_logger.error("Unable to resolve " + allocationState + " to a valid supported allocation State"); + throw new InvalidParameterValueException("Unable to resolve " + allocationState + " to a supported state"); + } else { + cluster.setAllocationState(newAllocationState); + doUpdate = true; + } + } + if (doUpdate) { + Transaction txn = Transaction.currentTxn(); + try { + txn.start(); + _clusterDao.update(cluster.getId(), cluster); + txn.commit(); + } catch (Exception e) { + s_logger.error("Unable to update cluster due to " + e.getMessage(), e); + throw new CloudRuntimeException("Failed to update cluster. Please contact Cloud Support."); + } + } + return cluster; + } + + @Override + public Host cancelMaintenance(CancelMaintenanceCmd cmd) { + Long hostId = cmd.getId(); + + // verify input parameters + HostVO host = _hostDao.findById(hostId); + if (host == null || host.getRemoved() != null) { + throw new InvalidParameterValueException("Host with id " + hostId.toString() + " doesn't exist"); + } + + boolean success = _agentMgr.cancelMaintenance(hostId); + if (!success) { + throw new CloudRuntimeException("Internal error cancelling maintenance."); + } + return host; + } + + @Override + public Host reconnectHost(ReconnectHostCmd cmd) throws AgentUnavailableException { + Long hostId = cmd.getId(); + + HostVO host = _hostDao.findById(hostId); + if (host == null) { + throw new InvalidParameterValueException("Host with id " + hostId.toString() + " doesn't exist"); + } + + boolean result = _agentMgr.reconnect(hostId); + if (result) { + return host; + } + throw new CloudRuntimeException("Failed to reconnect host with id " + hostId.toString() + ", internal error."); + } + + @Override + public Host maintain(PrepareForMaintenanceCmd cmd) { + Long hostId = cmd.getId(); + HostVO host = _hostDao.findById(hostId); + + if (host == null) { + s_logger.debug("Unable to find host " + hostId); + throw new InvalidParameterValueException("Unable to find host with ID: " + hostId + ". Please specify a valid host ID."); + } + + if (_hostDao.countBy(host.getClusterId(), Status.PrepareForMaintenance, Status.ErrorInMaintenance) > 0) { + throw new InvalidParameterValueException("There are other servers in PrepareForMaintenance OR ErrorInMaintenance STATUS in cluster " + host.getClusterId()); + } + + if (_storageMgr.isLocalStorageActiveOnHost(host)) { + throw new InvalidParameterValueException("There are active VMs using the host's local storage pool. Please stop all VMs on this host that use local storage."); + } + + try { + if (_agentMgr.maintain(hostId)) { + return _hostDao.findById(hostId); + } else { + throw new CloudRuntimeException("Unable to prepare for maintenance host " + hostId); + } + } catch (AgentUnavailableException e) { + throw new CloudRuntimeException("Unable to prepare for maintenance host " + hostId); + } + } + + @Override + public Host updateHost(UpdateHostCmd cmd) { + Long hostId = cmd.getId(); + Long guestOSCategoryId = cmd.getOsCategoryId(); + + if (guestOSCategoryId != null) { + + // Verify that the host exists + HostVO host = _hostDao.findById(hostId); + if (host == null) { + throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist"); + } + + // Verify that the guest OS Category exists + if (guestOSCategoryId > 0) { + if (_guestOSCategoryDao.findById(guestOSCategoryId) == null) { + throw new InvalidParameterValueException("Please specify a valid guest OS category."); + } + } + + GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId); + Map hostDetails = _hostDetailsDao.findDetails(hostId); + + if (guestOSCategory != null) { + // Save a new entry for guest.os.category.id + hostDetails.put("guest.os.category.id", String.valueOf(guestOSCategory.getId())); + } else { + // Delete any existing entry for guest.os.category.id + hostDetails.remove("guest.os.category.id"); + } + _hostDetailsDao.persist(hostId, hostDetails); + } + + String allocationState = cmd.getAllocationState(); + if (allocationState != null) { + // Verify that the host exists + HostVO host = _hostDao.findById(hostId); + if (host == null) { + throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist"); + } + + try { + HostAllocationState newAllocationState = Host.HostAllocationState.valueOf(allocationState); + if (newAllocationState == null) { + s_logger.error("Unable to resolve " + allocationState + " to a valid supported allocation State"); + throw new InvalidParameterValueException("Unable to resolve " + allocationState + " to a supported state"); + } else { + host.setHostAllocationState(newAllocationState); + } + } catch (IllegalArgumentException ex) { + s_logger.error("Unable to resolve " + allocationState + " to a valid supported allocation State"); + throw new InvalidParameterValueException("Unable to resolve " + allocationState + " to a supported state"); + } + + _hostDao.update(hostId, host); + } + + HostVO updatedHost = _hostDao.findById(hostId); + return updatedHost; + } + + @Override + public Cluster getCluster(Long clusterId) { + return _clusterDao.findById(clusterId); + } @Override public boolean configure(String name, Map params) throws ConfigurationException { - // TODO Auto-generated method stub - return false; + _name = name; + return true; } @Override public boolean start() { - // TODO Auto-generated method stub - return false; + return true; } @Override public boolean stop() { - // TODO Auto-generated method stub - return false; + return true; } @Override public String getName() { - // TODO Auto-generated method stub - return null; + return _name; } } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index fd1874bbf42..7bfca95b861 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -167,7 +167,7 @@ import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.host.HostVO; import com.cloud.host.Status; -import com.cloud.host.dao.DetailsDao; +import com.cloud.host.dao.HostDetailsDao; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.info.ConsoleProxyInfo; @@ -284,7 +284,7 @@ public class ManagementServerImpl implements ManagementServer { private final AccountVlanMapDao _accountVlanMapDao; private final PodVlanMapDao _podVlanMapDao; private final HostDao _hostDao; - private final DetailsDao _detailsDao; + private final HostDetailsDao _detailsDao; private final UserDao _userDao; private final UserVmDao _userVmDao; private final ConfigurationDao _configDao; @@ -344,7 +344,7 @@ public class ManagementServerImpl implements ManagementServer { _accountVlanMapDao = locator.getDao(AccountVlanMapDao.class); _podVlanMapDao = locator.getDao(PodVlanMapDao.class); _hostDao = locator.getDao(HostDao.class); - _detailsDao = locator.getDao(DetailsDao.class); + _detailsDao = locator.getDao(HostDetailsDao.class); _hostPodDao = locator.getDao(HostPodDao.class); _jobDao = locator.getDao(AsyncJobDao.class); _clusterDao = locator.getDao(ClusterDao.class); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 4b635ace62b..2ae4c8c8867 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -112,7 +112,7 @@ import com.cloud.exception.StorageUnavailableException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; -import com.cloud.host.dao.DetailsDao; +import com.cloud.host.dao.HostDetailsDao; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuruManager; @@ -217,7 +217,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag @Inject protected ConsoleProxyDao _consoleProxyDao; @Inject - protected DetailsDao _detailsDao; + protected HostDetailsDao _detailsDao; @Inject protected SnapshotDao _snapshotDao; @Inject diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 6a1c83a5f2f..81f19f9197b 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -63,7 +63,7 @@ import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.HostVO; -import com.cloud.host.dao.DetailsDao; +import com.cloud.host.dao.HostDetailsDao; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Snapshot; @@ -140,7 +140,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma @Inject protected SnapshotScheduleDao _snapshotScheduleDao; @Inject - protected DetailsDao _detailsDao; + protected HostDetailsDao _detailsDao; @Inject protected DomainDao _domainDao; @Inject diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index ad06b01e7c2..7217bab5083 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -109,7 +109,7 @@ import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.ha.HighAvailabilityManager; import com.cloud.host.Host; import com.cloud.host.HostVO; -import com.cloud.host.dao.DetailsDao; +import com.cloud.host.dao.HostDetailsDao; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.IPAddressVO; @@ -215,7 +215,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager @Inject protected HostDao _hostDao = null; @Inject - protected DetailsDao _detailsDao = null; + protected HostDetailsDao _detailsDao = null; @Inject protected DomainRouterDao _routerDao = null; @Inject