Add ability to pass kvp data via the key cloudstack-vm-userdata

This commit is contained in:
Devdeep Singh 2013-10-10 18:11:58 +05:30
parent 1d0a931dea
commit 53fd4e8c72
15 changed files with 11134 additions and 223 deletions

View File

@ -367,5 +367,17 @@ namespace CloudStack.Plugin.AgentShell {
this["testCifsPath"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("CentOS64")]
public string testKvpVmName {
get {
return ((string)(this["testKvpVmName"]));
}
set {
this["testKvpVmName"] = value;
}
}
}
}

View File

@ -98,5 +98,14 @@
<Setting Name="dom0MinMemory" Type="System.UInt64" Scope="Application">
<Value Profile="(Default)">2048</Value>
</Setting>
<Setting Name="testCifsUrl" Type="System.String" Scope="User">
<Value Profile="(Default)">cifs://10.1.1.1/secondary?user\u003dadministrator\u0026password\u003d1pass%40word1</Value>
</Setting>
<Setting Name="testCifsPath" Type="System.String" Scope="User">
<Value Profile="(Default)">template/tmpl/2/201/61d5316a-3cc4-30cf-a557-78691ff5c143.vhd</Value>
</Setting>
<Setting Name="testKvpVmName" Type="System.String" Scope="User">
<Value Profile="(Default)">CentOS64</Value>
</Setting>
</Settings>
</SettingsFile>
</SettingsFile>

View File

@ -76,6 +76,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="CloudStackTypes.cs" />
<Compile Include="WmiCallsV2.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="HypervResourceController.cs" />
<Compile Include="Utils.cs" />
@ -99,4 +100,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>

View File

@ -754,7 +754,7 @@ namespace HypervResource
}
}
// POST api/HypervResource/StartCommand
// POST api/HypervResource/StopCommand
[HttpPost]
[ActionName(CloudStackTypes.StopCommand)]
public JContainer StopCommand([FromBody]dynamic cmd)
@ -1396,4 +1396,4 @@ namespace HypervResource
}
}
}
}
}

View File

@ -1247,223 +1247,4 @@ namespace HypervResource
throw ex;
}
}
public class WmiException : Exception
{
public WmiException()
{
}
public WmiException(string message)
: base(message)
{
}
public WmiException(string message, Exception inner)
: base(message, inner)
{
}
}
/// <summary>
/// http://msdn.microsoft.com/en-us/library/hh850031%28v=vs.85%29.aspx
/// </summary>
public static class ReturnCode
{
public const UInt32 Completed = 0;
public const UInt32 Started = 4096;
public const UInt32 Failed = 32768;
public const UInt32 AccessDenied = 32769;
public const UInt32 NotSupported = 32770;
public const UInt32 Unknown = 32771;
public const UInt32 Timeout = 32772;
public const UInt32 InvalidParameter = 32773;
public const UInt32 SystemInUse = 32774;
public const UInt32 InvalidState = 32775;
public const UInt32 IncorrectDataType = 32776;
public const UInt32 SystemNotAvailable = 32777;
public const UInt32 OutofMemory = 32778;
public static string ToString(UInt32 value)
{
string result = "Unknown return code";
switch (value)
{
case Completed: result = "Completed"; break;
case Started: result = "Started"; break;
case Failed: result = "Failed"; break;
case AccessDenied: result = "AccessDenied"; break;
case NotSupported: result = "NotSupported"; break;
case Unknown: result = "Unknown"; break;
case Timeout: result = "Timeout"; break;
case InvalidParameter: result = "InvalidParameter"; break;
case SystemInUse: result = "SystemInUse"; break;
case InvalidState: result = "InvalidState"; break;
case IncorrectDataType: result = "IncorrectDataType"; break;
case SystemNotAvailable: result = "SystemNotAvailable"; break;
case OutofMemory: result = "OutofMemory"; break;
}
return result;
}
}
/// <summary>
/// http://msdn.microsoft.com/en-us/library/hh850031%28v=vs.85%29.aspx
/// </summary>
public static class JobState
{
public const UInt16 New = 2;
public const UInt16 Starting = 3;
public const UInt16 Running = 4;
public const UInt16 Suspended = 5;
public const UInt16 ShuttingDown = 6;
public const UInt16 Completed = 7;
public const UInt16 Terminated = 8;
public const UInt16 Killed = 9;
public const UInt16 Exception = 10;
public const UInt16 Service = 11;
public static string ToString(UInt16 value)
{
string result = "Unknown JobState code";
switch (value)
{
case New: result = "New"; break;
case Starting: result = "Starting"; break;
case Running: result = "Running"; break;
case Suspended: result = "Suspended"; break;
case ShuttingDown: result = "ShuttingDown"; break;
case Completed: result = "Completed"; break;
case Terminated: result = "Terminated"; break;
case Killed: result = "Killed"; break;
case Exception: result = "Exception"; break;
case Service: result = "Service"; break;
}
return result;
}
}
/// <summary>
/// http://msdn.microsoft.com/en-us/library/cc723874%28v=vs.85%29.aspx
/// </summary>
public class RequiredState
{
public const UInt16 Enabled = 2; // Turns the VM on.
public const UInt16 Disabled = 3; // Turns the VM off.
public const UInt16 Reboot = 10; // A hard reset of the VM.
public const UInt16 Reset = 11; // For future use.
public const UInt16 Paused = 32768; // Pauses the VM.
public const UInt16 Suspended = 32769; // Saves the state of the VM.
public static string ToString(UInt16 value)
{
string result = "Unknown RequiredState code";
switch (value)
{
case Enabled: result = "Enabled"; break;
case Disabled: result = "Disabled"; break;
case Reboot: result = "Reboot"; break;
case Reset: result = "Reset"; break;
case Paused: result = "Paused"; break;
case Suspended: result = "Suspended"; break;
}
return result;
}
}
/// <summary>
/// http://msdn.microsoft.com/en-us/library/cc136822%28v=vs.85%29.aspx
/// </summary>
public class EnabledState
{
/// <summary>
/// The state of the VM could not be determined.
/// </summary>
public const UInt16 Unknown = 0;
/// <summary>
/// The VM is running.
/// </summary>
public const UInt16 Enabled = 2;
/// <summary>
/// The VM is turned off.
/// </summary>
public const UInt16 Disabled = 3;
/// <summary>
/// The VM is paused.
/// </summary>
public const UInt16 Paused = 32768;
/// <summary>
/// The VM is in a saved state.
/// </summary>
public const UInt16 Suspended = 32769;
/// <summary>
/// The VM is starting. This is a transitional state between 3 (Disabled)
/// or 32769 (Suspended) and 2 (Enabled) initiated by a call to the
/// RequestStateChange method with a RequestedState parameter of 2 (Enabled).
/// </summary>
public const UInt16 Starting = 32770;
/// <summary>
/// Starting with Windows Server 2008 R2 this value is not supported.
/// If the VM is performing a snapshot operation, the element at index 1
/// of the OperationalStatus property array will contain 32768 (Creating Snapshot),
/// 32769 (Applying Snapshot), or 32770 (Deleting Snapshot).
/// </summary>
public const UInt16 Snapshotting = 32771;
/// <summary>
/// The VM is saving its state. This is a transitional state between 2 (Enabled)
/// and 32769 (Suspended) initiated by a call to the RequestStateChange method
/// with a RequestedState parameter of 32769 (Suspended).
/// </summary>
public const UInt16 Saving = 32773;
/// <summary>
/// The VM is turning off. This is a transitional state between 2 (Enabled)
/// and 3 (Disabled) initiated by a call to the RequestStateChange method
/// with a RequestedState parameter of 3 (Disabled) or a guest operating system
/// initiated power off.
/// </summary>
public const UInt16 Stopping = 32774;
/// <summary>
/// The VM is pausing. This is a transitional state between 2 (Enabled) and 32768 (Paused) initiated by a call to the RequestStateChange method with a RequestedState parameter of 32768 (Paused).
/// </summary>
public const UInt16 Pausing = 32776;
/// <summary>
/// The VM is resuming from a paused state. This is a transitional state between 32768 (Paused) and 2 (Enabled).
/// </summary>
public const UInt16 Resuming = 32777;
public static string ToString(UInt16 value)
{
string result = "Unknown";
switch (value)
{
case Enabled: result = "Enabled"; break;
case Disabled: result = "Disabled"; break;
case Paused: result = "Paused"; break;
case Suspended: result = "Suspended"; break;
case Starting: result = "Starting"; break;
case Snapshotting: result = "Snapshotting"; break; // NOT used
case Saving: result = "Saving"; break;
case Stopping: result = "Stopping"; break;
case Pausing: result = "Pausing"; break;
case Resuming: result = "Resuming"; break;
}
return result;
}
public static string ToCloudStackState(UInt16 value)
{
string result = "Unknown";
switch (value)
{
case Enabled: result = "Running"; break;
case Disabled: result = "Stopped"; break;
case Paused: result = "Unknown"; break;
case Suspended: result = "Unknown"; break;
case Starting: result = "Starting"; break;
case Snapshotting: result = "Unknown"; break; // NOT used
case Saving: result = "Saving"; break;
case Stopping: result = "Stopping"; break;
case Pausing: result = "Unknown"; break;
case Resuming: result = "Starting"; break;
}
return result;
}
}
}

