You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ra...@apache.org on 2013/10/11 13:16:20 UTC

[1/2] git commit: updated refs/heads/hyperv to 16422cb

Updated Branches:
  refs/heads/hyperv f1c2c502e -> 16422cbc0


Implemented commands that are required for VR to bootup and Vm deployment to work


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/16422cbc
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/16422cbc
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/16422cbc

Branch: refs/heads/hyperv
Commit: 16422cbc0eaa9c0bb4e65e526dd341ec6e6c6a64
Parents: 33e19bf
Author: Rajesh Battala <ra...@citrix.com>
Authored: Fri Oct 11 13:42:42 2013 +0530
Committer: Rajesh Battala <ra...@citrix.com>
Committed: Fri Oct 11 16:43:32 2013 +0530

----------------------------------------------------------------------
 .../resource/HypervDirectConnectResource.java   | 690 ++++++++++++++++++-
 1 file changed, 689 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/16422cbc/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
index e22f284..57a9dfd 100644
--- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
+++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
@@ -16,11 +16,18 @@
 // under the License.
 package com.cloud.hypervisor.hyperv.resource;
 
+import java.io.File;
 import java.io.IOException;
+import java.net.ConnectException;
+import java.net.InetSocketAddress;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.channels.SocketChannel;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 import javax.naming.ConfigurationException;
 
@@ -36,6 +43,10 @@ import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
+import com.cloud.agent.api.GetDomRVersionAnswer;
+import com.cloud.agent.api.GetDomRVersionCmd;
+import com.cloud.agent.api.NetworkUsageAnswer;
+import com.cloud.agent.api.NetworkUsageCommand;
 import com.cloud.agent.api.PingCommand;
 import com.cloud.agent.api.PingRoutingCommand;
 import com.cloud.agent.api.StartupCommand;
@@ -43,12 +54,31 @@ import com.cloud.agent.api.StartupRoutingCommand;
 import com.cloud.agent.api.StartupStorageCommand;
 import com.cloud.agent.api.UnsupportedAnswer;
 import com.cloud.agent.api.StartupRoutingCommand.VmState;
+import com.cloud.agent.api.check.CheckSshAnswer;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.routing.CreateIpAliasCommand;
+import com.cloud.agent.api.routing.DhcpEntryCommand;
+import com.cloud.agent.api.routing.DnsMasqConfigCommand;
+import com.cloud.agent.api.routing.IpAliasTO;
+import com.cloud.agent.api.routing.IpAssocAnswer;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.SavePasswordCommand;
+import com.cloud.agent.api.routing.VmDataCommand;
+import com.cloud.agent.api.to.DhcpTO;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.dc.DataCenter.NetworkType;
 import com.cloud.host.Host.Type;
 import com.cloud.hypervisor.Hypervisor;
 import com.cloud.network.Networks.RouterPrivateIpStrategy;
 import com.cloud.resource.ServerResource;
 import com.cloud.resource.ServerResourceBase;
 import com.cloud.serializer.GsonHelper;
