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());
+        }
+    }
+}