diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java.orig b/server/src/com/cloud/agent/manager/AgentManagerImpl.java.orig
deleted file mode 100755
index 710a4585b4c..00000000000
--- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java.orig
+++ /dev/null
@@ -1,5883 +0,0 @@
-/**
- * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
- *
- * This software is licensed under the GNU General Public License v3 or later.
- *
- * It is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-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;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import javax.ejb.Local;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.Listener;
-import com.cloud.agent.StartupCommandProcessor;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.AgentControlCommand;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckHealthCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.GetHostStatsAnswer;
-import com.cloud.agent.api.GetHostStatsCommand;
-import com.cloud.agent.api.MaintainCommand;
-import com.cloud.agent.api.PingAnswer;
-import com.cloud.agent.api.PingCommand;
-import com.cloud.agent.api.PingRoutingCommand;
-import com.cloud.agent.api.PoolEjectCommand;
-import com.cloud.agent.api.ReadyAnswer;
-import com.cloud.agent.api.ReadyCommand;
-import com.cloud.agent.api.ShutdownCommand;
-import com.cloud.agent.api.StartupAnswer;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupExternalDhcpCommand;
-import com.cloud.agent.api.StartupExternalFirewallCommand;
-import com.cloud.agent.api.StartupExternalLoadBalancerCommand;
-import com.cloud.agent.api.StartupProxyCommand;
-import com.cloud.agent.api.StartupPxeServerCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.StartupStorageCommand;
-import com.cloud.agent.api.UnsupportedAnswer;
-import com.cloud.agent.manager.allocator.HostAllocator;
-import com.cloud.agent.manager.allocator.PodAllocator;
-import com.cloud.agent.transport.Request;
-import com.cloud.agent.transport.Response;
-import com.cloud.alert.AlertManager;
-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;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.cluster.StackMaid;
-import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenterIpAddressVO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.PodCluster;
-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.dc.dao.VlanDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlanner;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-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.InsufficientServerCapacityException;
-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;
-import com.cloud.host.DetailVO;
-import com.cloud.host.Host;
-import com.cloud.host.Host.HostAllocationState;
-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.host.dao.DetailsDao;
-import com.cloud.host.dao.HostDao;
-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.maint.UpgradeManager;
-import com.cloud.network.IPAddressVO;
-import com.cloud.network.NetworkManager;
-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;
-import com.cloud.storage.StoragePoolVO;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.GuestOSCategoryDao;
-import com.cloud.storage.dao.StoragePoolDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateHostDao;
-import com.cloud.storage.dao.VolumeDao;
-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.user.dao.UserStatisticsDao;
-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;
-import com.cloud.utils.component.Manager;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.Ip;
-import com.cloud.utils.net.MacAddress;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.nio.HandlerFactory;
-import com.cloud.utils.nio.Link;
-import com.cloud.utils.nio.NioServer;
-import com.cloud.utils.nio.Task;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineProfileImpl;
-import com.cloud.vm.dao.VMInstanceDao;
-
-/**
- * Implementation of the Agent Manager. This class controls the connection to the agents.
- *
- * @config {@table || Param Name | Description | Values | Default || || port | port to listen on for agent connection. | Integer
- * | 8250 || || workers | # of worker threads | Integer | 5 || || router.template.id | default id for template | Integer
- * | 1 || || router.ram.size | default ram for router vm in mb | Integer | 128 || || router.ip.address | ip address for
- * the router | ip | 10.1.1.1 || || wait | Time to wait for control commands to return | seconds | 1800 || || domain |
- * domain for domain routers| String | foo.com || || alert.wait | time to wait before alerting on a disconnected agent |
- * seconds | 1800 || || update.wait | time to wait before alerting on a updating agent | seconds | 600 || ||
- * ping.interval | ping interval in seconds | seconds | 60 || || instance.name | Name of the deployment String |
- * required || || start.retry | Number of times to retry start | Number | 2 || || ping.timeout | multiplier to
- * 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 {
- private static final Logger s_logger = Logger.getLogger(AgentManagerImpl.class);
-
- protected ConcurrentHashMap _agents = new ConcurrentHashMap(10007);
- protected List> _hostMonitors = new ArrayList>(17);
- protected List> _cmdMonitors = new ArrayList>(17);
- protected List> _creationMonitors = new ArrayList>(17);
- protected int _monitorId = 0;
-
- protected NioServer _connection;
- @Inject
- protected HostDao _hostDao = null;
- @Inject
- protected UserStatisticsDao _userStatsDao = null;
- @Inject
- protected DataCenterDao _dcDao = null;
- @Inject
- protected VlanDao _vlanDao = null;
- @Inject
- protected DataCenterIpAddressDao _privateIPAddressDao = null;
- @Inject
- protected IPAddressDao _publicIPAddressDao = null;
- @Inject
- protected HostPodDao _podDao = null;
- protected Adapters _hostAllocators = null;
- protected Adapters _podAllocators = null;
- @Inject
- protected EventDao _eventDao = null;
- @Inject
- protected VMInstanceDao _vmDao = null;
- @Inject
- protected VolumeDao _volDao = null;
- @Inject
- protected CapacityDao _capacityDao = null;
- @Inject
- protected ConfigurationDao _configDao = null;
- @Inject
- protected StoragePoolDao _storagePoolDao = null;
- @Inject
- protected StoragePoolHostDao _storagePoolHostDao = null;
- @Inject
- protected GuestOSCategoryDao _guestOSCategoryDao = null;
- @Inject
- protected DetailsDao _hostDetailsDao = null;
- @Inject
- protected ClusterDao _clusterDao = null;
- @Inject
- protected ClusterDetailsDao _clusterDetailsDao = null;
- @Inject
- protected HostTagsDao _hostTagsDao = null;
-
- @Inject(adapter = DeploymentPlanner.class)
- private Adapters _planners;
-<<<<<<< HEAD
-
- protected Adapters _discoverers = null;
- protected int _port;
-
- @Inject
- protected HighAvailabilityManager _haMgr = null;
- @Inject
- protected AlertManager _alertMgr = null;
-
- @Inject
- protected NetworkManager _networkMgr = null;
-
- @Inject
- protected UpgradeManager _upgradeMgr = null;
-
- @Inject
-=======
-
- protected Adapters _discoverers = null;
- protected int _port;
-
- @Inject
- protected HighAvailabilityManager _haMgr = null;
- @Inject
- protected AlertManager _alertMgr = null;
-
- @Inject
- protected NetworkManager _networkMgr = null;
-
- @Inject
- protected UpgradeManager _upgradeMgr = null;
-
- @Inject
->>>>>>> Build fixes after first pass at merge
- protected StorageManager _storageMgr = null;
-
- @Inject
- protected AccountManager _accountMgr = null;
-
- @Inject
- protected VirtualMachineManager _vmMgr = null;
-
- protected int _retry = 2;
-
- protected String _name;
- protected String _instance;
-
- protected int _wait;
- protected int _updateWait;
- protected int _alertWait;
- protected long _nodeId = -1;
- protected float _overProvisioningFactor = 1;
- protected float _cpuOverProvisioningFactor = 1;
-
- protected Random _rand = new Random(System.currentTimeMillis());
-
- protected int _pingInterval;
- protected long _pingTimeout;
- protected AgentMonitor _monitor = null;
-
- protected ExecutorService _executor;
-
- @Inject
- protected VMTemplateDao _tmpltDao;
- @Inject
- protected VMTemplateHostDao _vmTemplateHostDao;
-
- @Override
- public boolean configure(final String name, final Map params) throws ConfigurationException {
- _name = name;
-
- Request.initBuilder();
-
- final ComponentLocator locator = ComponentLocator.getCurrentLocator();
- ConfigurationDao configDao = locator.getDao(ConfigurationDao.class);
- if (configDao == null) {
- throw new ConfigurationException("Unable to get the configuration dao.");
- }
-
- final Map configs = configDao.getConfiguration("AgentManager", params);
- _port = NumbersUtil.parseInt(configs.get("port"), 8250);
- final int workers = NumbersUtil.parseInt(configs.get("workers"), 5);
-
- String value = configs.get("ping.interval");
- _pingInterval = NumbersUtil.parseInt(value, 60);
-
- value = configs.get("wait");
- _wait = NumbersUtil.parseInt(value, 1800) * 1000;
-
- value = configs.get("alert.wait");
- _alertWait = NumbersUtil.parseInt(value, 1800);
-
- value = configs.get("update.wait");
- _updateWait = NumbersUtil.parseInt(value, 600);
-
- value = configs.get("ping.timeout");
- final float multiplier = value != null ? Float.parseFloat(value) : 2.5f;
- _pingTimeout = (long) (multiplier * _pingInterval);
-
- s_logger.info("Ping Timeout is " + _pingTimeout);
-
- _instance = configs.get("instance.name");
- if (_instance == null) {
- _instance = "DEFAULT";
- }
-
- _hostAllocators = locator.getAdapters(HostAllocator.class);
- if (_hostAllocators == null || !_hostAllocators.isSet()) {
- throw new ConfigurationException("Unable to find an host allocator.");
- }
-
- _podAllocators = locator.getAdapters(PodAllocator.class);
- if (_podAllocators == null || !_podAllocators.isSet()) {
- throw new ConfigurationException("Unable to find an pod allocator.");
- }
-
- _discoverers = locator.getAdapters(Discoverer.class);
-
- if (_nodeId == -1) {
- // FIXME: We really should not do this like this. It should be done
- // at config time and is stored as a config variable.
- _nodeId = MacAddress.getMacAddress().toLong();
- }
-
- _hostDao.markHostsAsDisconnected(_nodeId, Status.Up, Status.Connecting, Status.Updating, Status.Disconnected, Status.Down);
-
- _monitor = new AgentMonitor(_nodeId, _hostDao, _volDao, _vmDao, _dcDao, _podDao, this, _alertMgr, _pingTimeout);
- registerForHostEvents(_monitor, true, true, false);
-
- _executor = new ThreadPoolExecutor(10, 100, 60l, TimeUnit.SECONDS, new LinkedBlockingQueue(), new NamedThreadFactory("AgentTaskPool"));
-
- String overProvisioningFactorStr = configs.get("storage.overprovisioning.factor");
- _overProvisioningFactor = NumbersUtil.parseFloat(overProvisioningFactorStr, 1);
-
- String cpuOverProvisioningFactorStr = configs.get("cpu.overprovisioning.factor");
- _cpuOverProvisioningFactor = NumbersUtil.parseFloat(cpuOverProvisioningFactorStr, 1);
- if (_cpuOverProvisioningFactor < 1) {
- _cpuOverProvisioningFactor = 1;
- }
-
- _connection = new NioServer("AgentManager", _port, workers + 10, this);
-
- s_logger.info("Listening on " + _port + " with " + workers + " workers");
- return true;
- }
-
- @Override
- public boolean isHostNativeHAEnabled(long hostId) {
- HostVO host = _hostDao.findById(hostId);
- if (host.getClusterId() != null) {
- ClusterDetailsVO detail = _clusterDetailsDao.findDetail(host.getClusterId(), "NativeHA");
- return detail == null ? false : Boolean.parseBoolean(detail.getValue());
- }
- return false;
- }
-<<<<<<< HEAD
-
- @Override
- public Task create(Task.Type type, Link link, byte[] data) {
- return new AgentHandler(type, link, data);
- }
-
- @Override
- public int registerForHostEvents(final Listener listener, boolean connections, boolean commands, boolean priority) {
- synchronized (_hostMonitors) {
- _monitorId++;
- if (connections) {
- if (priority) {
- _hostMonitors.add(0, new Pair(_monitorId, listener));
- } else {
- _hostMonitors.add(new Pair(_monitorId, listener));
- }
- }
- if (commands) {
- if (priority) {
- _cmdMonitors.add(0, new Pair(_monitorId, listener));
- } else {
- _cmdMonitors.add(new Pair(_monitorId, listener));
- }
- }
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Registering listener " + listener.getClass().getSimpleName() + " with id " + _monitorId);
- }
- return _monitorId;
- }
- }
-
- @Override
- public int registerForInitialConnects(final StartupCommandProcessor creator,boolean priority) {
- synchronized (_hostMonitors) {
- _monitorId++;
-
- if (priority) {
- _creationMonitors.add(0, new Pair(
- _monitorId, creator));
- } else {
- _creationMonitors.add(0, new Pair(
- _monitorId, creator));
- }
- }
-
- return _monitorId;
- }
-
- @Override
- public void unregisterForHostEvents(final int id) {
- s_logger.debug("Deregistering " + id);
- _hostMonitors.remove(id);
- }
-
- private AgentControlAnswer handleControlCommand(AgentAttache attache, final AgentControlCommand cmd) {
- AgentControlAnswer answer = null;
-
- for (Pair listener : _cmdMonitors) {
- answer = listener.second().processControlCommand(attache.getId(), cmd);
-
- if (answer != null) {
- return answer;
- }
- }
-
- s_logger.warn("No handling of agent control command: " + cmd.toString() + " sent from " + attache.getId());
- return new AgentControlAnswer(cmd);
- }
-
- public void handleCommands(AgentAttache attache, final long sequence, final Command[] cmds) {
- for (Pair listener : _cmdMonitors) {
- boolean processed = listener.second().processCommands(attache.getId(), sequence, cmds);
- if (s_logger.isTraceEnabled()) {
- s_logger.trace("SeqA " + attache.getId() + "-" + sequence + ": " + (processed ? "processed" : "not processed") + " by " + listener.getClass());
- }
- }
- }
-
- @Override
- public void notifyAnswersToMonitors(long agentId, long seq, Answer[] answers) {
- for (Pair listener : _cmdMonitors) {
- listener.second().processAnswers(agentId, seq, answers);
- }
- }
-
- public AgentAttache findAttache(long hostId) {
- return _agents.get(hostId);
- }
-
- @Override
- public Set getConnectedHosts() {
- // make the returning set be safe for concurrent iteration
- final HashSet result = new HashSet();
-
- synchronized (_agents) {
- final Set s = _agents.keySet();
- for (final Long id : s) {
- result.add(id);
- }
- }
- return result;
- }
-
- @Override
- public Host findHost(final Host.Type type, final DataCenterVO dc, final HostPodVO pod, final StoragePoolVO sp, final ServiceOfferingVO offering, final VMTemplateVO template, VMInstanceVO vm,
- Host currentHost, final Set avoid) {
- VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, null, null);
- DeployDestination dest = null;
- DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), pod.getId(), sp.getClusterId(), null, null);
- ExcludeList avoids = new ExcludeList();
- for (Host h : avoid) {
- avoids.addHost(h.getId());
- }
-
- for (DeploymentPlanner planner : _planners) {
- try {
- dest = planner.plan(vmProfile, plan, avoids);
- if (dest != null) {
- return dest.getHost();
- }
- } catch (InsufficientServerCapacityException e) {
-
- }
- }
-
- s_logger.warn("findHost() could not find a non-null host.");
- return null;
- }
-
- @Override
- public List listByDataCenter(long dcId) {
- List pods = _podDao.listByDataCenterId(dcId);
- ArrayList pcs = new ArrayList();
- for (HostPodVO pod : pods) {
- List clusters = _clusterDao.listByPodId(pod.getId());
- if (clusters.size() == 0) {
- pcs.add(new PodCluster(pod, null));
- } else {
- for (ClusterVO cluster : clusters) {
- pcs.add(new PodCluster(pod, cluster));
- }
- }
- }
- return pcs;
- }
-
- @Override
- public List listByPod(long podId) {
- ArrayList pcs = new ArrayList();
- HostPodVO pod = _podDao.findById(podId);
- if (pod == null) {
- return pcs;
- }
- List clusters = _clusterDao.listByPodId(pod.getId());
- if (clusters.size() == 0) {
- pcs.add(new PodCluster(pod, null));
- } else {
- for (ClusterVO cluster : clusters) {
- pcs.add(new PodCluster(pod, cluster));
- }
- }
- return pcs;
- }
-
- protected AgentAttache handleDirectConnect(ServerResource resource, StartupCommand[] startup, Map details, boolean old, List hostTags, String allocationState)
- throws ConnectionException {
- if (startup == null) {
- return null;
- }
- HostVO server = createHost(startup, resource, details, old, hostTags, allocationState);
- if (server == null) {
- return null;
- }
-
- long id = server.getId();
-
- AgentAttache attache = createAttache(id, server, resource);
-
- attache = notifyMonitorsOfConnection(attache, startup);
-
- return attache;
- }
-
- @Override
- public List extends Cluster> 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 extends ServerResource, 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 extends ServerResource, Map> 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(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 extends Host> 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 extends Host> 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 extends ServerResource, 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 extends ServerResource, Map> 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(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) {
- List clusters = _clusterDao.listByDcHyType(dcId, type.toString());
- int retry = 0;
- for (ClusterVO cluster : clusters) {
- List hosts = _hostDao.listBy(Host.Type.Routing, cluster.getId(), null, dcId);
- for (HostVO host : hosts) {
- retry++;
- if (retry > _retry) {
- return null;
- }
- Answer answer = null;
- try {
- answer = easySend(host.getId(), cmd);
- } catch (Exception e) {
- }
- if (answer != null) {
- return answer;
- }
- }
- }
- return null;
- }
-
- @Override
- @DB
- public boolean deleteHost(long hostId, boolean isForced, User caller) {
-
- // Check if the host exists
- HostVO host = _hostDao.findById(hostId);
- if (host == null) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Host: " + hostId + " does not even exist. Delete call is ignored.");
- }
- return true;
- }
-
- if (host.getType() == Type.SecondaryStorage) {
- return deleteSecondaryStorageHost(host);
- }
-
- AgentAttache attache = findAttache(hostId);
- // Get storage pool host mappings here because they can be removed as a part of handleDisconnect later
- List pools = _storagePoolHostDao.listByHostId(hostId);
-
- try {
-
- if (host.getType() == Type.Routing) {
- // Check if host is ready for removal
- Status currentState = host.getStatus();
- Status nextState = currentState.getNextStatus(Status.Event.Remove);
- if (nextState == null) {
- if (!(attache instanceof DirectAgentAttache)) {
- return false;
- }
- s_logger.debug("There is no transition from state " + currentState.toString() + " to state " + Status.Event.Remove.toString());
- return false;
- }
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Deleting Host: " + hostId + " Guid:" + host.getGuid());
- }
-
- // Check if there are vms running/starting/stopping on this host
- List vms = _vmDao.listByHostId(hostId);
-
- 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=" + hostId);
- 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=" + hostId;
- s_logger.warn(errorMsg);
- throw new CloudRuntimeException(errorMsg);
- }
- } 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=" + hostId);
- _haMgr.scheduleRestart(vm, false);
- }
- }
- } else {
- throw new CloudRuntimeException("Unable to delete the host as there are vms in " + vms.get(0).getState() + " state using this host and isForced=false specified");
- }
- }
-
- if (host.getHypervisorType() == HypervisorType.XenServer) {
- if (host.getClusterId() != null) {
- List hosts = _hostDao.listBy(Type.Routing, host.getClusterId(), host.getPodId(), host.getDataCenterId());
- hosts.add(host);
- boolean success = true;
- for (HostVO thost : hosts) {
- long thostId = thost.getId();
- PoolEjectCommand eject = new PoolEjectCommand(host.getGuid());
- Answer answer = easySend(thostId, eject);
- if (answer != null && answer.getResult()) {
- s_logger.debug("Eject Host: " + hostId + " from " + thostId + " Succeed");
- success = true;
- break;
- } else {
- success = false;
- s_logger.warn("Eject Host: " + hostId + " from " + thostId + " failed due to " + (answer != null ? answer.getDetails() : "no answer"));
- }
- }
- if (!success) {
- String msg = "Unable to eject host " + host.getGuid() + " due to there is no host up in this cluster, please execute xe pool-eject host-uuid=" + host.getGuid()
- + "in this host " + host.getPrivateIpAddress();
- s_logger.warn(msg);
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Unable to eject host " + host.getGuid(), msg);
- }
- }
- } else if (host.getHypervisorType() == HypervisorType.KVM) {
- try {
- ShutdownCommand cmd = new ShutdownCommand(ShutdownCommand.DeleteHost, null);
- send(host.getId(), cmd);
- } catch (AgentUnavailableException e) {
- s_logger.warn("Sending ShutdownCommand failed: ", e);
- } catch (OperationTimedoutException e) {
- s_logger.warn("Sending ShutdownCommand failed: ", e);
- }
- }
- }
-
- Transaction txn = Transaction.currentTxn();
- txn.start();
-
- _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null);
- if (attache != null) {
- handleDisconnect(attache, Status.Event.Remove, false);
- }
- // delete host details
- _hostDetailsDao.deleteDetails(hostId);
-
- host.setGuid(null);
- Long clusterId = host.getClusterId();
- host.setClusterId(null);
- _hostDao.update(host.getId(), host);
-
- _hostDao.remove(hostId);
- if (clusterId != null) {
- List hosts = _hostDao.listByCluster(clusterId);
- if (hosts.size() == 0) {
- ClusterVO cluster = _clusterDao.findById(clusterId);
- cluster.setGuid(null);
- _clusterDao.update(clusterId, cluster);
- }
- }
-
- // Delete the associated entries in host ref table
- _storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
-
- // For pool ids you got, delete local storage host entries in pool table where
- for (StoragePoolHostVO pool : pools) {
- Long poolId = pool.getPoolId();
- StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
- if (storagePool.isLocal()) {
- storagePool.setUuid(null);
- storagePool.setClusterId(null);
- _storagePoolDao.update(poolId, storagePool);
- _storagePoolDao.remove(poolId);
- s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId);
- }
- }
-
- // delete the op_host_capacity entry
- Object[] capacityTypes = { Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY };
- SearchCriteria hostCapacitySC = _capacityDao.createSearchCriteria();
- hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
- hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes);
- _capacityDao.remove(hostCapacitySC);
- txn.commit();
- return true;
- } catch (Throwable t) {
- s_logger.error("Unable to delete host: " + hostId, t);
- return false;
- }
- }
-
- @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 cmd){
- List hosts = _hostDao.listByCluster(cmd.getClusterId());
- for (HostVO host : hosts) {
- String resourceName = host.getResource();
- ServerResource resource = null;
- try {
- Class> clazz = Class.forName(resourceName);
- Constructor constructor = clazz.getConstructor();
- resource = (ServerResource) constructor.newInstance();
- } catch (ClassNotFoundException e) {
- s_logger.warn("Unable to find class " + host.getResource(), e);
- return false;
- } catch (InstantiationException e) {
- s_logger.warn("Unablet to instantiate class " + host.getResource(), e);
- return false;
- } catch (IllegalAccessException e) {
- s_logger.warn("Illegal access " + host.getResource(), e);
- return false;
- } catch (SecurityException e) {
- s_logger.warn("Security error on " + host.getResource(), e);
- return false;
- } catch (NoSuchMethodException e) {
- s_logger.warn("NoSuchMethodException error on " + host.getResource(), e);
- return false;
- } catch (IllegalArgumentException e) {
- s_logger.warn("IllegalArgumentException error on " + host.getResource(), e);
- return false;
- } catch (InvocationTargetException e) {
- s_logger.warn("InvocationTargetException error on " + host.getResource(), e);
- return false;
- }
-
- _hostDao.loadDetails(host);
-
- HashMap params = new HashMap(host.getDetails().size() + 5);
- params.putAll(host.getDetails());
-
- params.put("guid", host.getGuid());
- params.put("zone", Long.toString(host.getDataCenterId()));
- if (host.getPodId() != null) {
- params.put("pod", Long.toString(host.getPodId()));
- }
- if (host.getClusterId() != null) {
- params.put("cluster", Long.toString(host.getClusterId()));
- String guid = null;
- ClusterVO cluster = _clusterDao.findById(host.getClusterId());
- if (cluster.getGuid() == null) {
- guid = host.getDetail("pool");
- } else {
- guid = cluster.getGuid();
- }
- if (guid == null || guid.isEmpty()) {
- throw new CloudRuntimeException("Can not find guid for cluster " + cluster.getId() + " name " + cluster.getName());
- }
- params.put("pool", guid);
- }
-
- params.put("ipaddress", host.getPrivateIpAddress());
- params.put("secondary.storage.vm", "false");
- params.put("max.template.iso.size", _configDao.getValue("max.template.iso.size"));
- params.put("username", cmd.getUsername());
- params.put("password", cmd.getPassword());
-
- try {
- resource.configure(host.getName(), params);
- } catch (ConfigurationException e) {
- s_logger.warn("Unable to configure resource due to ", e);
- return false;
- }
-
- if (!resource.start()) {
- s_logger.warn("Unable to start the resource");
- return false;
- }
- host.setLastPinged(System.currentTimeMillis() >> 10);
- host.setManagementServerId(_nodeId);
- _hostDao.update(host.getId(), host);
- _executor.execute(new SimulateStartTask(host.getId(), resource, host.getDetails(), null));
- }
- return true;
- }
-
-
- @DB
- protected boolean deleteSecondaryStorageHost(HostVO secStorageHost) {
- long zoneId = secStorageHost.getDataCenterId();
- long hostId = secStorageHost.getId();
- Transaction txn = Transaction.currentTxn();
- try {
-
- List allVmsInZone = _vmDao.listByZoneId(zoneId);
- if (!allVmsInZone.isEmpty()) {
- s_logger.warn("Cannot delete secondary storage host when there are " + allVmsInZone.size() + " vms in zone " + zoneId);
- return false;
- }
- txn.start();
-
- if (!_hostDao.updateStatus(secStorageHost, Event.MaintenanceRequested, _nodeId)) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Unable to take host " + hostId + " into maintenance mode. Delete call is ignored");
- }
- return false;
- }
- if (!_hostDao.updateStatus(secStorageHost, Event.PreparationComplete, _nodeId)) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Unable to take host " + hostId + " into maintenance mode. Delete call is ignored");
- }
- return false;
- }
-
- AgentAttache attache = findAttache(hostId);
- if (attache != null) {
- handleDisconnect(attache, Status.Event.Remove, false);
- }
- // now delete the host
- secStorageHost.setGuid(null);
- _hostDao.update(secStorageHost.getId(), secStorageHost);
- _hostDao.remove(secStorageHost.getId());
-
- // delete the templates associated with this host
- SearchCriteria templateHostSC = _vmTemplateHostDao.createSearchCriteria();
- templateHostSC.addAnd("hostId", SearchCriteria.Op.EQ, secStorageHost.getId());
- _vmTemplateHostDao.remove(templateHostSC);
-
- // delete the op_host_capacity entry
- SearchCriteria secStorageCapacitySC = _capacityDao.createSearchCriteria();
- secStorageCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, secStorageHost.getId());
- secStorageCapacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, Capacity.CAPACITY_TYPE_SECONDARY_STORAGE);
- _capacityDao.remove(secStorageCapacitySC);
-
- /* Disconnected agent needs special handling here */
- secStorageHost.setGuid(null);
-
- txn.commit();
- return true;
- } catch (Throwable t) {
- s_logger.error("Unable to delete sec storage host: " + secStorageHost.getId(), t);
- return false;
- }
- }
-
- @Override
- public boolean isVirtualMachineUpgradable(final UserVm vm, final ServiceOffering offering) {
- Enumeration en = _hostAllocators.enumeration();
- boolean isMachineUpgradable = true;
- while (isMachineUpgradable && en.hasMoreElements()) {
- final HostAllocator allocator = en.nextElement();
- isMachineUpgradable = allocator.isVirtualMachineUpgradable(vm, offering);
- }
-
- return isMachineUpgradable;
- }
-
- protected int getPingInterval() {
- return _pingInterval;
- }
-
- @Override
- public Answer send(Long hostId, Command cmd, int timeout) throws AgentUnavailableException, OperationTimedoutException {
- Commands cmds = new Commands(OnError.Revert);
- cmds.addCommand(cmd);
- send(hostId, cmds, timeout);
- Answer[] answers = cmds.getAnswers();
- if (answers != null && !(answers[0] instanceof UnsupportedAnswer)) {
- return answers[0];
- }
-
- if (answers != null && (answers[0] instanceof UnsupportedAnswer)) {
- s_logger.warn("Unsupported Command: " + answers[0].getDetails());
- return answers[0];
- }
-
- return null;
- }
-
- @DB
- protected boolean noDbTxn() {
- Transaction txn = Transaction.currentTxn();
- return !txn.dbTxnStarted();
- }
-
- @Override
- public Answer[] send(Long hostId, Commands commands, int timeout) throws AgentUnavailableException, OperationTimedoutException {
- assert hostId != null : "Who's not checking the agent id before sending? ... (finger wagging)";
- if (hostId == null) {
- throw new AgentUnavailableException(-1);
- }
-
- // assert noDbTxn() :
- // "I know, I know. Why are we so strict as to not allow txn across an agent call? ... Why are we so cruel ... Why are we such a dictator .... Too bad... Sorry...but NO AGENT COMMANDS WRAPPED WITHIN DB TRANSACTIONS!";
-
- Command[] cmds = commands.toCommands();
-
- assert cmds.length > 0 : "Ask yourself this about a hundred times. Why am I sending zero length commands?";
-
- if (cmds.length == 0) {
- commands.setAnswers(new Answer[0]);
- }
-
- final AgentAttache agent = getAttache(hostId);
- if (agent == null || agent.isClosed()) {
- throw new AgentUnavailableException("agent not logged into this management server", hostId);
- }
-
- long seq = _hostDao.getNextSequence(hostId);
- Request req = new Request(seq, hostId, _nodeId, cmds, commands.stopOnError(), true, commands.revertOnError());
- Answer[] answers = agent.send(req, timeout);
- notifyAnswersToMonitors(hostId, seq, answers);
- commands.setAnswers(answers);
- return answers;
- }
-
- protected Status investigate(AgentAttache agent) {
- Long hostId = agent.getId();
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("checking if agent (" + hostId + ") is alive");
- }
-
- try {
- long seq = _hostDao.getNextSequence(hostId);
- Request req = new Request(seq, hostId, _nodeId, new CheckHealthCommand(), true);
- Answer[] answers = agent.send(req, 50 * 1000);
- if (answers != null && answers[0] != null) {
- Status status = answers[0].getResult() ? Status.Up : Status.Down;
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("agent (" + hostId + ") responded to checkHeathCommand, reporting that agent is " + status);
- }
- return status;
- }
- } catch (AgentUnavailableException e) {
- s_logger.debug("Agent is unavailable so we move on.");
- } catch (OperationTimedoutException e) {
- s_logger.debug("Timed Out " + e.getMessage());
- }
-
- return _haMgr.investigate(hostId);
- }
-
- protected AgentAttache getAttache(final Long hostId) throws AgentUnavailableException {
- assert (hostId != null) : "Who didn't check their id value?";
- if (hostId == null) {
- return null;
- }
- AgentAttache agent = findAttache(hostId);
- if (agent == null) {
- s_logger.debug("Unable to find agent for " + hostId);
- throw new AgentUnavailableException("Unable to find agent ", hostId);
- }
-
- return agent;
- }
-
- @Override
- public long send(Long hostId, Commands commands, Listener listener) throws AgentUnavailableException {
- final AgentAttache agent = getAttache(hostId);
- if (agent.isClosed()) {
- return -1;
- }
-
- Command[] cmds = commands.toCommands();
-
- assert cmds.length > 0 : "Why are you sending zero length commands?";
- if (cmds.length == 0) {
- return -1;
- }
- long seq = _hostDao.getNextSequence(hostId);
- Request req = new Request(seq, hostId, _nodeId, cmds, commands.stopOnError(), true, commands.revertOnError());
- agent.send(req, listener);
- return seq;
- }
-
- @Override
- public long gatherStats(final Long hostId, final Command cmd, final Listener listener) {
- try {
- return send(hostId, new Commands(cmd), listener);
- } catch (final AgentUnavailableException e) {
- return -1;
- }
- }
-
- public void removeAgent(AgentAttache attache, Status nextState) {
- if (attache == null) {
- return;
- }
- long hostId = attache.getId();
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Remove Agent : " + hostId);
- }
- AgentAttache removed = null;
- boolean conflict = false;
- synchronized (_agents) {
- removed = _agents.remove(hostId);
- if (removed != null && removed != attache) {
- conflict = true;
- _agents.put(hostId, removed);
- removed = attache;
- }
- }
- if (conflict) {
- s_logger.debug("Agent for host " + hostId + " is created when it is being disconnected");
- }
- if (removed != null) {
- removed.disconnect(nextState);
- }
- }
-
- @Override
- public void disconnect(final long hostId, final Status.Event event, final boolean investigate) {
- AgentAttache attache = findAttache(hostId);
-
- if (attache != null) {
- disconnect(attache, event, investigate);
- } else {
- HostVO host = _hostDao.findById(hostId);
- if (host != null && host.getRemoved() == null) {
- if (event != null && event.equals(Event.Remove)) {
- host.setGuid(null);
- host.setClusterId(null);
- }
- _hostDao.updateStatus(host, event, _nodeId);
- }
- }
- }
-
- public void disconnect(AgentAttache attache, final Status.Event event, final boolean investigate) {
- _executor.submit(new DisconnectTask(attache, event, investigate));
- }
-
- protected boolean handleDisconnect(AgentAttache attache, Status.Event event, boolean investigate) {
- if (attache == null) {
- return true;
- }
-
- long hostId = attache.getId();
-
- s_logger.info("Host " + hostId + " is disconnecting with event " + event.toString());
-
- HostVO host = _hostDao.findById(hostId);
- if (host == null) {
- s_logger.warn("Can't find host with " + hostId);
- removeAgent(attache, Status.Removed);
- return true;
-
- }
- final Status currentState = host.getStatus();
- if (currentState == Status.Down || currentState == Status.Alert || currentState == Status.Removed || currentState == Status.PrepareForMaintenance) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Host " + hostId + " is already " + currentState.toString());
- }
- if (currentState != Status.PrepareForMaintenance) {
- removeAgent(attache, currentState);
- }
- return true;
- }
- Status nextState = currentState.getNextStatus(event);
- if (nextState == null) {
- if (!(attache instanceof DirectAgentAttache)) {
- return false;
- }
-
- s_logger.debug("There is no transition from state " + currentState.toString() + " and event " + event.toString());
- assert false : "How did we get here. Look at the FSM";
- return false;
- }
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("The next state is " + nextState.toString() + ", current state is " + currentState);
- }
-
- // Now we go and correctly diagnose what the actual situation is
- if (nextState == Status.Alert && investigate) {
- s_logger.info("Investigating why host " + hostId + " has disconnected with event " + event.toString());
-
- final Status determinedState = investigate(attache);
- s_logger.info("The state determined is " + (determinedState != null ? determinedState.toString() : "undeterminable"));
-
- if (determinedState == null || determinedState == Status.Down) {
- s_logger.error("Host is down: " + host.getId() + "-" + host.getName() + ". Starting HA on the VMs");
-
- event = Event.HostDown;
- } else if (determinedState == Status.Up) {
- // we effectively pinged from the server here.
- s_logger.info("Agent is determined to be up and running");
- _hostDao.updateStatus(host, Event.Ping, _nodeId);
- return false;
- } else if (determinedState == Status.Disconnected) {
- s_logger.warn("Agent is disconnected but the host is still up: " + host.getId() + "-" + host.getName());
- if (currentState == Status.Disconnected) {
- if (((System.currentTimeMillis() >> 10) - host.getLastPinged()) > _alertWait) {
- s_logger.warn("Host " + host.getId() + " has been disconnected pass the time it should be disconnected.");
- event = Event.WaitedTooLong;
- } else {
- s_logger.debug("Host has been determined to be disconnected but it hasn't passed the wait time yet.");
- return false;
- }
- } else if (currentState == Status.Updating) {
- if (((System.currentTimeMillis() >> 10) - host.getLastPinged()) > _updateWait) {
- s_logger.warn("Host " + host.getId() + " has been updating for too long");
-
- event = Event.WaitedTooLong;
- } else {
- s_logger.debug("Host has been determined to be disconnected but it hasn't passed the wait time yet.");
- return false;
- }
- } else if (currentState == Status.Up) {
- DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
- HostPodVO podVO = _podDao.findById(host.getPodId());
- String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
- if ((host.getType() != Host.Type.SecondaryStorage) && (host.getType() != Host.Type.ConsoleProxy)) {
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host disconnected, " + hostDesc, "If the agent for host [" + hostDesc
- + "] is not restarted within " + _alertWait + " seconds, HA will begin on the VMs");
- }
- event = Event.AgentDisconnected;
- }
- } else {
- // if we end up here we are in alert state, send an alert
- DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
- HostPodVO podVO = _podDao.findById(host.getPodId());
- String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host in ALERT state, " + hostDesc, "In availability zone " + host.getDataCenterId()
- + ", host is in alert state: " + host.getId() + "-" + host.getName());
- }
- }
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Deregistering link for " + hostId + " with state " + nextState);
- }
-
- _hostDao.disconnect(host, event, _nodeId);
-
- removeAgent(attache, nextState);
-
- host = _hostDao.findById(host.getId());
- if (host.getStatus() == Status.Alert || host.getStatus() == Status.Down) {
- _haMgr.scheduleRestartForVmsOnHost(host, investigate);
- }
-
- for (Pair monitor : _hostMonitors) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Sending Disconnect to listener: " + monitor.second().getClass().getName());
- }
- monitor.second().processDisconnect(hostId, nextState);
- }
-
- return true;
- }
-
- protected AgentAttache notifyMonitorsOfConnection(AgentAttache attache, final StartupCommand[] cmd) throws ConnectionException {
- long hostId = attache.getId();
- HostVO host = _hostDao.findById(hostId);
- for (Pair monitor : _hostMonitors) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Sending Connect to listener: " + monitor.second().getClass().getSimpleName());
- }
- for (int i = 0; i < cmd.length; i++) {
- try {
- monitor.second().processConnect(host, cmd[i]);
- } catch (Exception e) {
- if (e instanceof ConnectionException) {
- ConnectionException ce = (ConnectionException)e;
- if (ce.isSetupError()) {
- s_logger.warn("Monitor " + monitor.second().getClass().getSimpleName() + " says there is an error in the connect process for " + hostId + " due to " + e.getMessage());
- handleDisconnect(attache, Event.AgentDisconnected, false);
- throw ce;
- } else {
- s_logger.info("Monitor " + monitor.second().getClass().getSimpleName() + " says not to continue the connect process for " + hostId + " due to " + e.getMessage());
- handleDisconnect(attache, Event.ShutdownRequested, false);
- return attache;
- }
- } else {
- s_logger.error("Monitor " + monitor.second().getClass().getSimpleName() + " says there is an error in the connect process for " + hostId + " due to " + e.getMessage(), e);
- handleDisconnect(attache, Event.AgentDisconnected, false);
- throw new CloudRuntimeException("Unable to connect " + attache.getId(), e);
- }
- }
- }
- }
-
- Long dcId = host.getDataCenterId();
- ReadyCommand ready = new ReadyCommand(dcId);
- Answer answer = easySend(hostId, ready);
- if (answer == null || !answer.getResult()) {
- // this is tricky part for secondary storage
- // make it as disconnected, wait for secondary storage VM to be up
- // return the attache instead of null, even it is disconnectede
- handleDisconnect(attache, Event.AgentDisconnected, false);
- }
-
- _hostDao.updateStatus(host, Event.Ready, _nodeId);
- attache.ready();
- return attache;
- }
-
- protected boolean notifyCreatorsOfConnection(StartupCommand[] cmd) throws ConnectionException {
- boolean handled = false;
- for (Pair monitor : _creationMonitors) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Sending Connect to creator: "
- + monitor.second().getClass().getSimpleName());
- }
- handled = monitor.second().processInitialConnect(cmd);
- if (handled) {
- break;
- }
- }
-
- return handled;
- }
-
- @Override
- public boolean start() {
- startDirectlyConnectedHosts();
- if (_monitor != null) {
- _monitor.start();
- }
- if (_connection != null) {
- _connection.start();
- }
-
- return true;
- }
-
- public void startDirectlyConnectedHosts() {
- List hosts = _hostDao.findDirectlyConnectedHosts();
- for (HostVO host : hosts) {
- loadDirectlyConnectedHost(host);
- }
- }
-
- @SuppressWarnings("rawtypes")
- protected void loadDirectlyConnectedHost(HostVO host) {
- String resourceName = host.getResource();
- ServerResource resource = null;
- try {
- Class> clazz = Class.forName(resourceName);
- Constructor constructor = clazz.getConstructor();
- resource = (ServerResource) constructor.newInstance();
- } catch (ClassNotFoundException e) {
- s_logger.warn("Unable to find class " + host.getResource(), e);
- return;
- } catch (InstantiationException e) {
- s_logger.warn("Unablet to instantiate class " + host.getResource(), e);
- return;
- } catch (IllegalAccessException e) {
- s_logger.warn("Illegal access " + host.getResource(), e);
- return;
- } catch (SecurityException e) {
- s_logger.warn("Security error on " + host.getResource(), e);
- return;
- } catch (NoSuchMethodException e) {
- s_logger.warn("NoSuchMethodException error on " + host.getResource(), e);
- return;
- } catch (IllegalArgumentException e) {
- s_logger.warn("IllegalArgumentException error on " + host.getResource(), e);
- return;
- } catch (InvocationTargetException e) {
- s_logger.warn("InvocationTargetException error on " + host.getResource(), e);
- return;
- }
-
- _hostDao.loadDetails(host);
-
- HashMap params = new HashMap(host.getDetails().size() + 5);
- params.putAll(host.getDetails());
-
- params.put("guid", host.getGuid());
- params.put("zone", Long.toString(host.getDataCenterId()));
- if (host.getPodId() != null) {
- params.put("pod", Long.toString(host.getPodId()));
- }
- if (host.getClusterId() != null) {
- params.put("cluster", Long.toString(host.getClusterId()));
- String guid = null;
- ClusterVO cluster = _clusterDao.findById(host.getClusterId());
- if (cluster.getGuid() == null) {
- guid = host.getDetail("pool");
- } else {
- guid = cluster.getGuid();
- }
- if (guid == null || guid.isEmpty()) {
- throw new CloudRuntimeException("Can not find guid for cluster " + cluster.getId() + " name " + cluster.getName());
- }
- params.put("pool", guid);
- }
-
- params.put("ipaddress", host.getPrivateIpAddress());
- params.put("secondary.storage.vm", "false");
- params.put("max.template.iso.size", _configDao.getValue("max.template.iso.size"));
-
- try {
- resource.configure(host.getName(), params);
- } catch (ConfigurationException e) {
- s_logger.warn("Unable to configure resource due to ", e);
- return;
- }
-
- if (!resource.start()) {
- s_logger.warn("Unable to start the resource");
- return;
- }
- host.setLastPinged(System.currentTimeMillis() >> 10);
- host.setManagementServerId(_nodeId);
- _hostDao.update(host.getId(), host);
- _executor.execute(new SimulateStartTask(host.getId(), resource, host.getDetails(), null));
- }
-
- protected AgentAttache simulateStart(ServerResource resource, Map details, boolean old, List hostTags, String allocationState) throws IllegalArgumentException {
- StartupCommand[] cmds = resource.initialize();
- if (cmds == null) {
- return null;
- }
-
- AgentAttache attache = null;
- if (s_logger.isDebugEnabled()) {
- new Request(0l, -1l, -1l, cmds, true, false, true).log(-1, "Startup request from directly connected host: ");
- // s_logger.debug("Startup request from directly connected host: "
- // + new Request(0l, -1l, -1l, cmds, true, false, true)
- // .toString());
- }
- try {
- attache = handleDirectConnect(resource, cmds, details, old, hostTags, allocationState);
- } catch (IllegalArgumentException ex) {
- s_logger.warn("Unable to connect due to ", ex);
- throw ex;
- } catch (Exception e) {
- s_logger.warn("Unable to connect due to ", e);
- }
-
- if (attache == null) {
- resource.disconnected();
- return null;
- }
- if (attache.isReady()) {
- StartupAnswer[] answers = new StartupAnswer[cmds.length];
- for (int i = 0; i < answers.length; i++) {
- answers[i] = new StartupAnswer(cmds[i], attache.getId(), _pingInterval);
- }
-
- attache.process(answers);
- }
- return attache;
- }
-
- @Override
- public boolean stop() {
- if (_monitor != null) {
- _monitor.signalStop();
- }
- if (_connection != null) {
- _connection.stop();
- }
-
- s_logger.info("Disconnecting agents: " + _agents.size());
- synchronized (_agents) {
- for (final AgentAttache agent : _agents.values()) {
- final HostVO host = _hostDao.findById(agent.getId());
- if (host == null) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cant not find host " + agent.getId());
- }
- } else {
- _hostDao.updateStatus(host, Event.ManagementServerDown, _nodeId);
- }
- }
- }
- return true;
- }
-
- @Override
- public Pair findPod(final VirtualMachineTemplate template, ServiceOfferingVO offering, final DataCenterVO dc, final long accountId, Set avoids) {
- final Enumeration en = _podAllocators.enumeration();
- while (en.hasMoreElements()) {
- final PodAllocator allocator = (PodAllocator) en.nextElement();
- final Pair pod = allocator.allocateTo(template, offering, dc, accountId, avoids);
- if (pod != null) {
- return pod;
- }
- }
- return null;
- }
-
- @Override
- public HostStats getHostStatistics(long hostId) {
- Answer answer = easySend(hostId, new GetHostStatsCommand(_hostDao.findById(hostId).getGuid(), _hostDao.findById(hostId).getName(), hostId));
-
- if (answer != null && (answer instanceof UnsupportedAnswer)) {
- return null;
- }
-
- if (answer == null || !answer.getResult()) {
- String msg = "Unable to obtain host " + hostId + " statistics. ";
- s_logger.warn(msg);
- return null;
- } else {
-
- // now construct the result object
- if (answer instanceof GetHostStatsAnswer) {
- return ((GetHostStatsAnswer) answer).getHostStats();
- }
- }
- return null;
- }
-
- @Override
- public Long getGuestOSCategoryId(long hostId) {
- HostVO host = _hostDao.findById(hostId);
- if (host == null) {
- return null;
- } else {
- _hostDao.loadDetails(host);
- DetailVO detail = _hostDetailsDao.findDetail(hostId, "guest.os.category.id");
- if (detail == null) {
- return null;
- } else {
- return Long.parseLong(detail.getValue());
- }
- }
- }
-
- @Override
- public String getHostTags(long hostId) {
- List hostTags = _hostTagsDao.gethostTags(hostId);
- if (hostTags == null) {
- return null;
- } else {
- return StringUtils.listToCsvTags(hostTags);
- }
- }
-
- @Override
- public String getName() {
- return _name;
- }
-
- protected class DisconnectTask implements Runnable {
- AgentAttache _attache;
- Status.Event _event;
- boolean _investigate;
-
- DisconnectTask(final AgentAttache attache, final Status.Event event, final boolean investigate) {
- _attache = attache;
- _event = event;
- _investigate = investigate;
- }
-
- @Override
- public void run() {
- try {
- handleDisconnect(_attache, _event, _investigate);
- } catch (final Exception e) {
- s_logger.error("Exception caught while handling disconnect: ", e);
- } finally {
- StackMaid.current().exitCleanup();
- }
- }
- }
-
- @Override
- public Answer easySend(final Long hostId, final Command cmd) {
- return easySend(hostId, cmd, _wait);
- }
-
- @Override
- public Answer easySend(final Long hostId, final Command cmd, int timeout) {
- try {
- Host h = _hostDao.findById(hostId);
- if (h == null || h.getRemoved() != null) {
- s_logger.debug("Host with id " + hostId.toString() + " doesn't exist");
- return null;
- }
- Status status = h.getStatus();
- if (!status.equals(Status.Up) && !status.equals(Status.Connecting)) {
- return null;
- }
- final Answer answer = send(hostId, cmd, timeout);
- if (answer == null) {
- s_logger.warn("send returns null answer");
- return null;
- }
-
- if (!answer.getResult()) {
- s_logger.warn("Unable to execute command: " + cmd.toString() + " due to " + answer.getDetails());
- return null;
- }
-
- if (s_logger.isDebugEnabled() && answer.getDetails() != null) {
- s_logger.debug("Details from executing " + cmd.getClass().toString() + ": " + answer.getDetails());
- }
-
- return answer;
-
- } catch (final AgentUnavailableException e) {
- s_logger.warn(e.getMessage());
- return null;
- } catch (final OperationTimedoutException e) {
- s_logger.warn("Operation timed out: " + e.getMessage());
- return null;
- } catch (final Exception e) {
- s_logger.warn("Exception while sending", e);
- return null;
- }
- }
-
- @Override
- public Answer send(final Long hostId, final Command cmd) throws AgentUnavailableException, OperationTimedoutException {
- return send(hostId, cmd, _wait);
- }
-
- @Override
- public Answer[] send(final Long hostId, Commands cmds) throws AgentUnavailableException, OperationTimedoutException {
- 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;
-
- host = _hostDao.findById(hostId);
- if (host == null || host.getRemoved() != null) {
- s_logger.warn("Unable to find host " + hostId);
- return false;
- }
-
- if (host.getStatus() != Status.Up && host.getStatus() != Status.Alert) {
- s_logger.info("Unable to disconnect host because it is not in the correct state: host=" + hostId + "; Status=" + host.getStatus());
- return false;
- }
-
- AgentAttache attache = findAttache(hostId);
- if (attache == null) {
- s_logger.info("Unable to disconnect host because it is not connected to this server: " + hostId);
- return false;
- }
-
- disconnect(attache, Event.ShutdownRequested, false);
- return true;
- }
-
- @Override
- public boolean cancelMaintenance(final long hostId) {
-
- HostVO host;
- host = _hostDao.findById(hostId);
- if (host == null || host.getRemoved() != null) {
- s_logger.warn("Unable to find host " + hostId);
- return true;
- }
-
- if (host.getStatus() != Status.PrepareForMaintenance && host.getStatus() != Status.Maintenance && host.getStatus() != Status.ErrorInMaintenance) {
- return true;
- }
-
- _haMgr.cancelScheduledMigrations(host);
- List vms = _haMgr.findTakenMigrationWork();
- for (VMInstanceVO vm : vms) {
- if (vm.getHostId() != null && vm.getHostId() == hostId) {
- s_logger.info("Unable to cancel migration because the vm is being migrated: " + vm.toString());
- return false;
- }
- }
- disconnect(hostId, Event.ResetRequested, false);
- 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) {
- return maintain(hostId);
- } else if (event == Event.ResetRequested) {
- return cancelMaintenance(hostId);
- } else if (event == Event.Remove) {
- User caller = _accountMgr.getActiveUser(User.UID_SYSTEM);
- return deleteHost(hostId, false, caller);
- } else if (event == Event.AgentDisconnected) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Received agent disconnect event for host " + hostId);
- }
- AgentAttache attache = null;
- attache = findAttache(hostId);
- if (attache != null) {
- handleDisconnect(attache, Event.AgentDisconnected, false);
- }
- return true;
- } else if (event == Event.ShutdownRequested) {
- return reconnect(hostId);
- }
- return false;
- }
-
- @Override
- public boolean maintain(final long hostId) throws AgentUnavailableException {
- HostVO host = _hostDao.findById(hostId);
- Status state;
-
- Answer answer = easySend(hostId, new MaintainCommand());
- if (answer == null || !answer.getResult()) {
- s_logger.warn("Unable to put host in maintainance mode: " + hostId);
- return false;
- }
-
- // Let's put this guy in maintenance state
- do {
- host = _hostDao.findById(hostId);
- if (host == null) {
- s_logger.debug("Unable to find host " + hostId);
- return false;
- }
- state = host.getStatus();
- if (state == Status.Disconnected || state == Status.Updating) {
- s_logger.debug("Unable to put host " + hostId + " in matinenance mode because it is currently in " + state.toString());
- throw new AgentUnavailableException("Agent is in " + state.toString() + " state. Please wait for it to become Alert state try again.", hostId);
- }
- } while (!_hostDao.updateStatus(host, Event.MaintenanceRequested, _nodeId));
-
- AgentAttache attache = findAttache(hostId);
- if (attache != null) {
- attache.setMaintenanceMode(true);
- }
-
- if (attache != null) {
- // Now cancel all of the commands except for the active one.
- attache.cancelAllCommands(Status.PrepareForMaintenance, false);
- }
-
- final Host.Type type = host.getType();
-
- if (type == Host.Type.Routing) {
-
- final List vms = _vmDao.listByHostId(hostId);
- if (vms.size() == 0) {
- return true;
- }
-
- List hosts = _hostDao.listBy(host.getClusterId(), host.getPodId(), host.getDataCenterId());
-
- for (final VMInstanceVO vm : vms) {
- if (hosts == null || hosts.size() <= 1) {
- // for the last host in this cluster, stop all the VMs
- _haMgr.scheduleStop(vm, hostId, WorkType.ForceStop);
- } else {
- _haMgr.scheduleMigration(vm);
- }
- }
- }
-
- 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) {
- return true;
- }
- // 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)) {
- return false;
- }
-
- // 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) {
- return false;
- }
- return true;
- }
-
- protected void checkCIDR(Host.Type type, HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask) throws IllegalArgumentException {
- // Skip this check for Storage Agents and Console Proxies
- if (type == Host.Type.Storage || type == Host.Type.ConsoleProxy) {
- return;
- }
-
- 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());
- }
-
- }
-
- public void checkIPConflicts(Host.Type type, HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask, String serverPublicIP, String serverPublicNetmask) {
- // If the server's private IP is the same as is public IP, this host has
- // a host-only private network. Don't check for conflicts with the
- // private IP address table.
- if (serverPrivateIP != serverPublicIP) {
- if (!_privateIPAddressDao.mark(dc.getId(), pod.getId(), serverPrivateIP)) {
- // If the server's private IP address is already in the
- // database, return false
- List existingPrivateIPs = _privateIPAddressDao.listByPodIdDcIdIpAddress(pod.getId(), dc.getId(), serverPrivateIP);
-
- assert existingPrivateIPs.size() <= 1 : " How can we get more than one ip address with " + serverPrivateIP;
- if (existingPrivateIPs.size() > 1) {
- throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() + " and zone: " + dc.getName());
- }
- if (existingPrivateIPs.size() == 1) {
- DataCenterIpAddressVO vo = existingPrivateIPs.get(0);
- if (vo.getInstanceId() != null) {
- throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() + " and zone: " + dc.getName());
- }
- }
- }
- }
-
- if (serverPublicIP != null && !_publicIPAddressDao.mark(dc.getId(), new Ip(serverPublicIP))) {
- // If the server's public IP address is already in the database,
- // return false
- List existingPublicIPs = _publicIPAddressDao.listByDcIdIpAddress(dc.getId(), serverPublicIP);
- if (existingPublicIPs.size() > 0) {
- throw new IllegalArgumentException("The public ip address of the server (" + serverPublicIP + ") is already in use in zone: " + dc.getName());
- }
- }
- }
-
- @Override
- public Host addHost(long zoneId, ServerResource resource, Type hostType, Map hostDetails) {
- // Check if the zone exists in the system
- if (_dcDao.findById(zoneId) == null) {
- throw new InvalidParameterValueException("Can't find zone with id " + zoneId);
- }
-
- Map details = hostDetails;
- String guid = details.get("guid");
- List currentHosts = _hostDao.listBy(hostType, zoneId);
- for (HostVO currentHost : currentHosts) {
- if (currentHost.getGuid().equals(guid)) {
- return currentHost;
- }
- }
-
- AgentAttache attache = simulateStart(resource, hostDetails, true, null, null);
- return _hostDao.findById(attache.getId());
- }
-
- public HostVO createHost(final StartupCommand startup, ServerResource resource, Map details, boolean directFirst, List hostTags, String allocationState)
- throws IllegalArgumentException {
- Host.Type type = null;
-
- if (startup instanceof StartupStorageCommand) {
- StartupStorageCommand ssCmd = ((StartupStorageCommand) startup);
- 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) {
- resource = null;
- }
- } else {
- type = Host.Type.Storage;
- }
- final Map hostDetails = ssCmd.getHostDetails();
- if (hostDetails != null) {
- if (details != null) {
- details.putAll(hostDetails);
- } else {
- details = hostDetails;
- }
- }
- }
- } else if (startup instanceof StartupRoutingCommand) {
- StartupRoutingCommand ssCmd = ((StartupRoutingCommand) startup);
- type = Host.Type.Routing;
- final Map hostDetails = ssCmd.getHostDetails();
- if (hostDetails != null) {
- if (details != null) {
- details.putAll(hostDetails);
- } else {
- details = hostDetails;
- }
- }
- } else if (startup instanceof StartupProxyCommand) {
- type = Host.Type.ConsoleProxy;
- } else if (startup instanceof StartupRoutingCommand) {
- type = Host.Type.Routing;
- } else if (startup instanceof StartupExternalFirewallCommand) {
- type = Host.Type.ExternalFirewall;
- } else if (startup instanceof StartupExternalLoadBalancerCommand) {
- type = Host.Type.ExternalLoadBalancer;
- } else if (startup instanceof StartupPxeServerCommand) {
- type = Host.Type.PxeServer;
- } else if (startup instanceof StartupExternalDhcpCommand) {
- type = Host.Type.ExternalDhcp;
- } else {
- assert false : "Did someone add a new Startup command?";
- }
-
- Long id = null;
- HostVO server = _hostDao.findByGuid(startup.getGuid());
- if (server == null) {
- server = _hostDao.findByGuid(startup.getGuidWithoutResource());
- }
- if (server != null && server.getRemoved() == null) {
- id = server.getId();
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Found the host " + id + " by guid: " + startup.getGuid());
- }
- if (directFirst) {
- s_logger.debug("Old host reconnected as new");
- return null;
- }
- } else {
- server = new HostVO(startup.getGuid());
- }
-
- server.setDetails(details);
- server.setHostTags(hostTags);
-
- if (allocationState != null) {
- try {
- HostAllocationState hostAllocationState = Host.HostAllocationState.valueOf(allocationState);
- if (hostAllocationState != null) {
- server.setHostAllocationState(hostAllocationState);
- }
- } catch (IllegalArgumentException ex) {
- s_logger.error("Unable to resolve " + allocationState + " to a valid supported host allocation State, defaulting to 'Enabled'");
- server.setHostAllocationState(Host.HostAllocationState.Enabled);
- }
- } else {
- server.setHostAllocationState(Host.HostAllocationState.Enabled);
- }
-
- updateHost(server, startup, type, _nodeId);
- if (resource != null) {
- server.setResource(resource.getClass().getName());
- }
- if (id == null) {
- /*
- * // ignore integrity check for agent-simulator if(!"0.0.0.0".equals(startup.getPrivateIpAddress()) &&
- * !"0.0.0.0".equals(startup.getStorageIpAddress())) { if (_hostDao.findByPrivateIpAddressInDataCenter
- * (server.getDataCenterId(), startup.getPrivateIpAddress()) != null) { throw newIllegalArgumentException(
- * "The private ip address is already in used: " + startup.getPrivateIpAddress()); }
- *
- * if (_hostDao.findByPrivateIpAddressInDataCenter(server.getDataCenterId (), startup.getStorageIpAddress()) !=
- * null) { throw new IllegalArgumentException ("The private ip address is already in used: " +
- * startup.getStorageIpAddress()); } }
- */
-
- if (startup instanceof StartupProxyCommand) {
- server.setProxyPort(((StartupProxyCommand) startup).getProxyPort());
- }
-
- server = _hostDao.persist(server);
- id = server.getId();
-
- s_logger.info("New " + server.getType().toString() + " host connected w/ guid " + startup.getGuid() + " and id is " + id);
- } else {
- if (!_hostDao.connect(server, _nodeId)) {
- throw new CloudRuntimeException("Agent cannot connect because the current state is " + server.getStatus().toString());
- }
- s_logger.info("Old " + server.getType().toString() + " host reconnected w/ id =" + id);
- }
- createCapacityEntry(startup, server);
-
- return server;
- }
-
- public HostVO createHost(final StartupCommand[] startup, ServerResource resource, Map details, boolean directFirst, List hostTags, String allocationState)
- throws IllegalArgumentException {
- StartupCommand firstCmd = startup[0];
- HostVO result = createHost(firstCmd, resource, details, directFirst, hostTags, allocationState);
- if (result == null) {
- return null;
- }
- return result;
- }
-
-public AgentAttache handleConnect(final Link link,
- final StartupCommand[] startup) throws IllegalArgumentException,
- ConnectionException {
- HostVO server = null;
- boolean handled = notifyCreatorsOfConnection(startup);
- if (!handled) {
- server = createHost(startup, null, null, false, null, null);
- } else {
- server = _hostDao.findByGuid(startup[0].getGuid());
- }
-
- if (server == null) {
- return null;
- }
- long id = server.getId();
-
- AgentAttache attache = createAttache(id, server, link);
-
- attache = notifyMonitorsOfConnection(attache, startup);
-
- return attache;
- }
-
- protected AgentAttache createAttache(long id, HostVO server, Link link) {
- s_logger.debug("create ConnectedAgentAttache for " + id);
- final AgentAttache attache = new ConnectedAgentAttache(this, id, link, server.getStatus() == Status.Maintenance || server.getStatus() == Status.ErrorInMaintenance
- || server.getStatus() == Status.PrepareForMaintenance);
- link.attach(attache);
- AgentAttache old = null;
- synchronized (_agents) {
- old = _agents.get(id);
- _agents.put(id, attache);
- }
- if (old != null) {
- old.disconnect(Status.Removed);
- }
- return attache;
- }
-
- protected AgentAttache createAttache(long id, HostVO server, ServerResource resource) {
- if (resource instanceof DummySecondaryStorageResource || resource instanceof KvmDummyResourceBase) {
- return new DummyAttache(this, id, false);
- }
- s_logger.debug("create DirectAgentAttache for " + id);
- final DirectAgentAttache attache = new DirectAgentAttache(this, id, resource, server.getStatus() == Status.Maintenance || server.getStatus() == Status.ErrorInMaintenance
- || server.getStatus() == Status.PrepareForMaintenance, this);
- AgentAttache old = null;
- synchronized (_agents) {
- old = _agents.get(id);
- _agents.put(id, attache);
- }
- if (old != null) {
- old.disconnect(Status.Removed);
- }
- return attache;
- }
-
- @Override
- public boolean maintenanceFailed(long hostId) {
- HostVO host = _hostDao.findById(hostId);
- if (host == null) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cant not find host " + hostId);
- }
- return false;
- } else {
- return _hostDao.updateStatus(host, Event.UnableToMigrate, _nodeId);
- }
- }
-
- @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");
-
- String dataCenter = startup.getDataCenter();
- String pod = startup.getPod();
- String cluster = startup.getCluster();
-
- if (pod != null && dataCenter != null && pod.equalsIgnoreCase("default") && dataCenter.equalsIgnoreCase("default")) {
- List pods = _podDao.listAllIncludingRemoved();
- for (HostPodVO hpv : pods) {
- if (checkCIDR(type, hpv, startup.getPrivateIpAddress(), startup.getPrivateNetmask())) {
- pod = hpv.getName();
- dataCenter = _dcDao.findById(hpv.getDataCenterId()).getName();
- break;
- }
- }
- }
- long dcId = -1;
- DataCenterVO dc = _dcDao.findByName(dataCenter);
- if (dc == null) {
- try {
- dcId = Long.parseLong(dataCenter);
- dc = _dcDao.findById(dcId);
- } catch (final NumberFormatException e) {
- }
- }
- if (dc == null) {
- throw new IllegalArgumentException("Host " + startup.getPrivateIpAddress() + " sent incorrect data center: " + dataCenter);
- }
- dcId = dc.getId();
-
- HostPodVO p = _podDao.findByName(pod, dcId);
- if (p == null) {
- try {
- final long podId = Long.parseLong(pod);
- p = _podDao.findById(podId);
- } catch (final NumberFormatException e) {
- }
- }
- Long podId = null;
- if (p == null) {
- if (type != Host.Type.SecondaryStorage && type != Host.Type.ExternalFirewall && type != Host.Type.ExternalLoadBalancer) {
-
- /*
- * s_logger.info("Unable to find the pod so we are creating one." ); p = createPod(pod, dcId,
- * startup.getPrivateIpAddress(), NetUtils.getCidrSize(startup.getPrivateNetmask())); podId = p.getId();
- */
- s_logger.error("Host " + startup.getPrivateIpAddress() + " sent incorrect pod: " + pod + " in " + dataCenter);
- throw new IllegalArgumentException("Host " + startup.getPrivateIpAddress() + " sent incorrect pod: " + pod + " in " + dataCenter);
- }
- } else {
- podId = p.getId();
- }
-
- Long clusterId = null;
- if (cluster != null) {
- try {
- clusterId = Long.valueOf(cluster);
- } catch (NumberFormatException e) {
- ClusterVO c = _clusterDao.findBy(cluster, podId);
- if (c == null) {
- c = new ClusterVO(dcId, podId, cluster);
- c = _clusterDao.persist(c);
- }
- clusterId = c.getId();
- }
- }
-
- if (type == Host.Type.Routing) {
- StartupRoutingCommand scc = (StartupRoutingCommand) startup;
-
- HypervisorType hypervisorType = scc.getHypervisorType();
- boolean doCidrCheck = true;
-
- ClusterVO clusterVO = _clusterDao.findById(clusterId);
- if (clusterVO.getHypervisorType() != scc.getHypervisorType()) {
- throw new IllegalArgumentException("Can't add host whose hypervisor type is: " + scc.getHypervisorType() + " into cluster: " + clusterId + " whose hypervisor type is: "
- + clusterVO.getHypervisorType());
- }
-
- /*
- * KVM:Enforcement that all the hosts in the cluster have the same os type, for migration
- */
- if (scc.getHypervisorType() == HypervisorType.KVM) {
- List hostsInCluster = _hostDao.listByCluster(clusterId);
- if (!hostsInCluster.isEmpty()) {
- HostVO oneHost = hostsInCluster.get(0);
- _hostDao.loadDetails(oneHost);
- String hostOsInCluster = oneHost.getDetail("Host.OS");
- String hostOs = scc.getHostDetails().get("Host.OS");
- if (!hostOsInCluster.equalsIgnoreCase(hostOs)) {
- throw new IllegalArgumentException("Can't add host: " + startup.getPrivateIpAddress() + " with hostOS: " + hostOs + " into a cluster," + "in which there are "
- + hostOsInCluster + " hosts added");
- }
- }
- }
-
- // If this command is from the agent simulator, don't do the CIDR
- // check
- if (scc.getAgentTag() != null && startup.getAgentTag().equalsIgnoreCase("vmops-simulator")) {
- doCidrCheck = false;
- }
-
- // If this command is from a KVM agent, or from an agent that has a
- // null hypervisor type, don't do the CIDR check
- if (hypervisorType == null || hypervisorType == HypervisorType.KVM || hypervisorType == HypervisorType.VMware || hypervisorType == HypervisorType.BareMetal
- || hypervisorType == HypervisorType.Simulator) {
- doCidrCheck = false;
- }
-
- if (doCidrCheck) {
- s_logger.info("Host: " + host.getName() + " connected with hypervisor type: " + hypervisorType + ". Checking CIDR...");
- } else {
- s_logger.info("Host: " + host.getName() + " connected with hypervisor type: " + hypervisorType + ". Skipping CIDR check...");
- }
-
- if (doCidrCheck) {
- checkCIDR(type, p, dc, scc.getPrivateIpAddress(), scc.getPrivateNetmask());
- }
-
- // Check if the private/public IPs of the server are already in the
- // private/public IP address tables
- checkIPConflicts(type, p, dc, scc.getPrivateIpAddress(), scc.getPublicIpAddress(), scc.getPublicIpAddress(), scc.getPublicNetmask());
- }
-
- host.setDataCenterId(dc.getId());
- host.setPodId(podId);
- host.setClusterId(clusterId);
- host.setPrivateIpAddress(startup.getPrivateIpAddress());
- host.setPrivateNetmask(startup.getPrivateNetmask());
- host.setPrivateMacAddress(startup.getPrivateMacAddress());
- host.setPublicIpAddress(startup.getPublicIpAddress());
- host.setPublicMacAddress(startup.getPublicMacAddress());
- host.setPublicNetmask(startup.getPublicNetmask());
- host.setStorageIpAddress(startup.getStorageIpAddress());
- host.setStorageMacAddress(startup.getStorageMacAddress());
- host.setStorageNetmask(startup.getStorageNetmask());
- host.setVersion(startup.getVersion());
- host.setName(startup.getName());
- host.setType(type);
- host.setManagementServerId(msId);
- host.setStorageUrl(startup.getIqn());
- host.setLastPinged(System.currentTimeMillis() >> 10);
- if (startup instanceof StartupRoutingCommand) {
- final StartupRoutingCommand scc = (StartupRoutingCommand) startup;
- host.setCaps(scc.getCapabilities());
- host.setCpus(scc.getCpus());
- host.setTotalMemory(scc.getMemory());
- host.setSpeed(scc.getSpeed());
- HypervisorType hyType = scc.getHypervisorType();
- host.setHypervisorType(hyType);
-
- } else if (startup instanceof StartupStorageCommand) {
- final StartupStorageCommand ssc = (StartupStorageCommand) startup;
- host.setParent(ssc.getParent());
- host.setTotalSize(ssc.getTotalSize());
- host.setHypervisorType(HypervisorType.None);
- if (ssc.getNfsShare() != null) {
- host.setStorageUrl(ssc.getNfsShare());
- }
- }
- if (startup.getStorageIpAddressDeux() != null) {
- host.setStorageIpAddressDeux(startup.getStorageIpAddressDeux());
- host.setStorageMacAddressDeux(startup.getStorageMacAddressDeux());
- host.setStorageNetmaskDeux(startup.getStorageNetmaskDeux());
- }
-
- }
-
- @Override
- public Host getHost(long hostId) {
- return _hostDao.findById(hostId);
- }
-
- // create capacity entries if none exist for this server
- private void createCapacityEntry(final StartupCommand startup, HostVO server) {
- SearchCriteria capacitySC = _capacityDao.createSearchCriteria();
- capacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
- capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
- capacitySC.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
- List capacities = _capacityDao.search(capacitySC, null);
-
- // remove old entries, we'll recalculate them anyway
- if (startup instanceof StartupStorageCommand) {
- if ((capacities != null) && !capacities.isEmpty()) {
- for (CapacityVO capacity : capacities) {
- _capacityDao.remove(capacity.getId());
- }
- }
- }
-
- if (startup instanceof StartupStorageCommand) {
- StartupStorageCommand ssCmd = (StartupStorageCommand) startup;
- if (ssCmd.getResourceType() == Storage.StorageResourceType.STORAGE_HOST) {
- CapacityVO capacity = new CapacityVO(server.getId(), server.getDataCenterId(), server.getPodId(), server.getClusterId(), 0L, (long) (server.getTotalSize() * _overProvisioningFactor),
- CapacityVO.CAPACITY_TYPE_STORAGE_ALLOCATED);
- _capacityDao.persist(capacity);
- }
- } else if (startup instanceof StartupRoutingCommand) {
- SearchCriteria capacityCPU = _capacityDao.createSearchCriteria();
- capacityCPU.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
- capacityCPU.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
- capacityCPU.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
- capacityCPU.addAnd("capacityType", SearchCriteria.Op.EQ, CapacityVO.CAPACITY_TYPE_CPU);
- List capacityVOCpus = _capacityDao.search(capacityCPU, null);
-
- if (capacityVOCpus != null && !capacityVOCpus.isEmpty()) {
- CapacityVO CapacityVOCpu = capacityVOCpus.get(0);
- long newTotalCpu = (server.getCpus().longValue() * server.getSpeed().longValue());
- if ((CapacityVOCpu.getTotalCapacity() <= newTotalCpu) || ((CapacityVOCpu.getUsedCapacity() + CapacityVOCpu.getReservedCapacity()) <= newTotalCpu)) {
- CapacityVOCpu.setTotalCapacity(newTotalCpu);
- } else if ((CapacityVOCpu.getUsedCapacity() + CapacityVOCpu.getReservedCapacity() > newTotalCpu) && (CapacityVOCpu.getUsedCapacity() < newTotalCpu)) {
- CapacityVOCpu.setReservedCapacity(0);
- CapacityVOCpu.setTotalCapacity(newTotalCpu);
- } else {
- s_logger.debug("What? new cpu is :" + newTotalCpu + ", old one is " + CapacityVOCpu.getUsedCapacity() + "," + CapacityVOCpu.getReservedCapacity() + ","
- + CapacityVOCpu.getTotalCapacity());
- }
- _capacityDao.update(CapacityVOCpu.getId(), CapacityVOCpu);
- } else {
- CapacityVO capacity = new CapacityVO(server.getId(), server.getDataCenterId(), server.getPodId(), server.getClusterId(), 0L, (server.getCpus().longValue() * server.getSpeed()
- .longValue()), CapacityVO.CAPACITY_TYPE_CPU);
- _capacityDao.persist(capacity);
- }
-
- SearchCriteria capacityMem = _capacityDao.createSearchCriteria();
- capacityMem.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
- capacityMem.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
- capacityMem.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
- capacityMem.addAnd("capacityType", SearchCriteria.Op.EQ, CapacityVO.CAPACITY_TYPE_MEMORY);
- List capacityVOMems = _capacityDao.search(capacityMem, null);
-
- if (capacityVOMems != null && !capacityVOMems.isEmpty()) {
- CapacityVO CapacityVOMem = capacityVOMems.get(0);
- long newTotalMem = server.getTotalMemory();
- if (CapacityVOMem.getTotalCapacity() <= newTotalMem || (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() <= newTotalMem)) {
- CapacityVOMem.setTotalCapacity(newTotalMem);
- } else if (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() > newTotalMem && CapacityVOMem.getUsedCapacity() < newTotalMem) {
- CapacityVOMem.setReservedCapacity(0);
- CapacityVOMem.setTotalCapacity(newTotalMem);
- } else {
- s_logger.debug("What? new cpu is :" + newTotalMem + ", old one is " + CapacityVOMem.getUsedCapacity() + "," + CapacityVOMem.getReservedCapacity() + ","
- + CapacityVOMem.getTotalCapacity());
- }
- _capacityDao.update(CapacityVOMem.getId(), CapacityVOMem);
- } else {
- CapacityVO capacity = new CapacityVO(server.getId(), server.getDataCenterId(), server.getPodId(), server.getClusterId(), 0L, server.getTotalMemory(), CapacityVO.CAPACITY_TYPE_MEMORY);
- _capacityDao.persist(capacity);
- }
- }
-
- }
-
- // protected void upgradeAgent(final Link link, final byte[] request, final
- // String reason) {
- //
- // if (reason == UnsupportedVersionException.IncompatibleVersion) {
- // final UpgradeResponse response = new UpgradeResponse(request,
- // _upgradeMgr.getAgentUrl());
- // try {
- // s_logger.info("Asking for the agent to update due to incompatible version: "
- // + response.toString());
- // link.send(response.toBytes());
- // } catch (final ClosedChannelException e) {
- // s_logger.warn("Unable to send response due to connection closed: " +
- // response.toString());
- // }
- // return;
- // }
- //
- // assert (reason == UnsupportedVersionException.UnknownVersion) :
- // "Unknown reason: " + reason;
- // final UpgradeResponse response = new UpgradeResponse(request,
- // _upgradeMgr.getAgentUrl());
- // try {
- // s_logger.info("Asking for the agent to update due to unknown version: " +
- // response.toString());
- // link.send(response.toBytes());
- // } catch (final ClosedChannelException e) {
- // s_logger.warn("Unable to send response due to connection closed: " +
- // response.toString());
- // }
- // }
-
- protected class SimulateStartTask implements Runnable {
- ServerResource resource;
- Map details;
- long id;
- ActionDelegate actionDelegate;
-
- public SimulateStartTask(long id, ServerResource resource, Map details, ActionDelegate actionDelegate) {
- this.id = id;
- this.resource = resource;
- this.details = details;
- this.actionDelegate = actionDelegate;
- }
-
- @Override
- public void run() {
- AgentAttache at = null;
- try {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Simulating start for resource " + resource.getName() + " id " + id);
- }
- simulateStart(resource, details, false, null, null);
- } catch (Exception e) {
- s_logger.warn("Unable to simulate start on resource " + id + " name " + resource.getName(), e);
- } finally {
- if (actionDelegate != null) {
- actionDelegate.action(new Long(id));
- }
- if (at == null) {
- HostVO host = _hostDao.findById(id);
- host.setManagementServerId(null);
- _hostDao.update(id, host);
- }
- StackMaid.current().exitCleanup();
- }
- }
- }
-
- public class AgentHandler extends Task {
- public AgentHandler(Task.Type type, Link link, byte[] data) {
- super(type, link, data);
- }
-
- protected void processRequest(final Link link, final Request request) {
- AgentAttache attache = (AgentAttache) link.attachment();
- final Command[] cmds = request.getCommands();
- Command cmd = cmds[0];
- boolean logD = true;
-
- Response response = null;
- if (attache == null) {
- s_logger.debug("Processing sequence " + request.getSequence() + ": Processing " + request.toString());
- if (!(cmd instanceof StartupCommand)) {
- s_logger.warn("Throwing away a request because it came through as the first command on a connect: " + request.toString());
- return;
- }
- StartupCommand startup = (StartupCommand) cmd;
- // if ((_upgradeMgr.registerForUpgrade(-1, startup.getVersion())
- // == UpgradeManager.State.RequiresUpdate) &&
- // (_upgradeMgr.getAgentUrl() != null)) {
- // final UpgradeCommand upgrade = new
- // UpgradeCommand(_upgradeMgr.getAgentUrl());
- // final Request req = new Request(1, -1, -1, new Command[] {
- // upgrade }, true, true);
- // s_logger.info("Agent requires upgrade: " + req.toString());
- // try {
- // link.send(req.toBytes());
- // } catch (ClosedChannelException e) {
- // s_logger.warn("Unable to tell agent it should update.");
- // }
- // return;
- // }
- try {
- StartupCommand[] startups = new StartupCommand[cmds.length];
- for (int i = 0; i < cmds.length; i++) {
- startups[i] = (StartupCommand) cmds[i];
- }
- attache = handleConnect(link, startups);
- } catch (final IllegalArgumentException e) {
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, 0, new Long(0), "Agent from " + startup.getPrivateIpAddress() + " is unable to connect due to " + e.getMessage(), "Agent from "
- + startup.getPrivateIpAddress() + " is unable to connect with " + request.toString() + " because of " + e.getMessage());
- s_logger.warn("Unable to create attache for agent: " + request.toString(), e);
- response = new Response(request, new StartupAnswer((StartupCommand) cmd, e.getMessage()), _nodeId, -1);
- } catch (ConnectionException e) {
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, 0, new Long(0), "Agent from " + startup.getPrivateIpAddress() + " is unable to connect due to " + e.getMessage(), "Agent from "
- + startup.getPrivateIpAddress() + " is unable to connect with " + request.toString() + " because of " + e.getMessage());
- s_logger.warn("Unable to create attache for agent: " + request.toString(), e);
- response = new Response(request, new StartupAnswer((StartupCommand) cmd, e.getMessage()), _nodeId, -1);
- } catch (final CloudRuntimeException e) {
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, 0, new Long(0), "Agent from " + startup.getPrivateIpAddress() + " is unable to connect due to " + e.getMessage(), "Agent from "
- + startup.getPrivateIpAddress() + " is unable to connect with " + request.toString() + " because of " + e.getMessage());
- s_logger.warn("Unable to create attache for agent: " + request.toString(), e);
- }
- if (attache == null) {
- if (response == null) {
- s_logger.warn("Unable to create attache for agent: " + request.toString());
- response = new Response(request, new StartupAnswer((StartupCommand) request.getCommand(), "Unable to register this agent"), _nodeId, -1);
- }
- try {
- link.send(response.toBytes(), true);
- } catch (final ClosedChannelException e) {
- s_logger.warn("Response was not sent: " + response.toString());
- }
- return;
- }
- }
-
- final long hostId = attache.getId();
-
- if (s_logger.isDebugEnabled()) {
- if (cmd instanceof PingRoutingCommand) {
- final PingRoutingCommand ping = (PingRoutingCommand) cmd;
- if (ping.getNewStates().size() > 0) {
- s_logger.debug("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request.toString());
- } else {
- logD = false;
- s_logger.debug("Ping from " + hostId);
- s_logger.trace("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request.toString());
- }
- } else if (cmd instanceof PingCommand) {
- logD = false;
- s_logger.debug("Ping from " + hostId);
- s_logger.trace("SeqA " + attache.getId() + "-" + request.getSequence() + ": Processing " + request.toString());
- } else {
- s_logger.debug("SeqA " + attache.getId() + "-" + request.getSequence() + ": Processing " + request.toString());
- }
- }
-
- final Answer[] answers = new Answer[cmds.length];
- for (int i = 0; i < cmds.length; i++) {
- cmd = cmds[i];
- Answer answer = null;
- try {
- if (cmd instanceof StartupRoutingCommand) {
- final StartupRoutingCommand startup = (StartupRoutingCommand) cmd;
- answer = new StartupAnswer(startup, attache.getId(), getPingInterval());
- } else if (cmd instanceof StartupProxyCommand) {
- final StartupProxyCommand startup = (StartupProxyCommand) cmd;
- answer = new StartupAnswer(startup, attache.getId(), getPingInterval());
- } else if (cmd instanceof StartupStorageCommand) {
- final StartupStorageCommand startup = (StartupStorageCommand) cmd;
- answer = new StartupAnswer(startup, attache.getId(), getPingInterval());
- } else if (cmd instanceof ShutdownCommand) {
- final ShutdownCommand shutdown = (ShutdownCommand) cmd;
- final String reason = shutdown.getReason();
- s_logger.info("Host " + attache.getId() + " has informed us that it is shutting down with reason " + reason + " and detail " + shutdown.getDetail());
- if (reason.equals(ShutdownCommand.Update)) {
- disconnect(attache, Event.UpdateNeeded, false);
- } else if (reason.equals(ShutdownCommand.Requested)) {
- disconnect(attache, Event.ShutdownRequested, false);
- }
- return;
- } else if (cmd instanceof AgentControlCommand) {
- answer = handleControlCommand(attache, (AgentControlCommand) cmd);
- } else {
- handleCommands(attache, request.getSequence(), new Command[] { cmd });
- if (cmd instanceof PingCommand) {
- long cmdHostId = ((PingCommand) cmd).getHostId();
-
- // if the router is sending a ping, verify the
- // gateway was pingable
- if (cmd instanceof PingRoutingCommand) {
- boolean gatewayAccessible = ((PingRoutingCommand) cmd).isGatewayAccessible();
- HostVO host = _hostDao.findById(Long.valueOf(cmdHostId));
- if (!gatewayAccessible) {
- // alert that host lost connection to
- // gateway (cannot ping the default route)
- DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
- HostPodVO podVO = _podDao.findById(host.getPodId());
- String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
-
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId(), "Host lost connection to gateway, " + hostDesc, "Host [" + hostDesc
- + "] lost connection to gateway (default route) and is possibly having network connection issues.");
- } else {
- _alertMgr.clearAlert(AlertManager.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId());
- }
- }
- answer = new PingAnswer((PingCommand) cmd);
- } else if (cmd instanceof ReadyAnswer) {
- HostVO host = _hostDao.findById(attache.getId());
- if (host == null) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cant not find host " + attache.getId());
- }
- }
- answer = new Answer(cmd);
- } else {
- answer = new Answer(cmd);
- }
- }
- } catch (final Throwable th) {
- s_logger.warn("Caught: ", th);
- answer = new Answer(cmd, false, th.getMessage());
- }
- answers[i] = answer;
- }
-
-=======
-
- @Override
- public Task create(Task.Type type, Link link, byte[] data) {
- return new AgentHandler(type, link, data);
- }
-
- @Override
- public int registerForInitialConnects(final StartupCommandProcessor creator,boolean priority) {
- synchronized (_hostMonitors) {
- _monitorId++;
-
- if (priority) {
- _creationMonitors.add(0, new Pair(
- _monitorId, creator));
- } else {
- _creationMonitors.add(0, new Pair(
- _monitorId, creator));
- }
- }
-
- return _monitorId;
- }
-
- @Override
- public int registerForHostEvents(final Listener listener, boolean connections, boolean commands, boolean priority) {
- synchronized (_hostMonitors) {
- _monitorId++;
- if (connections) {
- if (priority) {
- _hostMonitors.add(0, new Pair(_monitorId, listener));
- } else {
- _hostMonitors.add(new Pair(_monitorId, listener));
- }
- }
- if (commands) {
- if (priority) {
- _cmdMonitors.add(0, new Pair(_monitorId, listener));
- } else {
- _cmdMonitors.add(new Pair(_monitorId, listener));
- }
- }
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Registering listener " + listener.getClass().getSimpleName() + " with id " + _monitorId);
- }
- return _monitorId;
- }
- }
-
- @Override
- public void unregisterForHostEvents(final int id) {
- s_logger.debug("Deregistering " + id);
- _hostMonitors.remove(id);
- }
-
- private AgentControlAnswer handleControlCommand(AgentAttache attache, final AgentControlCommand cmd) {
- AgentControlAnswer answer = null;
-
- for (Pair listener : _cmdMonitors) {
- answer = listener.second().processControlCommand(attache.getId(), cmd);
-
- if (answer != null) {
- return answer;
- }
- }
-
- s_logger.warn("No handling of agent control command: " + cmd.toString() + " sent from " + attache.getId());
- return new AgentControlAnswer(cmd);
- }
-
- public void handleCommands(AgentAttache attache, final long sequence, final Command[] cmds) {
- for (Pair listener : _cmdMonitors) {
- boolean processed = listener.second().processCommands(attache.getId(), sequence, cmds);
- if (s_logger.isTraceEnabled()) {
- s_logger.trace("SeqA " + attache.getId() + "-" + sequence + ": " + (processed ? "processed" : "not processed") + " by " + listener.getClass());
- }
- }
- }
-
- @Override
- public void notifyAnswersToMonitors(long agentId, long seq, Answer[] answers) {
- for (Pair listener : _cmdMonitors) {
- listener.second().processAnswers(agentId, seq, answers);
- }
- }
-
- public AgentAttache findAttache(long hostId) {
- return _agents.get(hostId);
- }
-
- @Override
- public Set getConnectedHosts() {
- // make the returning set be safe for concurrent iteration
- final HashSet result = new HashSet();
-
- synchronized (_agents) {
- final Set s = _agents.keySet();
- for (final Long id : s) {
- result.add(id);
- }
- }
- return result;
- }
-
- @Override
- public Host findHost(final Host.Type type, final DataCenterVO dc, final HostPodVO pod, final StoragePoolVO sp, final ServiceOfferingVO offering, final VMTemplateVO template, VMInstanceVO vm,
- Host currentHost, final Set avoid) {
- VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, null, null);
- DeployDestination dest = null;
- DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), pod.getId(), sp.getClusterId(), null, null);
- ExcludeList avoids = new ExcludeList();
- for (Host h : avoid) {
- avoids.addHost(h.getId());
- }
-
- for (DeploymentPlanner planner : _planners) {
- try {
- dest = planner.plan(vmProfile, plan, avoids);
- if (dest != null) {
- return dest.getHost();
- }
- } catch (InsufficientServerCapacityException e) {
-
- }
- }
-
- s_logger.warn("findHost() could not find a non-null host.");
- return null;
- }
-
- @Override
- public List listByDataCenter(long dcId) {
- List pods = _podDao.listByDataCenterId(dcId);
- ArrayList pcs = new ArrayList();
- for (HostPodVO pod : pods) {
- List clusters = _clusterDao.listByPodId(pod.getId());
- if (clusters.size() == 0) {
- pcs.add(new PodCluster(pod, null));
- } else {
- for (ClusterVO cluster : clusters) {
- pcs.add(new PodCluster(pod, cluster));
- }
- }
- }
- return pcs;
- }
-
- @Override
- public List listByPod(long podId) {
- ArrayList pcs = new ArrayList();
- HostPodVO pod = _podDao.findById(podId);
- if (pod == null) {
- return pcs;
- }
- List clusters = _clusterDao.listByPodId(pod.getId());
- if (clusters.size() == 0) {
- pcs.add(new PodCluster(pod, null));
- } else {
- for (ClusterVO cluster : clusters) {
- pcs.add(new PodCluster(pod, cluster));
- }
- }
- return pcs;
- }
-
- protected AgentAttache handleDirectConnect(ServerResource resource, StartupCommand[] startup, Map details, boolean old, List hostTags, String allocationState)
- throws ConnectionException {
- if (startup == null) {
- return null;
- }
- HostVO server = createHost(startup, resource, details, old, hostTags, allocationState);
- if (server == null) {
- return null;
- }
-
- long id = server.getId();
-
- AgentAttache attache = createAttache(id, server, resource);
-
- attache = notifyMonitorsOfConnection(attache, startup);
-
- return attache;
- }
-
- @Override
- public List extends Cluster> 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 extends ServerResource, 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 extends ServerResource, Map> 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(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 extends Host> 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 extends Host> 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 extends ServerResource, 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 extends ServerResource, Map> 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(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) {
- List clusters = _clusterDao.listByDcHyType(dcId, type.toString());
- int retry = 0;
- for (ClusterVO cluster : clusters) {
- List hosts = _hostDao.listBy(Host.Type.Routing, cluster.getId(), null, dcId);
- for (HostVO host : hosts) {
- retry++;
- if (retry > _retry) {
- return null;
- }
- Answer answer = null;
- try {
- answer = easySend(host.getId(), cmd);
- } catch (Exception e) {
- }
- if (answer != null) {
- return answer;
- }
- }
- }
- return null;
- }
-
- @Override
- @DB
- public boolean deleteHost(long hostId, boolean isForced, User caller) {
-
- // Check if the host exists
- HostVO host = _hostDao.findById(hostId);
- if (host == null) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Host: " + hostId + " does not even exist. Delete call is ignored.");
- }
- return true;
- }
-
- if (host.getType() == Type.SecondaryStorage) {
- return deleteSecondaryStorageHost(host);
- }
-
- AgentAttache attache = findAttache(hostId);
- // Get storage pool host mappings here because they can be removed as a part of handleDisconnect later
- List pools = _storagePoolHostDao.listByHostId(hostId);
-
- try {
-
- if (host.getType() == Type.Routing) {
- // Check if host is ready for removal
- Status currentState = host.getStatus();
- Status nextState = currentState.getNextStatus(Status.Event.Remove);
- if (nextState == null) {
- if (!(attache instanceof DirectAgentAttache)) {
- return false;
- }
- s_logger.debug("There is no transition from state " + currentState.toString() + " to state " + Status.Event.Remove.toString());
- return false;
- }
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Deleting Host: " + hostId + " Guid:" + host.getGuid());
- }
-
- // Check if there are vms running/starting/stopping on this host
- List vms = _vmDao.listByHostId(hostId);
-
- 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=" + hostId);
- 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=" + hostId;
- s_logger.warn(errorMsg);
- throw new CloudRuntimeException(errorMsg);
- }
- } 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=" + hostId);
- _haMgr.scheduleRestart(vm, false);
- }
- }
- } else {
- throw new CloudRuntimeException("Unable to delete the host as there are vms in " + vms.get(0).getState() + " state using this host and isForced=false specified");
- }
- }
-
- if (host.getHypervisorType() == HypervisorType.XenServer) {
- if (host.getClusterId() != null) {
- List hosts = _hostDao.listBy(Type.Routing, host.getClusterId(), host.getPodId(), host.getDataCenterId());
- hosts.add(host);
- boolean success = true;
- for (HostVO thost : hosts) {
- long thostId = thost.getId();
- PoolEjectCommand eject = new PoolEjectCommand(host.getGuid());
- Answer answer = easySend(thostId, eject);
- if (answer != null && answer.getResult()) {
- s_logger.debug("Eject Host: " + hostId + " from " + thostId + " Succeed");
- success = true;
- break;
- } else {
- success = false;
- s_logger.warn("Eject Host: " + hostId + " from " + thostId + " failed due to " + (answer != null ? answer.getDetails() : "no answer"));
- }
- }
- if (!success) {
- String msg = "Unable to eject host " + host.getGuid() + " due to there is no host up in this cluster, please execute xe pool-eject host-uuid=" + host.getGuid()
- + "in this host " + host.getPrivateIpAddress();
- s_logger.warn(msg);
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Unable to eject host " + host.getGuid(), msg);
- }
- }
- } else if (host.getHypervisorType() == HypervisorType.KVM) {
- try {
- ShutdownCommand cmd = new ShutdownCommand(ShutdownCommand.DeleteHost, null);
- send(host.getId(), cmd);
- } catch (AgentUnavailableException e) {
- s_logger.warn("Sending ShutdownCommand failed: ", e);
- } catch (OperationTimedoutException e) {
- s_logger.warn("Sending ShutdownCommand failed: ", e);
- }
- }
- }
-
- Transaction txn = Transaction.currentTxn();
- txn.start();
-
- _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null);
- if (attache != null) {
- handleDisconnect(attache, Status.Event.Remove, false);
- }
- // delete host details
- _hostDetailsDao.deleteDetails(hostId);
-
- host.setGuid(null);
- Long clusterId = host.getClusterId();
- host.setClusterId(null);
- _hostDao.update(host.getId(), host);
-
- _hostDao.remove(hostId);
- if (clusterId != null) {
- List hosts = _hostDao.listByCluster(clusterId);
- if (hosts.size() == 0) {
- ClusterVO cluster = _clusterDao.findById(clusterId);
- cluster.setGuid(null);
- _clusterDao.update(clusterId, cluster);
- }
- }
-
- // Delete the associated entries in host ref table
- _storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
-
- // For pool ids you got, delete local storage host entries in pool table where
- for (StoragePoolHostVO pool : pools) {
- Long poolId = pool.getPoolId();
- StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
- if (storagePool.isLocal()) {
- storagePool.setUuid(null);
- storagePool.setClusterId(null);
- _storagePoolDao.update(poolId, storagePool);
- _storagePoolDao.remove(poolId);
- s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId);
- }
- }
-
- // delete the op_host_capacity entry
- Object[] capacityTypes = { Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY };
- SearchCriteria hostCapacitySC = _capacityDao.createSearchCriteria();
- hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
- hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes);
- _capacityDao.remove(hostCapacitySC);
- txn.commit();
- return true;
- } catch (Throwable t) {
- s_logger.error("Unable to delete host: " + hostId, t);
- return false;
- }
- }
-
- @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);
- }
-
- @DB
- protected boolean deleteSecondaryStorageHost(HostVO secStorageHost) {
- long zoneId = secStorageHost.getDataCenterId();
- long hostId = secStorageHost.getId();
- Transaction txn = Transaction.currentTxn();
- try {
-
- List allVmsInZone = _vmDao.listByZoneId(zoneId);
- if (!allVmsInZone.isEmpty()) {
- s_logger.warn("Cannot delete secondary storage host when there are " + allVmsInZone.size() + " vms in zone " + zoneId);
- return false;
- }
- txn.start();
-
- if (!_hostDao.updateStatus(secStorageHost, Event.MaintenanceRequested, _nodeId)) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Unable to take host " + hostId + " into maintenance mode. Delete call is ignored");
- }
- return false;
- }
- if (!_hostDao.updateStatus(secStorageHost, Event.PreparationComplete, _nodeId)) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Unable to take host " + hostId + " into maintenance mode. Delete call is ignored");
- }
- return false;
- }
-
- AgentAttache attache = findAttache(hostId);
- if (attache != null) {
- handleDisconnect(attache, Status.Event.Remove, false);
- }
- // now delete the host
- secStorageHost.setGuid(null);
- _hostDao.update(secStorageHost.getId(), secStorageHost);
- _hostDao.remove(secStorageHost.getId());
-
- // delete the templates associated with this host
- SearchCriteria templateHostSC = _vmTemplateHostDao.createSearchCriteria();
- templateHostSC.addAnd("hostId", SearchCriteria.Op.EQ, secStorageHost.getId());
- _vmTemplateHostDao.remove(templateHostSC);
-
- // delete the op_host_capacity entry
- SearchCriteria secStorageCapacitySC = _capacityDao.createSearchCriteria();
- secStorageCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, secStorageHost.getId());
- secStorageCapacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, Capacity.CAPACITY_TYPE_SECONDARY_STORAGE);
- _capacityDao.remove(secStorageCapacitySC);
-
- /* Disconnected agent needs special handling here */
- secStorageHost.setGuid(null);
-
- txn.commit();
- return true;
- } catch (Throwable t) {
- s_logger.error("Unable to delete sec storage host: " + secStorageHost.getId(), t);
- return false;
- }
- }
-
- @Override
- public boolean isVirtualMachineUpgradable(final UserVm vm, final ServiceOffering offering) {
- Enumeration en = _hostAllocators.enumeration();
- boolean isMachineUpgradable = true;
- while (isMachineUpgradable && en.hasMoreElements()) {
- final HostAllocator allocator = en.nextElement();
- isMachineUpgradable = allocator.isVirtualMachineUpgradable(vm, offering);
- }
-
- return isMachineUpgradable;
- }
-
- protected int getPingInterval() {
- return _pingInterval;
- }
-
- @Override
- public Answer send(Long hostId, Command cmd, int timeout) throws AgentUnavailableException, OperationTimedoutException {
- Commands cmds = new Commands(OnError.Revert);
- cmds.addCommand(cmd);
- send(hostId, cmds, timeout);
- Answer[] answers = cmds.getAnswers();
- if (answers != null && !(answers[0] instanceof UnsupportedAnswer)) {
- return answers[0];
- }
-
- if (answers != null && (answers[0] instanceof UnsupportedAnswer)) {
- s_logger.warn("Unsupported Command: " + answers[0].getDetails());
- return answers[0];
- }
-
- return null;
- }
-
- @DB
- protected boolean noDbTxn() {
- Transaction txn = Transaction.currentTxn();
- return !txn.dbTxnStarted();
- }
-
- @Override
- public Answer[] send(Long hostId, Commands commands, int timeout) throws AgentUnavailableException, OperationTimedoutException {
- assert hostId != null : "Who's not checking the agent id before sending? ... (finger wagging)";
- if (hostId == null) {
- throw new AgentUnavailableException(-1);
- }
-
- // assert noDbTxn() :
- // "I know, I know. Why are we so strict as to not allow txn across an agent call? ... Why are we so cruel ... Why are we such a dictator .... Too bad... Sorry...but NO AGENT COMMANDS WRAPPED WITHIN DB TRANSACTIONS!";
-
- Command[] cmds = commands.toCommands();
-
- assert cmds.length > 0 : "Ask yourself this about a hundred times. Why am I sending zero length commands?";
-
- if (cmds.length == 0) {
- commands.setAnswers(new Answer[0]);
- }
-
- final AgentAttache agent = getAttache(hostId);
- if (agent == null || agent.isClosed()) {
- throw new AgentUnavailableException("agent not logged into this management server", hostId);
- }
-
- long seq = _hostDao.getNextSequence(hostId);
- Request req = new Request(seq, hostId, _nodeId, cmds, commands.stopOnError(), true, commands.revertOnError());
- Answer[] answers = agent.send(req, timeout);
- notifyAnswersToMonitors(hostId, seq, answers);
- commands.setAnswers(answers);
- return answers;
- }
-
- protected Status investigate(AgentAttache agent) {
- Long hostId = agent.getId();
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("checking if agent (" + hostId + ") is alive");
- }
-
- try {
- long seq = _hostDao.getNextSequence(hostId);
- Request req = new Request(seq, hostId, _nodeId, new CheckHealthCommand(), true);
- Answer[] answers = agent.send(req, 50 * 1000);
- if (answers != null && answers[0] != null) {
- Status status = answers[0].getResult() ? Status.Up : Status.Down;
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("agent (" + hostId + ") responded to checkHeathCommand, reporting that agent is " + status);
- }
- return status;
- }
- } catch (AgentUnavailableException e) {
- s_logger.debug("Agent is unavailable so we move on.");
- } catch (OperationTimedoutException e) {
- s_logger.debug("Timed Out " + e.getMessage());
- }
-
- return _haMgr.investigate(hostId);
- }
-
- protected AgentAttache getAttache(final Long hostId) throws AgentUnavailableException {
- assert (hostId != null) : "Who didn't check their id value?";
- if (hostId == null) {
- return null;
- }
- AgentAttache agent = findAttache(hostId);
- if (agent == null) {
- s_logger.debug("Unable to find agent for " + hostId);
- throw new AgentUnavailableException("Unable to find agent ", hostId);
- }
-
- return agent;
- }
-
- @Override
- public long send(Long hostId, Commands commands, Listener listener) throws AgentUnavailableException {
- final AgentAttache agent = getAttache(hostId);
- if (agent.isClosed()) {
- return -1;
- }
-
- Command[] cmds = commands.toCommands();
-
- assert cmds.length > 0 : "Why are you sending zero length commands?";
- if (cmds.length == 0) {
- return -1;
- }
- long seq = _hostDao.getNextSequence(hostId);
- Request req = new Request(seq, hostId, _nodeId, cmds, commands.stopOnError(), true, commands.revertOnError());
- agent.send(req, listener);
- return seq;
- }
-
- @Override
- public long gatherStats(final Long hostId, final Command cmd, final Listener listener) {
- try {
- return send(hostId, new Commands(cmd), listener);
- } catch (final AgentUnavailableException e) {
- return -1;
- }
- }
-
- public void removeAgent(AgentAttache attache, Status nextState) {
- if (attache == null) {
- return;
- }
- long hostId = attache.getId();
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Remove Agent : " + hostId);
- }
- AgentAttache removed = null;
- boolean conflict = false;
- synchronized (_agents) {
- removed = _agents.remove(hostId);
- if (removed != null && removed != attache) {
- conflict = true;
- _agents.put(hostId, removed);
- removed = attache;
- }
- }
- if (conflict) {
- s_logger.debug("Agent for host " + hostId + " is created when it is being disconnected");
- }
- if (removed != null) {
- removed.disconnect(nextState);
- }
- }
-
- @Override
- public void disconnect(final long hostId, final Status.Event event, final boolean investigate) {
- AgentAttache attache = findAttache(hostId);
-
- if (attache != null) {
- disconnect(attache, event, investigate);
- } else {
- HostVO host = _hostDao.findById(hostId);
- if (host != null && host.getRemoved() == null) {
- if (event != null && event.equals(Event.Remove)) {
- host.setGuid(null);
- host.setClusterId(null);
- }
- _hostDao.updateStatus(host, event, _nodeId);
- }
- }
- }
-
- public void disconnect(AgentAttache attache, final Status.Event event, final boolean investigate) {
- _executor.submit(new DisconnectTask(attache, event, investigate));
- }
-
- protected boolean handleDisconnect(AgentAttache attache, Status.Event event, boolean investigate) {
- if (attache == null) {
- return true;
- }
-
- long hostId = attache.getId();
-
- s_logger.info("Host " + hostId + " is disconnecting with event " + event.toString());
-
- HostVO host = _hostDao.findById(hostId);
- if (host == null) {
- s_logger.warn("Can't find host with " + hostId);
- removeAgent(attache, Status.Removed);
- return true;
-
- }
- final Status currentState = host.getStatus();
- if (currentState == Status.Down || currentState == Status.Alert || currentState == Status.Removed || currentState == Status.PrepareForMaintenance) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Host " + hostId + " is already " + currentState.toString());
- }
- if (currentState != Status.PrepareForMaintenance) {
- removeAgent(attache, currentState);
- }
- return true;
- }
- Status nextState = currentState.getNextStatus(event);
- if (nextState == null) {
- if (!(attache instanceof DirectAgentAttache)) {
- return false;
- }
-
- s_logger.debug("There is no transition from state " + currentState.toString() + " and event " + event.toString());
- assert false : "How did we get here. Look at the FSM";
- return false;
- }
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("The next state is " + nextState.toString() + ", current state is " + currentState);
- }
-
- // Now we go and correctly diagnose what the actual situation is
- if (nextState == Status.Alert && investigate) {
- s_logger.info("Investigating why host " + hostId + " has disconnected with event " + event.toString());
-
- final Status determinedState = investigate(attache);
- s_logger.info("The state determined is " + (determinedState != null ? determinedState.toString() : "undeterminable"));
-
- if (determinedState == null || determinedState == Status.Down) {
- s_logger.error("Host is down: " + host.getId() + "-" + host.getName() + ". Starting HA on the VMs");
-
- event = Event.HostDown;
- } else if (determinedState == Status.Up) {
- // we effectively pinged from the server here.
- s_logger.info("Agent is determined to be up and running");
- _hostDao.updateStatus(host, Event.Ping, _nodeId);
- return false;
- } else if (determinedState == Status.Disconnected) {
- s_logger.warn("Agent is disconnected but the host is still up: " + host.getId() + "-" + host.getName());
- if (currentState == Status.Disconnected) {
- if (((System.currentTimeMillis() >> 10) - host.getLastPinged()) > _alertWait) {
- s_logger.warn("Host " + host.getId() + " has been disconnected pass the time it should be disconnected.");
- event = Event.WaitedTooLong;
- } else {
- s_logger.debug("Host has been determined to be disconnected but it hasn't passed the wait time yet.");
- return false;
- }
- } else if (currentState == Status.Updating) {
- if (((System.currentTimeMillis() >> 10) - host.getLastPinged()) > _updateWait) {
- s_logger.warn("Host " + host.getId() + " has been updating for too long");
-
- event = Event.WaitedTooLong;
- } else {
- s_logger.debug("Host has been determined to be disconnected but it hasn't passed the wait time yet.");
- return false;
- }
- } else if (currentState == Status.Up) {
- DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
- HostPodVO podVO = _podDao.findById(host.getPodId());
- String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
- if ((host.getType() != Host.Type.SecondaryStorage) && (host.getType() != Host.Type.ConsoleProxy)) {
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host disconnected, " + hostDesc, "If the agent for host [" + hostDesc
- + "] is not restarted within " + _alertWait + " seconds, HA will begin on the VMs");
- }
- event = Event.AgentDisconnected;
- }
- } else {
- // if we end up here we are in alert state, send an alert
- DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
- HostPodVO podVO = _podDao.findById(host.getPodId());
- String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host in ALERT state, " + hostDesc, "In availability zone " + host.getDataCenterId()
- + ", host is in alert state: " + host.getId() + "-" + host.getName());
- }
- }
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Deregistering link for " + hostId + " with state " + nextState);
- }
-
- _hostDao.disconnect(host, event, _nodeId);
-
- removeAgent(attache, nextState);
-
- host = _hostDao.findById(host.getId());
- if (host.getStatus() == Status.Alert || host.getStatus() == Status.Down) {
- _haMgr.scheduleRestartForVmsOnHost(host, investigate);
- }
-
- for (Pair monitor : _hostMonitors) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Sending Disconnect to listener: " + monitor.second().getClass().getName());
- }
- monitor.second().processDisconnect(hostId, nextState);
- }
-
- return true;
- }
-
- protected AgentAttache notifyMonitorsOfConnection(AgentAttache attache, final StartupCommand[] cmd) throws ConnectionException {
- long hostId = attache.getId();
- HostVO host = _hostDao.findById(hostId);
- for (Pair monitor : _hostMonitors) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Sending Connect to listener: " + monitor.second().getClass().getSimpleName());
- }
- for (int i = 0; i < cmd.length; i++) {
- try {
- monitor.second().processConnect(host, cmd[i]);
- } catch (Exception e) {
- if (e instanceof ConnectionException) {
- ConnectionException ce = (ConnectionException)e;
- if (ce.isSetupError()) {
- s_logger.warn("Monitor " + monitor.second().getClass().getSimpleName() + " says there is an error in the connect process for " + hostId + " due to " + e.getMessage());
- handleDisconnect(attache, Event.AgentDisconnected, false);
- throw ce;
- } else {
- s_logger.info("Monitor " + monitor.second().getClass().getSimpleName() + " says not to continue the connect process for " + hostId + " due to " + e.getMessage());
- handleDisconnect(attache, Event.ShutdownRequested, false);
- return attache;
- }
- } else {
- s_logger.error("Monitor " + monitor.second().getClass().getSimpleName() + " says there is an error in the connect process for " + hostId + " due to " + e.getMessage(), e);
- handleDisconnect(attache, Event.AgentDisconnected, false);
- throw new CloudRuntimeException("Unable to connect " + attache.getId(), e);
- }
- }
- }
- }
-
- Long dcId = host.getDataCenterId();
- ReadyCommand ready = new ReadyCommand(dcId);
- Answer answer = easySend(hostId, ready);
- if (answer == null || !answer.getResult()) {
- // this is tricky part for secondary storage
- // make it as disconnected, wait for secondary storage VM to be up
- // return the attache instead of null, even it is disconnectede
- handleDisconnect(attache, Event.AgentDisconnected, false);
- }
-
- _hostDao.updateStatus(host, Event.Ready, _nodeId);
- attache.ready();
- return attache;
- }
-
- protected boolean notifyCreatorsOfConnection(StartupCommand[] cmd) throws ConnectionException {
- boolean handled = false;
- for (Pair monitor : _creationMonitors) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Sending Connect to creator: "
- + monitor.second().getClass().getSimpleName());
- }
- handled = monitor.second().processInitialConnect(cmd);
- if (handled) {
- break;
- }
- }
-
- return handled;
- }
-
- @Override
- public boolean start() {
- startDirectlyConnectedHosts();
- if (_monitor != null) {
- _monitor.start();
- }
- if (_connection != null) {
- _connection.start();
- }
-
- return true;
- }
-
- public void startDirectlyConnectedHosts() {
- List hosts = _hostDao.findDirectlyConnectedHosts();
- for (HostVO host : hosts) {
- loadDirectlyConnectedHost(host);
- }
- }
-
- @SuppressWarnings("rawtypes")
- protected void loadDirectlyConnectedHost(HostVO host) {
- String resourceName = host.getResource();
- ServerResource resource = null;
- try {
- Class> clazz = Class.forName(resourceName);
- Constructor constructor = clazz.getConstructor();
- resource = (ServerResource) constructor.newInstance();
- } catch (ClassNotFoundException e) {
- s_logger.warn("Unable to find class " + host.getResource(), e);
- return;
- } catch (InstantiationException e) {
- s_logger.warn("Unablet to instantiate class " + host.getResource(), e);
- return;
- } catch (IllegalAccessException e) {
- s_logger.warn("Illegal access " + host.getResource(), e);
- return;
- } catch (SecurityException e) {
- s_logger.warn("Security error on " + host.getResource(), e);
- return;
- } catch (NoSuchMethodException e) {
- s_logger.warn("NoSuchMethodException error on " + host.getResource(), e);
- return;
- } catch (IllegalArgumentException e) {
- s_logger.warn("IllegalArgumentException error on " + host.getResource(), e);
- return;
- } catch (InvocationTargetException e) {
- s_logger.warn("InvocationTargetException error on " + host.getResource(), e);
- return;
- }
-
- _hostDao.loadDetails(host);
-
- HashMap params = new HashMap(host.getDetails().size() + 5);
- params.putAll(host.getDetails());
-
- params.put("guid", host.getGuid());
- params.put("zone", Long.toString(host.getDataCenterId()));
- if (host.getPodId() != null) {
- params.put("pod", Long.toString(host.getPodId()));
- }
- if (host.getClusterId() != null) {
- params.put("cluster", Long.toString(host.getClusterId()));
- String guid = null;
- ClusterVO cluster = _clusterDao.findById(host.getClusterId());
- if (cluster.getGuid() == null) {
- guid = host.getDetail("pool");
- } else {
- guid = cluster.getGuid();
- }
- if (guid == null || guid.isEmpty()) {
- throw new CloudRuntimeException("Can not find guid for cluster " + cluster.getId() + " name " + cluster.getName());
- }
- params.put("pool", guid);
- }
-
- params.put("ipaddress", host.getPrivateIpAddress());
- params.put("secondary.storage.vm", "false");
- params.put("max.template.iso.size", _configDao.getValue("max.template.iso.size"));
-
- try {
- resource.configure(host.getName(), params);
- } catch (ConfigurationException e) {
- s_logger.warn("Unable to configure resource due to ", e);
- return;
- }
-
- if (!resource.start()) {
- s_logger.warn("Unable to start the resource");
- return;
- }
- host.setLastPinged(System.currentTimeMillis() >> 10);
- host.setManagementServerId(_nodeId);
- _hostDao.update(host.getId(), host);
- _executor.execute(new SimulateStartTask(host.getId(), resource, host.getDetails(), null));
- }
-
- protected AgentAttache simulateStart(ServerResource resource, Map details, boolean old, List hostTags, String allocationState) throws IllegalArgumentException {
- StartupCommand[] cmds = resource.initialize();
- if (cmds == null) {
- return null;
- }
-
- AgentAttache attache = null;
- if (s_logger.isDebugEnabled()) {
- new Request(0l, -1l, -1l, cmds, true, false, true).log(-1, "Startup request from directly connected host: ");
- // s_logger.debug("Startup request from directly connected host: "
- // + new Request(0l, -1l, -1l, cmds, true, false, true)
- // .toString());
- }
- try {
- attache = handleDirectConnect(resource, cmds, details, old, hostTags, allocationState);
- } catch (IllegalArgumentException ex) {
- s_logger.warn("Unable to connect due to ", ex);
- throw ex;
- } catch (Exception e) {
- s_logger.warn("Unable to connect due to ", e);
- }
-
- if (attache == null) {
- resource.disconnected();
- return null;
- }
- if (attache.isReady()) {
- StartupAnswer[] answers = new StartupAnswer[cmds.length];
- for (int i = 0; i < answers.length; i++) {
- answers[i] = new StartupAnswer(cmds[i], attache.getId(), _pingInterval);
- }
-
- attache.process(answers);
- }
- return attache;
- }
-
- @Override
- public boolean stop() {
- if (_monitor != null) {
- _monitor.signalStop();
- }
- if (_connection != null) {
- _connection.stop();
- }
-
- s_logger.info("Disconnecting agents: " + _agents.size());
- synchronized (_agents) {
- for (final AgentAttache agent : _agents.values()) {
- final HostVO host = _hostDao.findById(agent.getId());
- if (host == null) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cant not find host " + agent.getId());
- }
- } else {
- _hostDao.updateStatus(host, Event.ManagementServerDown, _nodeId);
- }
- }
- }
- return true;
- }
-
- @Override
- public Pair findPod(final VirtualMachineTemplate template, ServiceOfferingVO offering, final DataCenterVO dc, final long accountId, Set avoids) {
- final Enumeration en = _podAllocators.enumeration();
- while (en.hasMoreElements()) {
- final PodAllocator allocator = (PodAllocator) en.nextElement();
- final Pair pod = allocator.allocateTo(template, offering, dc, accountId, avoids);
- if (pod != null) {
- return pod;
- }
- }
- return null;
- }
-
- @Override
- public HostStats getHostStatistics(long hostId) {
- Answer answer = easySend(hostId, new GetHostStatsCommand(_hostDao.findById(hostId).getGuid(), _hostDao.findById(hostId).getName(), hostId));
-
- if (answer != null && (answer instanceof UnsupportedAnswer)) {
- return null;
- }
-
- if (answer == null || !answer.getResult()) {
- String msg = "Unable to obtain host " + hostId + " statistics. ";
- s_logger.warn(msg);
- return null;
- } else {
-
- // now construct the result object
- if (answer instanceof GetHostStatsAnswer) {
- return ((GetHostStatsAnswer) answer).getHostStats();
- }
- }
- return null;
- }
-
- @Override
- public Long getGuestOSCategoryId(long hostId) {
- HostVO host = _hostDao.findById(hostId);
- if (host == null) {
- return null;
- } else {
- _hostDao.loadDetails(host);
- DetailVO detail = _hostDetailsDao.findDetail(hostId, "guest.os.category.id");
- if (detail == null) {
- return null;
- } else {
- return Long.parseLong(detail.getValue());
- }
- }
- }
-
- @Override
- public String getHostTags(long hostId) {
- List hostTags = _hostTagsDao.gethostTags(hostId);
- if (hostTags == null) {
- return null;
- } else {
- return StringUtils.listToCsvTags(hostTags);
- }
- }
-
- @Override
- public String getName() {
- return _name;
- }
-
- protected class DisconnectTask implements Runnable {
- AgentAttache _attache;
- Status.Event _event;
- boolean _investigate;
-
- DisconnectTask(final AgentAttache attache, final Status.Event event, final boolean investigate) {
- _attache = attache;
- _event = event;
- _investigate = investigate;
- }
-
- @Override
- public void run() {
- try {
- handleDisconnect(_attache, _event, _investigate);
- } catch (final Exception e) {
- s_logger.error("Exception caught while handling disconnect: ", e);
- } finally {
- StackMaid.current().exitCleanup();
- }
- }
- }
-
- @Override
- public Answer easySend(final Long hostId, final Command cmd) {
- return easySend(hostId, cmd, _wait);
- }
-
- @Override
- public Answer easySend(final Long hostId, final Command cmd, int timeout) {
- try {
- Host h = _hostDao.findById(hostId);
- if (h == null || h.getRemoved() != null) {
- s_logger.debug("Host with id " + hostId.toString() + " doesn't exist");
- return null;
- }
- Status status = h.getStatus();
- if (!status.equals(Status.Up) && !status.equals(Status.Connecting)) {
- return null;
- }
- final Answer answer = send(hostId, cmd, timeout);
- if (answer == null) {
- s_logger.warn("send returns null answer");
- return null;
- }
-
- if (!answer.getResult()) {
- s_logger.warn("Unable to execute command: " + cmd.toString() + " due to " + answer.getDetails());
- return null;
- }
-
- if (s_logger.isDebugEnabled() && answer.getDetails() != null) {
- s_logger.debug("Details from executing " + cmd.getClass().toString() + ": " + answer.getDetails());
- }
-
- return answer;
-
- } catch (final AgentUnavailableException e) {
- s_logger.warn(e.getMessage());
- return null;
- } catch (final OperationTimedoutException e) {
- s_logger.warn("Operation timed out: " + e.getMessage());
- return null;
- } catch (final Exception e) {
- s_logger.warn("Exception while sending", e);
- return null;
- }
- }
-
- @Override
- public Answer send(final Long hostId, final Command cmd) throws AgentUnavailableException, OperationTimedoutException {
- return send(hostId, cmd, _wait);
- }
-
- @Override
- public Answer[] send(final Long hostId, Commands cmds) throws AgentUnavailableException, OperationTimedoutException {
- 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;
-
- host = _hostDao.findById(hostId);
- if (host == null || host.getRemoved() != null) {
- s_logger.warn("Unable to find host " + hostId);
- return false;
- }
-
- if (host.getStatus() != Status.Up && host.getStatus() != Status.Alert) {
- s_logger.info("Unable to disconnect host because it is not in the correct state: host=" + hostId + "; Status=" + host.getStatus());
- return false;
- }
-
- AgentAttache attache = findAttache(hostId);
- if (attache == null) {
- s_logger.info("Unable to disconnect host because it is not connected to this server: " + hostId);
- return false;
- }
-
- disconnect(attache, Event.ShutdownRequested, false);
- return true;
- }
-
- @Override
- public boolean cancelMaintenance(final long hostId) {
-
- HostVO host;
- host = _hostDao.findById(hostId);
- if (host == null || host.getRemoved() != null) {
- s_logger.warn("Unable to find host " + hostId);
- return true;
- }
-
- if (host.getStatus() != Status.PrepareForMaintenance && host.getStatus() != Status.Maintenance && host.getStatus() != Status.ErrorInMaintenance) {
- return true;
- }
-
- _haMgr.cancelScheduledMigrations(host);
- List vms = _haMgr.findTakenMigrationWork();
- for (VMInstanceVO vm : vms) {
- if (vm.getHostId() != null && vm.getHostId() == hostId) {
- s_logger.info("Unable to cancel migration because the vm is being migrated: " + vm.toString());
- return false;
- }
- }
- disconnect(hostId, Event.ResetRequested, false);
- 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) {
- return maintain(hostId);
- } else if (event == Event.ResetRequested) {
- return cancelMaintenance(hostId);
- } else if (event == Event.Remove) {
- User caller = _accountMgr.getActiveUser(User.UID_SYSTEM);
- return deleteHost(hostId, false, caller);
- } else if (event == Event.AgentDisconnected) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Received agent disconnect event for host " + hostId);
- }
- AgentAttache attache = null;
- attache = findAttache(hostId);
- if (attache != null) {
- handleDisconnect(attache, Event.AgentDisconnected, false);
- }
- return true;
- } else if (event == Event.ShutdownRequested) {
- return reconnect(hostId);
- }
- return false;
- }
-
- @Override
- public boolean maintain(final long hostId) throws AgentUnavailableException {
- HostVO host = _hostDao.findById(hostId);
- Status state;
-
- Answer answer = easySend(hostId, new MaintainCommand());
- if (answer == null || !answer.getResult()) {
- s_logger.warn("Unable to put host in maintainance mode: " + hostId);
- return false;
- }
-
- // Let's put this guy in maintenance state
- do {
- host = _hostDao.findById(hostId);
- if (host == null) {
- s_logger.debug("Unable to find host " + hostId);
- return false;
- }
- state = host.getStatus();
- if (state == Status.Disconnected || state == Status.Updating) {
- s_logger.debug("Unable to put host " + hostId + " in matinenance mode because it is currently in " + state.toString());
- throw new AgentUnavailableException("Agent is in " + state.toString() + " state. Please wait for it to become Alert state try again.", hostId);
- }
- } while (!_hostDao.updateStatus(host, Event.MaintenanceRequested, _nodeId));
-
- AgentAttache attache = findAttache(hostId);
- if (attache != null) {
- attache.setMaintenanceMode(true);
- }
-
- if (attache != null) {
- // Now cancel all of the commands except for the active one.
- attache.cancelAllCommands(Status.PrepareForMaintenance, false);
- }
-
- final Host.Type type = host.getType();
-
- if (type == Host.Type.Routing) {
-
- final List vms = _vmDao.listByHostId(hostId);
- if (vms.size() == 0) {
- return true;
- }
-
- List hosts = _hostDao.listBy(host.getClusterId(), host.getPodId(), host.getDataCenterId());
-
- for (final VMInstanceVO vm : vms) {
- if (hosts == null || hosts.size() <= 1) {
- // for the last host in this cluster, stop all the VMs
- _haMgr.scheduleStop(vm, hostId, WorkType.ForceStop);
- } else {
- _haMgr.scheduleMigration(vm);
- }
- }
- }
-
- 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) {
- return true;
- }
- // 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)) {
- return false;
- }
-
- // 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) {
- return false;
- }
- return true;
- }
-
- protected void checkCIDR(Host.Type type, HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask) throws IllegalArgumentException {
- // Skip this check for Storage Agents and Console Proxies
- if (type == Host.Type.Storage || type == Host.Type.ConsoleProxy) {
- return;
- }
-
- 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());
- }
-
- }
-
- public void checkIPConflicts(Host.Type type, HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask, String serverPublicIP, String serverPublicNetmask) {
- // If the server's private IP is the same as is public IP, this host has
- // a host-only private network. Don't check for conflicts with the
- // private IP address table.
- if (serverPrivateIP != serverPublicIP) {
- if (!_privateIPAddressDao.mark(dc.getId(), pod.getId(), serverPrivateIP)) {
- // If the server's private IP address is already in the
- // database, return false
- List existingPrivateIPs = _privateIPAddressDao.listByPodIdDcIdIpAddress(pod.getId(), dc.getId(), serverPrivateIP);
-
- assert existingPrivateIPs.size() <= 1 : " How can we get more than one ip address with " + serverPrivateIP;
- if (existingPrivateIPs.size() > 1) {
- throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() + " and zone: " + dc.getName());
- }
- if (existingPrivateIPs.size() == 1) {
- DataCenterIpAddressVO vo = existingPrivateIPs.get(0);
- if (vo.getInstanceId() != null) {
- throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() + " and zone: " + dc.getName());
- }
- }
- }
- }
-
- if (serverPublicIP != null && !_publicIPAddressDao.mark(dc.getId(), new Ip(serverPublicIP))) {
- // If the server's public IP address is already in the database,
- // return false
- List existingPublicIPs = _publicIPAddressDao.listByDcIdIpAddress(dc.getId(), serverPublicIP);
- if (existingPublicIPs.size() > 0) {
- throw new IllegalArgumentException("The public ip address of the server (" + serverPublicIP + ") is already in use in zone: " + dc.getName());
- }
- }
- }
-
- @Override
- public Host addHost(long zoneId, ServerResource resource, Type hostType, Map hostDetails) {
- // Check if the zone exists in the system
- if (_dcDao.findById(zoneId) == null) {
- throw new InvalidParameterValueException("Can't find zone with id " + zoneId);
- }
-
- Map details = hostDetails;
- String guid = details.get("guid");
- List currentHosts = _hostDao.listBy(hostType, zoneId);
- for (HostVO currentHost : currentHosts) {
- if (currentHost.getGuid().equals(guid)) {
- return currentHost;
- }
- }
-
- AgentAttache attache = simulateStart(resource, hostDetails, true, null, null);
- return _hostDao.findById(attache.getId());
- }
-
- public HostVO createHost(final StartupCommand startup, ServerResource resource, Map details, boolean directFirst, List hostTags, String allocationState)
- throws IllegalArgumentException {
- Host.Type type = null;
-
- if (startup instanceof StartupStorageCommand) {
- StartupStorageCommand ssCmd = ((StartupStorageCommand) startup);
- 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) {
- resource = null;
- }
- } else {
- type = Host.Type.Storage;
- }
- final Map hostDetails = ssCmd.getHostDetails();
- if (hostDetails != null) {
- if (details != null) {
- details.putAll(hostDetails);
- } else {
- details = hostDetails;
- }
- }
- }
- } else if (startup instanceof StartupRoutingCommand) {
- StartupRoutingCommand ssCmd = ((StartupRoutingCommand) startup);
- type = Host.Type.Routing;
- final Map hostDetails = ssCmd.getHostDetails();
- if (hostDetails != null) {
- if (details != null) {
- details.putAll(hostDetails);
- } else {
- details = hostDetails;
- }
- }
- } else if (startup instanceof StartupProxyCommand) {
- type = Host.Type.ConsoleProxy;
- } else if (startup instanceof StartupRoutingCommand) {
- type = Host.Type.Routing;
- } else if (startup instanceof StartupExternalFirewallCommand) {
- type = Host.Type.ExternalFirewall;
- } else if (startup instanceof StartupExternalLoadBalancerCommand) {
- type = Host.Type.ExternalLoadBalancer;
- } else if (startup instanceof StartupPxeServerCommand) {
- type = Host.Type.PxeServer;
- } else if (startup instanceof StartupExternalDhcpCommand) {
- type = Host.Type.ExternalDhcp;
- } else {
- assert false : "Did someone add a new Startup command?";
- }
-
- Long id = null;
- HostVO server = _hostDao.findByGuid(startup.getGuid());
- if (server == null) {
- server = _hostDao.findByGuid(startup.getGuidWithoutResource());
- }
- if (server != null && server.getRemoved() == null) {
- id = server.getId();
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Found the host " + id + " by guid: " + startup.getGuid());
- }
- if (directFirst) {
- s_logger.debug("Old host reconnected as new");
- return null;
- }
- } else {
- server = new HostVO(startup.getGuid());
- }
-
- server.setDetails(details);
- server.setHostTags(hostTags);
-
- if (allocationState != null) {
- try {
- HostAllocationState hostAllocationState = Host.HostAllocationState.valueOf(allocationState);
- if (hostAllocationState != null) {
- server.setHostAllocationState(hostAllocationState);
- }
- } catch (IllegalArgumentException ex) {
- s_logger.error("Unable to resolve " + allocationState + " to a valid supported host allocation State, defaulting to 'Enabled'");
- server.setHostAllocationState(Host.HostAllocationState.Enabled);
- }
- } else {
- server.setHostAllocationState(Host.HostAllocationState.Enabled);
- }
-
- updateHost(server, startup, type, _nodeId);
- if (resource != null) {
- server.setResource(resource.getClass().getName());
- }
- if (id == null) {
- /*
- * // ignore integrity check for agent-simulator if(!"0.0.0.0".equals(startup.getPrivateIpAddress()) &&
- * !"0.0.0.0".equals(startup.getStorageIpAddress())) { if (_hostDao.findByPrivateIpAddressInDataCenter
- * (server.getDataCenterId(), startup.getPrivateIpAddress()) != null) { throw newIllegalArgumentException(
- * "The private ip address is already in used: " + startup.getPrivateIpAddress()); }
- *
- * if (_hostDao.findByPrivateIpAddressInDataCenter(server.getDataCenterId (), startup.getStorageIpAddress()) !=
- * null) { throw new IllegalArgumentException ("The private ip address is already in used: " +
- * startup.getStorageIpAddress()); } }
- */
-
- if (startup instanceof StartupProxyCommand) {
- server.setProxyPort(((StartupProxyCommand) startup).getProxyPort());
- }
-
- server = _hostDao.persist(server);
- id = server.getId();
-
- s_logger.info("New " + server.getType().toString() + " host connected w/ guid " + startup.getGuid() + " and id is " + id);
- } else {
- if (!_hostDao.connect(server, _nodeId)) {
- throw new CloudRuntimeException("Agent cannot connect because the current state is " + server.getStatus().toString());
- }
- s_logger.info("Old " + server.getType().toString() + " host reconnected w/ id =" + id);
- }
- createCapacityEntry(startup, server);
-
- return server;
- }
-
- public HostVO createHost(final StartupCommand[] startup, ServerResource resource, Map details, boolean directFirst, List hostTags, String allocationState)
- throws IllegalArgumentException {
- StartupCommand firstCmd = startup[0];
- HostVO result = createHost(firstCmd, resource, details, directFirst, hostTags, allocationState);
- if (result == null) {
- return null;
- }
- return result;
- }
-
- public AgentAttache handleConnect(final Link link, final StartupCommand[] startup) throws IllegalArgumentException, ConnectionException {
- HostVO server = null;
- boolean handled = notifyCreatorsOfConnection(startup);
- if (!handled) {
- server = createHost(startup, null, null, false, null, null);
- } else {
- server = _hostDao.findByGuid(startup[0].getGuid());
- }
-
- if (server == null) {
- return null;
- }
- long id = server.getId();
-
- AgentAttache attache = createAttache(id, server, link);
-
- attache = notifyMonitorsOfConnection(attache, startup);
-
- return attache;
- }
-
- public AgentAttache findAgent(long hostId) {
- synchronized (_agents) {
- return _agents.get(hostId);
- }
- }
-
- protected AgentAttache createAttache(long id, HostVO server, Link link) {
- s_logger.debug("create ConnectedAgentAttache for " + id);
- final AgentAttache attache = new ConnectedAgentAttache(this, id, link, server.getStatus() == Status.Maintenance || server.getStatus() == Status.ErrorInMaintenance
- || server.getStatus() == Status.PrepareForMaintenance);
- link.attach(attache);
- AgentAttache old = null;
- synchronized (_agents) {
- old = _agents.get(id);
- _agents.put(id, attache);
- }
- if (old != null) {
- old.disconnect(Status.Removed);
- }
- return attache;
- }
-
- protected AgentAttache createAttache(long id, HostVO server, ServerResource resource) {
- if (resource instanceof DummySecondaryStorageResource || resource instanceof KvmDummyResourceBase) {
- return new DummyAttache(this, id, false);
- }
- s_logger.debug("create DirectAgentAttache for " + id);
- final DirectAgentAttache attache = new DirectAgentAttache(this, id, resource, server.getStatus() == Status.Maintenance || server.getStatus() == Status.ErrorInMaintenance
- || server.getStatus() == Status.PrepareForMaintenance, this);
- AgentAttache old = null;
- synchronized (_agents) {
- old = _agents.get(id);
- _agents.put(id, attache);
- }
- if (old != null) {
- old.disconnect(Status.Removed);
- }
- return attache;
- }
-
- @Override
- public boolean maintenanceFailed(long hostId) {
- HostVO host = _hostDao.findById(hostId);
- if (host == null) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cant not find host " + hostId);
- }
- return false;
- } else {
- return _hostDao.updateStatus(host, Event.UnableToMigrate, _nodeId);
- }
- }
-
- @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");
-
- String dataCenter = startup.getDataCenter();
- String pod = startup.getPod();
- String cluster = startup.getCluster();
-
- if (pod != null && dataCenter != null && pod.equalsIgnoreCase("default") && dataCenter.equalsIgnoreCase("default")) {
- List pods = _podDao.listAllIncludingRemoved();
- for (HostPodVO hpv : pods) {
- if (checkCIDR(type, hpv, startup.getPrivateIpAddress(), startup.getPrivateNetmask())) {
- pod = hpv.getName();
- dataCenter = _dcDao.findById(hpv.getDataCenterId()).getName();
- break;
- }
- }
- }
- long dcId = -1;
- DataCenterVO dc = _dcDao.findByName(dataCenter);
- if (dc == null) {
- try {
- dcId = Long.parseLong(dataCenter);
- dc = _dcDao.findById(dcId);
- } catch (final NumberFormatException e) {
- }
- }
- if (dc == null) {
- throw new IllegalArgumentException("Host " + startup.getPrivateIpAddress() + " sent incorrect data center: " + dataCenter);
- }
- dcId = dc.getId();
-
- HostPodVO p = _podDao.findByName(pod, dcId);
- if (p == null) {
- try {
- final long podId = Long.parseLong(pod);
- p = _podDao.findById(podId);
- } catch (final NumberFormatException e) {
- }
- }
- Long podId = null;
- if (p == null) {
- if (type != Host.Type.SecondaryStorage && type != Host.Type.ExternalFirewall && type != Host.Type.ExternalLoadBalancer) {
-
- /*
- * s_logger.info("Unable to find the pod so we are creating one." ); p = createPod(pod, dcId,
- * startup.getPrivateIpAddress(), NetUtils.getCidrSize(startup.getPrivateNetmask())); podId = p.getId();
- */
- s_logger.error("Host " + startup.getPrivateIpAddress() + " sent incorrect pod: " + pod + " in " + dataCenter);
- throw new IllegalArgumentException("Host " + startup.getPrivateIpAddress() + " sent incorrect pod: " + pod + " in " + dataCenter);
- }
- } else {
- podId = p.getId();
- }
-
- Long clusterId = null;
- if (cluster != null) {
- try {
- clusterId = Long.valueOf(cluster);
- } catch (NumberFormatException e) {
- ClusterVO c = _clusterDao.findBy(cluster, podId);
- if (c == null) {
- c = new ClusterVO(dcId, podId, cluster);
- c = _clusterDao.persist(c);
- }
- clusterId = c.getId();
- }
- }
-
- if (type == Host.Type.Routing) {
- StartupRoutingCommand scc = (StartupRoutingCommand) startup;
-
- HypervisorType hypervisorType = scc.getHypervisorType();
- boolean doCidrCheck = true;
-
- ClusterVO clusterVO = _clusterDao.findById(clusterId);
- if (clusterVO.getHypervisorType() != scc.getHypervisorType()) {
- throw new IllegalArgumentException("Can't add host whose hypervisor type is: " + scc.getHypervisorType() + " into cluster: " + clusterId + " whose hypervisor type is: "
- + clusterVO.getHypervisorType());
- }
-
- /*
- * KVM:Enforcement that all the hosts in the cluster have the same os type, for migration
- */
- if (scc.getHypervisorType() == HypervisorType.KVM) {
- List hostsInCluster = _hostDao.listByCluster(clusterId);
- if (!hostsInCluster.isEmpty()) {
- HostVO oneHost = hostsInCluster.get(0);
- _hostDao.loadDetails(oneHost);
- String hostOsInCluster = oneHost.getDetail("Host.OS");
- String hostOs = scc.getHostDetails().get("Host.OS");
- if (!hostOsInCluster.equalsIgnoreCase(hostOs)) {
- throw new IllegalArgumentException("Can't add host: " + startup.getPrivateIpAddress() + " with hostOS: " + hostOs + " into a cluster," + "in which there are "
- + hostOsInCluster + " hosts added");
- }
- }
- }
-
- // If this command is from the agent simulator, don't do the CIDR
- // check
- if (scc.getAgentTag() != null && startup.getAgentTag().equalsIgnoreCase("vmops-simulator")) {
- doCidrCheck = false;
- }
-
- // If this command is from a KVM agent, or from an agent that has a
- // null hypervisor type, don't do the CIDR check
- if (hypervisorType == null || hypervisorType == HypervisorType.KVM || hypervisorType == HypervisorType.VMware || hypervisorType == HypervisorType.BareMetal
- || hypervisorType == HypervisorType.Simulator) {
- doCidrCheck = false;
- }
-
- if (doCidrCheck) {
- s_logger.info("Host: " + host.getName() + " connected with hypervisor type: " + hypervisorType + ". Checking CIDR...");
- } else {
- s_logger.info("Host: " + host.getName() + " connected with hypervisor type: " + hypervisorType + ". Skipping CIDR check...");
- }
-
- if (doCidrCheck) {
- checkCIDR(type, p, dc, scc.getPrivateIpAddress(), scc.getPrivateNetmask());
- }
-
- // Check if the private/public IPs of the server are already in the
- // private/public IP address tables
- checkIPConflicts(type, p, dc, scc.getPrivateIpAddress(), scc.getPublicIpAddress(), scc.getPublicIpAddress(), scc.getPublicNetmask());
- }
-
- host.setDataCenterId(dc.getId());
- host.setPodId(podId);
- host.setClusterId(clusterId);
- host.setPrivateIpAddress(startup.getPrivateIpAddress());
- host.setPrivateNetmask(startup.getPrivateNetmask());
- host.setPrivateMacAddress(startup.getPrivateMacAddress());
- host.setPublicIpAddress(startup.getPublicIpAddress());
- host.setPublicMacAddress(startup.getPublicMacAddress());
- host.setPublicNetmask(startup.getPublicNetmask());
- host.setStorageIpAddress(startup.getStorageIpAddress());
- host.setStorageMacAddress(startup.getStorageMacAddress());
- host.setStorageNetmask(startup.getStorageNetmask());
- host.setVersion(startup.getVersion());
- host.setName(startup.getName());
- host.setType(type);
- host.setManagementServerId(msId);
- host.setStorageUrl(startup.getIqn());
- host.setLastPinged(System.currentTimeMillis() >> 10);
- if (startup instanceof StartupRoutingCommand) {
- final StartupRoutingCommand scc = (StartupRoutingCommand) startup;
- host.setCaps(scc.getCapabilities());
- host.setCpus(scc.getCpus());
- host.setTotalMemory(scc.getMemory());
- host.setSpeed(scc.getSpeed());
- HypervisorType hyType = scc.getHypervisorType();
- host.setHypervisorType(hyType);
-
- } else if (startup instanceof StartupStorageCommand) {
- final StartupStorageCommand ssc = (StartupStorageCommand) startup;
- host.setParent(ssc.getParent());
- host.setTotalSize(ssc.getTotalSize());
- host.setHypervisorType(HypervisorType.None);
- if (ssc.getNfsShare() != null) {
- host.setStorageUrl(ssc.getNfsShare());
- }
- }
- if (startup.getStorageIpAddressDeux() != null) {
- host.setStorageIpAddressDeux(startup.getStorageIpAddressDeux());
- host.setStorageMacAddressDeux(startup.getStorageMacAddressDeux());
- host.setStorageNetmaskDeux(startup.getStorageNetmaskDeux());
- }
-
- }
-
- @Override
- public Host getHost(long hostId) {
- return _hostDao.findById(hostId);
- }
-
- // create capacity entries if none exist for this server
- private void createCapacityEntry(final StartupCommand startup, HostVO server) {
- SearchCriteria capacitySC = _capacityDao.createSearchCriteria();
- capacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
- capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
- capacitySC.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
- List capacities = _capacityDao.search(capacitySC, null);
-
- // remove old entries, we'll recalculate them anyway
- if (startup instanceof StartupStorageCommand) {
- if ((capacities != null) && !capacities.isEmpty()) {
- for (CapacityVO capacity : capacities) {
- _capacityDao.remove(capacity.getId());
- }
- }
- }
-
- if (startup instanceof StartupStorageCommand) {
- StartupStorageCommand ssCmd = (StartupStorageCommand) startup;
- if (ssCmd.getResourceType() == Storage.StorageResourceType.STORAGE_HOST) {
- CapacityVO capacity = new CapacityVO(server.getId(), server.getDataCenterId(), server.getPodId(), server.getClusterId(), 0L, (long) (server.getTotalSize() * _overProvisioningFactor),
- CapacityVO.CAPACITY_TYPE_STORAGE_ALLOCATED);
- _capacityDao.persist(capacity);
- }
- } else if (startup instanceof StartupRoutingCommand) {
- SearchCriteria capacityCPU = _capacityDao.createSearchCriteria();
- capacityCPU.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
- capacityCPU.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
- capacityCPU.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
- capacityCPU.addAnd("capacityType", SearchCriteria.Op.EQ, CapacityVO.CAPACITY_TYPE_CPU);
- List capacityVOCpus = _capacityDao.search(capacityCPU, null);
-
- if (capacityVOCpus != null && !capacityVOCpus.isEmpty()) {
- CapacityVO CapacityVOCpu = capacityVOCpus.get(0);
- long newTotalCpu = (server.getCpus().longValue() * server.getSpeed().longValue());
- if ((CapacityVOCpu.getTotalCapacity() <= newTotalCpu) || ((CapacityVOCpu.getUsedCapacity() + CapacityVOCpu.getReservedCapacity()) <= newTotalCpu)) {
- CapacityVOCpu.setTotalCapacity(newTotalCpu);
- } else if ((CapacityVOCpu.getUsedCapacity() + CapacityVOCpu.getReservedCapacity() > newTotalCpu) && (CapacityVOCpu.getUsedCapacity() < newTotalCpu)) {
- CapacityVOCpu.setReservedCapacity(0);
- CapacityVOCpu.setTotalCapacity(newTotalCpu);
- } else {
- s_logger.debug("What? new cpu is :" + newTotalCpu + ", old one is " + CapacityVOCpu.getUsedCapacity() + "," + CapacityVOCpu.getReservedCapacity() + ","
- + CapacityVOCpu.getTotalCapacity());
- }
- _capacityDao.update(CapacityVOCpu.getId(), CapacityVOCpu);
- } else {
- CapacityVO capacity = new CapacityVO(server.getId(), server.getDataCenterId(), server.getPodId(), server.getClusterId(), 0L, (server.getCpus().longValue() * server.getSpeed()
- .longValue()), CapacityVO.CAPACITY_TYPE_CPU);
- _capacityDao.persist(capacity);
- }
-
- SearchCriteria capacityMem = _capacityDao.createSearchCriteria();
- capacityMem.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
- capacityMem.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
- capacityMem.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
- capacityMem.addAnd("capacityType", SearchCriteria.Op.EQ, CapacityVO.CAPACITY_TYPE_MEMORY);
- List capacityVOMems = _capacityDao.search(capacityMem, null);
-
- if (capacityVOMems != null && !capacityVOMems.isEmpty()) {
- CapacityVO CapacityVOMem = capacityVOMems.get(0);
- long newTotalMem = server.getTotalMemory();
- if (CapacityVOMem.getTotalCapacity() <= newTotalMem || (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() <= newTotalMem)) {
- CapacityVOMem.setTotalCapacity(newTotalMem);
- } else if (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() > newTotalMem && CapacityVOMem.getUsedCapacity() < newTotalMem) {
- CapacityVOMem.setReservedCapacity(0);
- CapacityVOMem.setTotalCapacity(newTotalMem);
- } else {
- s_logger.debug("What? new cpu is :" + newTotalMem + ", old one is " + CapacityVOMem.getUsedCapacity() + "," + CapacityVOMem.getReservedCapacity() + ","
- + CapacityVOMem.getTotalCapacity());
- }
- _capacityDao.update(CapacityVOMem.getId(), CapacityVOMem);
- } else {
- CapacityVO capacity = new CapacityVO(server.getId(), server.getDataCenterId(), server.getPodId(), server.getClusterId(), 0L, server.getTotalMemory(), CapacityVO.CAPACITY_TYPE_MEMORY);
- _capacityDao.persist(capacity);
- }
- }
-
- }
-
- // protected void upgradeAgent(final Link link, final byte[] request, final
- // String reason) {
- //
- // if (reason == UnsupportedVersionException.IncompatibleVersion) {
- // final UpgradeResponse response = new UpgradeResponse(request,
- // _upgradeMgr.getAgentUrl());
- // try {
- // s_logger.info("Asking for the agent to update due to incompatible version: "
- // + response.toString());
- // link.send(response.toBytes());
- // } catch (final ClosedChannelException e) {
- // s_logger.warn("Unable to send response due to connection closed: " +
- // response.toString());
- // }
- // return;
- // }
- //
- // assert (reason == UnsupportedVersionException.UnknownVersion) :
- // "Unknown reason: " + reason;
- // final UpgradeResponse response = new UpgradeResponse(request,
- // _upgradeMgr.getAgentUrl());
- // try {
- // s_logger.info("Asking for the agent to update due to unknown version: " +
- // response.toString());
- // link.send(response.toBytes());
- // } catch (final ClosedChannelException e) {
- // s_logger.warn("Unable to send response due to connection closed: " +
- // response.toString());
- // }
- // }
-
- protected class SimulateStartTask implements Runnable {
- ServerResource resource;
- Map details;
- long id;
- ActionDelegate actionDelegate;
-
- public SimulateStartTask(long id, ServerResource resource, Map details, ActionDelegate actionDelegate) {
- this.id = id;
- this.resource = resource;
- this.details = details;
- this.actionDelegate = actionDelegate;
- }
-
- @Override
- public void run() {
- AgentAttache at = null;
- try {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Simulating start for resource " + resource.getName() + " id " + id);
- }
- simulateStart(resource, details, false, null, null);
- } catch (Exception e) {
- s_logger.warn("Unable to simulate start on resource " + id + " name " + resource.getName(), e);
- } finally {
- if (actionDelegate != null) {
- actionDelegate.action(new Long(id));
- }
- if (at == null) {
- HostVO host = _hostDao.findById(id);
- host.setManagementServerId(null);
- _hostDao.update(id, host);
- }
- StackMaid.current().exitCleanup();
- }
- }
- }
-
- public class AgentHandler extends Task {
- public AgentHandler(Task.Type type, Link link, byte[] data) {
- super(type, link, data);
- }
-
- protected void processRequest(final Link link, final Request request) {
- AgentAttache attache = (AgentAttache) link.attachment();
- final Command[] cmds = request.getCommands();
- Command cmd = cmds[0];
- boolean logD = true;
-
- Response response = null;
- if (attache == null) {
- s_logger.debug("Processing sequence " + request.getSequence() + ": Processing " + request.toString());
- if (!(cmd instanceof StartupCommand)) {
- s_logger.warn("Throwing away a request because it came through as the first command on a connect: " + request.toString());
- return;
- }
- StartupCommand startup = (StartupCommand) cmd;
- // if ((_upgradeMgr.registerForUpgrade(-1, startup.getVersion())
- // == UpgradeManager.State.RequiresUpdate) &&
- // (_upgradeMgr.getAgentUrl() != null)) {
- // final UpgradeCommand upgrade = new
- // UpgradeCommand(_upgradeMgr.getAgentUrl());
- // final Request req = new Request(1, -1, -1, new Command[] {
- // upgrade }, true, true);
- // s_logger.info("Agent requires upgrade: " + req.toString());
- // try {
- // link.send(req.toBytes());
- // } catch (ClosedChannelException e) {
- // s_logger.warn("Unable to tell agent it should update.");
- // }
- // return;
- // }
- try {
- StartupCommand[] startups = new StartupCommand[cmds.length];
- for (int i = 0; i < cmds.length; i++) {
- startups[i] = (StartupCommand) cmds[i];
- }
- attache = handleConnect(link, startups);
- } catch (final IllegalArgumentException e) {
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, 0, new Long(0), "Agent from " + startup.getPrivateIpAddress() + " is unable to connect due to " + e.getMessage(), "Agent from "
- + startup.getPrivateIpAddress() + " is unable to connect with " + request.toString() + " because of " + e.getMessage());
- s_logger.warn("Unable to create attache for agent: " + request.toString(), e);
- response = new Response(request, new StartupAnswer((StartupCommand) cmd, e.getMessage()), _nodeId, -1);
- } catch (ConnectionException e) {
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, 0, new Long(0), "Agent from " + startup.getPrivateIpAddress() + " is unable to connect due to " + e.getMessage(), "Agent from "
- + startup.getPrivateIpAddress() + " is unable to connect with " + request.toString() + " because of " + e.getMessage());
- s_logger.warn("Unable to create attache for agent: " + request.toString(), e);
- response = new Response(request, new StartupAnswer((StartupCommand) cmd, e.getMessage()), _nodeId, -1);
- } catch (final CloudRuntimeException e) {
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, 0, new Long(0), "Agent from " + startup.getPrivateIpAddress() + " is unable to connect due to " + e.getMessage(), "Agent from "
- + startup.getPrivateIpAddress() + " is unable to connect with " + request.toString() + " because of " + e.getMessage());
- s_logger.warn("Unable to create attache for agent: " + request.toString(), e);
- }
- if (attache == null) {
- if (response == null) {
- s_logger.warn("Unable to create attache for agent: " + request.toString());
- response = new Response(request, new StartupAnswer((StartupCommand) request.getCommand(), "Unable to register this agent"), _nodeId, -1);
- }
- try {
- link.send(response.toBytes(), true);
- } catch (final ClosedChannelException e) {
- s_logger.warn("Response was not sent: " + response.toString());
- }
- return;
- }
- }
-
- final long hostId = attache.getId();
-
- if (s_logger.isDebugEnabled()) {
- if (cmd instanceof PingRoutingCommand) {
- final PingRoutingCommand ping = (PingRoutingCommand) cmd;
- if (ping.getNewStates().size() > 0) {
- s_logger.debug("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request.toString());
- } else {
- logD = false;
- s_logger.debug("Ping from " + hostId);
- s_logger.trace("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request.toString());
- }
- } else if (cmd instanceof PingCommand) {
- logD = false;
- s_logger.debug("Ping from " + hostId);
- s_logger.trace("SeqA " + attache.getId() + "-" + request.getSequence() + ": Processing " + request.toString());
- } else {
- s_logger.debug("SeqA " + attache.getId() + "-" + request.getSequence() + ": Processing " + request.toString());
- }
- }
-
- final Answer[] answers = new Answer[cmds.length];
- for (int i = 0; i < cmds.length; i++) {
- cmd = cmds[i];
- Answer answer = null;
- try {
- if (cmd instanceof StartupRoutingCommand) {
- final StartupRoutingCommand startup = (StartupRoutingCommand) cmd;
- answer = new StartupAnswer(startup, attache.getId(), getPingInterval());
- } else if (cmd instanceof StartupProxyCommand) {
- final StartupProxyCommand startup = (StartupProxyCommand) cmd;
- answer = new StartupAnswer(startup, attache.getId(), getPingInterval());
- } else if (cmd instanceof StartupStorageCommand) {
- final StartupStorageCommand startup = (StartupStorageCommand) cmd;
- answer = new StartupAnswer(startup, attache.getId(), getPingInterval());
- } else if (cmd instanceof ShutdownCommand) {
- final ShutdownCommand shutdown = (ShutdownCommand) cmd;
- final String reason = shutdown.getReason();
- s_logger.info("Host " + attache.getId() + " has informed us that it is shutting down with reason " + reason + " and detail " + shutdown.getDetail());
- if (reason.equals(ShutdownCommand.Update)) {
- disconnect(attache, Event.UpdateNeeded, false);
- } else if (reason.equals(ShutdownCommand.Requested)) {
- disconnect(attache, Event.ShutdownRequested, false);
- }
- return;
- } else if (cmd instanceof AgentControlCommand) {
- answer = handleControlCommand(attache, (AgentControlCommand) cmd);
- } else {
- handleCommands(attache, request.getSequence(), new Command[] { cmd });
- if (cmd instanceof PingCommand) {
- long cmdHostId = ((PingCommand) cmd).getHostId();
-
- // if the router is sending a ping, verify the
- // gateway was pingable
- if (cmd instanceof PingRoutingCommand) {
- boolean gatewayAccessible = ((PingRoutingCommand) cmd).isGatewayAccessible();
- HostVO host = _hostDao.findById(Long.valueOf(cmdHostId));
- if (!gatewayAccessible) {
- // alert that host lost connection to
- // gateway (cannot ping the default route)
- DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
- HostPodVO podVO = _podDao.findById(host.getPodId());
- String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
-
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId(), "Host lost connection to gateway, " + hostDesc, "Host [" + hostDesc
- + "] lost connection to gateway (default route) and is possibly having network connection issues.");
- } else {
- _alertMgr.clearAlert(AlertManager.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId());
- }
- }
- answer = new PingAnswer((PingCommand) cmd);
- } else if (cmd instanceof ReadyAnswer) {
- HostVO host = _hostDao.findById(attache.getId());
- if (host == null) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cant not find host " + attache.getId());
- }
- }
- answer = new Answer(cmd);
- } else {
- answer = new Answer(cmd);
- }
- }
- } catch (final Throwable th) {
- s_logger.warn("Caught: ", th);
- answer = new Answer(cmd, false, th.getMessage());
- }
- answers[i] = answer;
- }
-
->>>>>>> Build fixes after first pass at merge
- response = new Response(request, answers, _nodeId, attache.getId());
- if (s_logger.isDebugEnabled()) {
- if (logD) {
- s_logger.debug("SeqA " + attache.getId() + "-" + response.getSequence() + ": Sending " + response.toString());
- } else {
- s_logger.trace("SeqA " + attache.getId() + "-" + response.getSequence() + ": Sending " + response.toString());
- }
- }
- try {
- link.send(response.toBytes());
- } catch (final ClosedChannelException e) {
- s_logger.warn("Unable to send response because connection is closed: " + response.toString());
- }
- }
-
- protected void processResponse(final Link link, final Response response) {
- final AgentAttache attache = (AgentAttache) link.attachment();
- if (attache == null) {
- s_logger.warn("Unable to process: " + response.toString());
- }
-
- if (!attache.processAnswers(response.getSequence(), response)) {
- s_logger.info("Host " + attache.getId() + " - Seq " + response.getSequence() + ": Response is not processed: " + response.toString());
- }
- }
-
- @Override
- protected void doTask(final Task task) throws Exception {
- Transaction txn = Transaction.open(Transaction.CLOUD_DB);
- try {
- final Type type = task.getType();
- if (type == Task.Type.DATA) {
- final byte[] data = task.getData();
- try {
- final Request event = Request.parse(data);
- if (event instanceof Response) {
- processResponse(task.getLink(), (Response) event);
- } else {
- processRequest(task.getLink(), event);
- }
- } catch (final UnsupportedVersionException e) {
- s_logger.warn(e.getMessage());
- // upgradeAgent(task.getLink(), data, e.getReason());
- }
- } else if (type == Task.Type.CONNECT) {
- } else if (type == Task.Type.DISCONNECT) {
- final Link link = task.getLink();
- final AgentAttache attache = (AgentAttache) link.attachment();
- if (attache != null) {
- disconnect(attache, Event.AgentDisconnected, true);
- } else {
- s_logger.info("Connection from " + link.getIpAddress() + " closed but no cleanup was done.");
- link.close();
- link.terminated();
- }
- }
- } finally {
- StackMaid.current().exitCleanup();
- txn.close();
- }
- }
- }
-
- protected AgentManagerImpl() {
- }
-}
diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java.orig b/server/src/com/cloud/capacity/CapacityManagerImpl.java.orig
deleted file mode 100644
index 02dd218d3fe..00000000000
--- a/server/src/com/cloud/capacity/CapacityManagerImpl.java.orig
+++ /dev/null
@@ -1,708 +0,0 @@
-/**
- * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
- *
- * This software is licensed under the GNU General Public License v3 or later.
- *
- * It is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package com.cloud.capacity;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.ejb.Local;
-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.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.StartupStorageCommand;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.exception.ConnectionException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.Storage;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.component.Inject;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.fsm.StateListener;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Event;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.VMInstanceDao;
-
-@Local(value=CapacityManager.class)
-public class CapacityManagerImpl implements CapacityManager , StateListener, Listener{
- private static final Logger s_logger = Logger.getLogger(CapacityManagerImpl.class);
- String _name;
- @Inject CapacityDao _capacityDao;
- @Inject ConfigurationDao _configDao;
- @Inject ServiceOfferingDao _offeringsDao;
- @Inject HostDao _hostDao;
- @Inject VMInstanceDao _vmDao;
- @Inject AgentManager _agentManager;
-
- private int _hostCapacityCheckerDelay;
- private int _hostCapacityCheckerInterval;
- private int _vmCapacityReleaseInterval;
- private ScheduledExecutorService _executor;
- private boolean _stopped;
-<<<<<<< HEAD
-
- protected int _overProvisioningFactor = 1;
- protected float _cpuOverProvisioningFactor = 1;
-
-=======
- private int _storageOverProvisioningFactor = 1;
- private float _cpuOverProvisioningFactor = 1.0f;
-
->>>>>>> Ensure capacity gets counted for agents that connect up
-
-
- @Override
- public boolean configure(String name, Map params) throws ConfigurationException {
- _name = name;
- _hostCapacityCheckerDelay = NumbersUtil.parseInt(_configDao.getValue(Config.HostCapacityCheckerWait.key()), 3600);
- _hostCapacityCheckerInterval = NumbersUtil.parseInt(_configDao.getValue(Config.HostCapacityCheckerInterval.key()), 3600);
- _vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
- _storageOverProvisioningFactor = NumbersUtil.parseInt(_configDao.getValue(Config.StorageOverprovisioningFactor.key()), 1);
- _cpuOverProvisioningFactor = NumbersUtil.parseFloat(_configDao.getValue(Config.CPUOverprovisioningFactor.key()), 1.0f);
-
- if (_cpuOverProvisioningFactor < 1.0f) {
- _cpuOverProvisioningFactor = 1.0f;
- }
- _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("HostCapacity-Checker"));
- VirtualMachine.State.getStateMachine().registerListener(this);
- _agentManager.registerForHostEvents(new StorageCapacityListener(_capacityDao, _storageOverProvisioningFactor), true, false, false);
- _agentManager.registerForHostEvents(new ComputeCapacityListener(_capacityDao, _cpuOverProvisioningFactor), true, false, false);
-
- return true;
- }
-
- @Override
- public boolean start() {
- _executor.schedule(new HostCapacityCollector(), _hostCapacityCheckerDelay, TimeUnit.SECONDS);
- return true;
- }
-
- @Override
- public boolean stop() {
- _executor.shutdownNow();
- _stopped = true;
- return true;
- }
-
- @Override
- public String getName() {
- return _name;
- }
-
- @DB
- @Override
- public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId) {
- ServiceOfferingVO svo = _offeringsDao.findById(vm.getServiceOfferingId());
- CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_CPU);
- CapacityVO capacityMemory = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_MEMORY);
-
- if (capacityCpu == null || capacityMemory == null || svo == null) {
- return false;
- }
-
- Transaction txn = Transaction.currentTxn();
- try {
- txn.start();
-
- int vmCPU = svo.getCpu() * svo.getSpeed();
- long vmMem = svo.getRamSize() * 1024L * 1024L;
-
- capacityCpu = _capacityDao.lockRow(capacityCpu.getId(), true);
- capacityMemory = _capacityDao.lockRow(capacityMemory.getId(), true);
-
- long usedCpu = capacityCpu.getUsedCapacity();
- long usedMem = capacityMemory.getUsedCapacity();
- long reservedCpu = capacityCpu.getReservedCapacity();
- long reservedMem = capacityMemory.getReservedCapacity();
- long actualTotalCpu = capacityCpu.getTotalCapacity();
- String opFactor = _configDao.getValue(Config.CPUOverprovisioningFactor.key());
- float cpuOverprovisioningFactor = NumbersUtil.parseFloat(opFactor, 1);
- long totalCpu = (long)(actualTotalCpu * cpuOverprovisioningFactor);
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu);
- }
- long totalMem = capacityMemory.getTotalCapacity();
-
- if (!moveFromReserved) {
- /*move resource from used*/
- if (usedCpu >= vmCPU) {
- capacityCpu.setUsedCapacity(usedCpu - vmCPU);
- }
- if (usedMem >= vmMem) {
- capacityMemory.setUsedCapacity(usedMem - vmMem);
- }
-
- if (moveToReservered) {
- if (reservedCpu + vmCPU <= totalCpu) {
- capacityCpu.setReservedCapacity(reservedCpu + vmCPU);
- }
- if (reservedMem + vmMem <= totalMem) {
- capacityMemory.setReservedCapacity(reservedMem + vmMem);
- }
- }
- } else {
- if (reservedCpu >= vmCPU) {
- capacityCpu.setReservedCapacity(reservedCpu - vmCPU);
- }
- if (reservedMem >= vmMem) {
- capacityMemory.setReservedCapacity(reservedMem - vmMem);
- }
- }
-
- s_logger.debug("release cpu from host: " + hostId + ", old used: " + usedCpu + ",reserved: " + reservedCpu + ", actual total: " + actualTotalCpu + ", total with overprovisioning: " + totalCpu +
- "; new used: " + capacityCpu.getUsedCapacity() + ",reserved:" + capacityCpu.getReservedCapacity() +
- "; movedfromreserved: " + moveFromReserved + ",moveToReservered" + moveToReservered);
-
- s_logger.debug("release mem from host: " + hostId + ", old used: " + usedMem + ",reserved: " + reservedMem + ", total: " + totalMem +
- "; new used: " + capacityMemory.getUsedCapacity() + ",reserved:" + capacityMemory.getReservedCapacity() +
- "; movedfromreserved: " + moveFromReserved + ",moveToReservered" + moveToReservered);
-
- _capacityDao.update(capacityCpu.getId(), capacityCpu);
- _capacityDao.update(capacityMemory.getId(), capacityMemory);
- txn.commit();
- return true;
- } catch (Exception e) {
- s_logger.debug("Failed to transit vm's state, due to " + e.getMessage());
- txn.rollback();
- return false;
- }
- }
-
- @DB
- @Override
- public void allocateVmCapacity(VirtualMachine vm, boolean fromLastHost) {
-
- long hostId = vm.getHostId();
-
- ServiceOfferingVO svo = _offeringsDao.findById(vm.getServiceOfferingId());
-
- CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_CPU);
- CapacityVO capacityMem = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_MEMORY);
-
- if (capacityCpu == null || capacityMem == null || svo == null) {
- return;
- }
-
- int cpu = svo.getCpu() * svo.getSpeed();
- long ram = svo.getRamSize() * 1024L * 1024L;
-
- String opFactor = _configDao.getValue(Config.CPUOverprovisioningFactor.key());
- float cpuOverprovisioningFactor = NumbersUtil.parseFloat(opFactor, 1);
-
- Transaction txn = Transaction.currentTxn();
-
- try {
- txn.start();
- capacityCpu = _capacityDao.lockRow(capacityCpu.getId(), true);
- capacityMem = _capacityDao.lockRow(capacityMem.getId(), true);
-
- long usedCpu = capacityCpu.getUsedCapacity();
- long usedMem = capacityMem.getUsedCapacity();
- long reservedCpu = capacityCpu.getReservedCapacity();
- long reservedMem = capacityMem.getReservedCapacity();
- long actualTotalCpu = capacityCpu.getTotalCapacity();
- long totalCpu = (long)(actualTotalCpu * cpuOverprovisioningFactor);
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu);
- }
- long totalMem = capacityMem.getTotalCapacity();
-
- long freeCpu = totalCpu - (reservedCpu + usedCpu);
- long freeMem = totalMem - (reservedMem + usedMem);
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("We are allocating VM, increasing the used capacity of this host:"+ hostId);
- s_logger.debug("Current Used CPU: "+usedCpu + " , Free CPU:"+freeCpu+" ,Requested CPU: "+cpu);
- s_logger.debug("Current Used RAM: "+usedMem + " , Free RAM:"+freeMem+" ,Requested RAM: "+ram);
- }
- capacityCpu.setUsedCapacity(usedCpu + cpu);
- capacityMem.setUsedCapacity(usedMem + ram);
-
- if (fromLastHost) {
- /*alloc from reserved*/
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("We are allocating VM to the last host again, so adjusting the reserved capacity if it is not less than required");
- s_logger.debug("Reserved CPU: "+reservedCpu + " , Requested CPU: "+cpu);
- s_logger.debug("Reserved RAM: "+reservedMem + " , Requested RAM: "+ram);
- }
- if (reservedCpu >= cpu && reservedMem >= ram) {
- capacityCpu.setReservedCapacity(reservedCpu - cpu);
- capacityMem.setReservedCapacity(reservedMem - ram);
- }
- } else {
- /*alloc from free resource*/
- if (!((reservedCpu + usedCpu + cpu <= totalCpu) && (reservedMem + usedMem + ram <= totalMem))) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Host doesnt seem to have enough free capacity, but increasing the used capacity anyways, since the VM is already starting on this host ");
- }
- }
- }
-
- s_logger.debug("CPU STATS after allocation: for host: " + hostId + ", old used: " + usedCpu + ", old reserved: " +
- reservedCpu + ", actual total: " + actualTotalCpu + ", total with overprovisioning: " + totalCpu +
- "; new used:" + capacityCpu.getUsedCapacity() + ", reserved:" + capacityCpu.getReservedCapacity() +
- "; requested cpu:" + cpu + ",alloc_from_last:" + fromLastHost);
-
- s_logger.debug("RAM STATS after allocation: for host: " + hostId + ", old used: " + usedMem + ", old reserved: " +
- reservedMem + ", total: " + totalMem + "; new used: " + capacityMem.getUsedCapacity() + ", reserved: " +
- capacityMem.getReservedCapacity() + "; requested mem: " + ram + ",alloc_from_last:" + fromLastHost);
-
- _capacityDao.update(capacityCpu.getId(), capacityCpu);
- _capacityDao.update(capacityMem.getId(), capacityMem);
- txn.commit();
- } catch (Exception e) {
- txn.rollback();
- return;
- }
- }
-
- @Override
- public boolean checkIfHostHasCapacity(long hostId, Integer cpu, long ram, boolean checkFromReservedCapacity, float cpuOverprovisioningFactor){
- boolean hasCapacity = false;
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Checking if host: " + hostId + " has enough capacity for requested CPU: "+ cpu + " and requested RAM: "+ ram + " , cpuOverprovisioningFactor: "+cpuOverprovisioningFactor);
- }
-
- CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_CPU);
- CapacityVO capacityMem = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_MEMORY);
-
- if (capacityCpu == null || capacityMem == null) {
- if(capacityCpu == null){
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cannot checkIfHostHasCapacity, Capacity entry for CPU not found in Db, for hostId: "+ hostId);
- }
- }
- if(capacityMem == null){
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cannot checkIfHostHasCapacity, Capacity entry for RAM not found in Db, for hostId: "+ hostId);
- }
- }
-
- return false;
- }
-
- long usedCpu = capacityCpu.getUsedCapacity();
- long usedMem = capacityMem.getUsedCapacity();
- long reservedCpu = capacityCpu.getReservedCapacity();
- long reservedMem = capacityMem.getReservedCapacity();
- long actualTotalCpu = capacityCpu.getTotalCapacity();
- long totalCpu = (long)(actualTotalCpu * cpuOverprovisioningFactor);
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu);
- }
-
- long totalMem = capacityMem.getTotalCapacity();
-
-
- String failureReason = "";
- if (checkFromReservedCapacity) {
- long freeCpu = reservedCpu;
- long freeMem = reservedMem;
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("We need to allocate to the last host again, so checking if there is enough reserved capacity");
- s_logger.debug("Reserved CPU: "+freeCpu + " , Requested CPU: "+cpu);
- s_logger.debug("Reserved RAM: "+freeMem + " , Requested RAM: "+ram);
- }
- /*alloc from reserved*/
- if (reservedCpu >= cpu){
- if(reservedMem >= ram) {
- hasCapacity = true;
- }else{
- failureReason = "Host does not have enough reserved RAM available";
- }
- }else{
- failureReason = "Host does not have enough reserved CPU available";
- }
- } else {
- long freeCpu = totalCpu - (reservedCpu + usedCpu);
- long freeMem = totalMem - (reservedMem + usedMem);
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Free CPU: "+freeCpu + " , Requested CPU: "+cpu);
- s_logger.debug("Free RAM: "+freeMem + " , Requested RAM: "+ram);
- }
- /*alloc from free resource*/
- if ((reservedCpu + usedCpu + cpu <= totalCpu)) {
- if((reservedMem + usedMem + ram <= totalMem)){
- hasCapacity = true;
- }else{
- failureReason = "Host does not have enough RAM available";
- }
- }else{
- failureReason = "Host does not have enough CPU available";
- }
- }
-
- if (hasCapacity) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Host has enough CPU and RAM available");
- }
-
- s_logger.debug("STATS: Can alloc CPU from host: " + hostId + ", used: " + usedCpu + ", reserved: " +
- reservedCpu + ", actual total: "+actualTotalCpu + ", total with overprovisioning: " + totalCpu +
- "; requested cpu:" + cpu + ",alloc_from_last_host?:" + checkFromReservedCapacity);
-
- s_logger.debug("STATS: Can alloc MEM from host: " + hostId + ", used: " + usedMem + ", reserved: " +
- reservedMem + ", total: " + totalMem + "; requested mem: " + ram + ",alloc_from_last_host?:" + checkFromReservedCapacity);
- } else {
-
- if (checkFromReservedCapacity) {
- s_logger.debug("STATS: Failed to alloc resource from host: " + hostId + " reservedCpu: " + reservedCpu + ", requested cpu: " + cpu +
- ", reservedMem: " + reservedMem + ", requested mem: " + ram);
- } else {
- s_logger.debug("STATS: Failed to alloc resource from host: " + hostId + " reservedCpu: " + reservedCpu + ", used cpu: " + usedCpu + ", requested cpu: " + cpu +
- ", actual total cpu: "+actualTotalCpu + ", total cpu with overprovisioning: " + totalCpu +
- ", reservedMem: " + reservedMem + ", used Mem: " + usedMem + ", requested mem: " + ram + ", total Mem:" + totalMem);
- }
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug(failureReason + ", cannot allocate to this host.");
- }
- }
-
- return hasCapacity;
-
- }
-
- public class HostCapacityCollector implements Runnable {
-
- @Override
- public void run() {
- while (!_stopped) {
- try {
- Thread.sleep(_hostCapacityCheckerInterval * 1000);
- } catch (InterruptedException e1) {
-
- }
- // get all hosts...even if they are not in 'UP' state
- List hosts = _hostDao.listByType(Host.Type.Routing);
-
- // prep the service offerings
- List offerings = _offeringsDao.listAllIncludingRemoved();
- Map offeringsMap = new HashMap();
- for (ServiceOfferingVO offering : offerings) {
- offeringsMap.put(offering.getId(), offering);
- }
-
- for (HostVO host : hosts) {
-
- long usedCpu = 0;
- long usedMemory = 0;
- long reservedMemory = 0;
- long reservedCpu = 0;
-
- List vms = _vmDao.listUpByHostId(host.getId());
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Found " + vms.size() + " VMs on host " + host.getId());
- }
-
- for (VMInstanceVO vm : vms) {
- ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId());
- usedMemory += so.getRamSize() * 1024L * 1024L;
- usedCpu += so.getCpu() * so.getSpeed();
- }
-
- List vmsByLastHostId = _vmDao.listByLastHostId(host.getId());
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Found " + vmsByLastHostId.size() + " VM, not running on host " + host.getId());
- }
- for (VMInstanceVO vm : vmsByLastHostId) {
- long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - vm.getUpdateTime().getTime())/1000;
- if (secondsSinceLastUpdate < _vmCapacityReleaseInterval) {
- ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId());
- reservedMemory += so.getRamSize() * 1024L * 1024L;
- reservedCpu += so.getCpu() * so.getSpeed();
- }
- }
-
- CapacityVO cpuCap = _capacityDao.findByHostIdType(host.getId(), CapacityVO.CAPACITY_TYPE_CPU);
- CapacityVO memCap = _capacityDao.findByHostIdType(host.getId(), CapacityVO.CAPACITY_TYPE_MEMORY);
-
- if (cpuCap.getUsedCapacity() == usedCpu && cpuCap.getReservedCapacity() == reservedCpu) {
- s_logger.debug("No need to calibrate cpu capacity, host:" + host.getId() + " usedCpu: " + cpuCap.getUsedCapacity() + " reservedCpu: " + cpuCap.getReservedCapacity());
- } else if (cpuCap.getReservedCapacity() != reservedCpu) {
- s_logger.debug("Calibrate reserved cpu for host: " + host.getId() + " old reservedCpu:" + cpuCap.getReservedCapacity() + " new reservedCpu:" + reservedCpu);
- cpuCap.setReservedCapacity(reservedCpu);
- } else if (cpuCap.getUsedCapacity() != usedCpu) {
- s_logger.debug("Calibrate used cpu for host: " + host.getId() + " old usedCpu:" + cpuCap.getUsedCapacity() + " new usedCpu:" + usedCpu);
- cpuCap.setUsedCapacity(usedCpu);
- }
-
- if (memCap.getUsedCapacity() == usedMemory && memCap.getReservedCapacity() == reservedMemory) {
- s_logger.debug("No need to calibrate memory capacity, host:" + host.getId() + " usedMem: " + memCap.getUsedCapacity() + " reservedMem: " + memCap.getReservedCapacity());
- } else if (memCap.getReservedCapacity() != reservedMemory) {
- s_logger.debug("Calibrate reserved memory for host: " + host.getId() + " old reservedMem:" + memCap.getReservedCapacity() + " new reservedMem:" + reservedMemory);
- memCap.setReservedCapacity(reservedMemory);
- } else if (memCap.getUsedCapacity() != usedMemory) {
- /*Didn't calibrate for used memory, because VMs can be in state(starting/migrating) that I don't know on which host they are allocated*/
- s_logger.debug("Calibrate used memory for host: " + host.getId() + " old usedMem: " + memCap.getUsedCapacity() + " new usedMem: " + usedMemory);
- memCap.setUsedCapacity(usedMemory);
- }
-
- try {
- _capacityDao.update(cpuCap.getId(), cpuCap);
- _capacityDao.update(memCap.getId(), memCap);
- } catch (Exception e) {
-
- }
- }
-
- }
- }
- }
-
- @Override
- public boolean preStateTransitionEvent(State oldState,
- Event event, State newState, VirtualMachine vm, boolean transitionStatus, Long id) {
- return true;
- }
-
- @Override
- public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean status, Long oldHostId) {
- if (!status) {
- return false;
- }
-
- s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event +
- "vm's original host id: " + vm.getLastHostId() + " new host id: " + vm.getHostId() + " host id before state transition: " + oldHostId);
-
-
- if (oldState == State.Starting) {
- if (event == Event.OperationFailed) {
- releaseVmCapacity(vm, false, false, oldHostId);
- } else if (event == Event.OperationRetry) {
- releaseVmCapacity(vm, false, false, oldHostId);
- } else if (event == Event.AgentReportStopped) {
- releaseVmCapacity(vm, false, true, oldHostId);
- }
- } else if (oldState == State.Running) {
- if (event == Event.AgentReportStopped) {
- releaseVmCapacity(vm, false, true, oldHostId);
- }
- } else if (oldState == State.Migrating) {
- if (event == Event.AgentReportStopped) {
- /*Release capacity from original host*/
- releaseVmCapacity(vm, false, false, vm.getLastHostId());
- releaseVmCapacity(vm, false, true, oldHostId);
- } else if (event == Event.OperationFailed) {
- /*Release from dest host*/
- releaseVmCapacity(vm, false, false, oldHostId);
- } else if (event == Event.OperationSucceeded) {
- releaseVmCapacity(vm, false, false, vm.getLastHostId());
- }
- } else if (oldState == State.Stopping) {
- if (event == Event.AgentReportStopped || event == Event.OperationSucceeded) {
- releaseVmCapacity(vm, false, true, oldHostId);
- }
- } else if (oldState == State.Stopped) {
- if (event == Event.DestroyRequested) {
- releaseVmCapacity(vm, true, false, vm.getLastHostId());
- }
- }
-
-
- if((newState == State.Starting || newState == State.Migrating) && vm.getHostId() != null){
- boolean fromLastHost = false;
- if(vm.getLastHostId() == vm.getHostId()){
- s_logger.debug("VM starting again on the last host it was stopped on");
- fromLastHost = true;
- }
- allocateVmCapacity(vm,fromLastHost);
- }
-
- return true;
- }
-
- // create capacity entries if none exist for this server
- private void createCapacityEntry(final StartupCommand startup, HostVO server) {
- SearchCriteria capacitySC = _capacityDao
- .createSearchCriteria();
- capacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
- capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ,
- server.getDataCenterId());
- capacitySC.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
-
-
- if (startup instanceof StartupRoutingCommand) {
- SearchCriteria capacityCPU = _capacityDao
- .createSearchCriteria();
- capacityCPU.addAnd("hostOrPoolId", SearchCriteria.Op.EQ,
- server.getId());
- capacityCPU.addAnd("dataCenterId", SearchCriteria.Op.EQ,
- server.getDataCenterId());
- capacityCPU
- .addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
- capacityCPU.addAnd("capacityType", SearchCriteria.Op.EQ,
- CapacityVO.CAPACITY_TYPE_CPU);
- List capacityVOCpus = _capacityDao.search(capacitySC,
- null);
-
- if (capacityVOCpus != null && !capacityVOCpus.isEmpty()) {
- CapacityVO CapacityVOCpu = capacityVOCpus.get(0);
- long newTotalCpu = (long) (server.getCpus().longValue()
- * server.getSpeed().longValue() * _cpuOverProvisioningFactor);
- if ((CapacityVOCpu.getTotalCapacity() <= newTotalCpu)
- || ((CapacityVOCpu.getUsedCapacity() + CapacityVOCpu
- .getReservedCapacity()) <= newTotalCpu)) {
- CapacityVOCpu.setTotalCapacity(newTotalCpu);
- } else if ((CapacityVOCpu.getUsedCapacity()
- + CapacityVOCpu.getReservedCapacity() > newTotalCpu)
- && (CapacityVOCpu.getUsedCapacity() < newTotalCpu)) {
- CapacityVOCpu.setReservedCapacity(0);
- CapacityVOCpu.setTotalCapacity(newTotalCpu);
- } else {
- s_logger.debug("What? new cpu is :" + newTotalCpu
- + ", old one is " + CapacityVOCpu.getUsedCapacity()
- + "," + CapacityVOCpu.getReservedCapacity() + ","
- + CapacityVOCpu.getTotalCapacity());
- }
- _capacityDao.update(CapacityVOCpu.getId(), CapacityVOCpu);
- } else {
- CapacityVO capacity = new CapacityVO(
- server.getId(),
- server.getDataCenterId(),
- server.getPodId(),
- server.getClusterId(),
- 0L,
- (long) (server.getCpus().longValue()
- * server.getSpeed().longValue() * _cpuOverProvisioningFactor),
- CapacityVO.CAPACITY_TYPE_CPU);
- _capacityDao.persist(capacity);
- }
-
- SearchCriteria capacityMem = _capacityDao
- .createSearchCriteria();
- capacityMem.addAnd("hostOrPoolId", SearchCriteria.Op.EQ,
- server.getId());
- capacityMem.addAnd("dataCenterId", SearchCriteria.Op.EQ,
- server.getDataCenterId());
- capacityMem
- .addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
- capacityMem.addAnd("capacityType", SearchCriteria.Op.EQ,
- CapacityVO.CAPACITY_TYPE_MEMORY);
- List capacityVOMems = _capacityDao.search(capacityMem,
- null);
-
- if (capacityVOMems != null && !capacityVOMems.isEmpty()) {
- CapacityVO CapacityVOMem = capacityVOMems.get(0);
- long newTotalMem = server.getTotalMemory();
- if (CapacityVOMem.getTotalCapacity() <= newTotalMem
- || (CapacityVOMem.getUsedCapacity()
- + CapacityVOMem.getReservedCapacity() <= newTotalMem)) {
- CapacityVOMem.setTotalCapacity(newTotalMem);
- } else if (CapacityVOMem.getUsedCapacity()
- + CapacityVOMem.getReservedCapacity() > newTotalMem
- && CapacityVOMem.getUsedCapacity() < newTotalMem) {
- CapacityVOMem.setReservedCapacity(0);
- CapacityVOMem.setTotalCapacity(newTotalMem);
- } else {
- s_logger.debug("What? new cpu is :" + newTotalMem
- + ", old one is " + CapacityVOMem.getUsedCapacity()
- + "," + CapacityVOMem.getReservedCapacity() + ","
- + CapacityVOMem.getTotalCapacity());
- }
- _capacityDao.update(CapacityVOMem.getId(), CapacityVOMem);
- } else {
- CapacityVO capacity = new CapacityVO(server.getId(),
- server.getDataCenterId(), server.getPodId(), server.getClusterId(), 0L,
- server.getTotalMemory(),
- CapacityVO.CAPACITY_TYPE_MEMORY);
- _capacityDao.persist(capacity);
- }
- }
-
- }
-
- @Override
- public boolean processAnswers(long agentId, long seq, Answer[] answers) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean processCommands(long agentId, long seq, Command[] commands) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public void processConnect(HostVO host, StartupCommand cmd) throws ConnectionException {
- if (cmd instanceof StartupRoutingCommand) {
- createCapacityEntry(cmd, host);
- }
-
- }
-
- @Override
- public boolean processDisconnect(long agentId, Status state) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean isRecurring() {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public int getTimeout() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public boolean processTimeout(long agentId, long seq) {
- // TODO Auto-generated method stub
- return false;
- }
-
-
-}