+import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.ssh.SshHelper;
+import com.cloud.vm.VirtualMachineName;
 import com.google.gson.Gson;
 
 /**
@@ -68,6 +98,11 @@ public class HypervDirectConnectResource extends ServerResourceBase implements
     private String _guid;
     private String _agentIp;
     private int _port = DEFAULT_AGENT_PORT;
+    protected final long _ops_timeout = 900000;  // 15 minutes time out to time
+
+    protected final int _retry = 24;
+    protected final int _sleep = 10000;
+    protected final int DEFAULT_DOMR_SSHPORT = 3922;
 
     private String _clusterGuid;
 
@@ -296,6 +331,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements
         // Using java.net.URI, see
         // http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URI.html
         URI agentUri = null;
+        Class<? extends Command> clazz = cmd.getClass();
+        Answer answer = null;
         try {
             String cmdName = cmd.getClass().getName();
             agentUri =
@@ -307,10 +344,36 @@ public class HypervDirectConnectResource extends ServerResourceBase implements
             s_logger.error(errMsg, e);
             return null;
         }
+
+        if (clazz == CheckSshCommand.class) {
+            answer = execute((CheckSshCommand) cmd);
+        } else if (clazz == GetDomRVersionCmd.class) {
+            answer = execute((GetDomRVersionCmd)cmd);
+        } else if (cmd instanceof NetworkUsageCommand) {
+           answer = execute((NetworkUsageCommand) cmd);
+        } else if (clazz == IpAssocCommand.class) {
+           answer = execute((IpAssocCommand) cmd);
+        } else if (clazz == DnsMasqConfigCommand.class) {
+            return execute((DnsMasqConfigCommand) cmd);
+        } else if (clazz == CreateIpAliasCommand.class) {
+            return execute((CreateIpAliasCommand) cmd);
+        } else if (clazz == DhcpEntryCommand.class) {
+            answer = execute((DhcpEntryCommand) cmd);
+        } else if (clazz == VmDataCommand.class) {
+            answer = execute((VmDataCommand) cmd);
+        } else if (clazz == SavePasswordCommand.class) {
+            answer = execute((SavePasswordCommand) cmd);
+        }
+
+        else {
+
+        // Else send the cmd to hyperv agent.
+
         String ansStr = postHttpRequest(s_gson.toJson(cmd), agentUri);
 
         if (ansStr == null) {
-            return null;
+            // return null;
+           return Answer.createUnsupportedCommandAnswer(cmd);
         }
         // Only Answer instances are returned by remote agents.
         // E.g. see Response.getAnswers()
@@ -320,9 +383,586 @@ public class HypervDirectConnectResource extends ServerResourceBase implements
         if (result.length > 0) {
             return result[0];
         }
+        }
+        return answer;
+    }
+
+    protected Answer execute(SavePasswordCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+
+            s_logger.info("Executing resource SavePasswordCommand. vmName: " + cmd.getVmName() + ", vmIp: " + cmd.getVmIpAddress() + ", password: "
+                    + StringUtils.getMaskedPasswordForDisplay(cmd.getPassword()));
+        }
+
+        String controlIp = getRouterSshControlIp(cmd);
+        final String password = cmd.getPassword();
+        final String vmIpAddress = cmd.getVmIpAddress();
+
+        // Run save_password_to_domr.sh
+        String args = " -v " + vmIpAddress;
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Run command on domain router " + controlIp + ", /root/savepassword.sh " + args + " -p " + StringUtils.getMaskedPasswordForDisplay(cmd.getPassword()));
+        }
+
+        args += " -p " + password;
+
+
+        try {
+
+            Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/savepassword.sh " + args);
+
+            if (!result.first()) {
+                s_logger.error("savepassword command on domain router " + controlIp + " failed, message: " + result.second());
+
+                return new Answer(cmd, false, "SavePassword failed due to " + result.second());
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("savepassword command on domain router " + controlIp + " completed");
+            }
+
+        } catch (Throwable e) {
+            String msg = "SavePasswordCommand failed due to " + e;
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+        return new Answer(cmd);
+    }
+
+
+
+    protected Answer execute(VmDataCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource VmDataCommand: " + s_gson.toJson(cmd));
+        }
+
+        String routerPrivateIpAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        String controlIp = getRouterSshControlIp(cmd);
+
+        String vmIpAddress = cmd.getVmIpAddress();
+        List<String[]> vmData = cmd.getVmData();
+        String[] vmDataArgs = new String[vmData.size() * 2 + 4];
+        vmDataArgs[0] = "routerIP";
+        vmDataArgs[1] = routerPrivateIpAddress;
+        vmDataArgs[2] = "vmIP";
+        vmDataArgs[3] = vmIpAddress;
+        int i = 4;
+        for (String[] vmDataEntry : vmData) {
+            String folder = vmDataEntry[0];
+            String file = vmDataEntry[1];
+            String contents = (vmDataEntry[2] != null) ? vmDataEntry[2] : "none";
+
+            vmDataArgs[i] = folder + "," + file;
+            vmDataArgs[i + 1] = contents;
+            i += 2;
+        }
+
+        String content = encodeDataArgs(vmDataArgs);
+        String tmpFileName = UUID.randomUUID().toString();
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Run vm_data command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", data: " + content);
+        }
+
+        try {
+            SshHelper.scpTo(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/tmp", content.getBytes(), tmpFileName, null);
+
+            try {
+                Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
+                        "/root/userdata.py " + tmpFileName);
+
+                if (!result.first()) {
+                    s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second());
+                    return new Answer(cmd, false, "VmDataCommand failed due to " + result.second());
+                }
+            } finally {
+
+                SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "rm /tmp/" + tmpFileName);
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("vm_data command on domain router " + controlIp + " completed");
+            }
+
+        } catch (Throwable e) {
+            String msg = "VmDataCommand failed due to " + e;
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+        return new Answer(cmd);
+    }
+
+
+    private String encodeDataArgs(String[] dataArgs) {
+        StringBuilder sb = new StringBuilder();
+
+        for (String arg : dataArgs) {
+            sb.append(arg);
+            sb.append("\n");
+        }
+
+        return sb.toString();
+    }
+
+
+    protected Answer execute(DhcpEntryCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource DhcpEntryCommand: " + s_gson.toJson(cmd));
+        }
+
+        // ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/root/edithosts.sh $mac $ip $vm $dfltrt $ns $staticrt" >/dev/null
+
+        String args = " -m " + cmd.getVmMac();
+        if (cmd.getVmIpAddress() != null) {
+            args += " -4 " + cmd.getVmIpAddress();
+        }
+        args += " -h " + cmd.getVmName();
+
+        if (cmd.getDefaultRouter() != null) {
+            args += " -d " + cmd.getDefaultRouter();
+        }
+
+        if (cmd.getDefaultDns() != null) {
+            args += " -n " + cmd.getDefaultDns();
+        }
+
+        if (cmd.getStaticRoutes() != null) {
+            args += " -s " + cmd.getStaticRoutes();
+        }
+
+        if (cmd.getVmIp6Address() != null) {
+            args += " -6 " + cmd.getVmIp6Address();
+            args += " -u " + cmd.getDuid();
+        }
+
+        if (!cmd.isDefault()) {
+            args += " -N";
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/edithosts.sh " + args);
+        }
+
+        try {
+            String controlIp = getRouterSshControlIp(cmd);
+            Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
+                    "/root/edithosts.sh " + args);
+
+            if (!result.first()) {
+                s_logger.error("dhcp_entry command on domR " + controlIp + " failed, message: " + result.second());
+
+                return new Answer(cmd, false, "DhcpEntry failed due to " + result.second());
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("dhcp_entry command on domain router " + controlIp + " completed");
+            }
+
+        } catch (Throwable e) {
+            String msg = "DhcpEntryCommand failed due to " + e;
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+
+        return new Answer(cmd);
+    }
+
+
+
+
+
+    protected Answer execute(final CreateIpAliasCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing createIpAlias command: " + s_gson.toJson(cmd));
+        }
+        cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        List<IpAliasTO> ipAliasTOs = cmd.getIpAliasList();
+        String args="";
+        for (IpAliasTO ipaliasto : ipAliasTOs) {
+            args = args + ipaliasto.getAlias_count()+":"+ipaliasto.getRouterip()+":"+ipaliasto.getNetmask()+"-";
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/createIpAlias " + args);
+        }
+
+        try {
+            String controlIp = getRouterSshControlIp(cmd);
+            Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
+                    "/root/createIpAlias.sh " + args);
+
+            if (!result.first()) {
+                s_logger.error("CreateIpAlias command on domr " + controlIp + " failed, message: " + result.second());
+
+                return new Answer(cmd, false, "createipAlias failed due to " + result.second());
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("createIpAlias command on domain router " + controlIp + " completed");
+            }
+
+        } catch (Throwable e) {
+            String msg = "createIpAlias failed due to " + e;
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+
+        return new Answer(cmd);
+    }
+
+
+    protected Answer execute(final DnsMasqConfigCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing dnsmasqConfig command: " + s_gson.toJson(cmd));
+        }
+        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        String controlIp = getRouterSshControlIp(cmd);
+
+        assert(controlIp != null);
+
+        List<DhcpTO> dhcpTos = cmd.getIps();
+        String args ="";
+        for(DhcpTO dhcpTo : dhcpTos) {
+            args = args + dhcpTo.getRouterIp()+":"+dhcpTo.getGateway()+":"+dhcpTo.getNetmask()+":"+dhcpTo.getStartIpOfSubnet()+"-";
+        }
+        //File keyFile = mgr.getSystemVMKeyFile();
+
+        try {
+            Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/dnsmasq.sh " + args);
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Run command on domain router " + routerIp + ",  /root/dnsmasq.sh");
+            }
+
+            if (!result.first()) {
+                s_logger.error("Unable update dnsmasq config file");
+                return new Answer(cmd, false, "dnsmasq config update failed due to: " + result.second());
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("dnsmasq config command on domain router " + routerIp + " completed");
+            }
+        }catch (Throwable e) {
+            String msg = "Dnsmasqconfig command failed due to " + e.getMessage();
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+
+        return new Answer(cmd);
+    }
+
+
+
+    protected Answer execute(IpAssocCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource IPAssocCommand: " + s_gson.toJson(cmd));
+        }
+
+        int i = 0;
+        String[] results = new String[cmd.getIpAddresses().length];
+
+        try {
+
+            IpAddressTO[] ips = cmd.getIpAddresses();
+            String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+            String controlIp = getRouterSshControlIp(cmd);
+            for (IpAddressTO ip : ips) {
+                assignPublicIpAddress(routerName, controlIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), ip.getVlanGateway(), ip.getVlanNetmask(),ip.getVifMacAddress());
+                results[i++] = ip.getPublicIp() + " - success";
+            }
+
+            for (; i < cmd.getIpAddresses().length; i++) {
+                results[i++] = IpAssocAnswer.errorResult;
+            }
+            } catch (Throwable e) {
+            s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e);
+
+            for (; i < cmd.getIpAddresses().length; i++) {
+                results[i++] = IpAssocAnswer.errorResult;
+            }
+        }
+
+        return new IpAssocAnswer(cmd, results);
+    }
+
+    protected void assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP,
+            final boolean sourceNat, final String vlanId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws Exception {
+
+        //String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId);
+        //Pair<Integer, VirtualDevice> publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName);
+
+        if (s_logger.isDebugEnabled()) {
+            //s_logger.debug("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo.first());
+        }
+
+        boolean addVif = false;
+        boolean removeVif = false;
+        if (add ) { // && publicNicInfo.first().intValue() == -1) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Plug new NIC to associate" + privateIpAddress + " to " + publicIpAddress);
+            }
+
+            addVif = true;
+        } else if (!add && firstIP) {
+            removeVif = true;
+
+            if (s_logger.isDebugEnabled()) {
+                //s_logger.debug("Unplug NIC " + publicNicInfo.first());
+            }
+        }
+
+/*        if (addVif) {
+            plugPublicNic(vmMo, vlanId, vifMacAddress);
+            publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName);
+            if (publicNicInfo.first().intValue() >= 0) {
+                networkUsage(privateIpAddress, "addVif", "eth" + publicNicInfo.first());
+            }
+        }
+*/
+/*        if (publicNicInfo.first().intValue() < 0) {
+            String msg = "Failed to find DomR VIF to associate/disassociate IP with.";
+            s_logger.error(msg);
+            throw new InternalErrorException(msg);
+        }
+*/
+        String args = null;
+
+        if (add) {
+            args = " -A ";
+        } else {
+            args = " -D ";
+        }
+
+        if (sourceNat) {
+            args += " -s ";
+        }
+        if (firstIP) {
+            args += " -f ";
+        }
+        String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask));
+        args += " -l ";
+        args += publicIpAddress + "/" + cidrSize;
+
+        args += " -c ";
+        args += "eth" +"2";  // currently hardcoding to eth 2 (which is default public ipd)//publicNicInfo.first();
+
+        args += " -g ";
+        args += vlanGateway;
+
+        if (addVif) {
+            args += " -n ";
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Run command on domain router " + privateIpAddress + ", /opt/cloud/bin/ipassoc.sh " + args);
+        }
+
+        Pair<Boolean, String> result = SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/ipassoc.sh " + args);
+
+        if (!result.first()) {
+            s_logger.error("ipassoc command on domain router " + privateIpAddress + " failed. message: " + result.second());
+            throw new Exception("ipassoc failed due to " + result.second());
+        }
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("ipassoc command on domain router " + privateIpAddress + " completed");
+        }
+    }
+
+
+   protected Answer execute(GetDomRVersionCmd cmd) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Executing resource GetDomRVersionCmd: " + s_gson.toJson(cmd));
+            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/get_template_version.sh ");
+        }
+
+        Pair<Boolean, String> result;
+        try {
+            String controlIp = getRouterSshControlIp(cmd);
+            result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
+                    "/opt/cloud/bin/get_template_version.sh ");
+
+            if (!result.first()) {
+                s_logger.error("GetDomRVersionCmd on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second());
+
+                return new GetDomRVersionAnswer(cmd, "GetDomRVersionCmd failed due to " + result.second());
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("GetDomRVersionCmd on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed");
+            }
+        } catch (Throwable e) {
+            String msg = "GetDomRVersionCmd failed due to " + e;
+            s_logger.error(msg, e);
+            return new GetDomRVersionAnswer(cmd, msg);
+        }
+        String[] lines = result.second().split("&");
+        if (lines.length != 2) {
+            return new GetDomRVersionAnswer(cmd, result.second());
+        }
+        return new GetDomRVersionAnswer(cmd, result.second(), lines[0], lines[1]);
+    }
+
+
+    private static String getRouterSshControlIp(NetworkElementCommand cmd) {
+        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        String routerGuestIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP);
+        String zoneNetworkType = cmd.getAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE);
+
+        if(routerGuestIp != null && zoneNetworkType != null && NetworkType.valueOf(zoneNetworkType) == NetworkType.Basic) {
+            if(s_logger.isDebugEnabled())
+                s_logger.debug("In Basic zone mode, use router's guest IP for SSH control. guest IP : " + routerGuestIp);
+
+            return routerGuestIp;
+        }
+
+        if(s_logger.isDebugEnabled())
+            s_logger.debug("Use router's private IP for SSH control. IP : " + routerIp);
+        return routerIp;
+    }
+
+    protected Answer execute(NetworkUsageCommand cmd) {
+/*        if ( cmd.isForVpc() ) {
+            return VPCNetworkUsage(cmd);
+        }
+*/        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource NetworkUsageCommand "+ s_gson.toJson(cmd));
+        }
+        if(cmd.getOption()!=null && cmd.getOption().equals("create") ){
+            String result = networkUsage(cmd.getPrivateIP(), "create", null);
+            NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "true", 0L, 0L);
+            return answer;
+        }
+        long[] stats = getNetworkStats(cmd.getPrivateIP());
+
+        NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]);
+        return answer;
+    }
+    private long[] getNetworkStats(String privateIP) {
+        String result = networkUsage(privateIP, "get", null);
+        long[] stats = new long[2];
+        if (result != null) {
+            try {
+                String[] splitResult = result.split(":");
+                int i = 0;
+                while (i < splitResult.length - 1) {
+                    stats[0] += (new Long(splitResult[i++])).longValue();
+                    stats[1] += (new Long(splitResult[i++])).longValue();
+                }
+            } catch (Throwable e) {
+                s_logger.warn("Unable to parse return from script return of network usage command: " + e.toString(), e);
+            }
+        }
+        return stats;
+    }
+
+
+    protected CheckSshAnswer execute(CheckSshCommand cmd) {
+        String vmName = cmd.getName();
+        String privateIp = cmd.getIp();
+        int cmdPort = cmd.getPort();
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort);
+        }
+
+        try {
+            String result = connect(cmd.getName(), privateIp, cmdPort);
+            if (result != null) {
+                s_logger.error("Can not ping System vm " + vmName + "due to:" + result);
+                return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + "due to:" + result);
+            }
+        } catch (Exception e) {
+            s_logger.error("Can not ping System vm " + vmName + "due to exception");
+            return new CheckSshAnswer(cmd, e);
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Ping command port succeeded for vm " + vmName);
+        }
+
+        if (VirtualMachineName.isValidRouterName(vmName)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Execute network usage setup command on " + vmName);
+            }
+            networkUsage(privateIp, "create", null);
+        }
+
+        return new CheckSshAnswer(cmd);
+    }
+
+
+    protected String networkUsage(final String privateIpAddress, final String option, final String ethName) {
+        String args = null;
+        if (option.equals("get")) {
+            args = "-g";
+        } else if (option.equals("create")) {
+            args = "-c";
+        } else if (option.equals("reset")) {
+            args = "-r";
+        } else if (option.equals("addVif")) {
+            args = "-a";
+            args += ethName;
+        } else if (option.equals("deleteVif")) {
+            args = "-d";
+            args += ethName;
+        }
+
+        try {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Executing /opt/cloud/bin/netusage.sh " + args + " on DomR " + privateIpAddress);
+            }
+
+            Pair<Boolean, String> result = SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/netusage.sh " + args);
+
+            if (!result.first()) {
+                return null;
+            }
+
+            return result.second();
+        } catch (Throwable e) {
+            s_logger.error("Unable to execute NetworkUsage command on DomR (" + privateIpAddress + "), domR may not be ready yet. failure due to "
+                    + e);
+        }
+
         return null;
     }
 
