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