You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by de...@apache.org on 2014/02/11 08:28:49 UTC

git commit: updated refs/heads/master to b86d45b

Updated Branches:
  refs/heads/master c1cfaa2d1 -> b86d45b00


CLOUDSTACK-6054: Changes for making vmsync work for hyper-v. Made changes to PingCommand and
StartupCommand to return the state of all vms on the host.


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

Branch: refs/heads/master
Commit: b86d45b0036482cfc9c9fc55f62954a1b9599188
Parents: c1cfaa2
Author: Anshul Gangwar <an...@citrix.com>
Authored: Mon Feb 10 09:41:41 2014 -0800
Committer: Devdeep Singh <de...@gmail.com>
Committed: Tue Feb 11 12:19:41 2014 +0530

----------------------------------------------------------------------
 .../HypervResource/CloudStackTypes.cs           |  1 +
 .../HypervResource/HypervResourceController.cs  | 76 ++++++++++++++------
 .../HypervResource/IWmiCallsV2.cs               |  1 +
 .../ServerResource/HypervResource/WmiCallsV2.cs | 25 +++++++
 .../resource/HypervDirectConnectResource.java   | 51 ++++++++++++-
 5 files changed, 131 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b86d45b0/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
index c2421ef..2f5be7f 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
@@ -918,5 +918,6 @@ namespace HypervResource
         public const string DeleteCommand = "org.apache.cloudstack.storage.command.DeleteCommand";
         public const string DettachAnswer = "org.apache.cloudstack.storage.command.DettachAnswer";
         public const string DettachCommand = "org.apache.cloudstack.storage.command.DettachCommand";
+        public const string HostVmStateReportCommand = "org.apache.cloudstack.HostVmStateReportCommand";
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b86d45b0/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
index 718ef05..5ba78fe 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
@@ -2103,42 +2103,76 @@ namespace HypervResource
             }
         }
 
-        // POST api/HypervResource/GetVncPortCommand
+        // POST api/HypervResource/GetVncPortCommand
+        [HttpPost]
+        [ActionName(CloudStackTypes.GetVncPortCommand)]
+        public JContainer GetVncPortCommand([FromBody]dynamic cmd)
+        {
+            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
+            {
+                logger.Info(CloudStackTypes.GetVncPortCommand + cmd.ToString());
+
+                string details = null;
+                bool result = false;
+                string address = null;
+                int port = -9;
+
+                try
+                {
+                    string vmName = (string)cmd.name;
+                    var sys = wmiCallsV2.GetComputerSystem(vmName);
+                    address = "instanceId=" + sys.Name ;
+                    result = true;
+                }
+                catch (Exception sysEx)
+                {
+                    details = CloudStackTypes.GetVncPortAnswer + " failed due to " + sysEx.Message;
+                    logger.Error(details, sysEx);
+                }
+
+                object ansContent = new
+                {
+                    result = result,
+                    details = details,
+                    address = address,
+                    port = port
+                };
+
+                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVncPortAnswer);
+            }
+        }
+
+        // POST api/HypervResource/HostVmStateReportCommand
         [HttpPost]
-        [ActionName(CloudStackTypes.GetVncPortCommand)]
-        public JContainer GetVncPortCommand([FromBody]dynamic cmd)
+        [ActionName(CloudStackTypes.HostVmStateReportCommand)]
+        public JContainer HostVmStateReportCommand([FromBody]dynamic cmd)
         {
             using (log4net.NDC.Push(Guid.NewGuid().ToString()))
             {
-                logger.Info(CloudStackTypes.GetVncPortCommand + cmd.ToString());
+                logger.Info(CloudStackTypes.HostVmStateReportCommand + cmd.ToString());
 
                 string details = null;
-                bool result = false;
-                string address = null;
-                int port = -9;
+                Dictionary<string, string>[] hostVmStateReport = null;
 
                 try
                 {
-                    string vmName = (string)cmd.name;
-                    var sys = wmiCallsV2.GetComputerSystem(vmName);
-                    address = "instanceId=" + sys.Name ;
-                    result = true;
+                    var vmCollection = wmiCallsV2.GetComputerSystemCollection();
+                    hostVmStateReport = new Dictionary<string, string>[vmCollection.Count];
+                    int i = 0;
+                    foreach (ComputerSystem vm in vmCollection)
+                    {
+                        var dict = new Dictionary<string, string>();
+                        dict.Add(vm.ElementName, EnabledState.ToCloudStackPowerState(vm.EnabledState));
+                        hostVmStateReport[i++] = dict;
+                    }
                 }
                 catch (Exception sysEx)
                 {
-                    details = CloudStackTypes.GetVncPortAnswer + " failed due to " + sysEx.Message;
+                    details = CloudStackTypes.HostVmStateReportCommand + " failed due to " + sysEx.Message;
                     logger.Error(details, sysEx);
                 }
 
-                object ansContent = new
-                {
-                    result = result,
-                    details = details,
-                    address = address,
-                    port = port
-                };
-
-                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVncPortAnswer);
+                return JArray.FromObject(hostVmStateReport);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b86d45b0/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
index 9042d7c..da6ad83 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
@@ -42,6 +42,7 @@ namespace HypervResource
         void MigrateVm(string vmName, string destination);
         void DetachDisk(string displayName, string diskFileName);
         ComputerSystem GetComputerSystem(string displayName);
+        ComputerSystem.ComputerSystemCollection GetComputerSystemCollection();
         string GetDefaultDataRoot();
         string GetDefaultVirtualDiskFolder();
         ResourceAllocationSettingData GetDvdDriveSettings(VirtualSystemSettingData vmSettings);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b86d45b0/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
index dde6e21..d2b9ce1 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
@@ -1874,6 +1874,12 @@ namespace HypervResource
             return null;
         }
 