+    private File getSystemVMPatchIsoFile() {
+        // locate systemvm.iso
+        URL url = this.getClass().getClassLoader().getResource("vms/systemvm.iso");
+        File isoFile = null;
+        if (url != null) {
+            isoFile = new File(url.getPath());
+        }
+
+        if(isoFile == null || !isoFile.exists()) {
+            isoFile = new File("/usr/share/cloudstack-common/vms/systemvm.iso");
+        }
+
+        assert(isoFile != null);
+        if(!isoFile.exists()) {
+            s_logger.error("Unable to locate systemvm.iso in your setup at " + isoFile.toString());
+        }
+        return isoFile;
+    }
+
+    public File getSystemVMKeyFile() {
+        URL url = this.getClass().getClassLoader().getResource("scripts/vm/systemvm/id_rsa.cloud");
+        File keyFile = null;
+        if ( url != null ){
+            keyFile = new File(url.getPath());
+        }
+        if (keyFile == null || !keyFile.exists()) {
+            keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud");
+        }
+        assert(keyFile != null);
+        if(!keyFile.exists()) {
+            s_logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile.toString());
+        }
+        return keyFile;
+    }
+
+
     public static String postHttpRequest(final String jsonCmd,
             final URI agentUri) {
         // Using Apache's HttpClient for HTTP POST
@@ -450,5 +1090,53 @@ public class HypervDirectConnectResource extends ServerResourceBase implements
     public void setRunLevel(final int level) {
         // TODO Auto-generated method stub
     }
+    protected String connect(final String vmName, final String ipAddress, final int port) {
+        long startTick = System.currentTimeMillis();
+
+        // wait until we have at least been waiting for _ops_timeout time or
+        // at least have tried _retry times, this is to coordinate with system
+        // VM patching/rebooting time that may need
+        int retry = _retry;
+        while (System.currentTimeMillis() - startTick <= _ops_timeout || --retry > 0) {
+            SocketChannel sch = null;
+            try {
+                s_logger.info("Trying to connect to " + ipAddress);
+                sch = SocketChannel.open();
+                sch.configureBlocking(true);
+                sch.socket().setSoTimeout(5000);
+
+                InetSocketAddress addr = new InetSocketAddress(ipAddress, port);
+                sch.connect(addr);
+                return null;
+            } catch (IOException e) {
+                s_logger.info("Could not connect to " + ipAddress + " due to " + e.toString());
+                if (e instanceof ConnectException) {
+                    // if connection is refused because of VM is being started,
+                    // we give it more sleep time
+                    // to avoid running out of retry quota too quickly
+                    try {
+                        Thread.sleep(5000);
+                    } catch (InterruptedException ex) {
+                    }
+                }
+            } finally {
+                if (sch != null) {
+                    try {
+                        sch.close();
+                    } catch (IOException e) {
+                    }
+                }
+            }
+
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ex) {
+            }
+        }
+
+        s_logger.info("Unable to logon to " + ipAddress);
+
+        return "Unable to connect";
+    }
 
 }