View File

@ -0,0 +1,501 @@
// 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.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CloudStack.Plugin.WmiWrappers.ROOT.VIRTUALIZATION.V2;
using log4net;
using System.Globalization;
using System.Management;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using CloudStack.Plugin.WmiWrappers.ROOT.CIMV2;
using System.IO;
namespace HypervResource
{
public class WmiCallsV2
{
public static String CloudStackUserDataKey = "cloudstack-vm-userdata";
public static void Initialize()
{
// Trigger assembly load into curren appdomain
}
private static ILog logger = LogManager.GetLogger(typeof(WmiCallsV2));
/// <summary>
/// Returns ComputerSystem lacking any NICs and VOLUMEs
/// </summary>
public static ComputerSystem AddUserData(ComputerSystem vm, string userData)
{
// Obtain controller for Hyper-V virtualisation subsystem
VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService();
// Create object to hold the data.
KvpExchangeDataItem kvpItem = KvpExchangeDataItem.CreateInstance();
kvpItem.LateBoundObject["Name"] = WmiCallsV2.CloudStackUserDataKey;
kvpItem.LateBoundObject["Data"] = userData;
kvpItem.LateBoundObject["Source"] = 0;
logger.Debug("VM " + vm.Name + " gets userdata " + userData);
String kvpStr = kvpItem.LateBoundObject.GetText(TextFormat.CimDtd20);
// Update the resource settings for the VM.
ManagementPath jobPath;
uint ret_val = vmMgmtSvc.AddKvpItems(new String[] { kvpStr }, vm.Path, out jobPath);
// If the Job is done asynchronously
if (ret_val == ReturnCode.Started)
{
JobCompleted(jobPath);
}
else if (ret_val != ReturnCode.Completed)
{
var errMsg = string.Format(
"Failed to update VM {0} (GUID {1}) due to {2} (ModifyVirtualSystem call), existing VM not deleted",
vm.ElementName,
vm.Name,
ReturnCode.ToString(ret_val));
var ex = new WmiException(errMsg);
logger.Error(errMsg, ex);
throw ex;
}
return vm;
}
/// <summary>
/// Returns ComputerSystem lacking any NICs and VOLUMEs
/// </summary>
public static void DeleteHostKvpItem(ComputerSystem vm, string key)
{
// Obtain controller for Hyper-V virtualisation subsystem
VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService();
// Create object to hold the data.
KvpExchangeDataItem kvpItem = KvpExchangeDataItem.CreateInstance();
kvpItem.LateBoundObject["Name"] = WmiCallsV2.CloudStackUserDataKey;
kvpItem.LateBoundObject["Data"] = "dummy";
kvpItem.LateBoundObject["Source"] = 0;
logger.Debug("VM " + vm.Name + " will have KVP key " + key + " removed.");
String kvpStr = kvpItem.LateBoundObject.GetText(TextFormat.CimDtd20);
// Update the resource settings for the VM.
ManagementPath jobPath;
uint ret_val = vmMgmtSvc.RemoveKvpItems(new String[] { kvpStr }, vm.Path, out jobPath);
// If the Job is done asynchronously
if (ret_val == ReturnCode.Started)
{
JobCompleted(jobPath);
}
else if (ret_val != ReturnCode.Completed)
{
var errMsg = string.Format(
"Failed to update VM {0} (GUID {1}) due to {2} (ModifyVirtualSystem call), existing VM not deleted",
vm.ElementName,
vm.Name,
ReturnCode.ToString(ret_val));
var ex = new WmiException(errMsg);
logger.Error(errMsg, ex);
throw ex;
}
}
public static VirtualSystemManagementService GetVirtualisationSystemManagementService()
{
// VirtualSystemManagementService is a singleton, most anonymous way of lookup is by asking for the set
// of local instances, which should be size 1.
var virtSysMgmtSvcCollection = VirtualSystemManagementService.GetInstances();
foreach (VirtualSystemManagementService item in virtSysMgmtSvcCollection)
{
return item;
}
var errMsg = string.Format("No Hyper-V subsystem on server");
var ex = new WmiException(errMsg);
logger.Error(errMsg, ex);
throw ex;
}
/// <summary>
/// Similar to http://msdn.microsoft.com/en-us/library/hh850031%28v=vs.85%29.aspx
/// </summary>
/// <param name="jobPath"></param>
/// <returns></returns>
private static void JobCompleted(ManagementPath jobPath)
{
ConcreteJob jobObj = null;
for(;;)
{
jobObj = new ConcreteJob(jobPath);
if (jobObj.JobState != JobState.Starting && jobObj.JobState != JobState.Running)
{
break;
}
logger.InfoFormat("In progress... {0}% completed.", jobObj.PercentComplete);
System.Threading.Thread.Sleep(1000);
}
if (jobObj.JobState != JobState.Completed)
{
var errMsg = string.Format(
"Hyper-V Job failed, Error Code:{0}, Description: {1}",
jobObj.ErrorCode,
jobObj.ErrorDescription);
var ex = new WmiException(errMsg);
logger.Error(errMsg, ex);
throw ex;
}
logger.DebugFormat("WMI job succeeded: {0}, Elapsed={1}", jobObj.Description, jobObj.ElapsedTime);
}
public static ComputerSystem GetComputerSystem(string displayName)
{
var wmiQuery = String.Format("ElementName=\"{0}\"", displayName);
ComputerSystem.ComputerSystemCollection vmCollection = ComputerSystem.GetInstances(wmiQuery);
// Return the first one
foreach (ComputerSystem vm in vmCollection)
{
return vm;
}
return null;
}
public static List<string> GetVmElementNames()
{
List<string> result = new List<string>();
ComputerSystem.ComputerSystemCollection vmCollection = ComputerSystem.GetInstances();
// Return the first one
foreach (ComputerSystem vm in vmCollection)
{
if (vm.Caption.StartsWith("Hosting Computer System") )
{
continue;
}
result.Add(vm.ElementName);
}
return result;
}
public static VirtualSystemSettingData GetVmSettings(ComputerSystem vm)
{
// An ASSOCIATOR object provides the cross reference from the ComputerSettings and the
// VirtualSystemSettingData, but generated wrappers do not expose a ASSOCIATOR OF query as a method.
// Instead, we use the System.Management to code the equivalant of
// string query = string.Format( "ASSOCIATORS OF {{{0}}} WHERE ResultClass = {1}", vm.path, resultclassName);
//
var wmiObjQuery = new RelatedObjectQuery(vm.Path.Path, VirtualSystemSettingData.CreatedClassName);
// NB: default scope of ManagementObjectSearcher is '\\.\root\cimv2', which does not contain
// the virtualisation objects.
var wmiObjectSearch = new ManagementObjectSearcher(vm.Scope, wmiObjQuery);
var wmiObjCollection = new VirtualSystemSettingData.VirtualSystemSettingDataCollection(wmiObjectSearch.Get());
// When snapshots are taken into account, there can be multiple settings objects
// take the first one that isn't a snapshot
foreach (VirtualSystemSettingData wmiObj in wmiObjCollection)
{
if (wmiObj.VirtualSystemType == "Microsoft:Hyper-V:System:Realized" ||
wmiObj.VirtualSystemType == "Microsoft:Hyper-V:System:Planned")
{
return wmiObj;
}
}
var errMsg = string.Format("No VirtualSystemSettingData for VM {0}, path {1}", vm.ElementName, vm.Path.Path);
var ex = new WmiException(errMsg);
logger.Error(errMsg, ex);
throw ex;
}
public static KvpExchangeComponentSettingData GetKvpSettings(VirtualSystemSettingData vmSettings)
{
// An ASSOCIATOR object provides the cross reference from the VirtualSystemSettingData and the
// KvpExchangeComponentSettingData, but generated wrappers do not expose a ASSOCIATOR OF query as a method.
// Instead, we use the System.Management to code the equivalant of
// string query = string.Format( "ASSOCIATORS OF {{{0}}} WHERE ResultClass = {1}", vmSettings.path, resultclassName);
//
var wmiObjQuery = new RelatedObjectQuery(vmSettings.Path.Path, KvpExchangeComponentSettingData.CreatedClassName);
// NB: default scope of ManagementObjectSearcher is '\\.\root\cimv2', which does not contain
// the virtualisation objects.
var wmiObjectSearch = new ManagementObjectSearcher(vmSettings.Scope, wmiObjQuery);
var wmiObjCollection = new KvpExchangeComponentSettingData.KvpExchangeComponentSettingDataCollection(wmiObjectSearch.Get());
foreach (KvpExchangeComponentSettingData wmiObj in wmiObjCollection)
{
return wmiObj;
}
var errMsg = string.Format("No KvpExchangeComponentSettingData in VirtualSystemSettingData {0}", vmSettings.Path.Path);
var ex = new WmiException(errMsg);
logger.Error(errMsg, ex);
throw ex;
}
}
public class WmiException : Exception
{
public WmiException()
{
}
public WmiException(string message)
: base(message)
{
}
public WmiException(string message, Exception inner)
: base(message, inner)
{
}
}
/// <summary>
/// Covers V2 API, see
/// http://msdn.microsoft.com/en-us/library/hh850031%28v=vs.85%29.aspx
/// </summary>
public static class ReturnCode
{
public const UInt32 Completed = 0;
public const UInt32 Started = 4096;
public const UInt32 Failed = 32768;
public const UInt32 AccessDenied = 32769;
public const UInt32 NotSupported = 32770;
public const UInt32 Unknown = 32771;
public const UInt32 Timeout = 32772;
public const UInt32 InvalidParameter = 32773;
public const UInt32 SystemInUse = 32774;
public const UInt32 InvalidState = 32775;
public const UInt32 IncorrectDataType = 32776;
public const UInt32 SystemNotAvailable = 32777;
public const UInt32 OutofMemory = 32778;
public static string ToString(UInt32 value)
{
string result = "Unknown return code";
switch (value)
{
case Completed: result = "Completed"; break;
case Started: result = "Started"; break;
case Failed: result = "Failed"; break;
case AccessDenied: result = "AccessDenied"; break;
case NotSupported: result = "NotSupported"; break;
case Unknown: result = "Unknown"; break;
case Timeout: result = "Timeout"; break;
case InvalidParameter: result = "InvalidParameter"; break;
case SystemInUse: result = "SystemInUse"; break;
case InvalidState: result = "InvalidState"; break;
case IncorrectDataType: result = "IncorrectDataType"; break;
case SystemNotAvailable: result = "SystemNotAvailable"; break;
case OutofMemory: result = "OutofMemory"; break;
}
return result;
}
}
/// <summary>
/// Covers V2 API, see
/// http://msdn.microsoft.com/en-us/library/hh850031%28v=vs.85%29.aspx
/// </summary>
public static class JobState
{
public const UInt16 New = 2;
public const UInt16 Starting = 3;
public const UInt16 Running = 4;
public const UInt16 Suspended = 5;
public const UInt16 ShuttingDown = 6;
public const UInt16 Completed = 7;
public const UInt16 Terminated = 8;
public const UInt16 Killed = 9;
public const UInt16 Exception = 10;
public const UInt16 Service = 11;
public static string ToString(UInt16 value)
{
string result = "Unknown JobState code";
switch (value)
{
case New: result = "New"; break;
case Starting: result = "Starting"; break;
case Running: result = "Running"; break;
case Suspended: result = "Suspended"; break;
case ShuttingDown: result = "ShuttingDown"; break;
case Completed: result = "Completed"; break;
case Terminated: result = "Terminated"; break;
case Killed: result = "Killed"; break;
case Exception: result = "Exception"; break;
case Service: result = "Service"; break;
}
return result;
}
}
/// <summary>
/// V2 API (see http://msdn.microsoft.com/en-us/library/hh850279(v=vs.85).aspx)
/// has removed 'Paused' and 'Suspended' as compared to the
/// V1 API (see http://msdn.microsoft.com/en-us/library/cc723874%28v=vs.85%29.aspx)
/// However, Paused and Suspended appear on the VM state transition table
/// (see http://msdn.microsoft.com/en-us/library/hh850116(v=vs.85).aspx#methods)
/// </summary>
public class RequiredState
{
public const UInt16 Enabled = 2; // Turns the VM on.
public const UInt16 Disabled = 3; // Turns the VM off.
public const UInt16 ShutDown = 4;
public const UInt16 Offline = 6;
public const UInt16 Test = 7;
public const UInt16 Defer = 8;
public const UInt16 Quiesce = 9;
public const UInt16 Reboot = 10; // A hard reset of the VM.
public const UInt16 Reset = 11; // For future use.
public const UInt16 Paused = 32768; // Pauses the VM.
public const UInt16 Suspended = 32769; // Saves the state of the VM.
public static string ToString(UInt16 value)
{
string result = "Unknown RequiredState code";
switch (value)
{
case Enabled: result = "Enabled"; break;
case Disabled: result = "Disabled"; break;
case ShutDown: result = "ShutDown"; break;
case Offline: result = "Offline"; break;
case Test: result = "Test"; break;
case Defer: result = "Defer"; break;
case Quiesce: result = "Quiesce"; break;
case Reboot: result = "Reboot"; break;
case Reset: result = "Reset"; break;
}
return result;
}
}
/// <summary>
/// V2 API specifies the states below in its state transition graph at
/// http://msdn.microsoft.com/en-us/library/hh850116(v=vs.85).aspx#methods
/// However, the CIM standard has additional possibilities based on the description
/// of EnabledState.
/// The previous V1 API is described by
/// http://msdn.microsoft.com/en-us/library/cc136822%28v=vs.85%29.aspx
/// </summary>
public class EnabledState
{
/// <summary>
/// The state of the VM could not be determined.
/// </summary>
public const UInt16 Unknown = 0;
/// <summary>
/// The VM is running.
/// </summary>
public const UInt16 Enabled = 2;
/// <summary>
/// The VM is turned off.
/// </summary>
public const UInt16 Disabled = 3;
/// <summary>
/// The VM is paused.
/// </summary>
public const UInt16 Paused = 32768;
/// <summary>
/// The VM is in a saved state.
/// </summary>
public const UInt16 Suspended = 32769;
/// <summary>
/// The VM is starting. This is a transitional state between 3 (Disabled)
/// or 32769 (Suspended) and 2 (Enabled) initiated by a call to the
/// RequestStateChange method with a RequestedState parameter of 2 (Enabled).
/// </summary>
public const UInt16 Starting = 32770;
/// <summary>
/// Starting with Windows Server 2008 R2 this value is not supported.
/// If the VM is performing a snapshot operation, the element at index 1
/// of the OperationalStatus property array will contain 32768 (Creating Snapshot),
/// 32769 (Applying Snapshot), or 32770 (Deleting Snapshot).
/// </summary>
public const UInt16 Snapshotting = 32771;
/// <summary>
/// The VM is saving its state. This is a transitional state between 2 (Enabled)
/// and 32769 (Suspended) initiated by a call to the RequestStateChange method
/// with a RequestedState parameter of 32769 (Suspended).
/// </summary>
public const UInt16 Saving = 32773;
/// <summary>
/// The VM is turning off. This is a transitional state between 2 (Enabled)
/// and 3 (Disabled) initiated by a call to the RequestStateChange method
/// with a RequestedState parameter of 3 (Disabled) or a guest operating system
/// initiated power off.
/// </summary>
public const UInt16 Stopping = 32774;
/// <summary>
/// The VM is pausing. This is a transitional state between 2 (Enabled) and 32768 (Paused) initiated by a call to the RequestStateChange method with a RequestedState parameter of 32768 (Paused).
/// </summary>
public const UInt16 Pausing = 32776;
/// <summary>
/// The VM is resuming from a paused state. This is a transitional state between 32768 (Paused) and 2 (Enabled).
/// </summary>
public const UInt16 Resuming = 32777;
public static string ToString(UInt16 value)
{
string result = "Unknown";
switch (value)
{
case Enabled: result = "Enabled"; break;
case Disabled: result = "Disabled"; break;
case Paused: result = "Paused"; break;
case Suspended: result = "Suspended"; break;
case Starting: result = "Starting"; break;
case Snapshotting: result = "Snapshotting"; break; // NOT used
case Saving: result = "Saving"; break;
case Stopping: result = "Stopping"; break;
case Pausing: result = "Pausing"; break;
case Resuming: result = "Resuming"; break;
}
return result;
}
public static string ToCloudStackState(UInt16 value)
{
string result = "Unknown";
switch (value)
{
case Enabled: result = "Running"; break;
case Disabled: result = "Stopped"; break;
case Paused: result = "Unknown"; break;
case Suspended: result = "Unknown"; break;
case Starting: result = "Starting"; break;
case Snapshotting: result = "Unknown"; break; // NOT used
case Saving: result = "Saving"; break;
case Stopping: result = "Stopping"; break;
case Pausing: result = "Unknown"; break;
case Resuming: result = "Starting"; break;
}
return result;
}
}
}

