| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| package com.cloud.hypervisor.ovm3.resources.helpers; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.math.BigInteger; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import javax.naming.ConfigurationException; |
| |
| import org.apache.commons.io.FileUtils; |
| import org.apache.logging.log4j.Logger; |
| import org.apache.logging.log4j.LogManager; |
| |
| import com.cloud.agent.api.Answer; |
| import com.cloud.agent.api.CheckHealthAnswer; |
| import com.cloud.agent.api.CheckHealthCommand; |
| import com.cloud.agent.api.CheckOnHostAnswer; |
| import com.cloud.agent.api.CheckOnHostCommand; |
| import com.cloud.agent.api.CheckVirtualMachineAnswer; |
| import com.cloud.agent.api.CheckVirtualMachineCommand; |
| import com.cloud.agent.api.FenceAnswer; |
| import com.cloud.agent.api.FenceCommand; |
| import com.cloud.agent.api.GetHostStatsAnswer; |
| import com.cloud.agent.api.GetHostStatsCommand; |
| import com.cloud.agent.api.HostStatsEntry; |
| import com.cloud.agent.api.HostVmStateReportEntry; |
| import com.cloud.agent.api.MaintainAnswer; |
| import com.cloud.agent.api.MaintainCommand; |
| import com.cloud.agent.api.ReadyAnswer; |
| import com.cloud.agent.api.ReadyCommand; |
| import com.cloud.agent.api.StartupRoutingCommand; |
| import com.cloud.hypervisor.Hypervisor.HypervisorType; |
| import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin; |
| import com.cloud.hypervisor.ovm3.objects.Common; |
| import com.cloud.hypervisor.ovm3.objects.Connection; |
| import com.cloud.hypervisor.ovm3.objects.Linux; |
| import com.cloud.hypervisor.ovm3.objects.Network; |
| import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException; |
| import com.cloud.hypervisor.ovm3.objects.Pool; |
| import com.cloud.hypervisor.ovm3.objects.Xen; |
| import com.cloud.utils.exception.CloudRuntimeException; |
| import com.cloud.utils.script.Script; |
| import com.cloud.utils.ssh.SSHCmdHelper; |
| import com.cloud.vm.VirtualMachine.PowerState; |
| import com.cloud.vm.VirtualMachine.State; |
| import com.trilead.ssh2.SCPClient; |
| |
| public class Ovm3HypervisorSupport { |
| protected Logger logger = LogManager.getLogger(getClass()); |
| private Connection c; |
| private Ovm3Configuration config; |
| |
| public Ovm3HypervisorSupport(Connection conn, Ovm3Configuration ovm3config) { |
| c = conn; |
| config = ovm3config; |
| } |
| |
| /* statemap bounces */ |
| private Map<String, PowerState> powerStateMaps; |
| { |
| powerStateMaps = new HashMap<String, PowerState>(); |
| powerStateMaps.put("Stopping", PowerState.PowerOn); |
| powerStateMaps.put("Running", PowerState.PowerOn); |
| powerStateMaps.put("Stopped", PowerState.PowerOff); |
| powerStateMaps.put("Error", PowerState.PowerUnknown); |
| powerStateMaps.put("Suspended", PowerState.PowerOn); |
| powerStateMaps.put("Paused", PowerState.PowerOn); |
| /* unknown ? */ |
| powerStateMaps.put("Migrating", PowerState.PowerOn); |
| } |
| private Map<String, State> vmStateMap = new HashMap<String, State>(); |
| private Map<String, State> stateMaps; |
| { |
| stateMaps = new HashMap<String, State>(); |
| stateMaps.put("Stopping", State.Stopping); |
| stateMaps.put("Running", State.Running); |
| stateMaps.put("Stopped", State.Stopped); |
| stateMaps.put("Error", State.Error); |
| stateMaps.put("Suspended", State.Running); |
| stateMaps.put("Paused", State.Running); |
| stateMaps.put("Migrating", State.Migrating); |
| } |
| |
| /** |
| * removeVmState: get rid of the state of a VM |
| * |
| * @param vmName |
| */ |
| public void revmoveVmState(String vmName) { |
| vmStateMap.remove(vmName); |
| } |
| |
| /** |
| * vmStateMapClear: clear out the statemap and repopulate it. |
| * |
| * @throws Ovm3ResourceException |
| */ |
| public void vmStateMapClear() throws Ovm3ResourceException { |
| synchronized (vmStateMap) { |
| vmStateMap.clear(); |
| syncState(this.vmStateMap); |
| } |
| } |
| |
| /** |
| * vmStateStarting: set the state of a vm to starting |
| * |
| * @param vmName |
| */ |
| public void setVmStateStarting(String vmName) { |
| setVmState(vmName, State.Starting); |
| } |
| |
| /** |
| * getVmState: get the state for a vm |
| * |
| * @param vmName |
| * @return |
| */ |
| public State getVmState(String vmName) { |
| return vmStateMap.get(vmName); |
| } |
| |
| /** |
| * vmStateChange: set the state of a vm to state |
| * |
| * @param vmName |
| * @param state |
| */ |
| public void setVmState(String vmName, State state) { |
| synchronized (vmStateMap) { |
| vmStateMap.put(vmName, state); |
| } |
| } |
| |
| /** |
| * getSystemVMKeyFile: |
| * Figure out where the cloud keyfile lives for access to the systemvm. |
| * |
| * @param filename |
| * @return keyfileURI |
| */ |
| public File getSystemVMKeyFile(String filename) { |
| String keyPath = Script.findScript("", "scripts/vm/systemvm/" |
| + filename); |
| File keyFile = null; |
| if (keyPath != null) { |
| logger.debug("found SshKey " + keyPath); |
| keyFile = new File(keyPath); |
| } |
| if (keyFile == null || !keyFile.exists()) { |
| String key = "client/target/generated-webapp/WEB-INF/classes/scripts/vm/systemvm/" |
| + filename; |
| logger.warn("findScript failed, going for generated " + key); |
| keyFile = new File(key); |
| } |
| if (keyFile == null || !keyFile.exists()) { |
| String key = "/usr/share/cloudstack-common/scripts/vm/systemvm/" |
| + filename; |
| logger.warn("generated key retrieval failed " + key); |
| keyFile = new File(key); |
| } |
| return keyFile; |
| } |
| |
| /** |
| * fillHostInfo: Startup the routing for the host. |
| * |
| * @param cmd |
| */ |
| public void fillHostInfo(StartupRoutingCommand cmd) { |
| try { |
| /* get data we need from parts */ |
| Linux host = new Linux(c); |
| if (!host.getOvmVersion().startsWith("3.2.") && !host.getOvmVersion().startsWith("3.3.")) { |
| logger.error("Hypervisor not supported: " + host.getOvmVersion()); |
| throw new CloudRuntimeException( |
| "OVM 3.2. or 3.3. are only supported, not " |
| + host.getOvmVersion()); |
| } else { |
| logger.debug("Hypervisor version: " + host.getOvmVersion()); |
| } |
| cmd.setName(host.getHostName()); |
| cmd.setSpeed(host.getCpuKhz()); |
| cmd.setCpus(host.getTotalThreads()); |
| cmd.setCpuSockets(host.getCpuSockets()); |
| cmd.setMemory(host.getMemory().longValue()); |
| BigInteger totalmem = BigInteger.valueOf(host.getMemory() |
| .longValue()); |
| BigInteger freemem = BigInteger.valueOf(host.getFreeMemory() |
| .longValue()); |
| cmd.setDom0MinMemory(totalmem.subtract(freemem).longValue()); |
| // setPoolSync and setCaps. |
| cmd.setGuid(config.getCsHostGuid()); |
| cmd.setDataCenter(config.getAgentZoneId().toString()); |
| cmd.setPod(config.getAgentPodId().toString()); |
| /* TODO: cmd.setOwner(host.getManagerUuid()); */ |
| cmd.setCluster(config.getAgentClusterId().toString()); |
| cmd.setHypervisorVersion(host.getOvmVersion()); |
| cmd.setVersion(host.getAgentVersion()); |
| cmd.setHypervisorType(HypervisorType.Ovm3); |
| cmd.setCaps(host.getCapabilities()); |
| cmd.setPrivateIpAddress(c.getIp()); |
| cmd.setStorageIpAddress(c.getIp()); |
| Network net = new Network(c); |
| String defaultBridge = net.getBridgeByIp(c.getIp()).getName(); |
| if (defaultBridge == null) { |
| throw new CloudRuntimeException( |
| "Unable to obtain valid bridge with " + c.getIp()); |
| } |
| |
| if (config.getAgentPublicNetworkName() == null) { |
| config.setAgentPublicNetworkName(defaultBridge); |
| } |
| if (config.getAgentPrivateNetworkName() == null) { |
| config.setAgentPrivateNetworkName(config |
| .getAgentPublicNetworkName()); |
| } |
| if (config.getAgentGuestNetworkName() == null) { |
| config.setAgentGuestNetworkName(config |
| .getAgentPublicNetworkName()); |
| } |
| if (config.getAgentStorageNetworkName() == null) { |
| config.setAgentStorageNetworkName(config |
| .getAgentPrivateNetworkName()); |
| } |
| Map<String, String> d = cmd.getHostDetails(); |
| d.put("public.network.device", config.getAgentPublicNetworkName()); |
| d.put("private.network.device", config.getAgentPrivateNetworkName()); |
| d.put("guest.network.device", config.getAgentGuestNetworkName()); |
| d.put("storage.network.device", config.getAgentStorageNetworkName()); |
| d.put("isprimary", config.getAgentIsPrimary().toString()); |
| d.put("hasprimary", config.getAgentHasPrimary().toString()); |
| cmd.setHostDetails(d); |
| logger.debug("Add an Ovm3 host " + config.getAgentHostname() + ":" |
| + cmd.getHostDetails()); |
| } catch (Ovm3ResourceException e) { |
| throw new CloudRuntimeException("Ovm3ResourceException: " |
| + e.getMessage(), e); |
| } |
| } |
| |
| /** |
| * setupServer: |
| * Add the cloudstack plugin and setup the agent. |
| * Add the ssh keys to the host. |
| * |
| * @param c |
| * @throws IOException |
| */ |
| public Boolean setupServer(String key) throws IOException { |
| logger.debug("Setup all bits on agent: " + config.getAgentHostname()); |
| /* version dependent patching ? */ |
| try { |
| com.trilead.ssh2.Connection sshConnection = SSHCmdHelper |
| .acquireAuthorizedConnection(config.getAgentIp(), |
| config.getAgentSshUserName(), |
| config.getAgentSshPassword()); |
| if (sshConnection == null) { |
| throw new ConfigurationException(String.format("Unable to " |
| + "connect to server(IP=%1$s, username=%2$s, " |
| + "password=%3$s", config.getAgentIp(), |
| config.getAgentSshUserName(), |
| config.getAgentSshPassword())); |
| } |
| SCPClient scp = new SCPClient(sshConnection); |
| String userDataScriptDir = "scripts/vm/hypervisor/ovm3/"; |
| String userDataScriptPath = Script.findScript("", userDataScriptDir); |
| if (userDataScriptPath == null) { |
| throw new ConfigurationException("Can not find " |
| + userDataScriptDir); |
| } |
| String mkdir = "mkdir -p " + config.getAgentScriptsDir(); |
| if (!SSHCmdHelper.sshExecuteCmd(sshConnection, mkdir)) { |
| throw new ConfigurationException("Failed " + mkdir + " on " |
| + config.getAgentHostname()); |
| } |
| for (String script : config.getAgentScripts()) { |
| script = userDataScriptPath + "/" + script; |
| scp.put(script, config.getAgentScriptsDir(), "0755"); |
| } |
| String prepareCmd = String.format(config.getAgentScriptsDir() + "/" |
| + config.getAgentScript() + " --ssl=" + c.getUseSsl() + " " |
| + "--port=" + c.getPort()); |
| if (!SSHCmdHelper.sshExecuteCmd(sshConnection, prepareCmd)) { |
| throw new ConfigurationException("Failed to insert module on " |
| + config.getAgentHostname()); |
| } else { |
| /* because of OVM 3.3.1 (might be 2000) */ |
| Thread.sleep(5000); |
| } |
| CloudstackPlugin cSp = new CloudstackPlugin(c); |
| cSp.ovsUploadSshKey(config.getAgentSshKeyFileName(), |
| FileUtils.readFileToString(getSystemVMKeyFile(key))); |
| cSp.dom0CheckStorageHealthCheck(config.getAgentScriptsDir(), |
| config.getAgentCheckStorageScript(), |
| config.getCsHostGuid(), |
| config.getAgentStorageCheckTimeout(), |
| config.getAgentStorageCheckInterval()); |
| } catch (Exception es) { |
| logger.error("Unexpected exception ", es); |
| String msg = "Unable to install module in agent"; |
| throw new CloudRuntimeException(msg); |
| } |
| return true; |
| } |
| |
| /** |
| * Get all the VMs |
| * |
| * @return |
| * @throws Ovm3ResourceException |
| */ |
| private Map<String, Xen.Vm> getAllVms() throws Ovm3ResourceException { |
| try { |
| Xen vms = new Xen(c); |
| return vms.getRunningVmConfigs(); |
| } catch (Exception e) { |
| logger.debug("getting VM list from " + config.getAgentHostname() |
| + " failed", e); |
| throw new CloudRuntimeException("Exception on getting VMs from " |
| + config.getAgentHostname() + ":" + e.getMessage(), e); |
| } |
| } |
| |
| /** |
| * getAllVmStates: Get the state of all the VMs |
| * |
| * @return |
| * @throws Ovm3ResourceException |
| */ |
| private Map<String, State> getAllVmStates(Map<String, State> vmStateMap) |
| throws Ovm3ResourceException { |
| Map<String, Xen.Vm> vms = getAllVms(); |
| final Map<String, State> states = new HashMap<String, State>(); |
| for (final Map.Entry<String, Xen.Vm> entry : vms.entrySet()) { |
| Xen.Vm vm = entry.getValue(); |
| State ns = State.Running; |
| String as = vm.getVmState(); |
| if (vm.isControlDomain() || as == null) { |
| continue; |
| } |
| /* The domain is currently running on a CPU */ |
| /* need a more exact match! */ |
| if (as.contains("r")) { |
| ns = State.Running; |
| /* The domain is blocked, and not running or runnable. */ |
| } else if (as.contains("b")) { |
| ns = State.Running; |
| /* The domain has been paused */ |
| } else if (as.contains("p")) { |
| ns = State.Running; |
| /* The guest has requested to be shutdown, still migrating... */ |
| } else if (as.contains("s")) { |
| if (vmStateMap.get(vm.getVmName()) == State.Migrating) { |
| ns = State.Migrating; |
| } else { |
| ns = State.Stopped; |
| } |
| /* The domain has crashed */ |
| } else if (as.contains("c")) { |
| ns = State.Error; |
| /* |
| * The domain is in process of dying (if we see this twice we |
| * have a problem ?) |
| */ |
| } else if (as.contains("d")) { |
| ns = State.Stopping; |
| } else { |
| ns = State.Unknown; |
| } |
| logger.trace("state " + ns + " for " + vm.getVmName() |
| + " based on " + as); |
| states.put(vm.getVmName(), ns); |
| } |
| return states; |
| } |
| |
| /** |
| * syncState: Sync the state the VMs are in on the hypervisor. |
| * |
| * @return |
| * @throws Ovm3ResourceException |
| */ |
| public Map<String, State> syncState() throws Ovm3ResourceException { |
| return syncState(this.vmStateMap); |
| } |
| |
| private Map<String, State> syncState(Map<String, State> vmStateMap) |
| throws Ovm3ResourceException { |
| Map<String, State> newStates; |
| Map<String, State> oldStates = null; |
| final Map<String, State> changes = new HashMap<String, State>(); |
| try { |
| newStates = getAllVmStates(vmStateMap); |
| } catch (Ovm3ResourceException e) { |
| logger.error("Ovm3 full sync failed: ", e); |
| throw e; |
| } |
| synchronized (vmStateMap) { |
| oldStates = new HashMap<String, State>(vmStateMap.size()); |
| oldStates.putAll(vmStateMap); |
| |
| for (final Map.Entry<String, State> entry : newStates.entrySet()) { |
| final String vmName = entry.getKey(); |
| State newState = entry.getValue(); |
| final State oldState = oldStates.remove(vmName); |
| logger.trace("state for " + vmName + ", old: " + oldState |
| + ", new: " + newState); |
| |
| /* eurh ? */ |
| if (newState == State.Stopped && oldState != State.Stopping |
| && oldState != null && oldState != State.Stopped) { |
| logger.trace("Getting power state...."); |
| newState = State.Running; |
| } |
| |
| if (logger.isTraceEnabled()) { |
| logger.trace("VM " + vmName + ": ovm has state " + newState |
| + " and we have state " |
| + (oldState != null ? oldState.toString() : "null")); |
| } |
| |
| if (newState == State.Migrating) { |
| logger.trace(vmName + " is migrating, skipping state check"); |
| continue; |
| } |
| |
| if (oldState == null) { |
| vmStateMap.put(vmName, newState); |
| logger.debug("New state without old state: " + vmName); |
| changes.put(vmName, newState); |
| } else if (oldState == State.Starting) { |
| if (newState == State.Running) { |
| vmStateMap.put(vmName, newState); |
| } else if (newState == State.Stopped) { |
| logger.debug("Ignoring vm " + vmName |
| + " because of a lag in starting the vm."); |
| } |
| } else if (oldState == State.Migrating) { |
| if (newState == State.Running) { |
| logger.debug("Detected that a migrating VM is now running: " |
| + vmName); |
| vmStateMap.put(vmName, newState); |
| } |
| } else if (oldState == State.Stopping) { |
| if (newState == State.Stopped) { |
| vmStateMap.put(vmName, newState); |
| } else if (newState == State.Running) { |
| logger.debug("Ignoring vm " + vmName |
| + " because of a lag in stopping the vm. "); |
| /* should kill it hard perhaps ? */ |
| } |
| } else if (oldState != newState) { |
| vmStateMap.put(vmName, newState); |
| if (newState == State.Stopped) { |
| // For now leave it be. |
| } |
| changes.put(vmName, newState); |
| } |
| } |
| |
| for (final Map.Entry<String, State> entry : oldStates.entrySet()) { |
| final String vmName = entry.getKey(); |
| final State oldState = entry.getValue(); |
| |
| if (oldState == State.Stopping) { |
| logger.debug("Removing VM " + vmName |
| + " in transition state stopping."); |
| vmStateMap.remove(vmName); |
| } else if (oldState == State.Starting) { |
| logger.debug("Removing VM " + vmName |
| + " in transition state starting."); |
| vmStateMap.remove(vmName); |
| } else if (oldState == State.Stopped) { |
| logger.debug("Stopped VM " + vmName + " removing."); |
| vmStateMap.remove(vmName); |
| } else if (oldState == State.Migrating) { |
| /* |
| * do something smarter here.. newstate should say stopping |
| * already |
| */ |
| logger.debug("Ignoring VM " + vmName |
| + " in migrating state."); |
| } else { |
| /* if it's not there name it stopping */ |
| State state = State.Stopping; |
| logger.debug("VM " + vmName |
| + " is now missing from ovm3 server so removing it"); |
| changes.put(vmName, state); |
| vmStateMap.remove(vmName); |
| vmStateMap.put(vmName, state); |
| } |
| } |
| } |
| return changes; |
| } |
| |
| /** |
| * convertStateToPower: Convert a state, running, starting, stopped etc to a |
| * power state. |
| * |
| * @param s |
| * @param powerStateMap |
| * @return |
| */ |
| private PowerState convertStateToPower(State s) { |
| final PowerState state = powerStateMaps.get(s.toString()); |
| return state == null ? PowerState.PowerUnknown : state; |
| } |
| |
| /** |
| * hostVmStateReport: Get all the VM states. |
| * |
| * @return |
| * @throws Ovm3ResourceException |
| */ |
| public Map<String, HostVmStateReportEntry> hostVmStateReport() |
| throws Ovm3ResourceException { |
| final Map<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>(); |
| for (final Map.Entry<String, State> vm : vmStateMap.entrySet()) { |
| logger.debug("VM " + vm.getKey() + " state: " + vm.getValue() + ":" |
| + convertStateToPower(vm.getValue())); |
| vmStates.put(vm.getKey(), new HostVmStateReportEntry( |
| convertStateToPower(vm.getValue()), c.getIp())); |
| } |
| return vmStates; |
| } |
| |
| /** |
| * CheckHealthAnwer: Check the health of an agent on the hypervisor. |
| * TODO: should elaborate here with checks... |
| * |
| * @param cmd |
| * @return |
| */ |
| public CheckHealthAnswer execute(CheckHealthCommand cmd) { |
| Common test = new Common(c); |
| String ping = "put"; |
| String pong; |
| try { |
| pong = test.echo(ping); |
| } catch (Ovm3ResourceException e) { |
| logger.debug("CheckHealth went wrong: " + config.getAgentHostname() |
| + ", " + e.getMessage(), e); |
| return new CheckHealthAnswer(cmd, false); |
| } |
| if (ping.contentEquals(pong)) { |
| return new CheckHealthAnswer(cmd, true); |
| } |
| logger.debug("CheckHealth did not receive " + ping + " but got " + pong |
| + " from " + config.getAgentHostname()); |
| return new CheckHealthAnswer(cmd, false); |
| } |
| |
| /** |
| * primaryCheck |
| * |
| * @return |
| */ |
| public boolean primaryCheck() { |
| if ("".equals(config.getOvm3PoolVip())) { |
| logger.debug("No cluster vip, not checking for primary"); |
| return false; |
| } |
| |
| try { |
| CloudstackPlugin cSp = new CloudstackPlugin(c); |
| if (cSp.dom0HasIp(config.getOvm3PoolVip())) { |
| logger.debug(config.getAgentHostname() |
| + " is a primary, already has vip " |
| + config.getOvm3PoolVip()); |
| config.setAgentIsPrimary(true); |
| } else if (cSp.ping(config.getOvm3PoolVip())) { |
| logger.debug(config.getAgentHostname() |
| + " has a primary, someone has vip " |
| + config.getOvm3PoolVip()); |
| config.setAgentHasPrimary(true); |
| } else { |
| logger.debug(config.getAgentHostname() |
| + " becomes a primary, no one has vip " |
| + config.getOvm3PoolVip()); |
| config.setAgentIsPrimary(true); |
| } |
| } catch (Ovm3ResourceException e) { |
| logger.debug(config.getAgentHostname() |
| + " can't reach primary: " + e.getMessage()); |
| config.setAgentHasPrimary(false); |
| } |
| return config.getAgentIsPrimary(); |
| } |
| |
| /* Check if the host is in ready state for CS */ |
| public ReadyAnswer execute(ReadyCommand cmd) { |
| try { |
| Linux host = new Linux(c); |
| Pool pool = new Pool(c); |
| |
| /* only interesting when doing cluster */ |
| if (!host.getIsPrimary() && config.getAgentInOvm3Cluster()) { |
| if (pool.getPoolPrimaryVip().equalsIgnoreCase(c.getIp())) { |
| /* check pool state here */ |
| return new ReadyAnswer(cmd); |
| } else { |
| logger.debug("Primary IP changes to " |
| + pool.getPoolPrimaryVip() + ", it should be " |
| + c.getIp()); |
| return new ReadyAnswer(cmd, "I am not the primary server"); |
| } |
| } else if (host.getIsPrimary()) { |
| logger.debug("Primary, not clustered " |
| + config.getAgentHostname()); |
| return new ReadyAnswer(cmd); |
| } else { |
| logger.debug("No primary, not clustered " |
| + config.getAgentHostname()); |
| return new ReadyAnswer(cmd); |
| } |
| } catch (CloudRuntimeException | Ovm3ResourceException e) { |
| logger.debug("XML RPC Exception" + e.getMessage(), e); |
| throw new CloudRuntimeException("XML RPC Exception" |
| + e.getMessage(), e); |
| } |
| |
| } |
| |
| /* check "the" virtual machine */ |
| public CheckVirtualMachineAnswer execute( |
| final CheckVirtualMachineCommand cmd) { |
| logger.debug("CheckVirtualMachineCommand: " + cmd.getVmName()); |
| String vmName = cmd.getVmName(); |
| try { |
| CloudstackPlugin plug = new CloudstackPlugin(c); |
| Integer vncPort = Integer.valueOf(plug.getVncPort(vmName)); |
| if (vncPort == 0) { |
| logger.warn("No VNC port for " + vmName); |
| } |
| /* we already have the state ftw */ |
| Map<String, State> states = getAllVmStates(vmStateMap); |
| State vmState = states.get(vmName); |
| if (vmState == null) { |
| logger.warn("Check state of " + vmName |
| + " return null in CheckVirtualMachineCommand"); |
| vmState = State.Stopped; |
| } |
| synchronized (vmStateMap) { |
| vmStateMap.put(vmName, State.Running); |
| } |
| return new CheckVirtualMachineAnswer(cmd, |
| convertStateToPower(vmState), vncPort); |
| } catch (Ovm3ResourceException e) { |
| logger.debug("Check migration for " + vmName + " failed", e); |
| return new CheckVirtualMachineAnswer(cmd, |
| convertStateToPower(State.Stopped), null); |
| } |
| } |
| |
| /* |
| * TODO: leave cluster, leave pool, release ownership, cleanout and |
| * start over ? |
| * For now leave it as we're not clustering in OVM terms. |
| */ |
| public MaintainAnswer execute(MaintainCommand cmd) { |
| logger.debug("MaintainCommand"); |
| /* |
| * try { |
| * Network net = new Network(c); |
| * net.stopOvsLocalConfig(config.getAgentControlNetworkName()); |
| * } catch (Ovm3ResourceException e) { |
| * logger.debug("unable to disable " + |
| * config.getAgentControlNetworkName(), e); |
| * } |
| */ |
| return new MaintainAnswer(cmd); |
| } |
| |
| public Answer execute(GetHostStatsCommand cmd) { |
| try { |
| CloudstackPlugin cSp = new CloudstackPlugin(c); |
| Map<String, String> stats = cSp.ovsDom0Stats(config |
| .getAgentPublicNetworkName()); |
| Double cpuUtil = Double.parseDouble(stats.get("cpu")); |
| Double rxBytes = Double.parseDouble(stats.get("rx")); |
| Double txBytes = Double.parseDouble(stats.get("tx")); |
| Double totalMemory = Double.parseDouble(stats.get("total")); |
| Double freeMemory = Double.parseDouble(stats.get("free")); |
| HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), |
| cpuUtil, rxBytes, txBytes, "host", totalMemory, freeMemory, |
| 0, 0); |
| return new GetHostStatsAnswer(cmd, hostStats); |
| } catch (Exception e) { |
| logger.debug("Unable to get host stats for: " + cmd.getHostName(), |
| e); |
| return new Answer(cmd, false, e.getMessage()); |
| } |
| } |
| |
| /* |
| * We rely on storage health with CheckOnHostCommand.... |
| */ |
| public FenceAnswer execute(FenceCommand cmd) { |
| logger.debug("FenceCommand"); |
| try { |
| Boolean res = false; |
| return new FenceAnswer(cmd, res, res.toString()); |
| } catch (Exception e) { |
| logger.error("Unable to fence" + cmd.getHostIp(), e); |
| return new FenceAnswer(cmd, false, e.getMessage()); |
| } |
| } |
| |
| public CheckOnHostAnswer execute(CheckOnHostCommand cmd) { |
| logger.debug("CheckOnHostCommand"); |
| CloudstackPlugin csp = new CloudstackPlugin(c); |
| try { |
| Boolean alive = csp.dom0CheckStorageHealth(config.getAgentScriptsDir(), |
| config.getAgentCheckStorageScript(), |
| cmd.getHost().getGuid(), |
| config.getAgentStorageCheckTimeout()); |
| String msg = ""; |
| if (alive == null) { |
| msg = "storage check failed for " + cmd.getHost().getGuid(); |
| } else if (alive) { |
| msg = "storage check ok for " + cmd.getHost().getGuid(); |
| } else { |
| msg = "storage dead for " + cmd.getHost().getGuid(); |
| } |
| logger.debug(msg); |
| return new CheckOnHostAnswer(cmd, alive, msg); |
| } catch (Ovm3ResourceException e) { |
| return new CheckOnHostAnswer(cmd, false, "Error while checking storage for " +cmd.getHost().getGuid() +": " + e.getMessage()); |
| } |
| } |
| } |