+        public ComputerSystem.ComputerSystemCollection GetComputerSystemCollection()
+        {
+            var wmiQuery = String.Format("Caption=\"Virtual Machine\"");
+            return ComputerSystem.GetInstances(wmiQuery);
+        }
+
         public Dictionary<String, VmState> GetVmSync(String privateIpAddress)
         {
             List<String> vms = GetVmElementNames();
@@ -2474,5 +2480,24 @@ namespace HypervResource
             }
             return result;
         }
+
+        public static string ToCloudStackPowerState(UInt16 value)
+        {
+            string result = "Unknown";
+            switch (value)
+            {
+                case Enabled: result = "PowerOn"; break;
+                case Disabled: result = "PowerOff"; break;
+                case Paused: result = "PowerUnknown"; break;
+                case Suspended: result = "PowerUnknown"; break;
+                case Starting: result = "PowerOn"; break;
+                case Snapshotting: result = "PowerUnknown"; break; // NOT used
+                case Saving: result = "PowerOn"; break;
+                case Stopping: result = "PowerOff"; break;
+                case Pausing: result = "PowerUnknown"; break;
+                case Resuming: result = "PowerOn"; break;
+            }
+            return result;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b86d45b0/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 2f64590..c79373a 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
@@ -62,6 +62,7 @@ import org.apache.http.util.EntityUtils;
 import org.apache.log4j.Logger;
 
 import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.CheckRouterAnswer;
@@ -139,6 +140,7 @@ import com.cloud.utils.StringUtils;
 import com.cloud.utils.net.NetUtils;
 import com.cloud.utils.ssh.SshHelper;
 import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.PowerState;
 import com.cloud.vm.VirtualMachineName;
 
 
@@ -148,6 +150,7 @@ import com.cloud.vm.VirtualMachineName;
 @Local(value = ServerResource.class)
 public class HypervDirectConnectResource extends ServerResourceBase implements ServerResource {
     public static final int DEFAULT_AGENT_PORT = 8250;
+    public static final String HOST_VM_STATE_REPORT_COMMAND = "org.apache.cloudstack.HostVmStateReportCommand";
     private static final Logger s_logger = Logger.getLogger(HypervDirectConnectResource.class.getName());
 
     private static final Gson s_gson = GsonHelper.getGson();
@@ -209,6 +212,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
         defaultStartRoutCmd.setPrivateIpAddress(_agentIp);
         defaultStartRoutCmd.setStorageIpAddress(_agentIp);
         defaultStartRoutCmd.setPool(_clusterGuid);
+        defaultStartRoutCmd.setHostVmStateReport(getHostVmStateReport());
 
         s_logger.debug("Generated StartupRoutingCommand for _agentIp \"" + _agentIp + "\"");
 
@@ -300,8 +304,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
 
     @Override
     public final PingCommand getCurrentStatus(final long id) {
-        // TODO, need to report VM states on host
-        PingCommand pingCmd = new PingRoutingCommand(getType(), id, null, null);
+        PingCommand pingCmd = new PingRoutingCommand(getType(), id, null, getHostVmStateReport());
 
         if (s_logger.isDebugEnabled()) {
             s_logger.debug("Ping host " + _name + " (IP " + _agentIp + ")");
@@ -316,6 +319,50 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
         return pingCmd;
     }
 
+    public final ArrayList<Map<String, String>> requestHostVmStateReport() {
+        URI agentUri = null;
+        try {
+            agentUri = new URI("https", null, _agentIp, _port, "/api/HypervResource/" + HOST_VM_STATE_REPORT_COMMAND, null, null);
+        } catch (URISyntaxException e) {
+            String errMsg = "Could not generate URI for Hyper-V agent";
+            s_logger.error(errMsg, e);
+            return null;
+        }
+        String incomingCmd = postHttpRequest("{}", agentUri);
+
+        if (incomingCmd == null) {
+            return null;
+        }
+        ArrayList<Map<String, String>> result = null;
+        try {
+            result = s_gson.fromJson(incomingCmd, new TypeToken<ArrayList<HashMap<String, String>>>() {
+            }.getType());
+        } catch (Exception ex) {
+            String errMsg = "Failed to deserialize Command[] " + incomingCmd;
+            s_logger.error(errMsg, ex);
+        }
+        s_logger.debug("HostVmStateReportCommand received response "
+                + s_gson.toJson(result));
+        if (!result.isEmpty()) {
+            return result;
+        }
+        return null;
+    }
+
+    protected HashMap<String, HostVmStateReportEntry> getHostVmStateReport() {
+        final HashMap<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>();
+        ArrayList<Map<String, String>> vmList = requestHostVmStateReport();
+        if (vmList == null || vmList.isEmpty()) {
+            return null;
+        }
+
+        for (Map<String, String> vmMap : vmList) {
+            String name = (String)vmMap.keySet().toArray()[0];
+            vmStates.put(name, new HostVmStateReportEntry(PowerState.valueOf(vmMap.get(name)), _guid, null));
+        }
+        return vmStates;
+    }
+
     // TODO: Is it valid to return NULL, or should we throw on error?
     // Returns StartupCommand with fields revised with values known only to the
     // host