[2/2] git commit: updated refs/heads/hyperv to 16422cb

Posted by ra...@apache.org.
modifified cloud-early-config to configure, when the VR boots up in HyperV Environment


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/33e19bf1
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/33e19bf1
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/33e19bf1

Branch: refs/heads/hyperv
Commit: 33e19bf1875b3a01d4ef3b790a92a152da1773f4
Parents: f1c2c50
Author: Rajesh Battala <ra...@citrix.com>
Authored: Fri Oct 11 12:13:41 2013 +0530
Committer: Rajesh Battala <ra...@citrix.com>
Committed: Fri Oct 11 16:43:32 2013 +0530

----------------------------------------------------------------------
 .../debian/config/etc/init.d/cloud-early-config    | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/33e19bf1/systemvm/patches/debian/config/etc/init.d/cloud-early-config
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config
index 88ecc11..1cc399f 100755
--- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config
+++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config
@@ -130,12 +130,11 @@ get_boot_params() {
      vmware)
           vmtoolsd --cmd 'machine.id.get' > /var/cache/cloud/cmdline 
           ;;
-     virtualpc)
-          # Hyper-V is recognized as virtualpc hypervisor type. Boot args are passed in the NTFS data-disk
-          mkdir -p $EXTRA_MOUNT
-          mount -t ntfs /dev/sdb1 $EXTRA_MOUNT
-          cp -f $EXTRA_MOUNT/cmdline /var/cache/cloud/cmdline
-          umount $EXTRA_MOUNT
+     virtualpc|hyperv)
+          # Hyper-V is recognized as virtualpc hypervisor type. Boot args are passed using KVP Daemon
+          #waiting for the hv_kvp_daemon to start up
+          #sleep 30 need to fix the race condition of hv_kvp_daemon and cloud-early-config
+          cp -f /var/opt/hyperv/.kvp_pool_0 /var/cache/cloud/cmdline
           ;;
   esac
 
@@ -157,6 +156,10 @@ patch() {
        cdrom_dev=/dev/cdrom
   elif [ -e /dev/cdrom1 ]; then
        cdrom_dev=/dev/cdrom1
+  elif [ -e /dev/cdrom2 ]; then
+       cdrom_dev=/dev/cdrom2
+  elif [ -e /dev/cdrom3 ]; then
+       cdrom_dev=/dev/cdrom3
   fi
   [ -f /var/cache/cloud/authorized_keys ] && privkey=/var/cache/cloud/authorized_keys
 
@@ -718,7 +721,7 @@ setup_dnsmasq() {
   [ $ETH0_IP ] && echo "dhcp-option=6,$NS" >> /etc/dnsmasq.conf
   [ $ETH0_IP6 ] && echo "dhcp-option=option6:dns-server,$NS6" >> /etc/dnsmasq.conf
 #adding the name data-server to the /etc/hosts for allowing the access to user-data service and ssh-key reset in every subnet.
-  //removing the existing entires to avoid duplicates on restarts.
+#removing the existing entires to avoid duplicates on restarts.
   sed -i  '/data-server/d' /etc/hosts
   if [ -n "$ETH0_IP" ]
           then