View File

@ -25,6 +25,7 @@ using log4net;
using HypervResource;
using CloudStack.Plugin.AgentShell;
using System.Collections.Generic;
using System.Xml;
namespace ServerResource.Tests
{
@ -760,6 +761,89 @@ namespace ServerResource.Tests
Assert.IsTrue((bool)ans.result, (string)ans.details); // always succeeds
}
[TestMethod]
public void TestPassingUserdataToVm()
{
// Sample data
String key = "cloudstack-vm-userdata";
String value = "username=root;password=1pass@word1";
// Find the VM
List<String> vmNames = WmiCallsV2.GetVmElementNames();
// Get associated WMI object
var vm = WmiCallsV2.GetComputerSystem(AgentSettings.Default.testKvpVmName);
// Get existing KVP
var vmSettings = WmiCallsV2.GetVmSettings(vm);
var kvpInfo = WmiCallsV2.GetKvpSettings(vmSettings);
// HostExchangesItems are embedded objects in the sense that the object value is stored and not a reference to the object.
string[] kvpProps = kvpInfo.HostExchangeItems;
// If the value already exists, delete it
foreach (var item in kvpProps)
{
String wmiObjectXml = item;
String existingKey;
String existingValue;
ParseKVP(wmiObjectXml, out existingKey, out existingValue);
if (existingKey == key)
{
WmiCallsV2.DeleteHostKvpItem(vm, existingKey);
break;
}
}
// Add new user data
WmiCallsV2.AddUserData(vm, value);
// Verify key added to subsystem
kvpInfo = WmiCallsV2.GetKvpSettings(vmSettings);
// HostExchangesItems are embedded objects in the sense that the object value is stored and not a reference to the object.
kvpProps = kvpInfo.HostExchangeItems;
// If the value already exists, delete it
bool userDataInPlace = false;
foreach (var item in kvpProps)
{
String wmiObjectXml = item;
String existingKey;
String existingValue;
ParseKVP(wmiObjectXml, out existingKey, out existingValue);
if (existingKey == key && existingValue == value)
{
WmiCallsV2.DeleteHostKvpItem(vm, existingKey);
userDataInPlace = true;
break;
}
}
Assert.IsTrue(userDataInPlace, "User data key / value did no save properly");
}
private static void ParseKVP(String wmiObjectXml, out String existingKey, out String existingValue)
{
// Reference: http://blogs.msdn.com/b/virtual_pc_guy/archive/2008/12/05/enumerating-parent-kvp-data.aspx
// Create XML parser
var xmlDoc = new XmlDocument();
// Load WMI object
xmlDoc.LoadXml(wmiObjectXml);
// Use xpath to get name and value
var namePropXpath = "/INSTANCE/PROPERTY[@NAME='Name']/VALUE";
var nameNode = xmlDoc.SelectSingleNode(namePropXpath);
existingKey = nameNode.InnerText;
var dataPropXpath = "/INSTANCE/PROPERTY[@NAME='Data']/VALUE";
var dataNode = xmlDoc.SelectSingleNode(dataPropXpath);
existingValue = dataNode.InnerText;
}
[TestMethod]
public void GetVmStatsCommandFail()
{

View File

@ -0,0 +1,653 @@
namespace CloudStack.Plugin.WmiWrappers.ROOT.VIRTUALIZATION.V2
{
using System;
using System.ComponentModel;
using System.Management;
using System.Collections;
using System.Globalization;
using System.ComponentModel.Design.Serialization;
using System.Reflection;
// Functions ShouldSerialize<PropertyName> are functions used by VS property browser to check if a particular property has to be serialized. These functions are added for all ValueType properties ( properties of type Int32, BOOL etc.. which cannot be set to null). These functions use Is<PropertyName>Null function. These functions are also used in the TypeConverter implementation for the properties to check for NULL value of property so that an empty value can be shown in Property browser in case of Drag and Drop in Visual studio.
// Functions Is<PropertyName>Null() are used to check if a property is NULL.
// Functions Reset<PropertyName> are added for Nullable Read/Write properties. These functions are used by VS designer in property browser to set a property to NULL.
// Every property added to the class for WMI property has attributes set to define its behavior in Visual Studio designer and also to define a TypeConverter to be used.
// An Early Bound class generated for the WMI class.Msvm_KvpExchangeDataItem
public class KvpExchangeDataItem : System.ComponentModel.Component {
// Private property to hold the WMI namespace in which the class resides.
private static string CreatedWmiNamespace = "ROOT\\virtualization\\v2";
// Private property to hold the name of WMI class which created this class.
private static string CreatedClassName = "Msvm_KvpExchangeDataItem";
// Private member variable to hold the ManagementScope which is used by the various methods.
private static System.Management.ManagementScope statMgmtScope = null;
private ManagementSystemProperties PrivateSystemProperties;
// Underlying lateBound WMI object.
private System.Management.ManagementObject PrivateLateBoundObject;
// Member variable to store the 'automatic commit' behavior for the class.
private bool AutoCommitProp;
// Private variable to hold the embedded property representing the instance.
private System.Management.ManagementBaseObject embeddedObj;
// The current WMI object used
private System.Management.ManagementBaseObject curObj;
// Flag to indicate if the instance is an embedded object.
private bool isEmbedded;
// Below are different overloads of constructors to initialize an instance of the class with a WMI object.
public KvpExchangeDataItem() {
this.InitializeObject(null, null, null);
}
public KvpExchangeDataItem(System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) {
this.InitializeObject(null, path, getOptions);
}
public KvpExchangeDataItem(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path) {
this.InitializeObject(mgmtScope, path, null);
}
public KvpExchangeDataItem(System.Management.ManagementPath path) {
this.InitializeObject(null, path, null);
}
public KvpExchangeDataItem(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) {
this.InitializeObject(mgmtScope, path, getOptions);
}
public KvpExchangeDataItem(System.Management.ManagementObject theObject) {
Initialize();
if ((CheckIfProperClass(theObject) == true)) {
PrivateLateBoundObject = theObject;
PrivateSystemProperties = new ManagementSystemProperties(PrivateLateBoundObject);
curObj = PrivateLateBoundObject;
}
else {
throw new System.ArgumentException("Class name does not match.");
}
}
public KvpExchangeDataItem(System.Management.ManagementBaseObject theObject) {
Initialize();
if ((CheckIfProperClass(theObject) == true)) {
embeddedObj = theObject;
PrivateSystemProperties = new ManagementSystemProperties(theObject);
curObj = embeddedObj;
isEmbedded = true;
}
else {
throw new System.ArgumentException("Class name does not match.");
}
}
// Property returns the namespace of the WMI class.
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string OriginatingNamespace {
get {
return "ROOT\\virtualization\\v2";
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string ManagementClassName {
get {
string strRet = CreatedClassName;
if ((curObj != null)) {
if ((curObj.ClassPath != null)) {
strRet = ((string)(curObj["__CLASS"]));
if (((strRet == null)
|| (strRet == string.Empty))) {
strRet = CreatedClassName;
}
}
}
return strRet;
}
}
// Property pointing to an embedded object to get System properties of the WMI object.
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ManagementSystemProperties SystemProperties {
get {
return PrivateSystemProperties;
}
}
// Property returning the underlying lateBound object.
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public System.Management.ManagementBaseObject LateBoundObject {
get {
return curObj;
}
}
// ManagementScope of the object.
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public System.Management.ManagementScope Scope {
get {
if ((isEmbedded == false)) {
return PrivateLateBoundObject.Scope;
}
else {
return null;
}
}
set {
if ((isEmbedded == false)) {
PrivateLateBoundObject.Scope = value;
}
}
}
// Property to show the commit behavior for the WMI object. If true, WMI object will be automatically saved after each property modification.(ie. Put() is called after modification of a property).
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool AutoCommit {
get {
return AutoCommitProp;
}
set {
AutoCommitProp = value;
}
}
// The ManagementPath of the underlying WMI object.
[Browsable(true)]
public System.Management.ManagementPath Path {
get {
if ((isEmbedded == false)) {
return PrivateLateBoundObject.Path;
}
else {
return null;
}
}
set {
if ((isEmbedded == false)) {
if ((CheckIfProperClass(null, value, null) != true)) {
throw new System.ArgumentException("Class name does not match.");
}
PrivateLateBoundObject.Path = value;
}
}
}
// Public static scope property which is used by the various methods.
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public static System.Management.ManagementScope StaticScope {
get {
return statMgmtScope;
}
set {
statMgmtScope = value;
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string Caption {
get {
return ((string)(curObj["Caption"]));
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string Data {
get {
return ((string)(curObj["Data"]));
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string Description {
get {
return ((string)(curObj["Description"]));
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string ElementName {
get {
return ((string)(curObj["ElementName"]));
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string InstanceID {
get {
return ((string)(curObj["InstanceID"]));
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string Name {
get {
return ((string)(curObj["Name"]));
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsSourceNull {
get {
if ((curObj["Source"] == null)) {
return true;
}
else {
return false;
}
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[TypeConverter(typeof(WMIValueTypeConverter))]
public ushort Source {
get {
if ((curObj["Source"] == null)) {
return System.Convert.ToUInt16(0);
}
return ((ushort)(curObj["Source"]));
}
}
private bool CheckIfProperClass(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions OptionsParam) {
if (((path != null)
&& (string.Compare(path.ClassName, this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))) {
return true;
}
else {
return CheckIfProperClass(new System.Management.ManagementObject(mgmtScope, path, OptionsParam));
}
}
private bool CheckIfProperClass(System.Management.ManagementBaseObject theObj) {
if (((theObj != null)
&& (string.Compare(((string)(theObj["__CLASS"])), this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))) {
return true;
}
else {
System.Array parentClasses = ((System.Array)(theObj["__DERIVATION"]));
if ((parentClasses != null)) {
int count = 0;
for (count = 0; (count < parentClasses.Length); count = (count + 1)) {
if ((string.Compare(((string)(parentClasses.GetValue(count))), this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0)) {
return true;
}
}
}
}
return false;
}
private bool ShouldSerializeSource() {
if ((this.IsSourceNull == false)) {
return true;
}
return false;
}
[Browsable(true)]
public void CommitObject() {
if ((isEmbedded == false)) {
PrivateLateBoundObject.Put();
}
}
[Browsable(true)]
public void CommitObject(System.Management.PutOptions putOptions) {
if ((isEmbedded == false)) {
PrivateLateBoundObject.Put(putOptions);
}
}
private void Initialize() {
AutoCommitProp = true;
isEmbedded = false;
}
private static string ConstructPath() {
string strPath = "ROOT\\virtualization\\v2:Msvm_KvpExchangeDataItem";
return strPath;
}
private void InitializeObject(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) {
Initialize();
if ((path != null)) {
if ((CheckIfProperClass(mgmtScope, path, getOptions) != true)) {
throw new System.ArgumentException("Class name does not match.");
}
}
PrivateLateBoundObject = new System.Management.ManagementObject(mgmtScope, path, getOptions);
PrivateSystemProperties = new ManagementSystemProperties(PrivateLateBoundObject);
curObj = PrivateLateBoundObject;
}
// Different overloads of GetInstances() help in enumerating instances of the WMI class.
public static KvpExchangeDataItemCollection GetInstances() {
return GetInstances(null, null, null);
}
public static KvpExchangeDataItemCollection GetInstances(string condition) {
return GetInstances(null, condition, null);
}
public static KvpExchangeDataItemCollection GetInstances(string[] selectedProperties) {
return GetInstances(null, null, selectedProperties);
}
public static KvpExchangeDataItemCollection GetInstances(string condition, string[] selectedProperties) {
return GetInstances(null, condition, selectedProperties);
}
public static KvpExchangeDataItemCollection GetInstances(System.Management.ManagementScope mgmtScope, System.Management.EnumerationOptions enumOptions) {
if ((mgmtScope == null)) {
if ((statMgmtScope == null)) {
mgmtScope = new System.Management.ManagementScope();
mgmtScope.Path.NamespacePath = "root\\virtualization\\v2";
}
else {
mgmtScope = statMgmtScope;
}
}
System.Management.ManagementPath pathObj = new System.Management.ManagementPath();
pathObj.ClassName = "Msvm_KvpExchangeDataItem";
pathObj.NamespacePath = "root\\virtualization\\v2";
System.Management.ManagementClass clsObject = new System.Management.ManagementClass(mgmtScope, pathObj, null);
if ((enumOptions == null)) {
enumOptions = new System.Management.EnumerationOptions();
enumOptions.EnsureLocatable = true;
}
return new KvpExchangeDataItemCollection(clsObject.GetInstances(enumOptions));
}
public static KvpExchangeDataItemCollection GetInstances(System.Management.ManagementScope mgmtScope, string condition) {
return GetInstances(mgmtScope, condition, null);
}
public static KvpExchangeDataItemCollection GetInstances(System.Management.ManagementScope mgmtScope, string[] selectedProperties) {
return GetInstances(mgmtScope, null, selectedProperties);
}
public static KvpExchangeDataItemCollection GetInstances(System.Management.ManagementScope mgmtScope, string condition, string[] selectedProperties) {
if ((mgmtScope == null)) {
if ((statMgmtScope == null)) {
mgmtScope = new System.Management.ManagementScope();
mgmtScope.Path.NamespacePath = "root\\virtualization\\v2";
}
else {
mgmtScope = statMgmtScope;
}
}
System.Management.ManagementObjectSearcher ObjectSearcher = new System.Management.ManagementObjectSearcher(mgmtScope, new SelectQuery("Msvm_KvpExchangeDataItem", condition, selectedProperties));
System.Management.EnumerationOptions enumOptions = new System.Management.EnumerationOptions();
enumOptions.EnsureLocatable = true;
ObjectSearcher.Options = enumOptions;
return new KvpExchangeDataItemCollection(ObjectSearcher.Get());
}
[Browsable(true)]
public static KvpExchangeDataItem CreateInstance() {
System.Management.ManagementScope mgmtScope = null;
if ((statMgmtScope == null)) {
mgmtScope = new System.Management.ManagementScope();
mgmtScope.Path.NamespacePath = CreatedWmiNamespace;
}
else {
mgmtScope = statMgmtScope;
}
System.Management.ManagementPath mgmtPath = new System.Management.ManagementPath(CreatedClassName);
System.Management.ManagementClass tmpMgmtClass = new System.Management.ManagementClass(mgmtScope, mgmtPath, null);
return new KvpExchangeDataItem(tmpMgmtClass.CreateInstance());
}
[Browsable(true)]
public void Delete() {
PrivateLateBoundObject.Delete();
}
// Enumerator implementation for enumerating instances of the class.
public class KvpExchangeDataItemCollection : object, ICollection {
private ManagementObjectCollection privColObj;
public KvpExchangeDataItemCollection(ManagementObjectCollection objCollection) {
privColObj = objCollection;
}
public virtual int Count {
get {
return privColObj.Count;
}
}
public virtual bool IsSynchronized {
get {
return privColObj.IsSynchronized;
}
}
public virtual object SyncRoot {
get {
return this;
}
}
public virtual void CopyTo(System.Array array, int index) {
privColObj.CopyTo(array, index);
int nCtr;
for (nCtr = 0; (nCtr < array.Length); nCtr = (nCtr + 1)) {
array.SetValue(new KvpExchangeDataItem(((System.Management.ManagementObject)(array.GetValue(nCtr)))), nCtr);
}
}
public virtual System.Collections.IEnumerator GetEnumerator() {
return new KvpExchangeDataItemEnumerator(privColObj.GetEnumerator());
}
public class KvpExchangeDataItemEnumerator : object, System.Collections.IEnumerator {
private ManagementObjectCollection.ManagementObjectEnumerator privObjEnum;
public KvpExchangeDataItemEnumerator(ManagementObjectCollection.ManagementObjectEnumerator objEnum) {
privObjEnum = objEnum;
}
public virtual object Current {
get {
return new KvpExchangeDataItem(((System.Management.ManagementObject)(privObjEnum.Current)));
}
}
public virtual bool MoveNext() {
return privObjEnum.MoveNext();
}
public virtual void Reset() {
privObjEnum.Reset();
}
}
}
// TypeConverter to handle null values for ValueType properties
public class WMIValueTypeConverter : TypeConverter {
private TypeConverter baseConverter;
private System.Type baseType;
public WMIValueTypeConverter(System.Type inBaseType) {
baseConverter = TypeDescriptor.GetConverter(inBaseType);
baseType = inBaseType;
}
public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type srcType) {
return baseConverter.CanConvertFrom(context, srcType);
}
public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) {
return baseConverter.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) {
return baseConverter.ConvertFrom(context, culture, value);
}
public override object CreateInstance(System.ComponentModel.ITypeDescriptorContext context, System.Collections.IDictionary dictionary) {
return baseConverter.CreateInstance(context, dictionary);
}
public override bool GetCreateInstanceSupported(System.ComponentModel.ITypeDescriptorContext context) {
return baseConverter.GetCreateInstanceSupported(context);
}
public override PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, object value, System.Attribute[] attributeVar) {
return baseConverter.GetProperties(context, value, attributeVar);
}
public override bool GetPropertiesSupported(System.ComponentModel.ITypeDescriptorContext context) {
return baseConverter.GetPropertiesSupported(context);
}
public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) {
return baseConverter.GetStandardValues(context);
}
public override bool GetStandardValuesExclusive(System.ComponentModel.ITypeDescriptorContext context) {
return baseConverter.GetStandardValuesExclusive(context);
}
public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) {
return baseConverter.GetStandardValuesSupported(context);
}
public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) {
if ((baseType.BaseType == typeof(System.Enum))) {
if ((value.GetType() == destinationType)) {
return value;
}
if ((((value == null)
&& (context != null))
&& (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) {
return "NULL_ENUM_VALUE" ;
}
return baseConverter.ConvertTo(context, culture, value, destinationType);
}
if (((baseType == typeof(bool))
&& (baseType.BaseType == typeof(System.ValueType)))) {
if ((((value == null)
&& (context != null))
&& (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) {
return "";
}
return baseConverter.ConvertTo(context, culture, value, destinationType);
}
if (((context != null)
&& (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) {
return "";
}
return baseConverter.ConvertTo(context, culture, value, destinationType);
}
}
// Embedded class to represent WMI system Properties.
[TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]
public class ManagementSystemProperties {
private System.Management.ManagementBaseObject PrivateLateBoundObject;
public ManagementSystemProperties(System.Management.ManagementBaseObject ManagedObject) {
PrivateLateBoundObject = ManagedObject;
}
[Browsable(true)]
public int GENUS {
get {
return ((int)(PrivateLateBoundObject["__GENUS"]));
}
}
[Browsable(true)]
public string CLASS {
get {
return ((string)(PrivateLateBoundObject["__CLASS"]));
}
}
[Browsable(true)]
public string SUPERCLASS {
get {
return ((string)(PrivateLateBoundObject["__SUPERCLASS"]));
}
}
[Browsable(true)]
public string DYNASTY {
get {
return ((string)(PrivateLateBoundObject["__DYNASTY"]));
}
}
[Browsable(true)]
public string RELPATH {
get {
return ((string)(PrivateLateBoundObject["__RELPATH"]));
}
}
[Browsable(true)]
public int PROPERTY_COUNT {
get {
return ((int)(PrivateLateBoundObject["__PROPERTY_COUNT"]));
}
}
[Browsable(true)]
public string[] DERIVATION {
get {
return ((string[])(PrivateLateBoundObject["__DERIVATION"]));
}
}
[Browsable(true)]
public string SERVER {
get {
return ((string)(PrivateLateBoundObject["__SERVER"]));
}
}
[Browsable(true)]
public string NAMESPACE {
get {
return ((string)(PrivateLateBoundObject["__NAMESPACE"]));
}
}
[Browsable(true)]
public string PATH {
get {
return ((string)(PrivateLateBoundObject["__PATH"]));
}
}
}
}
}

View File

@ -131,6 +131,27 @@
<Compile Include="ROOT.virtualization.Msvm_VmLANEndpoint.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ROOT.virtualization.v2.Msvm_ComputerSystem.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ROOT.virtualization.v2.Msvm_ConcreteJob.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ROOT.virtualization.v2.Msvm_KvpExchangeComponent.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ROOT.virtualization.v2.Msvm_KvpExchangeComponentSettingData.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ROOT.virtualization.v2.Msvm_KvpExchangeDataItem.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ROOT.virtualization.v2.Msvm_VirtualSystemManagementService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ROOT.virtualization.v2.Msvm_VirtualSystemSettingData.cs">
<SubType>Component</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="Readme.txt" />