You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2015/03/12 07:05:00 UTC
[08/12] git commit: updated refs/heads/master to c27c694
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());
+ }
+ }
+}