http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3Configuration.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3Configuration.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3Configuration.java new file mode 100644 index 0000000..9950e4d --- /dev/null +++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3Configuration.java @@ -0,0 +1,466 @@ +/******************************************************************************* + * 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.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.naming.ConfigurationException; + +import org.apache.commons.lang.BooleanUtils; +import org.apache.log4j.Logger; + +import com.cloud.hypervisor.ovm3.objects.Network; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.net.NetUtils; + +/* holds config data for the Ovm3 Hypervisor */ +public class Ovm3Configuration { + private static final Logger LOGGER = Logger + .getLogger(Ovm3Configuration.class); + private String agentIp; + private Long agentZoneId; + private Long agentPodId; + private String agentPoolId; + private Long agentClusterId; + private String agentHostname; + private String csHostGuid; + private String agentSshUserName = "root"; + private String agentSshPassword; + private String agentOvsAgentUser = "oracle"; + private String agentOvsAgentPassword; + private Integer agentOvsAgentPort = 8899; + private Boolean agentOvsAgentSsl = false; + private String agentSshKeyFile = "id_rsa.cloud"; + private String agentOwnedByUuid = "d1a749d4295041fb99854f52ea4dea97"; + private Boolean agentIsMaster = false; + private Boolean agentHasMaster = false; + private Boolean agentInOvm3Pool = false; + private Boolean agentInOvm3Cluster = false; + private String ovm3PoolVip = ""; + private String agentPrivateNetworkName; + private String agentPublicNetworkName; + private String agentGuestNetworkName; + private String agentStorageNetworkName; + private String agentControlNetworkName = "control0"; + private String agentOvmRepoPath = "/OVS/Repositories"; + private String agentSecStoragePath = "/nfsmnt"; + private String agentScript = "cloudstack.py"; + private String agentCheckStorageScript = "storagehealth.py"; + private Integer agentStorageCheckTimeout = 120; + private Integer agentStorageCheckInterval = 1; + private List<String> agentScripts = Arrays.asList(agentCheckStorageScript, agentScript); + private String agentScriptsDir = "/opt/cloudstack/bin"; + private int domRSshPort = 3922; + private String domRCloudPath = "/opt/cloud/bin/"; + private String virtualdiskdir = "VirtualDisks"; + private String templatedir = "Templates"; + private Map<String, Network.Interface> agentInterfaces = null; + private Boolean istest = false; + private Map<String, Object> rawParams = new HashMap<String, Object>(); + + public Ovm3Configuration(Map<String, Object> params) + throws ConfigurationException { + setAgentZoneId(Long.parseLong((String) params.get("zone"))); + setAgentPodId(Long.parseLong(validateParam("PodId", + (String) params.get("pod")))); + setAgentClusterId(Long.parseLong((String) params.get("cluster"))); + setOvm3PoolVip(String.valueOf(params.get("ovm3vip"))); + setAgentInOvm3Pool(BooleanUtils.toBoolean((String) params + .get("ovm3pool"))); + setAgentInOvm3Cluster(BooleanUtils.toBoolean((String) params + .get("ovm3cluster"))); + setAgentHostname(validateParam("Hostname", (String) params.get("host"))); + setAgentIp((String) params.get("ip")); + if (params.get("agentport") != null) { + setAgentOvsAgentPort(Integer.parseInt((String) params + .get("agentport"))); + } + setAgentSshUserName(validateParam("Username", + (String) params.get("username"))); + setAgentSshPassword(validateParam("Password", + (String) params.get("password"))); + setCsHostGuid(validateParam("Cloudstack Host GUID", (String) params.get("guid"))); + setAgentOvsAgentUser(validateParam("OVS Username", + (String) params.get("agentusername"))); + setAgentOvsAgentPassword(validateParam("OVS Password", + (String) params.get("agentpassword"))); + setAgentPrivateNetworkName((String) params + .get("private.network.device")); + setAgentPublicNetworkName((String) params.get("public.network.device")); + setAgentGuestNetworkName((String) params.get("guest.network.device")); + setAgentStorageNetworkName((String) params + .get("storage.network.device1")); + this.setAgentStorageCheckTimeout(NumbersUtil.parseInt( + (String) params.get("ovm3.heartbeat.timeout"), + agentStorageCheckTimeout)); + this.setAgentStorageCheckInterval(NumbersUtil.parseInt( + (String) params.get("ovm3.heartbeat.interval"), + agentStorageCheckInterval)); + validatePoolAndCluster(); + if (params.containsKey("istest")) { + setIsTest((Boolean) params.get("istest")); + } + } + + /** + * validatePoolAndCluster: + * A cluster is impossible with a pool. + * A pool is impossible without a vip. + */ + private void validatePoolAndCluster() { + if (agentInOvm3Cluster) { + LOGGER.debug("Clustering requires a pool, setting pool to true"); + agentInOvm3Pool = true; + } + if (!NetUtils.isValidIp(ovm3PoolVip)) { + LOGGER.debug("No VIP, Setting ovm3pool and ovm3cluster to false"); + agentInOvm3Pool = false; + agentInOvm3Cluster = false; + ovm3PoolVip = ""; + } + } + + public String getAgentName() { + return agentHostname; + } + + public void setAgentName(String agentName) { + this.agentHostname = agentName; + } + + public String getAgentIp() { + return agentIp; + } + + public void setAgentIp(String agentIp) { + this.agentIp = agentIp; + } + + public Long getAgentZoneId() { + return agentZoneId; + } + + public void setAgentZoneId(Long agentZoneId) { + this.agentZoneId = agentZoneId; + } + + public Long getAgentPodId() { + return agentPodId; + } + + public void setAgentPodId(Long agentPodId) { + this.agentPodId = agentPodId; + } + + public String getAgentPoolId() { + return agentPoolId; + } + + public void setAgentPoolId(String agentPoolId) { + this.agentPoolId = agentPoolId; + } + + public Long getAgentClusterId() { + return agentClusterId; + } + + public void setAgentClusterId(Long agentClusterId) { + this.agentClusterId = agentClusterId; + } + + public String getAgentHostname() { + return agentHostname; + } + + public void setAgentHostname(String agentHostname) { + this.agentHostname = agentHostname; + } + + public String getCsHostGuid() { + return csHostGuid; + } + + public void setCsHostGuid(String csHostGuid) { + this.csHostGuid = csHostGuid; + } + + public String getAgentSshUserName() { + return agentSshUserName; + } + + public void setAgentSshUserName(String agentSshUserName) { + this.agentSshUserName = agentSshUserName; + } + + public String getAgentSshPassword() { + return agentSshPassword; + } + + public void setAgentSshPassword(String agentSshPassword) { + this.agentSshPassword = agentSshPassword; + } + + public String getAgentOvsAgentUser() { + return agentOvsAgentUser; + } + + public void setAgentOvsAgentUser(String agentOvsAgentUser) { + this.agentOvsAgentUser = agentOvsAgentUser; + } + + public String getAgentOvsAgentPassword() { + return agentOvsAgentPassword; + } + + public void setAgentOvsAgentPassword(String agentOvsAgentPassword) { + this.agentOvsAgentPassword = agentOvsAgentPassword; + } + + public Integer getAgentOvsAgentPort() { + return agentOvsAgentPort; + } + + public void setAgentOvsAgentPort(Integer agentOvsAgentPort) { + this.agentOvsAgentPort = agentOvsAgentPort; + } + + public Boolean getAgentOvsAgentSsl() { + return agentOvsAgentSsl; + } + + public void setAgentOvsAgentSsl(Boolean agentOvsAgentSsl) { + this.agentOvsAgentSsl = agentOvsAgentSsl; + } + + public String getAgentSshKeyFileName() { + return agentSshKeyFile; + } + + public void setAgentSshKeyFileName(String agentSshFile) { + this.agentSshKeyFile = agentSshFile; + } + + public String getAgentOwnedByUuid() { + return agentOwnedByUuid; + } + + public void setAgentOwnedByUuid(String agentOwnedByUuid) { + this.agentOwnedByUuid = agentOwnedByUuid; + } + + public Boolean getAgentIsMaster() { + return agentIsMaster; + } + + public void setAgentIsMaster(Boolean agentIsMaster) { + this.agentIsMaster = agentIsMaster; + } + + public Boolean getAgentHasMaster() { + return agentHasMaster; + } + + public void setAgentHasMaster(Boolean agentHasMaster) { + this.agentHasMaster = agentHasMaster; + } + + public Boolean getAgentInOvm3Pool() { + return agentInOvm3Pool; + } + + public void setAgentInOvm3Pool(Boolean agentInOvm3Pool) { + this.agentInOvm3Pool = agentInOvm3Pool; + } + + public Boolean getAgentInOvm3Cluster() { + return agentInOvm3Cluster; + } + + public void setAgentInOvm3Cluster(Boolean agentInOvm3Cluster) { + this.agentInOvm3Cluster = agentInOvm3Cluster; + } + + public String getOvm3PoolVip() { + return ovm3PoolVip; + } + + public void setOvm3PoolVip(String ovm3PoolVip) { + this.ovm3PoolVip = ovm3PoolVip; + } + + public String getAgentPrivateNetworkName() { + return agentPrivateNetworkName; + } + + public void setAgentPrivateNetworkName(String agentPrivateNetworkName) { + this.agentPrivateNetworkName = agentPrivateNetworkName; + } + + public String getAgentPublicNetworkName() { + return agentPublicNetworkName; + } + + public void setAgentPublicNetworkName(String agentPublicNetworkName) { + this.agentPublicNetworkName = agentPublicNetworkName; + } + + public String getAgentGuestNetworkName() { + return agentGuestNetworkName; + } + + public void setAgentGuestNetworkName(String agentGuestNetworkName) { + this.agentGuestNetworkName = agentGuestNetworkName; + } + + public String getAgentStorageNetworkName() { + return agentStorageNetworkName; + } + + public void setAgentStorageNetworkName(String agentStorageNetworkName) { + this.agentStorageNetworkName = agentStorageNetworkName; + } + + public String getAgentControlNetworkName() { + return agentControlNetworkName; + } + + public void setAgentControlNetworkName(String agentControlNetworkName) { + this.agentControlNetworkName = agentControlNetworkName; + } + + public String getAgentOvmRepoPath() { + return agentOvmRepoPath; + } + + public void setAgentOvmRepoPath(String agentOvmRepoPath) { + this.agentOvmRepoPath = agentOvmRepoPath; + } + + public String getAgentSecStoragePath() { + return agentSecStoragePath; + } + + public void setAgentSecStoragePath(String agentSecStoragePath) { + this.agentSecStoragePath = agentSecStoragePath; + } + + public int getDomRSshPort() { + return domRSshPort; + } + + public void setDomRSshPort(int domRSshPort) { + this.domRSshPort = domRSshPort; + } + + public String getDomRCloudPath() { + return domRCloudPath; + } + + public void setDomRCloudPath(String domRCloudPath) { + this.domRCloudPath = domRCloudPath; + } + public Boolean getIsTest() { + return istest; + } + public void setIsTest(Boolean t) { + istest = t; + } + public String getAgentScript() { + return agentScript; + } + + public void setAgentScript(String agentScript) { + this.agentScript = agentScript; + } + + public String getAgentScriptsDir() { + return agentScriptsDir; + } + + public void setAgentScriptsDir(String agentScriptsDir) { + this.agentScriptsDir = agentScriptsDir; + } + + public Map<String, Network.Interface> getAgentInterfaces() { + return agentInterfaces; + } + + public void setAgentInterfaces(Map<String, Network.Interface> agentInterfaces) { + this.agentInterfaces = agentInterfaces; + } + public List<String> getAgentScripts() { + return agentScripts; + } + + public void setAgentScripts(List<String> agentScripts) { + this.agentScripts = agentScripts; + } + public String getAgentCheckStorageScript() { + return agentCheckStorageScript; + } + + public void setAgentCheckStorageScript(String agentCheckStorageScript) { + this.agentCheckStorageScript = agentCheckStorageScript; + } + public Integer getAgentStorageCheckTimeout() { + return agentStorageCheckTimeout; + } + public void setAgentStorageCheckTimeout(Integer agentStorageCheckTimeout) { + this.agentStorageCheckTimeout = agentStorageCheckTimeout; + } + + public Integer getAgentStorageCheckInterval() { + return agentStorageCheckInterval; + } + + public void setAgentStorageCheckInterval(Integer agentStorageCheckInterval) { + this.agentStorageCheckInterval = agentStorageCheckInterval; + } + public String getVirtualDiskDir() { + return this.virtualdiskdir; + } + public String getTemplateDir() { + return this.templatedir; + } + /** + * ValidateParam: Validate the input for configure + * @param name + * @param param + * @return param + * @throws ConfigurationException + */ + private String validateParam(String name, String param) throws ConfigurationException { + if (param == null) { + String msg = "Unable to get " + name + " params are null"; + LOGGER.debug(msg); + throw new ConfigurationException(msg); + } + return param; + } + + public Map<String, Object> getRawParams() { + return rawParams; + } + public void setRawParams(Map<String, Object> params) { + rawParams.putAll(params); + } +}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorNetwork.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorNetwork.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorNetwork.java new file mode 100644 index 0000000..d688b0b --- /dev/null +++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorNetwork.java @@ -0,0 +1,251 @@ +/******************************************************************************* + * 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.util.List; + +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckNetworkAnswer; +import com.cloud.agent.api.CheckNetworkCommand; +import com.cloud.agent.api.PingTestCommand; +import com.cloud.agent.api.to.NicTO; +import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin; +import com.cloud.hypervisor.ovm3.objects.Connection; +import com.cloud.hypervisor.ovm3.objects.Network; +import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException; +import com.cloud.network.PhysicalNetworkSetupInfo; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; + +public class Ovm3HypervisorNetwork { + private static final Logger LOGGER = Logger + .getLogger(Ovm3HypervisorNetwork.class); + private Connection c; + private Ovm3Configuration config; + public Ovm3HypervisorNetwork(Connection conn, Ovm3Configuration ovm3config) { + c = conn; + config = ovm3config; + } + + public void configureNetworking() throws ConfigurationException { + /* TODO: setup meta tags for the management interface (probably + * required with multiple interfaces)? + */ + try { + Network net = new Network(c); + String controlIface = config.getAgentControlNetworkName(); + if (controlIface != null + && net.getInterfaceByName(controlIface) == null) { + LOGGER.debug("starting " + controlIface); + net.startOvsLocalConfig(controlIface); + /* ovs replies too "fast" so the bridge can be "busy" */ + int contCount = 0; + while (net.getInterfaceByName(controlIface) == null) { + LOGGER.debug("waiting for " + controlIface); + Thread.sleep(1 * 1000); + if (contCount > 9) { + throw new ConfigurationException("Unable to configure " + + controlIface + " on host " + + config.getAgentHostname()); + } + contCount++; + } + } else { + LOGGER.debug("already have " + controlIface); + } + /* + * The bridge is remembered upon reboot, but not the IP or the + * config. Zeroconf also adds the route again by default. + */ + net.ovsIpConfig(controlIface, "static", + NetUtils.getLinkLocalGateway(), + NetUtils.getLinkLocalNetMask()); + CloudstackPlugin cSp = new CloudstackPlugin(c); + cSp.ovsControlInterface(controlIface, + NetUtils.getLinkLocalCIDR()); + } catch (InterruptedException e) { + LOGGER.error("interrupted?", e); + } catch (Ovm3ResourceException e) { + String msg = "Basic configuration failed on " + config.getAgentHostname(); + LOGGER.error(msg, e); + throw new ConfigurationException(msg + ", " + e.getMessage()); + } + } + + /**/ + private boolean isNetworkSetupByName(String nameTag) { + if (nameTag != null) { + LOGGER.debug("Looking for network setup by name " + nameTag); + + try { + Network net = new Network(c); + net.getInterfaceList(); + if (net.getBridgeByName(nameTag) != null) { + LOGGER.debug("Found bridge with name: " + nameTag); + return true; + } + } catch (Ovm3ResourceException e) { + LOGGER.debug("Unxpected error looking for name: " + nameTag, e); + return false; + } + } + LOGGER.debug("No bridge with name: " + nameTag); + return false; + } + + /* this might have to change in the future, works for now... */ + public CheckNetworkAnswer execute(CheckNetworkCommand cmd) { + LOGGER.debug("Checking if network name setup is done on " + + config.getAgentHostname()); + + List<PhysicalNetworkSetupInfo> infoList = cmd + .getPhysicalNetworkInfoList(); + /* here we assume all networks are set */ + for (PhysicalNetworkSetupInfo info : infoList) { + if (info.getGuestNetworkName() == null) { + info.setGuestNetworkName(config.getAgentGuestNetworkName()); + } + if (info.getPublicNetworkName() == null) { + info.setPublicNetworkName(config.getAgentPublicNetworkName()); + } + if (info.getPrivateNetworkName() == null) { + info.setPrivateNetworkName(config.getAgentPrivateNetworkName()); + } + if (info.getStorageNetworkName() == null) { + info.setStorageNetworkName(config.getAgentStorageNetworkName()); + } + + if (!isNetworkSetupByName(info.getGuestNetworkName())) { + String msg = "Guest Physical Network id:" + + info.getPhysicalNetworkId() + + ", Guest Network is not configured on the backend by name " + + info.getGuestNetworkName(); + LOGGER.error(msg); + return new CheckNetworkAnswer(cmd, false, msg); + } + if (!isNetworkSetupByName(info.getPrivateNetworkName())) { + String msg = "Private Physical Network id:" + + info.getPhysicalNetworkId() + + ", Private Network is not configured on the backend by name " + + info.getPrivateNetworkName(); + LOGGER.error(msg); + return new CheckNetworkAnswer(cmd, false, msg); + } + if (!isNetworkSetupByName(info.getPublicNetworkName())) { + String msg = "Public Physical Network id:" + + info.getPhysicalNetworkId() + + ", Public Network is not configured on the backend by name " + + info.getPublicNetworkName(); + LOGGER.error(msg); + return new CheckNetworkAnswer(cmd, false, msg); + } + /* Storage network is optional, will revert to private otherwise */ + } + + return new CheckNetworkAnswer(cmd, true, + "Network Setup check by names is done"); + + } + + public Answer execute(PingTestCommand cmd) { + try { + if (cmd.getComputingHostIp() != null) { + CloudstackPlugin cSp = new CloudstackPlugin(c); + if (!cSp.ping(cmd.getComputingHostIp())) { + return new Answer(cmd, false, "ping failed"); + } + } else { + return new Answer(cmd, false, "why asks me to ping a router???"); + } + return new Answer(cmd, true, "success"); + } catch (Ovm3ResourceException e) { + LOGGER.debug("Ping " + cmd.getComputingHostIp() + " failed", e); + return new Answer(cmd, false, e.getMessage()); + } + } + + private String createVlanBridge(String networkName, Integer vlanId) + throws Ovm3ResourceException { + if (vlanId < 1 || vlanId > 4094) { + String msg = "Incorrect vlan " + vlanId + + ", needs to be between 1 and 4094"; + LOGGER.error(msg); + throw new CloudRuntimeException(msg); + } + Network net = new Network(c); + /* figure out if our bridged vlan exists, if not then create */ + String brName = networkName + "." + vlanId.toString(); + try { + String physInterface = net.getPhysicalByBridgeName(networkName); + if (net.getInterfaceByName(brName) == null) { + net.startOvsVlanBridge(brName, physInterface, vlanId); + } else { + LOGGER.debug("Interface " + brName + " already exists"); + } + } catch (Ovm3ResourceException e) { + String msg = "Unable to create vlan " + vlanId.toString() + + " bridge for " + networkName; + LOGGER.warn(msg + ": " + e); + throw new CloudRuntimeException(msg + ":" + e.getMessage()); + } + return brName; + } + /* getNetwork needs to be split in pure retrieval versus creation */ + public String getNetwork(NicTO nic) throws Ovm3ResourceException { + String vlanId = null; + String bridgeName = null; + if (nic.getBroadcastType() == BroadcastDomainType.Vlan) { + vlanId = BroadcastDomainType.getValue(nic.getBroadcastUri()); + } + + if (nic.getType() == TrafficType.Guest) { + if (nic.getBroadcastType() == BroadcastDomainType.Vlan + && !"untagged".equalsIgnoreCase(vlanId)) { + /* This is completely the wrong place for this, we should NEVER + * create a network when we're just trying to figure out if it's there + * The name of this is misleading and wrong. + */ + bridgeName = createVlanBridge(config.getAgentGuestNetworkName(), + Integer.valueOf(vlanId)); + } else { + bridgeName = config.getAgentGuestNetworkName(); + } + + /* VLANs for other mgmt traffic ? */ + } else if (nic.getType() == TrafficType.Control) { + bridgeName = config.getAgentControlNetworkName(); + } else if (nic.getType() == TrafficType.Public) { + bridgeName = config.getAgentPublicNetworkName(); + } else if (nic.getType() == TrafficType.Management) { + bridgeName = config.getAgentPrivateNetworkName(); + } else if (nic.getType() == TrafficType.Storage) { + bridgeName = config.getAgentStorageNetworkName(); + } else { + throw new CloudRuntimeException("Unknown network traffic type:" + + nic.getType()); + } + return bridgeName; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorSupport.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorSupport.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorSupport.java new file mode 100644 index 0000000..a9d8130 --- /dev/null +++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorSupport.java @@ -0,0 +1,752 @@ +/******************************************************************************* + * 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.log4j.Logger; + +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 { + private final Logger LOGGER = Logger.getLogger(Ovm3HypervisorSupport.class); + 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("ismaster", config.getAgentIsMaster().toString()); + d.put("hasmaster", config.getAgentHasMaster().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); + } + + /** + * materCheck + * + * @return + */ + public boolean masterCheck() { + if ("".equals(config.getOvm3PoolVip())) { + LOGGER.debug("No cluster vip, not checking for master"); + return false; + } + + try { + CloudstackPlugin cSp = new CloudstackPlugin(c); + if (cSp.dom0HasIp(config.getOvm3PoolVip())) { + LOGGER.debug(config.getAgentHostname() + + " is a master, already has vip " + + config.getOvm3PoolVip()); + config.setAgentIsMaster(true); + } else if (cSp.ping(config.getOvm3PoolVip())) { + LOGGER.debug(config.getAgentHostname() + + " has a master, someone has vip " + + config.getOvm3PoolVip()); + config.setAgentHasMaster(true); + } else { + LOGGER.debug(config.getAgentHostname() + + " becomes a master, no one has vip " + + config.getOvm3PoolVip()); + config.setAgentIsMaster(true); + } + } catch (Ovm3ResourceException e) { + LOGGER.debug(config.getAgentHostname() + + " can't reach master: " + e.getMessage()); + config.setAgentHasMaster(false); + } + return config.getAgentIsMaster(); + } + + /* 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.getIsMaster() && config.getAgentInOvm3Cluster()) { + if (pool.getPoolMasterVip().equalsIgnoreCase(c.getIp())) { + /* check pool state here */ + return new ReadyAnswer(cmd); + } else { + LOGGER.debug("Master IP changes to " + + pool.getPoolMasterVip() + ", it should be " + + c.getIp()); + return new ReadyAnswer(cmd, "I am not the master server"); + } + } else if (host.getIsMaster()) { + LOGGER.debug("Master, not clustered " + + config.getAgentHostname()); + return new ReadyAnswer(cmd); + } else { + LOGGER.debug("No master, 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()); + } + } +}
