You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2014/07/28 17:31:14 UTC
[1/3] CLOUDSTACK-6504: removed warnings coming in building hyper-v
agent code
Repository: cloudstack
Updated Branches:
refs/heads/4.4 48f9453a7 -> 8fb89cdc8
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8fb89cdc/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs
index 07dd78b..b40cb8f 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation (ASF) under one
+// 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
@@ -88,7 +88,7 @@ namespace HypervResource
{
IntPtr token = IntPtr.Zero;
- bool isSuccess = LogonUser(cifsShareDetails.User, cifsShareDetails.Domain, cifsShareDetails.Password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref token);
+ LogonUser(cifsShareDetails.User, cifsShareDetails.Domain, cifsShareDetails.Password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref token);
using (WindowsImpersonationContext remoteIdentity = new WindowsIdentity(token).Impersonate())
{
String dest = "";
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8fb89cdc/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 0214ad8..104ee2d 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
@@ -267,186 +267,180 @@ namespace HypervResource
else
{
errMsg = string.Format("Create VM failing, because there exists a VM with name {0}, state {1}",
- vmName,
- EnabledState.ToString(vmWmiObj.EnabledState));
- var ex = new WmiException(errMsg);
- logger.Error(errMsg, ex);
- throw ex;
- }
- }
-
- // Create vm carcase
- logger.DebugFormat("Going ahead with create VM {0}, {1} vcpus, {2}MB RAM", vmName, vcpus, memSize);
- var newVm = CreateVM(vmName, memSize, vcpus);
-
- // Add a SCSI controller for attaching/detaching data volumes.
- AddScsiController(newVm);
-
- foreach (var diskDrive in diskDrives)
- {
- string vhdFile = null;
- string diskName = null;
- string isoPath = null;
- VolumeObjectTO volInfo = VolumeObjectTO.ParseJson(diskDrive.data);
- TemplateObjectTO templateInfo = TemplateObjectTO.ParseJson(diskDrive.data);
-
- if (volInfo != null)
- {
- // assert
- errMsg = vmName + ": volume missing primaryDataStore for disk " + diskDrive.ToString();
- if (volInfo.primaryDataStore == null)
- {
- logger.Error(errMsg);
- throw new ArgumentException(errMsg);
- }
- diskName = volInfo.name;
-
- // assert
- errMsg = vmName + ": can't deal with DataStore type for disk " + diskDrive.ToString();
- if (volInfo.primaryDataStore == null)
- {
- logger.Error(errMsg);
- throw new ArgumentException(errMsg);
- }
- errMsg = vmName + ": Malformed PrimaryDataStore for disk " + diskDrive.ToString();
- if (String.IsNullOrEmpty(volInfo.primaryDataStore.Path))
- {
- logger.Error(errMsg);
- throw new ArgumentException(errMsg);
- }
- errMsg = vmName + ": Missing folder PrimaryDataStore for disk " + diskDrive.ToString() + ", missing path: " + volInfo.primaryDataStore.Path;
- if (!Directory.Exists(volInfo.primaryDataStore.Path))
- {
- logger.Error(errMsg);
- throw new ArgumentException(errMsg);
- }
-
- vhdFile = volInfo.FullFileName;
- if (!System.IO.File.Exists(vhdFile))
- {
- errMsg = vmName + ": non-existent volume, missing " + vhdFile + " for drive " + diskDrive.ToString();
- logger.Error(errMsg);
- throw new ArgumentException(errMsg);
- }
- logger.Debug("Going to create " + vmName + " with attached voluem " + diskName + " at " + vhdFile);
- }
- else if (templateInfo != null && templateInfo.nfsDataStoreTO != null)
- {
- NFSTO share = templateInfo.nfsDataStoreTO;
- // The share is mapped, now attach the iso
- isoPath = Utils.NormalizePath(Path.Combine(share.UncPath, templateInfo.path));
- }
-
- string driveType = diskDrive.type;
- string ideCtrllr = "0";
- string driveResourceType = null;
- switch (driveType) {
- case "ROOT":
- ideCtrllr = "0";
- driveResourceType = HARDDISK_DRIVE;
- break;
- case "ISO":
- ideCtrllr = "1";
- driveResourceType = ISO_DRIVE;
- break;
- case "DATADISK":
- break;
- default:
- // TODO: double check exception type
- errMsg = string.Format("Unknown disk type {0} for disk {1}, vm named {2}",
- string.IsNullOrEmpty(driveType) ? "NULL" : driveType,
- string.IsNullOrEmpty(diskName) ? "NULL" : diskName, vmName);
- var ex = new WmiException(errMsg);
- logger.Error(errMsg, ex);
- throw ex;
- }
-
- logger.DebugFormat("Create disk type {1} (Named: {0}), on vm {2} {3}", diskName, driveResourceType, vmName,
- string.IsNullOrEmpty(vhdFile) ? " no disk to insert" : ", inserting disk" + vhdFile);
- if (driveType.Equals("DATADISK"))
- {
- AttachDisk(vmName, vhdFile, (string)diskDrive.diskSeq);
- }
- else
- {
- AddDiskDriveToIdeController(newVm, vhdFile, ideCtrllr, driveResourceType);
- if (isoPath != null)
- {
- AttachIso(vmName, isoPath);
- }
- }
- }
-
- String publicIpAddress = "";
- int nicCount = 0;
- int enableState = 2;
-
- // Add the Nics to the VM in the deviceId order.
- foreach (var nc in nicInfo)
- {
- foreach (var nic in nicInfo)
- {
-
- int nicid = nic.deviceId;
+ vmName,
+ EnabledState.ToString(vmWmiObj.EnabledState));
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+ }
+
+ // Create vm carcase
+ logger.DebugFormat("Going ahead with create VM {0}, {1} vcpus, {2}MB RAM", vmName, vcpus, memSize);
+ var newVm = CreateVM(vmName, memSize, vcpus);
+
+ // Add a SCSI controller for attaching/detaching data volumes.
+ AddScsiController(newVm);
+
+ foreach (var diskDrive in diskDrives)
+ {
+ string vhdFile = null;
+ string diskName = null;
+ string isoPath = null;
+ VolumeObjectTO volInfo = VolumeObjectTO.ParseJson(diskDrive.data);
+ TemplateObjectTO templateInfo = TemplateObjectTO.ParseJson(diskDrive.data);
+
+ if (volInfo != null)
+ {
+ // assert
+ errMsg = vmName + ": volume missing primaryDataStore for disk " + diskDrive.ToString();
+ if (volInfo.primaryDataStore == null)
+ {
+ logger.Error(errMsg);
+ throw new ArgumentException(errMsg);
+ }
+ diskName = volInfo.name;
+
+ // assert
+ errMsg = vmName + ": can't deal with DataStore type for disk " + diskDrive.ToString();
+ if (volInfo.primaryDataStore == null)
+ {
+ logger.Error(errMsg);
+ throw new ArgumentException(errMsg);
+ }
+ errMsg = vmName + ": Malformed PrimaryDataStore for disk " + diskDrive.ToString();
+ if (String.IsNullOrEmpty(volInfo.primaryDataStore.Path))
+ {
+ logger.Error(errMsg);
+ throw new ArgumentException(errMsg);
+ }
+ errMsg = vmName + ": Missing folder PrimaryDataStore for disk " + diskDrive.ToString() + ", missing path: " + volInfo.primaryDataStore.Path;
+ if (!Directory.Exists(volInfo.primaryDataStore.Path))
+ {
+ logger.Error(errMsg);
+ throw new ArgumentException(errMsg);
+ }
+
+ vhdFile = volInfo.FullFileName;
+ if (!System.IO.File.Exists(vhdFile))
+ {
+ errMsg = vmName + ": non-existent volume, missing " + vhdFile + " for drive " + diskDrive.ToString();
+ logger.Error(errMsg);
+ throw new ArgumentException(errMsg);
+ }
+ logger.Debug("Going to create " + vmName + " with attached voluem " + diskName + " at " + vhdFile);
+ }
+ else if (templateInfo != null && templateInfo.nfsDataStoreTO != null)
+ {
+ NFSTO share = templateInfo.nfsDataStoreTO;
+ Utils.ConnectToRemote(share.UncPath, share.Domain, share.User, share.Password);
+ // The share is mapped, now attach the iso
+ isoPath = Utils.NormalizePath(Path.Combine(share.UncPath, templateInfo.path));
+ }
+
+ string driveType = diskDrive.type;
+ string ideCtrllr = "0";
+ string driveResourceType = null;
+ switch (driveType) {
+ case "ROOT":
+ ideCtrllr = "0";
+ driveResourceType = HARDDISK_DRIVE;
+ break;
+ case "ISO":
+ ideCtrllr = "1";
+ driveResourceType = ISO_DRIVE;
+ break;
+ case "DATADISK":
+ break;
+ default:
+ // TODO: double check exception type
+ errMsg = string.Format("Unknown disk type {0} for disk {1}, vm named {2}",
+ string.IsNullOrEmpty(driveType) ? "NULL" : driveType,
+ string.IsNullOrEmpty(diskName) ? "NULL" : diskName, vmName);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+
+ logger.DebugFormat("Create disk type {1} (Named: {0}), on vm {2} {3}", diskName, driveResourceType, vmName,
+ string.IsNullOrEmpty(vhdFile) ? " no disk to insert" : ", inserting disk" + vhdFile);
+ if (driveType.Equals("DATADISK"))
+ {
+ AttachDisk(vmName, vhdFile, (string)diskDrive.diskSeq);
+ }
+ else
+ {
+ AddDiskDriveToIdeController(newVm, vhdFile, ideCtrllr, driveResourceType);
+ if (isoPath != null)
+ {
+ AttachIso(vmName, isoPath);
+ }
+ }
+ }
+
+ int nicCount = 0;
+ // Add the Nics to the VM in the deviceId order.
+ foreach (var nc in nicInfo)
+ {
+ foreach (var nic in nicInfo)
+ {
+
+ int nicid = nic.deviceId;
Int32 networkRateMbps = nic.networkRateMbps;
- string mac = nic.mac;
- string vlan = null;
- string isolationUri = nic.isolationUri;
- string broadcastUri = nic.broadcastUri;
+ string mac = nic.mac;
+ string vlan = null;
+ string isolationUri = nic.isolationUri;
+ string broadcastUri = nic.broadcastUri;
string nicIp = nic.ip;
string nicNetmask = nic.netmask;
- if ( (broadcastUri != null ) || (isolationUri != null && isolationUri.StartsWith("vlan://")))
- {
- if (broadcastUri != null && broadcastUri.StartsWith("storage"))
- {
- vlan = broadcastUri.Substring("storage://".Length);
- }
- else
- {
- vlan = isolationUri.Substring("vlan://".Length);
- }
- int tmp;
+ if ( (broadcastUri != null ) || (isolationUri != null && isolationUri.StartsWith("vlan://")))
+ {
+ if (broadcastUri != null && broadcastUri.StartsWith("storage"))
+ {
+ vlan = broadcastUri.Substring("storage://".Length);
+ }
+ else
+ {
+ vlan = isolationUri.Substring("vlan://".Length);
+ }
+ int tmp;
if (vlan.Equals("untagged", StringComparison.CurrentCultureIgnoreCase) ) {
// recevied vlan is untagged, don't parse for the vlan in the isolation uri
vlan = null;
}
- else if (!int.TryParse(vlan, out tmp))
- {
- // TODO: double check exception type
- errMsg = string.Format("Invalid VLAN value {0} for on vm {1} for nic uuid {2}", isolationUri, vmName, nic.uuid);
- var ex = new WmiException(errMsg);
- logger.Error(errMsg, ex);
- throw ex;
- }
+ else if (!int.TryParse(vlan, out tmp))
+ {
+ // TODO: double check exception type
+ errMsg = string.Format("Invalid VLAN value {0} for on vm {1} for nic uuid {2}", isolationUri, vmName, nic.uuid);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+ }
+ if(nicIp.Equals("0.0.0.0") && nicNetmask.Equals("255.255.255.255") ) {
+ // this is the extra nic added to VR.
+ vlan = defaultvlan;
}
-
- if (nicid == nicCount)
- {
- if (nicIp.Equals("0.0.0.0") && nicNetmask.Equals("255.255.255.255"))
- {
- // this is the extra nic added to VR.
- vlan = null;
- enableState = 3;
- }
-
- // Create network adapter
- var newAdapter = CreateNICforVm(newVm, mac);
- String switchName ="";
- if (nic.name != null)
- {
- switchName = nic.name;
- }
- EthernetPortAllocationSettingData portSettings = null;
- // connection to vswitch
- portSettings = AttachNicToPort(newVm, newAdapter, switchName, enableState);
- //reset the flag for other nics
- enableState = 2;
- // set vlan
- if (vlan != null)
- {
- SetPortVlan(vlan, portSettings);
- }
-
+
+ if (nicid == nicCount)
+ {
+ // Create network adapter
+ var newAdapter = CreateNICforVm(newVm, mac);
+ String switchName ="";
+ if (nic.name != null)
+ {
+ switchName = nic.name;
+ }
+
+ // connection to vswitch
+ var portSettings = AttachNicToPort(newVm, newAdapter, switchName);
+
+ // set vlan
+ if (vlan != null)
+ {
+ SetPortVlan(vlan, portSettings);
+ }
+
if (networkRateMbps > 0)
{
SetBandWidthLimit((ulong)networkRateMbps, portSettings);
@@ -486,147 +480,574 @@ namespace HypervResource
SetState(newVm, RequiredState.Enabled);
// Mark the VM as created by cloudstack tag
TagVm(newVm);
-
- // we need to reboot to get the hv kvp daemon get started vr gets configured.
- if (vmName.StartsWith("r-") || vmName.StartsWith("s-") || vmName.StartsWith("v-"))
- {
- System.Threading.Thread.Sleep(90000);
- // wait for the second boot and then return with sucesss
- //if publicIPAddress is empty or null don't ping the ip
- /*if (publicIpAddress.Equals("") == true)
- {
- System.Threading.Thread.Sleep(90000);
- }
- else
- {
- pingResource(publicIpAddress);
- }*/
- }
- logger.InfoFormat("Started VM {0}", vmName);
- return newVm;
- }
-
- public static Boolean pingResource(String ip)
- {
- PingOptions pingOptions = null;
- PingReply pingReply = null;
- IPAddress ipAddress = null;
- Ping pingSender = new Ping();
- int numberOfPings = 6;
- int pingTimeout = 1000;
- int byteSize = 32;
- byte[] buffer = new byte[byteSize];
- ipAddress = IPAddress.Parse(ip);
- pingOptions = new PingOptions();
- for (int i = 0; i < numberOfPings; i++)
- {
- pingReply = pingSender.Send(ipAddress, pingTimeout, buffer, pingOptions);
- if (pingReply.Status == IPStatus.Success)
- {
- System.Threading.Thread.Sleep(30000);
- return true;
- }
- else
- {
- // wait for the second boot and then return with suces
- System.Threading.Thread.Sleep(30000);
- }
- }
- return false;
- }
-
- private EthernetPortAllocationSettingData AttachNicToPort(ComputerSystem newVm, SyntheticEthernetPortSettingData newAdapter, String vSwitchName, int enableState)
- {
- // Get the virtual switch
- VirtualEthernetSwitch vSwitch = GetExternalVirtSwitch(vSwitchName);
- //check the the recevied vSwitch is the same as vSwitchName.
- if (!vSwitchName.Equals("") && !vSwitch.ElementName.Equals(vSwitchName))
- {
- var errMsg = string.Format("Internal error, coudl not find Virtual Switch with the name : " +vSwitchName);
- var ex = new WmiException(errMsg);
- logger.Error(errMsg, ex);
- throw ex;
- }
-
- // Create port for adapter
- var defaultEthernetPortSettings = EthernetPortAllocationSettingData.GetInstances(vSwitch.Scope, "InstanceID LIKE \"%Default\"");
-
- // assert
- if (defaultEthernetPortSettings.Count != 1)
- {
- var errMsg = string.Format("Internal error, coudl not find default EthernetPortAllocationSettingData instance");
- var ex = new WmiException(errMsg);
- logger.Error(errMsg, ex);
- throw ex;
- }
-
- var defaultEthernetPortSettingsObj = defaultEthernetPortSettings.OfType<EthernetPortAllocationSettingData>().First();
- var newEthernetPortSettings = new EthernetPortAllocationSettingData((ManagementBaseObject)defaultEthernetPortSettingsObj.LateBoundObject.Clone());
- newEthernetPortSettings.LateBoundObject["Parent"] = newAdapter.Path.Path;
- newEthernetPortSettings.LateBoundObject["HostResource"] = new string[] { vSwitch.Path.Path };
- newEthernetPortSettings.LateBoundObject["EnabledState"] = enableState; //3 disabled 2 Enabled
- // Insert NIC into vm
- string[] newResources = new string[] { newEthernetPortSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
- ManagementPath[] newResourcePaths = AddVirtualResource(newResources, newVm);
-
- // assert
- if (newResourcePaths.Length != 1)
- {
- var errMsg = string.Format(
- "Failed to properly insert a single NIC on VM {0} (GUID {1}): number of resource created {2}",
- newVm.ElementName,
- newVm.Name,
- newResourcePaths.Length);
- var ex = new WmiException(errMsg);
- logger.Error(errMsg, ex);
- throw ex;
- }
-
- return new EthernetPortAllocationSettingData(newResourcePaths[0]);
- }
-
- /// this method is to add a dvd drive and attach the systemvm iso.
- ///
- public void patchSystemVmIso(String vmName, String systemVmIso)
- {
- ComputerSystem vmObject = GetComputerSystem(vmName);
- AddDiskDriveToIdeController(vmObject, "", "1", ISO_DRIVE);
- AttachIso(vmName, systemVmIso);
- }
-
- public void AttachDisk(string vmName, string diskPath, string addressOnController)
- {
- logger.DebugFormat("Got request to attach disk {0} to vm {1}", diskPath, vmName);
-
- ComputerSystem vm = GetComputerSystem(vmName);
- if (vm == null)
- {
- logger.DebugFormat("VM {0} not found", vmName);
- return;
- }
- else
- {
- ManagementPath newDrivePath = GetDiskDriveOnScsiController(vm, addressOnController);
- if (newDrivePath == null)
- {
- newDrivePath = AttachDiskDriveToScsiController(vm, addressOnController);
- }
- InsertDiskImage(vm, diskPath, HARDDISK_DISK, newDrivePath);
- }
- }
-
- /// </summary>
- /// <param name="vm"></param>
- /// <param name="cntrllerAddr"></param>
- /// <param name="driveResourceType">IDE_HARDDISK_DRIVE or IDE_ISO_DRIVE</param>
- public ManagementPath AddDiskDriveToIdeController(ComputerSystem vm, string vhdfile, string cntrllerAddr, string driveResourceType)
- {
- logger.DebugFormat("Creating DISK for VM {0} (GUID {1}) by attaching {2}",
- vm.ElementName,
- vm.Name,
- vhdfile);
-
- // Determine disk type for drive and assert drive type valid
+
+ // we need to reboot to get the hv kvp daemon get started vr gets configured.
+ if (vmName.StartsWith("r-") || vmName.StartsWith("s-") || vmName.StartsWith("v-"))
+ {
+ System.Threading.Thread.Sleep(90000);
+ }
+ logger.InfoFormat("Started VM {0}", vmName);
+ return newVm;
+ }
+
+ public static Boolean pingResource(String ip)
+ {
+ PingOptions pingOptions = null;
+ PingReply pingReply = null;
+ IPAddress ipAddress = null;
+ Ping pingSender = new Ping();
+ int numberOfPings = 6;
+ int pingTimeout = 1000;
+ int byteSize = 32;
+ byte[] buffer = new byte[byteSize];
+ ipAddress = IPAddress.Parse(ip);
+ pingOptions = new PingOptions();
+ for (int i = 0; i < numberOfPings; i++)
+ {
+ pingReply = pingSender.Send(ipAddress, pingTimeout, buffer, pingOptions);
+ if (pingReply.Status == IPStatus.Success)
+ {
+ System.Threading.Thread.Sleep(30000);
+ return true;
+ }
+ else
+ {
+ // wait for the second boot and then return with suces
+ System.Threading.Thread.Sleep(30000);
+ }
+ }
+ return false;
+ }
+
+ private EthernetPortAllocationSettingData AttachNicToPort(ComputerSystem newVm, SyntheticEthernetPortSettingData newAdapter, String vSwitchName)
+ {
+ // Get the virtual switch
+ VirtualEthernetSwitch vSwitch = GetExternalVirtSwitch(vSwitchName);
+ //check the the recevied vSwitch is the same as vSwitchName.
+ if (!vSwitchName.Equals("") && !vSwitch.ElementName.Equals(vSwitchName))
+ {
+ var errMsg = string.Format("Internal error, coudl not find Virtual Switch with the name : " +vSwitchName);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+
+ // Create port for adapter
+ var defaultEthernetPortSettings = EthernetPortAllocationSettingData.GetInstances(vSwitch.Scope, "InstanceID LIKE \"%Default\"");
+
+ // assert
+ if (defaultEthernetPortSettings.Count != 1)
+ {
+ var errMsg = string.Format("Internal error, coudl not find default EthernetPortAllocationSettingData instance");
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+
+ var defaultEthernetPortSettingsObj = defaultEthernetPortSettings.OfType<EthernetPortAllocationSettingData>().First();
+ var newEthernetPortSettings = new EthernetPortAllocationSettingData((ManagementBaseObject)defaultEthernetPortSettingsObj.LateBoundObject.Clone());
+ newEthernetPortSettings.LateBoundObject["Parent"] = newAdapter.Path.Path;
+ newEthernetPortSettings.LateBoundObject["HostResource"] = new string[] { vSwitch.Path.Path };
+
+ // Insert NIC into vm
+ string[] newResources = new string[] { newEthernetPortSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
+ ManagementPath[] newResourcePaths = AddVirtualResource(newResources, newVm);
+
+ // assert
+ if (newResourcePaths.Length != 1)
+ {
+ var errMsg = string.Format(
+ "Failed to properly insert a single NIC on VM {0} (GUID {1}): number of resource created {2}",
+ newVm.ElementName,
+ newVm.Name,
+ newResourcePaths.Length);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+
+ return new EthernetPortAllocationSettingData(newResourcePaths[0]);
+ }
+
+ /// this method is to add a dvd drive and attach the systemvm iso.
+ ///
+ public void patchSystemVmIso(String vmName, String systemVmIso)
+ {
+ ComputerSystem vmObject = GetComputerSystem(vmName);
+ AddDiskDriveToIdeController(vmObject, "", "1", ISO_DRIVE);
+ AttachIso(vmName, systemVmIso);
+ }
+
+ public void AttachDisk(string vmName, string diskPath, string addressOnController)
+ {
+ logger.DebugFormat("Got request to attach disk {0} to vm {1}", diskPath, vmName);
+
+ ComputerSystem vm = GetComputerSystem(vmName);
+ if (vm == null)
+ {
+ logger.DebugFormat("VM {0} not found", vmName);
+ return;
+ }
+ else
+ {
+ ManagementPath newDrivePath = GetDiskDriveOnScsiController(vm, addressOnController);
+ if (newDrivePath == null)
+ {
+ newDrivePath = AttachDiskDriveToScsiController(vm, addressOnController);
+ }
+ InsertDiskImage(vm, diskPath, HARDDISK_DISK, newDrivePath);
+ }
+ }
+
+ /// </summary>
+ /// <param name="vm"></param>
+ /// <param name="cntrllerAddr"></param>
+ /// <param name="driveResourceType">IDE_HARDDISK_DRIVE or IDE_ISO_DRIVE</param>
+ public ManagementPath AddDiskDriveToIdeController(ComputerSystem vm, string vhdfile, string cntrllerAddr, string driveResourceType)
+ {
+ logger.DebugFormat("Creating DISK for VM {0} (GUID {1}) by attaching {2}",
+ vm.ElementName,
+ vm.Name,
+ vhdfile);
+
+ // Determine disk type for drive and assert drive type valid
+ string diskResourceSubType = null;
+ switch(driveResourceType) {
+ case HARDDISK_DRIVE:
+ diskResourceSubType = HARDDISK_DISK;
+ break;
+ case ISO_DRIVE:
+ diskResourceSubType = ISO_DISK;
+ break;
+ default:
+ var errMsg = string.Format(
+ "Unrecognised disk drive type {0} for VM {1} (GUID {2})",
+ string.IsNullOrEmpty(driveResourceType) ? "NULL": driveResourceType,
+ vm.ElementName,
+ vm.Name);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+
+ ManagementPath newDrivePath = AttachNewDrive(vm, cntrllerAddr, driveResourceType);
+
+ // If there's not disk to insert, we are done.
+ if (String.IsNullOrEmpty(vhdfile))
+ {
+ logger.DebugFormat("No disk to be added to drive, disk drive {0} is complete", newDrivePath.Path);
+ }
+ else
+ {
+ InsertDiskImage(vm, vhdfile, diskResourceSubType, newDrivePath);
+ }
+ return newDrivePath;
+ }
+
+
+ public void DetachDisk(string displayName, string diskFileName)
+ {
+ logger.DebugFormat("Got request to detach virtual disk {0} from vm {1}", diskFileName, displayName);
+
+ ComputerSystem vm = GetComputerSystem(displayName);
+ if (vm == null)
+ {
+ logger.DebugFormat("VM {0} not found", displayName);
+ return;
+ }
+ else
+ {
+ RemoveStorageImage(vm, diskFileName);
+ }
+ }
+
+ /// <summary>
+ /// Removes a disk image from a drive, but does not remove the drive itself.
+ /// </summary>
+ /// <param name="vm"></param>
+ /// <param name="diskFileName"></param>
+ private void RemoveStorageImage(ComputerSystem vm, string diskFileName)
+ {
+ // Obtain StorageAllocationSettingData for disk
+ StorageAllocationSettingData.StorageAllocationSettingDataCollection storageSettingsObjs = StorageAllocationSettingData.GetInstances();
+
+ StorageAllocationSettingData imageToRemove = null;
+ foreach (StorageAllocationSettingData item in storageSettingsObjs)
+ {
+ if (item.HostResource == null || item.HostResource.Length != 1)
+ {
+ continue;
+ }
+
+ string hostResource = item.HostResource[0];
+ if (Path.Equals(hostResource, diskFileName))
+ {
+ imageToRemove = item;
+ break;
+ }
+ }
+
+ // assert
+ if (imageToRemove == null)
+ {
+ var errMsg = string.Format(
+ "Failed to remove disk image {0} from VM {1} (GUID {2}): the disk image is not attached.",
+ diskFileName,
+ vm.ElementName,
+ vm.Name);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+
+ RemoveStorageResource(imageToRemove.Path, vm);
+
+ logger.InfoFormat("Removed disk image {0} from VM {1} (GUID {2}): the disk image is not attached.",
+ diskFileName,
+ vm.ElementName,
+ vm.Name);
+ }
+
+ private ManagementPath AttachNewDrive(ComputerSystem vm, string cntrllerAddr, string driveType)
+ {
+ // Disk drives are attached to a 'Parent' IDE controller. We IDE Controller's settings for the 'Path', which our new Disk drive will use to reference it.
+ VirtualSystemSettingData vmSettings = GetVmSettings(vm);
+ var ctrller = GetIDEControllerSettings(vmSettings, cntrllerAddr);
+
+ // A description of the drive is created by modifying a clone of the default ResourceAllocationSettingData for that drive type
+ string defaultDriveQuery = String.Format("ResourceSubType LIKE \"{0}\" AND InstanceID LIKE \"%Default\"", driveType);
+ var newDiskDriveSettings = CloneResourceAllocationSetting(defaultDriveQuery);
+
+ // Set IDE controller and address on the controller for the new drive
+ newDiskDriveSettings.LateBoundObject["Parent"] = ctrller.Path.ToString();
+ newDiskDriveSettings.LateBoundObject["AddressOnParent"] = "0";
+ newDiskDriveSettings.CommitObject();
+
+ // Add this new disk drive to the VM
+ logger.DebugFormat("Creating disk drive type {0}, parent IDE controller is {1} and address on controller is {2}",
+ newDiskDriveSettings.ResourceSubType,
+ newDiskDriveSettings.Parent,
+ newDiskDriveSettings.AddressOnParent);
+ string[] newDriveResource = new string[] { newDiskDriveSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
+ ManagementPath[] newDrivePaths = AddVirtualResource(newDriveResource, vm);
+
+ // assert
+ if (newDrivePaths.Length != 1)
+ {
+ var errMsg = string.Format(
+ "Failed to add disk drive type {3} to VM {0} (GUID {1}): number of resource created {2}",
+ vm.ElementName,
+ vm.Name,
+ newDrivePaths.Length,
+ driveType);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+ logger.DebugFormat("New disk drive type {0} WMI path is {1}s",
+ newDiskDriveSettings.ResourceSubType,
+ newDrivePaths[0].Path);
+ return newDrivePaths[0];
+ }
+
+ private ManagementPath AddScsiController(ComputerSystem vm)
+ {
+ // A description of the controller is created by modifying a clone of the default ResourceAllocationSettingData for scsi controller
+ string scsiQuery = String.Format("ResourceSubType LIKE \"{0}\" AND InstanceID LIKE \"%Default\"", SCSI_CONTROLLER);
+ var scsiSettings = CloneResourceAllocationSetting(scsiQuery);
+
+ scsiSettings.LateBoundObject["ElementName"] = "SCSI Controller";
+ scsiSettings.CommitObject();
+
+ // Insert SCSI controller into vm
+ string[] newResources = new string[] { scsiSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
+ ManagementPath[] newResourcePaths = AddVirtualResource(newResources, vm);
+
+ // assert
+ if (newResourcePaths.Length != 1)
+ {
+ var errMsg = string.Format(
+ "Failed to add scsi controller to VM {0} (GUID {1}): number of resource created {2}",
+ vm.ElementName,
+ vm.Name,
+ newResourcePaths.Length);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+
+ logger.DebugFormat("New controller type {0} WMI path is {1}s",
+ scsiSettings.ResourceSubType,
+ newResourcePaths[0].Path);
+ return newResourcePaths[0];
+ }
+
+ private ManagementPath GetDiskDriveOnScsiController(ComputerSystem vm, string addrOnController)
+ {
+ VirtualSystemSettingData vmSettings = GetVmSettings(vm);
+ var wmiObjCollection = GetResourceAllocationSettings(vmSettings);
+ foreach (ResourceAllocationSettingData wmiObj in wmiObjCollection)
+ {
+ if (wmiObj.ResourceSubType == HARDDISK_DRIVE)
+ {
+ ResourceAllocationSettingData parent = new ResourceAllocationSettingData(new ManagementObject(wmiObj.Parent));
+ if (parent.ResourceSubType == SCSI_CONTROLLER && wmiObj.AddressOnParent == addrOnController)
+ {
+ return wmiObj.Path;
+ }
+ }
+ }
+ return null;
+ }
+
+ private ManagementPath AttachDiskDriveToScsiController(ComputerSystem vm, string addrOnController)
+ {
+ // Disk drives are attached to a 'Parent' Scsi controller.
+ VirtualSystemSettingData vmSettings = GetVmSettings(vm);
+ var ctrller = GetScsiControllerSettings(vmSettings);
+
+ // A description of the drive is created by modifying a clone of the default ResourceAllocationSettingData for that drive type
+ string defaultDriveQuery = String.Format("ResourceSubType LIKE \"{0}\" AND InstanceID LIKE \"%Default\"", HARDDISK_DRIVE);
+ var newDiskDriveSettings = CloneResourceAllocationSetting(defaultDriveQuery);
+
+ // Set IDE controller and address on the controller for the new drive
+ newDiskDriveSettings.LateBoundObject["Parent"] = ctrller.Path.ToString();
+ newDiskDriveSettings.LateBoundObject["AddressOnParent"] = addrOnController;
+ newDiskDriveSettings.CommitObject();
+
+ // Add this new disk drive to the VM
+ logger.DebugFormat("Creating disk drive type {0}, parent IDE controller is {1} and address on controller is {2}",
+ newDiskDriveSettings.ResourceSubType,
+ newDiskDriveSettings.Parent,
+ newDiskDriveSettings.AddressOnParent);
+ string[] newDriveResource = new string[] { newDiskDriveSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
+ ManagementPath[] newDrivePaths = AddVirtualResource(newDriveResource, vm);
+
+ // assert
+ if (newDrivePaths.Length != 1)
+ {
+ var errMsg = string.Format(
+ "Failed to add disk drive type {3} to VM {0} (GUID {1}): number of resource created {2}",
+ vm.ElementName,
+ vm.Name,
+ newDrivePaths.Length,
+ HARDDISK_DRIVE);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+ logger.DebugFormat("New disk drive type {0} WMI path is {1}s",
+ newDiskDriveSettings.ResourceSubType,
+ newDrivePaths[0].Path);
+ return newDrivePaths[0];
+ }
+
+
+ private void InsertDiskImage(ComputerSystem vm, string diskImagePath, string diskResourceSubType, ManagementPath drivePath)
+ {
+ // A description of the disk is created by modifying a clone of the default ResourceAllocationSettingData for that disk type
+ string defaultDiskQuery = String.Format("ResourceSubType LIKE \"{0}\" AND InstanceID LIKE \"%Default\"", diskResourceSubType);
+ var newDiskSettings = CloneStorageAllocationSetting(defaultDiskQuery);
+
+ // Set file containing the disk image
+ newDiskSettings.LateBoundObject["Parent"] = drivePath.Path;
+
+ // V2 API uses HostResource to specify image, see http://msdn.microsoft.com/en-us/library/hh859775(v=vs.85).aspx
+ newDiskSettings.LateBoundObject["HostResource"] = new string[] { diskImagePath };
+ newDiskSettings.CommitObject();
+
+ // Add the new Msvm_StorageAllocationSettingData object as a virtual hard disk to the vm.
+ string[] newDiskResource = new string[] { newDiskSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
+ ManagementPath[] newDiskPaths = AddStorageResource(newDiskResource, vm);
+ // assert
+ if (newDiskPaths.Length != 1)
+ {
+ var errMsg = string.Format(
+ "Failed to add disk image type {3} to VM {0} (GUID {1}): number of resource created {2}",
+ vm.ElementName,
+ vm.Name,
+ newDiskPaths.Length,
+ diskResourceSubType);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+ logger.InfoFormat("Created disk {2} for VM {0} (GUID {1}), image {3} ",
+ vm.ElementName,
+ vm.Name,
+ newDiskPaths[0].Path,
+ diskImagePath);
+ }
+
+ /// <summary>
+ /// Create Msvm_StorageAllocationSettingData corresponding to the ISO image, and
+ /// associate this with the VM's DVD drive.
+ /// </summary>
+ private void AttachIso(ComputerSystem vm, string isoPath)
+ {
+ // Disk drives are attached to a 'Parent' IDE controller. We IDE Controller's settings for the 'Path', which our new Disk drive will use to reference it.
+ VirtualSystemSettingData vmSettings = GetVmSettings(vm);
+ var driveWmiObj = GetDvdDriveSettings(vmSettings);
+ InsertDiskImage(vm, isoPath, ISO_DISK, driveWmiObj.Path);
+ }
+
+ private static ResourceAllocationSettingData CloneResourceAllocationSetting(string wmiQuery)
+ {
+ var defaultDiskDriveSettingsObjs = ResourceAllocationSettingData.GetInstances(wmiQuery);
+
+ // assert
+ if (defaultDiskDriveSettingsObjs.Count != 1)
+ {
+ var errMsg = string.Format("Failed to find Msvm_ResourceAllocationSettingData for the query {0}", wmiQuery);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+
+ ResourceAllocationSettingData defaultDiskDriveSettings = defaultDiskDriveSettingsObjs.OfType<ResourceAllocationSettingData>().First();
+ return new ResourceAllocationSettingData((ManagementBaseObject)defaultDiskDriveSettings.LateBoundObject.Clone());
+ }
+
+ // we need to reboot to get the hv kvp daemon get started vr gets configured.
+ if (vmName.StartsWith("r-") || vmName.StartsWith("s-") || vmName.StartsWith("v-"))
+ {
+ System.Threading.Thread.Sleep(90000);
+ // wait for the second boot and then return with sucesss
+ //if publicIPAddress is empty or null don't ping the ip
+ /*if (publicIpAddress.Equals("") == true)
+ {
+ System.Threading.Thread.Sleep(90000);
+ }
+ else
+ {
+ pingResource(publicIpAddress);
+ }*/
+ }
+ logger.InfoFormat("Started VM {0}", vmName);
+ return newVm;
+ }
+
+ public static Boolean pingResource(String ip)
+ {
+ PingOptions pingOptions = null;
+ PingReply pingReply = null;
+ IPAddress ipAddress = null;
+ Ping pingSender = new Ping();
+ int numberOfPings = 6;
+ int pingTimeout = 1000;
+ int byteSize = 32;
+ byte[] buffer = new byte[byteSize];
+ ipAddress = IPAddress.Parse(ip);
+ pingOptions = new PingOptions();
+ for (int i = 0; i < numberOfPings; i++)
+ {
+ pingReply = pingSender.Send(ipAddress, pingTimeout, buffer, pingOptions);
+ if (pingReply.Status == IPStatus.Success)
+ {
+ System.Threading.Thread.Sleep(30000);
+ return true;
+ }
+ else
+ {
+ // wait for the second boot and then return with suces
+ System.Threading.Thread.Sleep(30000);
+ }
+ }
+ return false;
+ }
+
+ private EthernetPortAllocationSettingData AttachNicToPort(ComputerSystem newVm, SyntheticEthernetPortSettingData newAdapter, String vSwitchName, int enableState)
+ {
+ // Get the virtual switch
+ VirtualEthernetSwitch vSwitch = GetExternalVirtSwitch(vSwitchName);
+ //check the the recevied vSwitch is the same as vSwitchName.
+ if (!vSwitchName.Equals("") && !vSwitch.ElementName.Equals(vSwitchName))
+ {
+ var errMsg = string.Format("Internal error, coudl not find Virtual Switch with the name : " +vSwitchName);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+
+ // Create port for adapter
+ var defaultEthernetPortSettings = EthernetPortAllocationSettingData.GetInstances(vSwitch.Scope, "InstanceID LIKE \"%Default\"");
+
+ // assert
+ if (defaultEthernetPortSettings.Count != 1)
+ {
+ var errMsg = string.Format("Internal error, coudl not find default EthernetPortAllocationSettingData instance");
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+
+ var defaultEthernetPortSettingsObj = defaultEthernetPortSettings.OfType<EthernetPortAllocationSettingData>().First();
+ var newEthernetPortSettings = new EthernetPortAllocationSettingData((ManagementBaseObject)defaultEthernetPortSettingsObj.LateBoundObject.Clone());
+ newEthernetPortSettings.LateBoundObject["Parent"] = newAdapter.Path.Path;
+ newEthernetPortSettings.LateBoundObject["HostResource"] = new string[] { vSwitch.Path.Path };
+ newEthernetPortSettings.LateBoundObject["EnabledState"] = enableState; //3 disabled 2 Enabled
+ // Insert NIC into vm
+ string[] newResources = new string[] { newEthernetPortSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
+ ManagementPath[] newResourcePaths = AddVirtualResource(newResources, newVm);
+
+ // assert
+ if (newResourcePaths.Length != 1)
+ {
+ var errMsg = string.Format(
+ "Failed to properly insert a single NIC on VM {0} (GUID {1}): number of resource created {2}",
+ newVm.ElementName,
+ newVm.Name,
+ newResourcePaths.Length);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+
+ return new EthernetPortAllocationSettingData(newResourcePaths[0]);
+ }
+
+ /// this method is to add a dvd drive and attach the systemvm iso.
+ ///
+ public void patchSystemVmIso(String vmName, String systemVmIso)
+ {
+ ComputerSystem vmObject = GetComputerSystem(vmName);
+ AddDiskDriveToIdeController(vmObject, "", "1", ISO_DRIVE);
+ AttachIso(vmName, systemVmIso);
+ }
+
+ public void AttachDisk(string vmName, string diskPath, string addressOnController)
+ {
+ logger.DebugFormat("Got request to attach disk {0} to vm {1}", diskPath, vmName);
+
+ ComputerSystem vm = GetComputerSystem(vmName);
+ if (vm == null)
+ {
+ logger.DebugFormat("VM {0} not found", vmName);
+ return;
+ }
+ else
+ {
+ ManagementPath newDrivePath = GetDiskDriveOnScsiController(vm, addressOnController);
+ if (newDrivePath == null)
+ {
+ newDrivePath = AttachDiskDriveToScsiController(vm, addressOnController);
+ }
+ InsertDiskImage(vm, diskPath, HARDDISK_DISK, newDrivePath);
+ }
+ }
+
+ /// </summary>
+ /// <param name="vm"></param>
+ /// <param name="cntrllerAddr"></param>
+ /// <param name="driveResourceType">IDE_HARDDISK_DRIVE or IDE_ISO_DRIVE</param>
+ public ManagementPath AddDiskDriveToIdeController(ComputerSystem vm, string vhdfile, string cntrllerAddr, string driveResourceType)
+ {
+ logger.DebugFormat("Creating DISK for VM {0} (GUID {1}) by attaching {2}",
+ vm.ElementName,
+ vm.Name,
+ vhdfile);
+
+ // Determine disk type for drive and assert drive type valid
string diskResourceSubType = null;
switch(driveResourceType) {
case HARDDISK_DRIVE:
@@ -2024,13 +2445,9 @@ namespace HypervResource
public VirtualEthernetSwitchManagementService GetVirtualSwitchManagementService()
{
- // VirtualSwitchManagementService is a singleton, most anonymous way of lookup is by asking for the set
- // of local instances, which should be size 1.
- var virtSwtichSvcCollection = VirtualEthernetSwitchManagementService.GetInstances();
- foreach (VirtualEthernetSwitchManagementService item in virtSwtichSvcCollection)
- {
- return item;
- }
+ ComputerSystem vm = GetComputerSystem(vmName);
+ // Obtain controller for Hyper-V virtualisation subsystem
+ VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService();
var errMsg = string.Format("No Hyper-V subsystem on server");
var ex = new WmiException(errMsg);
@@ -2183,195 +2600,259 @@ namespace HypervResource
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;
- }
- }
-
- private static void StorageJobCompleted(ManagementPath jobPath)
- {
- StorageJob jobObj = null;
- for (; ; )
- {
- jobObj = new StorageJob(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;
- }
- }
-
- public void GetProcessorResources(out uint sockets, out uint cores, out uint mhz)
- {
- // Processor processors
- cores = 0;
- mhz = 0;
- sockets = 0;
- Processor.ProcessorCollection procCol = Processor.GetInstances();
- foreach (Processor procInfo in procCol)
- {
- cores += procInfo.NumberOfCores;
- mhz = procInfo.MaxClockSpeed;
- sockets++;
- }
- }
-
- public void GetProcessorUsageInfo(out double cpuUtilization)
- {
- PerfFormattedData_Counters_ProcessorInformation.PerfFormattedData_Counters_ProcessorInformationCollection coll =
- PerfFormattedData_Counters_ProcessorInformation.GetInstances("Name=\"_Total\"");
- cpuUtilization = 100;
- // Use the first one
- foreach (PerfFormattedData_Counters_ProcessorInformation procInfo in coll)
- {
- // Idle during a given internal
- // See http://library.wmifun.net/cimv2/win32_perfformatteddata_counters_processorinformation.html
- cpuUtilization = 100.0 - (double)procInfo.PercentIdleTime;
- }
- }
-
-
- public void GetMemoryResources(out ulong physicalRamKBs, out ulong freeMemoryKBs)
- {
- OperatingSystem0 os = new OperatingSystem0();
- physicalRamKBs = os.TotalVisibleMemorySize;
- freeMemoryKBs = os.FreePhysicalMemory;
- }
-
- public string GetDefaultVirtualDiskFolder()
- {
- VirtualSystemManagementServiceSettingData.VirtualSystemManagementServiceSettingDataCollection coll = VirtualSystemManagementServiceSettingData.GetInstances();
- string defaultVirtualHardDiskPath = null;
- foreach (VirtualSystemManagementServiceSettingData settings in coll)
- {
- defaultVirtualHardDiskPath = settings.DefaultVirtualHardDiskPath;
- }
-
- // assert
- if (!System.IO.Directory.Exists(defaultVirtualHardDiskPath) ){
- var errMsg = string.Format(
- "Hyper-V DefaultVirtualHardDiskPath is invalid!");
- logger.Error(errMsg);
- return null;
- }
-
- return defaultVirtualHardDiskPath;
- }
-
- public 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 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();
- Dictionary<String, VmState> vmSyncStates = new Dictionary<string, VmState>();
- String vmState;
- foreach (String vm in vms)
- {
- vmState = EnabledState.ToCloudStackState(GetComputerSystem(vm).EnabledState);
- vmSyncStates.Add(vm, new VmState(vmState, privateIpAddress));
- }
- return vmSyncStates;
- }
-
- public 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 ProcessorSettingData GetProcSettings(VirtualSystemSettingData vmSettings)
- {
- // An ASSOCIATOR object provides the cross reference from the VirtualSystemSettingData and the
- // ProcessorSettingData, 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, ProcessorSettingData.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 ProcessorSettingData.ProcessorSettingDataCollection(wmiObjectSearch.Get());
-
- foreach (ProcessorSettingData wmiObj in wmiObjCollection)
+ if (jobObj.JobState != JobState.Completed)
{
- return wmiObj;
+ 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;
}
-
- var errMsg = string.Format("No ProcessorSettingData in VirtualSystemSettingData {0}", vmSettings.Path.Path);
- var ex = new WmiException(errMsg);
- logger.Error(errMsg, ex);
- throw ex;
}
- public MemorySettingData GetMemSettings(VirtualSystemSettingData vmSettings)
+ private static void StorageJobCompleted(ManagementPath jobPath)
{
- // An ASSOCIATOR object provides the cross reference from the VirtualSystemSettingData and the
- // MemorySettingData, 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, MemorySettingData.CreatedClassName);
-
- EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm);
- EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[pos]);
+ StorageJob jobObj = null;
+ for (; ; )
+ {
+ jobObj = new StorageJob(jobPath);
+ if (jobObj.JobState != JobState.Starting && jobObj.JobState != JobState.Running)
+ {
+ break;
+ }
+ logger.InfoFormat("In progress... {0}% completed.", jobObj.PercentComplete);
+ System.Threading.Thread.Sleep(1000);
+ }
- //Assign configuration to new NIC
- vlanSettings.LateBoundObject["AccessVlanId"] = vlanid;
- vlanSettings.LateBoundObject["OperationMode"] = 1;
- ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] {
- vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)});
+ 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;
+ }
}
- public void AttachIso(string displayName, string iso)
+ /// <summary>
+ /// Migrates a vm to the given destination host
+ /// </summary>
+ /// <param name="desplayName"></param>
+ /// <param name="destination host"></param>
+ public void MigrateVm(string vmName, string destination)
+ {
+ ComputerSystem vm = GetComputerSystem(vmName);
+ VirtualSystemMigrationSettingData migrationSettingData = VirtualSystemMigrationSettingData.CreateInstance();
+ VirtualSystemMigrationService service = GetVirtualisationSystemMigrationService();
+
+ IPAddress addr = IPAddress.Parse(destination);
+ IPHostEntry entry = Dns.GetHostEntry(addr);
+ string[] destinationHost = new string[] { destination };
+
+ migrationSettingData.LateBoundObject["MigrationType"] = MigrationType.VirtualSystem;
+ migrationSettingData.LateBoundObject["TransportType"] = TransportType.TCP;
+ migrationSettingData.LateBoundObject["DestinationIPAddressList"] = destinationHost;
+ string migrationSettings = migrationSettingData.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20);
+
+ ManagementPath jobPath;
+ var ret_val = service.MigrateVirtualSystemToHost(vm.Path, entry.HostName, migrationSettings, null, null, out jobPath);
+ if (ret_val == ReturnCode.Started)
+ {
+ MigrationJobCompleted(jobPath);
+ }
+ else if (ret_val != ReturnCode.Completed)
+ {
+ var errMsg = string.Format(
+ "Failed migrating VM {0} (GUID {1}) due to {2}",
+ vm.ElementName,
+ vm.Name,
+ ReturnCode.ToString(ret_val));
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+ }
+
+ /// <summary>
+ /// Migrates the volume of a vm to a given destination storage
+ /// </summary>
+ /// <param name="displayName"></param>
+ /// <param name="volume"></param>
+ /// <param name="destination storage pool"></param>
+ public void MigrateVolume(string vmName, string volume, string destination)
+ {
+ ComputerSystem vm = GetComputerSystem(vmName);
+ VirtualSystemMigrationSettingData migrationSettingData = VirtualSystemMigrationSettingData.CreateInstance();
+ VirtualSystemMigrationService service = GetVirtualisationSystemMigrationService();
+ StorageAllocationSettingData[] sasd = GetStorageSettings(vm);
+
+ string[] rasds = null;
+ if (sasd != null)
+ {
+ rasds = new string[1];
+ foreach (StorageAllocationSettingData item in sasd)
+ {
+ string vhdFileName = Path.GetFileNameWithoutExtension(item.HostResource[0]);
+ if (!String.IsNullOrEmpty(vhdFileName) && vhdFileName.Equals(volume))
+ {
+ string newVhdPath = Path.Combine(destination, Path.GetFileName(item.HostResource[0]));
+ item.LateBoundObject["HostResource"] = new string[] { newVhdPath };
+ item.LateBoundObject["PoolId"] = "";
+ rasds[0] = item.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20);
+ break;
+ }
+ }
+ }
+
+ migrationSettingData.LateBoundObject["MigrationType"] = MigrationType.Storage;
+ migrationSettingData.LateBoundObject["TransportType"] = TransportType.TCP;
+ string migrationSettings = migrationSettingData.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20);
+
+ ManagementPath jobPath;
+ var ret_val = service.MigrateVirtualSystemToHost(vm.Path, null, migrationSettings, rasds, null, out jobPath);
+ if (ret_val == ReturnCode.Started)
+ {
+ MigrationJobCompleted(jobPath);
+ }
+ else if (ret_val != ReturnCode.Completed)
+ {
+ var errMsg = string.Format(
+ "Failed migrating volume {0} of VM {1} (GUID {2}) due to {3}",
+ volume,
+ vm.ElementName,
+ vm.Name,
+ ReturnCode.ToString(ret_val));
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+ }
+
+ /// <summary>
+ /// Migrates the volume of a vm to a given destination storage
+ /// </summary>
+ /// <param name="displayName"></param>
+ /// <param name="destination host"></param>
+ /// <param name="volumeToPool"> volume to me migrated to which pool</param>
+ public void MigrateVmWithVolume(string vmName, string destination, Dictionary<string, string> volumeToPool)
+ {
+ ComputerSystem vm = GetComputerSystem(vmName);
+ VirtualSystemMigrationSettingData migrationSettingData = VirtualSystemMigrationSettingData.CreateInstance();
+ VirtualSystemMigrationService service = GetVirtualisationSystemMigrationService();
+ StorageAllocationSettingData[] sasd = GetStorageSettings(vm);
+
+ string[] rasds = null;
+ if (sasd != null)
+ {
+ rasds = new string[sasd.Length];
+ uint index = 0;
+ foreach (StorageAllocationSettingData item in sasd)
+ {
+ string vhdFileName = Path.GetFileNameWithoutExtension(item.HostResource[0]);
+ if (!String.IsNullOrEmpty(vhdFileName) && volumeToPool.ContainsKey(vhdFileName))
+ {
+ string newVhdPath = Path.Combine(volumeToPool[vhdFileName], Path.GetFileName(item.HostResource[0]));
+ item.LateBoundObject["HostResource"] = new string[] { newVhdPath };
+ item.LateBoundObject["PoolId"] = "";
+ }
+
+ rasds[index++] = item.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20);
+ }
+ }
+
+ IPAddress addr = IPAddress.Parse(destination);
+ IPHostEntry entry = Dns.GetHostEntry(addr);
+ string[] destinationHost = new string[] { destination };
+
+ migrationSettingData.LateBoundObject["MigrationType"] = MigrationType.VirtualSystemAndStorage;
+ migrationSettingData.LateBoundObject["TransportType"] = TransportType.TCP;
+ migrationSettingData.LateBoundObject["DestinationIPAddressList"] = destinationHost;
+ string migrationSettings = migrationSettingData.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20);
+
+ ManagementPath jobPath;
+ var ret_val = service.MigrateVirtualSystemToHost(vm.Path, entry.HostName, migrationSettings, rasds, null, out jobPath);
+ if (ret_val == ReturnCode.Started)
+ {
+ MigrationJobCompleted(jobPath);
+ }
+ else if (ret_val != ReturnCode.Completed)
+ {
+ var errMsg = string.Format(
+ "Failed migrating VM {0} and its volumes to destination {1} (GUID {2}) due to {3}",
+ vm.ElementName,
+ destination,
+ vm.Name,
+ ReturnCode.ToString(ret_val));
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+ }
+
+ /// <summary>
+ /// Create new storage media resources, e.g. hard disk images and ISO disk images
+ /// see http://msdn.microsoft.com/en-us/library/hh859775(v=vs.85).aspx
+ /// </summary>
+ /// <param name="wmiQuery"></param>
+ /// <returns></returns>
+ private static StorageAllocationSettingData CloneStorageAllocationSetting(string wmiQuery)
+ {
+ var defaultDiskImageSettingsObjs = StorageAllocationSettingData.GetInstances(wmiQuery);
+
+ // assert
+ if (defaultDiskImageSettingsObjs.Count != 1)
+ {
+ var errMsg = string.Format("Failed to find Msvm_StorageAllocationSettingData for the query {0}", wmiQuery);
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+
+ StorageAllocationSettingData defaultDiskDriveSettings = defaultDiskImageSettingsObjs.OfType<StorageAllocationSettingData>().First();
+ return new StorageAllocationSettingData((ManagementBaseObject)defaultDiskDriveSettings.LateBoundObject.Clone());
+ }
+
+ /// < summary>
+ /// Removes a storage resource from a computer system.
+ /// </summary>
+ /// <param name="storageSettings">Path that uniquely identifies the resource.</param>
+ /// <param name="vm">VM to which the disk image will be attached.</param>
+ // Add new
+ private void RemoveNetworkResource(ManagementPath resourcePath)
+ {
+ var virtSwitchMgmtSvc = GetVirtualSwitchManagementService();
+ ManagementPath jobPath;
+ var ret_val = virtSwitchMgmtSvc.RemoveResourceSettings(
+ new ManagementPath[] { resourcePath },
+ 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 remove network resources {0} from switch due to {1}",
+ resourcePath.Path,
+ ReturnCode.ToString(ret_val));
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+ }
+
+ /// < summary>
+ /// Removes a storage resource from a computer system.
+ /// </summary>
+ /// <param name="storageSettings">Path that uniquely identifies the resource.</param>
+ /// <param name="vm">VM to which the disk image will be attached.</param>
+ private void RemoveStorageResource(ManagementPath resourcePath, ComputerSystem vm)
{
logger.DebugFormat("Got request to attach iso {0} to vm {1}", iso, displayName);
[2/3] CLOUDSTACK-6504: removed warnings coming in building hyper-v
agent code
Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8fb89cdc/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 1a46b50..41a3a8a 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
@@ -189,1867 +189,607 @@ namespace HypervResource
using (log4net.NDC.Push(Guid.NewGuid().ToString()))
{
logger.Info(CloudStackTypes.SetupCommand + Utils.CleanString(cmd.ToString()));
-
- string details = null;
- bool result = false;
-
- try
- {
- result = true;
- }
- catch (Exception sysEx)
- {
- details = CloudStackTypes.SetupCommand + " failed due to " + sysEx.Message;
- logger.Error(details, sysEx);
- }
-
- object ansContent = new
- {
- result = result,
- details = "success - NOP",
- _reconnect = false,
- contextMap = contextMap
- };
-
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.SetupAnswer);
- }
- }
-
- // POST api/HypervResource/AttachCommand
- [HttpPost]
- [ActionName(CloudStackTypes.AttachCommand)]
- public JContainer AttachCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.AttachCommand + Utils.CleanString(cmd.ToString()));
-
- string details = null;
- bool result = false;
-
- try
- {
- string vmName = (string)cmd.vmName;
- DiskTO disk = DiskTO.ParseJson(cmd.disk);
-
- if (disk.type.Equals("ISO"))
- {
- TemplateObjectTO dataStore = disk.templateObjectTO;
- NFSTO share = dataStore.nfsDataStoreTO;
- string diskPath = Utils.NormalizePath(Path.Combine(share.UncPath, dataStore.path));
- wmiCallsV2.AttachIso(vmName, diskPath);
- result = true;
- }
- else if (disk.type.Equals("DATADISK"))
- {
- VolumeObjectTO volume = disk.volumeObjectTO;
- string diskPath = Utils.NormalizePath(volume.FullFileName);
- wmiCallsV2.AttachDisk(vmName, diskPath, disk.diskSequence);
- result = true;
- }
- else
- {
- details = "Invalid disk type to be attached to vm " + vmName;
- }
- }
- catch (Exception sysEx)
- {
- details = CloudStackTypes.AttachCommand + " failed due to " + sysEx.Message;
- logger.Error(details, sysEx);
- }
-
- object ansContent = new
- {
- result = result,
- details = details,
- disk = cmd.disk,
- contextMap = contextMap
- };
-
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.AttachAnswer);
- }
- }
-
- // POST api/HypervResource/DetachCommand
- [HttpPost]
- [ActionName(CloudStackTypes.DettachCommand)]
- public JContainer DetachCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.DettachCommand + Utils.CleanString(cmd.ToString()));
-
- string details = null;
- bool result = false;
-
- try
- {
- string vmName = (string)cmd.vmName;
- DiskTO disk = DiskTO.ParseJson(cmd.disk);
-
- if (disk.type.Equals("ISO"))
- {
- TemplateObjectTO dataStore = disk.templateObjectTO;
- NFSTO share = dataStore.nfsDataStoreTO;
- string diskPath = Utils.NormalizePath(Path.Combine(share.UncPath, dataStore.path));
- wmiCallsV2.DetachDisk(vmName, diskPath);
- result = true;
- }
- else if (disk.type.Equals("DATADISK"))
- {
- VolumeObjectTO volume = disk.volumeObjectTO;
- PrimaryDataStoreTO primary = volume.primaryDataStore;
- string diskPath = Utils.NormalizePath(volume.FullFileName);
- wmiCallsV2.DetachDisk(vmName, diskPath);
- result = true;
- }
- else
- {
- details = "Invalid disk type to be dettached from vm " + vmName;
- }
- }
- catch (Exception sysEx)
- {
- details = CloudStackTypes.DettachCommand + " failed due to " + sysEx.Message;
- logger.Error(details, sysEx);
- }
-
- object ansContent = new
- {
- result = result,
- details = details,
- contextMap = contextMap
- };
-
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.DettachAnswer);
- }
- }
-
- // POST api/HypervResource/RebootCommand
- [HttpPost]
- [ActionName(CloudStackTypes.RebootCommand)]
- public JContainer RebootCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
+
+ string details = null;
+ bool result = false;
+
+ try
+ {
+ result = true;
+ }
+ catch (Exception sysEx)
+ {
+ details = CloudStackTypes.SetupCommand + " failed due to " + sysEx.Message;
+ logger.Error(details, sysEx);
+ }
+
+ object ansContent = new
+ {
+ result = result,
+ details = "success - NOP",
+ _reconnect = false,
+ contextMap = contextMap
+ };
+
+ return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.SetupAnswer);
+ }
+ }
+
+ // POST api/HypervResource/AttachCommand
+ [HttpPost]
+ [ActionName(CloudStackTypes.AttachCommand)]
+ public JContainer AttachCommand([FromBody]dynamic cmd)
+ {
+ using (log4net.NDC.Push(Guid.NewGuid().ToString()))
+ {
+ logger.Info(CloudStackTypes.AttachCommand + Utils.CleanString(cmd.ToString()));
+
+ string details = null;
+ bool result = false;
+
+ try
+ {
+ string vmName = (string)cmd.vmName;
+ DiskTO disk = DiskTO.ParseJson(cmd.disk);
+
+ if (disk.type.Equals("ISO"))
+ {
+ TemplateObjectTO dataStore = disk.templateObjectTO;
+ NFSTO share = dataStore.nfsDataStoreTO;
+ Utils.ConnectToRemote(share.UncPath, share.Domain, share.User, share.Password);
+ string diskPath = Utils.NormalizePath(Path.Combine(share.UncPath, dataStore.path));
+ wmiCallsV2.AttachIso(vmName, diskPath);
+ result = true;
+ }
+ else if (disk.type.Equals("DATADISK"))
+ {
+ VolumeObjectTO volume = disk.volumeObjectTO;
+ PrimaryDataStoreTO primary = volume.primaryDataStore;
+ if (!primary.isLocal)
+ {
+ Utils.ConnectToRemote(primary.UncPath, primary.Domain, primary.User, primary.Password);
+ }
+ string diskPath = Utils.NormalizePath(volume.FullFileName);
+ wmiCallsV2.AttachDisk(vmName, diskPath, disk.diskSequence);
+ result = true;
+ }
+ else
+ {
+ details = "Invalid disk type to be attached to vm " + vmName;
+ }
+ }
+ catch (Exception sysEx)
+ {
+ details = CloudStackTypes.AttachCommand + " failed due to " + sysEx.Message;
+ logger.Error(details, sysEx);
+ }
+
+ object ansContent = new
+ {
+ result = result,
+ details = details,
+ disk = cmd.disk,
+ contextMap = contextMap
+ };
+
+ return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.AttachAnswer);
+ }
+ }
+
+ // POST api/HypervResource/DetachCommand
+ [HttpPost]
+ [ActionName(CloudStackTypes.DettachCommand)]
+ public JContainer DetachCommand([FromBody]dynamic cmd)
+ {
+ using (log4net.NDC.Push(Guid.NewGuid().ToString()))
+ {
+ logger.Info(CloudStackTypes.DettachCommand + Utils.CleanString(cmd.ToString()));
+
+ string details = null;
+ bool result = false;
+
+ try
+ {
+ string vmName = (string)cmd.vmName;
+ DiskTO disk = DiskTO.ParseJson(cmd.disk);
+
+ if (disk.type.Equals("ISO"))
+ {
+ TemplateObjectTO dataStore = disk.templateObjectTO;
+ NFSTO share = dataStore.nfsDataStoreTO;
+ string diskPath = Utils.NormalizePath(Path.Combine(share.UncPath, dataStore.path));
+ wmiCallsV2.DetachDisk(vmName, diskPath);
+ result = true;
+ }
+ else if (disk.type.Equals("DATADISK"))
+ {
+ VolumeObjectTO volume = disk.volumeObjectTO;
+ string diskPath = Utils.NormalizePath(volume.FullFileName);
+ wmiCallsV2.DetachDisk(vmName, diskPath);
+ result = true;
+ }
+ else
+ {
+ details = "Invalid disk type to be dettached from vm " + vmName;
+ }
+ }
+ catch (Exception sysEx)
+ {
+ details = CloudStackTypes.DettachCommand + " failed due to " + sysEx.Message;
+ logger.Error(details, sysEx);
+ }
+
+ object ansContent = new
+ {
+ result = result,
+ details = details,
+ contextMap = contextMap
+ };
+
+ return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.DettachAnswer);
+ }
+ }
+
+ // POST api/HypervResource/RebootCommand
+ [HttpPost]
+ [ActionName(CloudStackTypes.RebootCommand)]
+ public JContainer RebootCommand([FromBody]dynamic cmd)
+ {
+ using (log4net.NDC.Push(Guid.NewGuid().ToString()))
+ {
logger.Info(CloudStackTypes.RebootCommand + Utils.CleanString(cmd.ToString()));
- string details = null;
- bool result = false;
-
- try
- {
- string vmName = (string)cmd.vmName;
- var sys = wmiCallsV2.GetComputerSystem(vmName);
- if (sys == null)
- {
- details = CloudStackTypes.RebootCommand + " requested unknown VM " + vmName;
- logger.Error(details);
- }
- else
- {
- wmiCallsV2.SetState(sys, RequiredState.Reset);
- result = true;
- }
- }
- catch (Exception sysEx)
- {
- details = CloudStackTypes.RebootCommand + " failed due to " + sysEx.Message;
- logger.Error(details, sysEx);
- }
-
- object ansContent = new
- {
- result = result,
- details = details,
- contextMap = contextMap
- };
-
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.RebootAnswer);
- }
- }
-
- // POST api/HypervResource/DestroyCommand
- [HttpPost]
- [ActionName(CloudStackTypes.DestroyCommand)]
- public JContainer DestroyCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.DestroyCommand + Utils.CleanString(cmd.ToString()));
-
- string details = null;
- bool result = false;
-
- try
- {
- // Assert
- String errMsg = "No 'volume' details in " + CloudStackTypes.DestroyCommand + " " + Utils.CleanString(cmd.ToString());
- if (cmd.volume == null)
- {
- logger.Error(errMsg);
- throw new ArgumentException(errMsg);
- }
-
- // Assert
- errMsg = "No valide path in DestroyCommand in " + CloudStackTypes.DestroyCommand + " " + (String)cmd.ToString();
- if (cmd.volume.path == null)
- {
- logger.Error(errMsg);
- throw new ArgumentException(errMsg);
- }
-
- String path = (string)cmd.volume.path;
- if (!File.Exists(path))
- {
- logger.Info(CloudStackTypes.DestroyCommand + ", but volume at pass already deleted " + path);
- }
-
- string vmName = (string)cmd.vmName;
- if (!string.IsNullOrEmpty(vmName) && File.Exists(path))
- {
- // Make sure that this resource is removed from the VM
- wmiCallsV2.DetachDisk(vmName, path);
- }
-
- File.Delete(path);
- result = true;
- }
- catch (Exception sysEx)
- {
- details = CloudStackTypes.DestroyCommand + " failed due to " + sysEx.Message;
- logger.Error(details, sysEx);
- }
-
- object ansContent = new
- {
- result = result,
- details = details,
- contextMap = contextMap
- };
-
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
- }
- }
-
- // POST api/HypervResource/DeleteCommand
- [HttpPost]
- [ActionName(CloudStackTypes.DeleteCommand)]
- public JContainer DeleteCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.DestroyCommand + Utils.CleanString(cmd.ToString()));
-
- string details = null;
- bool result = false;
-
- try
- {
- // Assert
- String errMsg = "No 'volume' details in " + CloudStackTypes.DestroyCommand + " " + Utils.CleanString(cmd.ToString());
- VolumeObjectTO destVolumeObjectTO = VolumeObjectTO.ParseJson(cmd.data);
-
- if (destVolumeObjectTO.name == null)
- {
- logger.Error(errMsg);
- throw new ArgumentException(errMsg);
- }
-
- String path = destVolumeObjectTO.FullFileName;
- if (!File.Exists(path))
- {
- logger.Info(CloudStackTypes.DestroyCommand + ", but volume at pass already deleted " + path);
- }
-
- string vmName = (string)cmd.vmName;
- if (!string.IsNullOrEmpty(vmName) && File.Exists(path))
- {
- // Make sure that this resource is removed from the VM
- wmiCallsV2.DetachDisk(vmName, path);
- }
-
- File.Delete(path);
- result = true;
- }
- catch (Exception sysEx)
- {
- details = CloudStackTypes.DestroyCommand + " failed due to " + sysEx.Message;
- logger.Error(details, sysEx);
- }
-
- object ansContent = new
- {
- result = result,
- details = details,
- contextMap = contextMap
- };
-
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
- }
- }
-
-
- private static JArray ReturnCloudStackTypedJArray(object ansContent, string ansType)
- {
- JObject ansObj = Utils.CreateCloudStackObject(ansType, ansContent);
- JArray answer = new JArray(ansObj);
- logger.Info(Utils.CleanString(ansObj.ToString()));
- return answer;
- }
-
- // POST api/HypervResource/CreateCommand
- [HttpPost]
- [ActionName(CloudStackTypes.CreateCommand)]
- public JContainer CreateCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.CreateCommand + Utils.CleanString(cmd.ToString()));
-
- string details = null;
- bool result = false;
- VolumeInfo volume = new VolumeInfo();
-
- try
- {
- string diskType = cmd.diskCharacteristics.type;
- ulong disksize = cmd.diskCharacteristics.size;
- string templateUri = cmd.templateUrl;
-
- // assert: valid storagepool?
- string poolTypeStr = cmd.pool.type;
- string poolLocalPath = cmd.pool.path;
- string poolUuid = cmd.pool.uuid;
- string newVolPath = null;
- long volId = cmd.volId;
- string newVolName = null;
-
- if (ValidStoragePool(poolTypeStr, poolLocalPath, poolUuid, ref details))
- {
- // No template URI? Its a blank disk.
- if (string.IsNullOrEmpty(templateUri))
- {
- // assert
- VolumeType volType;
- if (!Enum.TryParse<VolumeType>(diskType, out volType) && volType != VolumeType.DATADISK)
- {
- details = "Cannot create volumes of type " + (string.IsNullOrEmpty(diskType) ? "NULL" : diskType);
- }
- else
- {
- newVolName = cmd.diskCharacteristics.name;
- newVolPath = Path.Combine(poolLocalPath, newVolName, diskType.ToLower());
- // TODO: make volume format and block size configurable
- wmiCallsV2.CreateDynamicVirtualHardDisk(disksize, newVolPath);
- if (File.Exists(newVolPath))
- {
- result = true;
- }
- else
- {
- details = "Failed to create DATADISK with name " + newVolName;
- }
- }
- }
- else
- {
- // TODO: Does this always work, or do I need to download template at times?
- if (templateUri.Contains("/") || templateUri.Contains("\\"))
- {
- details = "Problem with templateURL " + templateUri +
- " the URL should be volume UUID in primary storage created by previous PrimaryStorageDownloadCommand";
- logger.Error(details);
- }
- else
- {
- logger.Debug("Template's name in primary store should be " + templateUri);
- // HypervPhysicalDisk BaseVol = primaryPool.getPhysicalDisk(tmplturl);
- FileInfo srcFileInfo = new FileInfo(templateUri);
- newVolName = Guid.NewGuid() + srcFileInfo.Extension;
- newVolPath = Path.Combine(poolLocalPath, newVolName);
- logger.Debug("New volume will be at " + newVolPath);
- string oldVolPath = Path.Combine(poolLocalPath, templateUri);
- File.Copy(oldVolPath, newVolPath);
- if (File.Exists(newVolPath))
- {
- result = true;
- }
- else
- {
- details = "Failed to create DATADISK with name " + newVolName;
- }
- }
- volume = new VolumeInfo(
- volId, diskType,
- poolTypeStr, poolUuid, newVolName,
- newVolPath, newVolPath, (long)disksize, null);
- }
- }
- }
- catch (Exception sysEx)
- {
- // TODO: consider this as model for error processing in all commands
- details = CloudStackTypes.CreateCommand + " failed due to " + sysEx.Message;
- logger.Error(details, sysEx);
- }
-
- object ansContent = new
- {
- result = result,
- details = details,
- volume = volume,
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CreateAnswer);
- }
- }
-
- // POST api/HypervResource/PrimaryStorageDownloadCommand
- [HttpPost]
- [ActionName(CloudStackTypes.PrimaryStorageDownloadCommand)]
- public JContainer PrimaryStorageDownloadCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.PrimaryStorageDownloadCommand + Utils.CleanString(cmd.ToString()));
- string details = null;
- bool result = false;
- long size = 0;
- string newCopyFileName = null;
-
- string poolLocalPath = cmd.localPath;
- string poolUuid = cmd.poolUuid;
- if (!Directory.Exists(poolLocalPath))
- {
- details = "None existent local path " + poolLocalPath;
- }
- else
- {
- // Compose name for downloaded file.
- string sourceUrl = cmd.url;
- if (sourceUrl.ToLower().EndsWith(".vhd"))
- {
- newCopyFileName = Guid.NewGuid() + ".vhd";
- }
- if (sourceUrl.ToLower().EndsWith(".vhdx"))
- {
- newCopyFileName = Guid.NewGuid() + ".vhdx";
- }
-
- // assert
- if (newCopyFileName == null)
- {
- details = CloudStackTypes.PrimaryStorageDownloadCommand + " Invalid file extension for hypervisor type in source URL " + sourceUrl;
- logger.Error(details);
- }
- else
- {
- try
- {
- FileInfo newFile;
- if (CopyURI(sourceUrl, newCopyFileName, poolLocalPath, out newFile, ref details))
- {
- size = newFile.Length;
- result = true;
- }
- }
- catch (System.Exception ex)
- {
- details = CloudStackTypes.PrimaryStorageDownloadCommand + " Cannot download source URL " + sourceUrl + " due to " + ex.Message;
- logger.Error(details, ex);
- }
- }
- }
-
- object ansContent = new
- {
- result = result,
- details = details,
- templateSize = size,
- installPath = newCopyFileName,
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.PrimaryStorageDownloadAnswer);
- }
- }
-
- private static bool ValidStoragePool(string poolTypeStr, string poolLocalPath, string poolUuid, ref string details)
- {
- StoragePoolType poolType;
- if (!Enum.TryParse<StoragePoolType>(poolTypeStr, out poolType) || poolType != StoragePoolType.Filesystem)
- {
- details = "Primary storage pool " + poolUuid + " type " + poolType + " local path " + poolLocalPath + " has invalid StoragePoolType";
- logger.Error(details);
- return false;
- }
- else if (!Directory.Exists(poolLocalPath))
- {
- details = "Primary storage pool " + poolUuid + " type " + poolType + " local path " + poolLocalPath + " has invalid local path";
- logger.Error(details);
- return false;
- }
- return true;
- }
-
- /// <summary>
- /// Exceptions to watch out for:
- /// Exceptions related to URI creation
- /// System.SystemException
- /// +-System.ArgumentNullException
- /// +-System.FormatException
- /// +-System.UriFormatException
- ///
- /// Exceptions related to NFS URIs
- /// System.SystemException
- /// +-System.NotSupportedException
- /// +-System.ArgumentException
- /// +-System.ArgumentNullException
- /// +-System.Security.SecurityException;
- /// +-System.UnauthorizedAccessException
- /// +-System.IO.IOException
- /// +-System.IO.PathTooLongException
- ///
- /// Exceptions related to HTTP URIs
- /// System.SystemException
- /// +-System.InvalidOperationException
- /// +-System.Net.WebException
- /// +-System.NotSupportedException
- /// +-System.ArgumentNullException
- /// </summary>
- /// <param name="sourceUri"></param>
- /// <param name="newCopyFileName"></param>
- /// <param name="poolLocalPath"></param>
- /// <returns></returns>
- private bool CopyURI(string sourceUri, string newCopyFileName, string poolLocalPath, out FileInfo newFile, ref string details)
- {
- Uri source = new Uri(sourceUri);
- String destFilePath = Path.Combine(poolLocalPath, newCopyFileName);
- string[] pathSegments = source.Segments;
- String templateUUIDandExtension = pathSegments[pathSegments.Length - 1];
- newFile = new FileInfo(destFilePath);
-
- // NFS URI assumed to already be mounted locally. Mount location given by settings.
- if (source.Scheme.ToLower().Equals("nfs"))
- {
- String srcDiskPath = Path.Combine(HypervResourceController.config.LocalSecondaryStoragePath, templateUUIDandExtension);
- String taskMsg = "Copy NFS url in " + sourceUri + " at " + srcDiskPath + " to pool " + poolLocalPath;
- logger.Debug(taskMsg);
- File.Copy(srcDiskPath, destFilePath);
- }
- else if (source.Scheme.ToLower().Equals("http") || source.Scheme.ToLower().Equals("https"))
- {
- System.Net.WebClient webclient = new WebClient();
- webclient.DownloadFile(source, destFilePath);
- }
- else
- {
- details = "Unsupported URI scheme " + source.Scheme.ToLower() + " in source URI " + sourceUri;
- logger.Error(details);
- return false;
- }
-
- if (!File.Exists(destFilePath))
- {
- details = "Filed to copy " + sourceUri + " to primary pool destination " + destFilePath;
- logger.Error(details);
- return false;
- }
- return true;
- }
-
- // POST api/HypervResource/CheckHealthCommand
- [HttpPost]
- [ActionName(CloudStackTypes.CheckHealthCommand)]
- public JContainer CheckHealthCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.CheckHealthCommand + Utils.CleanString(cmd.ToString()));
- object ansContent = new
- {
- result = true,
- details = "resource is alive",
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckHealthAnswer);
- }
- }
-
- // POST api/HypervResource/CheckOnHostCommand
- [HttpPost]
- [ActionName(CloudStackTypes.CheckOnHostCommand)]
- public JContainer CheckOnHostCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.CheckOnHostCommand + Utils.CleanString(cmd.ToString()));
- string details = "host is not alive";
- bool result = true;
- try
- {
- foreach (string poolPath in config.getAllPrimaryStorages())
- {
- if (IsHostAlive(poolPath, (string)cmd.host.privateNetwork.ip))
- {
- result = false;
- details = "host is alive";
- break;
- }
- }
- }
- catch (Exception e)
- {
- logger.Error("Error Occurred in " + CloudStackTypes.CheckOnHostCommand + " : " + e.Message);
- }
-
- object ansContent = new
- {
- result = result,
- details = details,
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckOnHostAnswer);
- }
- }
-
- private bool IsHostAlive(string poolPath, string privateIp)
- {
- bool hostAlive = false;
- try
- {
- string hbFile = Path.Combine(poolPath, "hb-" + privateIp);
- FileInfo file = new FileInfo(hbFile);
- using (StreamReader sr = file.OpenText())
- {
- string epoch = sr.ReadLine();
- string[] dateTime = epoch.Split('@');
- string[] date = dateTime[0].Split('-');
- string[] time = dateTime[1].Split(':');
- DateTime epochTime = new DateTime(Convert.ToInt32(date[0]), Convert.ToInt32(date[1]), Convert.ToInt32(date[2]), Convert.ToInt32(time[0]),
- Convert.ToInt32(time[1]), Convert.ToInt32(time[2]), DateTimeKind.Utc);
- DateTime currentTime = DateTime.UtcNow;
- DateTime ThreeMinuteLaterEpoch = epochTime.AddMinutes(3);
- if (currentTime.CompareTo(ThreeMinuteLaterEpoch) < 0)
- {
- hostAlive = true;
- }
- sr.Close();
- }
- }
- catch (Exception e)
- {
- logger.Info("Exception occurred in verifying host " + e.Message);
- }
-
- return hostAlive;
- }
-
- // POST api/HypervResource/CheckSshCommand
- // TODO: create test
- [HttpPost]
- [ActionName(CloudStackTypes.CheckSshCommand)]
- public JContainer CheckSshCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.CheckSshCommand + Utils.CleanString(cmd.ToString()));
- object ansContent = new
- {
- result = true,
- details = "NOP, TODO: implement properly",
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckSshAnswer);
- }
- }
-
- // POST api/HypervResource/CheckVirtualMachineCommand
- [HttpPost]
- [ActionName(CloudStackTypes.CheckVirtualMachineCommand)]
- public JContainer CheckVirtualMachineCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.CheckVirtualMachineCommand + Utils.CleanString(cmd.ToString()));
- string details = null;
- bool result = false;
- string vmName = cmd.vmName;
- string state = null;
-
- // TODO: Look up the VM, convert Hyper-V state to CloudStack version.
- var sys = wmiCallsV2.GetComputerSystem(vmName);
- if (sys == null)
- {
- details = CloudStackTypes.CheckVirtualMachineCommand + " requested unknown VM " + vmName;
- logger.Error(details);
- }
- else
- {
- state = EnabledState.ToCloudStackState(sys.EnabledState); // TODO: V2 changes?
- result = true;
- }
-
- object ansContent = new
- {
- result = result,
- details = details,
- state = state,
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckVirtualMachineAnswer);
- }
- }
-
- // POST api/HypervResource/DeleteStoragePoolCommand
- [HttpPost]
- [ActionName(CloudStackTypes.DeleteStoragePoolCommand)]
- public JContainer DeleteStoragePoolCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.DeleteStoragePoolCommand + Utils.CleanString(cmd.ToString()));
- object ansContent = new
- {
- result = true,
- details = "Current implementation does not delete local path corresponding to storage pool!",
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
- }
- }
-
- /// <summary>
- /// NOP - legacy command -
- /// POST api/HypervResource/CreateStoragePoolCommand
- /// </summary>
- /// <param name="cmd"></param>
- /// <returns></returns>
- [HttpPost]
- [ActionName(CloudStackTypes.CreateStoragePoolCommand)]
- public JContainer CreateStoragePoolCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.CreateStoragePoolCommand + Utils.CleanString(cmd.ToString()));
- object ansContent = new
- {
- result = true,
- details = "success - NOP",
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
- }
- }
-
- // POST api/HypervResource/ModifyStoragePoolCommand
- [HttpPost]
- [ActionName(CloudStackTypes.ModifyStoragePoolCommand)]
- public JContainer ModifyStoragePoolCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.ModifyStoragePoolCommand + Utils.CleanString(cmd.ToString()));
- string details = null;
- string localPath;
- StoragePoolType poolType;
- object ansContent;
-
- bool result = ValidateStoragePoolCommand(cmd, out localPath, out poolType, ref details);
- if (!result)
- {
- ansContent = new
- {
- result = result,
- details = details,
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
- }
-
- var tInfo = new Dictionary<string, string>();
- long capacityBytes = 0;
- long availableBytes = 0;
- string hostPath = null;
- if (poolType == StoragePoolType.Filesystem)
- {
- GetCapacityForLocalPath(localPath, out capacityBytes, out availableBytes);
- hostPath = localPath;
- }
- else if (poolType == StoragePoolType.NetworkFilesystem ||
- poolType == StoragePoolType.SMB)
- {
- NFSTO share = new NFSTO();
- String uriStr = "cifs://" + (string)cmd.pool.host + (string)cmd.pool.path;
- share.uri = new Uri(uriStr);
- hostPath = Utils.NormalizePath(share.UncPath);
-
- // Check access to share.
- Utils.GetShareDetails(share.UncPath, out capacityBytes, out availableBytes);
- config.setPrimaryStorage((string)cmd.pool.uuid, hostPath);
- }
- else
- {
- result = false;
- }
-
- String uuid = null;
- var poolInfo = new
- {
- uuid = uuid,
- host = cmd.pool.host,
- hostPath = cmd.pool.path,
- localPath = hostPath,
- poolType = cmd.pool.type,
- capacityBytes = capacityBytes,
- availableBytes = availableBytes
- };
-
- ansContent = new
- {
- result = result,
- details = details,
- localPath = hostPath,
- templateInfo = tInfo,
- poolInfo = poolInfo,
- contextMap = contextMap
- };
-
- if (result)
- {
- try
- {
- if ((bool)cmd.add)
- {
- logger.Info("Adding HeartBeat Task to task scheduler for pool " + (string)cmd.pool.uuid);
- Utils.AddHeartBeatTask((string)cmd.pool.uuid, hostPath, config.PrivateIpAddress);
- }
- else
- {
- logger.Info("Deleting HeartBeat Task from task scheduler for pool " + (string)cmd.pool.uuid);
- Utils.RemoveHeartBeatTask(cmd.pool.uuid);
- }
- }
- catch (Exception e)
- {
- logger.Error("Error occurred in adding/delete HeartBeat Task to/from Task Scheduler : " + e.Message);
- }
- }
-
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.ModifyStoragePoolAnswer);
- }
- }
-
- private bool ValidateStoragePoolCommand(dynamic cmd, out string localPath, out StoragePoolType poolType, ref string details)
- {
- dynamic pool = cmd.pool;
- string poolTypeStr = pool.type;
- localPath = cmd.localPath;
- if (!Enum.TryParse<StoragePoolType>(poolTypeStr, out poolType))
- {
- details = "Request to create / modify unsupported pool type: " + (poolTypeStr == null ? "NULL" : poolTypeStr) + "in cmd " + JsonConvert.SerializeObject(cmd);
- logger.Error(details);
- return false;
- }
-
- if (poolType != StoragePoolType.Filesystem &&
- poolType != StoragePoolType.NetworkFilesystem &&
- poolType != StoragePoolType.SMB)
- {
- details = "Request to create / modify unsupported pool type: " + (poolTypeStr == null ? "NULL" : poolTypeStr) + "in cmd " + JsonConvert.SerializeObject(cmd);
- logger.Error(details);
- return false;
- }
-
- return true;
- }
-
- // POST api/HypervResource/PlugNicCommand
- [HttpPost]
- [ActionName(CloudStackTypes.PlugNicCommand)]
- public JContainer PlugNicCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.PlugNicCommand + Utils.CleanString(cmd.ToString()));
- object ansContent = new
- {
- result = true,
- details = "Hot Nic plug not supported, change any empty virtual network adapter network settings",
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.PlugNicAnswer);
- }
- }
-
-
- // POST api/HypervResource/CleanupNetworkRulesCmd
- [HttpPost]
- [ActionName(CloudStackTypes.CleanupNetworkRulesCmd)]
- public JContainer CleanupNetworkRulesCmd([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.CleanupNetworkRulesCmd + Utils.CleanString(cmd.ToString()));
- object ansContent = new
- {
- result = false,
- details = "nothing to cleanup in our current implementation",
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
- }
- }
-
- // POST api/HypervResource/CheckNetworkCommand
- [HttpPost]
- [ActionName(CloudStackTypes.CheckNetworkCommand)]
- public JContainer CheckNetworkCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.CheckNetworkCommand + Utils.CleanString(cmd.ToString()));
- object ansContent = new
- {
- result = true,
- details = (string)null,
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckNetworkAnswer);
- }
- }
-
- // POST api/HypervResource/ReadyCommand
- [HttpPost]
- [ActionName(CloudStackTypes.ReadyCommand)]
- public JContainer ReadyCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.ReadyCommand + Utils.CleanString(cmd.ToString()));
- object ansContent = new
- {
- result = true,
- details = (string)null,
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.ReadyAnswer);
- }
-
- }
-
- // POST api/HypervResource/StartCommand
- [HttpPost]
- [ActionName(CloudStackTypes.StartCommand)]
- public JContainer StartCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.StartCommand + Utils.CleanString(cmd.ToString()));
- string details = null;
- bool result = false;
-
- try
- {
- string systemVmIsoPath = systemVmIso;
- lock (systemVmIso)
- {
- systemVmIsoPath = systemVmIso;
- String uriStr = (String)cmd.secondaryStorage;
- if (!String.IsNullOrEmpty(uriStr))
- {
- if (String.IsNullOrEmpty(systemVmIsoPath) || !File.Exists(systemVmIsoPath))
- {
- NFSTO share = new NFSTO();
- share.uri = new Uri(uriStr);
- string defaultDataPath = wmiCallsV2.GetDefaultDataRoot();
-
- string secondaryPath = Utils.NormalizePath(Path.Combine(share.UncPath, "systemvm"));
- string[] choices = Directory.GetFiles(secondaryPath, "systemvm*.iso");
- if (choices.Length != 1)
- {
- String errMsg = "Couldn't locate the systemvm iso on " + secondaryPath;
- logger.Debug(errMsg);
- }
- else
- {
- systemVmIsoPath = Utils.NormalizePath(Path.Combine(defaultDataPath, Path.GetFileName(choices[0])));
- if (!File.Exists(systemVmIsoPath))
- {
- Utils.DownloadCifsFileToLocalFile(choices[0], share, systemVmIsoPath);
- }
- systemVmIso = systemVmIsoPath;
- }
- }
- }
- }
-
- wmiCallsV2.DeployVirtualMachine(cmd, systemVmIsoPath);
- result = true;
- }
- catch (Exception wmiEx)
- {
- details = CloudStackTypes.StartCommand + " fail on exception" + wmiEx.Message;
- logger.Error(details, wmiEx);
- }
-
- object ansContent = new
- {
- result = result,
- details = details,
- vm = cmd.vm,
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.StartAnswer);
- }
- }
-
- // POST api/HypervResource/StopCommand
- [HttpPost]
- [ActionName(CloudStackTypes.StopCommand)]
- public JContainer StopCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.StopCommand + Utils.CleanString(cmd.ToString()));
- string details = null;
- bool result = false;
- bool checkBeforeCleanup = cmd.checkBeforeCleanup;
- String vmName = cmd.vmName;
-
- if (checkBeforeCleanup == true)
- {
- ComputerSystem vm = wmiCallsV2.GetComputerSystem(vmName);
- if (vm == null || vm.EnabledState == 2)
- {
- // VM is not available or vm in running state
- return ReturnCloudStackTypedJArray(new { result = false, details = "VM is running on host, bailing out", vm = vmName, contextMap = contextMap }, CloudStackTypes.StopAnswer);
- }
- }
- try
- {
- wmiCallsV2.DestroyVm(cmd);
- result = true;
- }
- catch (Exception wmiEx)
- {
- details = CloudStackTypes.StopCommand + " fail on exception" + wmiEx.Message;
- logger.Error(details, wmiEx);
- }
-
- object ansContent = new
- {
- result = result,
- details = details,
- vm = cmd.vm,
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.StopAnswer);
- }
- }
-
- // POST api/HypervResource/CreateObjectCommand
- [HttpPost]
- [ActionName(CloudStackTypes.CreateObjectCommand)]
- public JContainer CreateObjectCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.CreateObjectCommand + Utils.CleanString(cmd.ToString()));
-
- bool result = false;
- string details = null;
- object newData = null;
- try
- {
- VolumeObjectTO volume = VolumeObjectTO.ParseJson(cmd.data);
- PrimaryDataStoreTO primary = volume.primaryDataStore;
- ulong volumeSize = volume.size;
- string volumeName = volume.uuid + ".vhdx";
- string volumePath = null;
-
- if (primary.isLocal)
- {
- volumePath = Path.Combine(primary.Path, volumeName);
- }
- else
- {
- volumePath = @"\\" + primary.uri.Host + primary.uri.LocalPath + @"\" + volumeName;
- volumePath = Utils.NormalizePath(volumePath);
- }
- volume.path = volume.uuid;
- wmiCallsV2.CreateDynamicVirtualHardDisk(volumeSize, volumePath);
- if (File.Exists(volumePath))
- {
- result = true;
- JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, volume);
- newData = ansObj;
- }
- else
- {
- details = "Failed to create disk with name " + volumePath;
- }
- }
- catch (Exception ex)
- {
- // Test by providing wrong key
- details = CloudStackTypes.CreateObjectCommand + " failed on exception, " + ex.Message;
- logger.Error(details, ex);
- }
-
- object ansContent = new
- {
- result = result,
- details = details,
- data = newData,
- contextMap = contextMap
- };
-
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CreateObjectAnswer);
- }
- }
-
- // POST api/HypervResource/MaintainCommand
- // TODO: should this be a NOP?
- [HttpPost]
- [ActionName(CloudStackTypes.MaintainCommand)]
- public JContainer MaintainCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.MaintainCommand + Utils.CleanString(cmd.ToString()));
-
- object ansContent = new
- {
- result = true,
- willMigrate = true,
- details = "success - NOP for MaintainCommand",
- _reconnect = false,
- contextMap = contextMap
- };
-
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.MaintainAnswer);
- }
- }
-
- // POST api/HypervResource/PingRoutingCommand
- // TODO: should this be a NOP?
- [HttpPost]
- [ActionName(CloudStackTypes.PingRoutingCommand)]
- public JContainer PingRoutingCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.PingRoutingCommand + Utils.CleanString(cmd.ToString()));
-
- object ansContent = new
- {
- result = true,
- details = "success - NOP for PingRoutingCommand",
- _reconnect = false,
- contextMap = contextMap
- };
-
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
- }
- }
-
- // POST api/HypervResource/PingCommand
- // TODO: should this be a NOP?
- [HttpPost]
- [ActionName(CloudStackTypes.PingCommand)]
- public JContainer PingCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.PingCommand + Utils.CleanString(cmd.ToString()));
-
- object ansContent = new
- {
- result = true,
- details = "success - NOP for PingCommand",
- _reconnect = false,
- contextMap = contextMap
- };
-
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
- }
- }
-
- // POST api/HypervResource/ModifyVmVnicVlanCommand
- [HttpPost]
- [ActionName(CloudStackTypes.ModifyVmNicConfigCommand)]
- public JContainer ModifyVmNicConfigCommand([FromBody]dynamic cmd)
- {
-
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.ModifyVmNicConfigCommand + Utils.CleanString(cmd.ToString()));
- bool result = false;
- String vmName = cmd.vmName;
- String vlan = cmd.vlan;
- string macAddress = cmd.macAddress;
- uint pos = cmd.index;
- bool enable = cmd.enable;
- string switchLableName = cmd.switchLableName;
- if (macAddress != null)
- {
- wmiCallsV2.ModifyVmVLan(vmName, vlan, macAddress);
- result = true;
- }
- else if (pos >= 1)
- {
- wmiCallsV2.ModifyVmVLan(vmName, vlan, pos, enable, switchLableName);
- result = true;
- }
-
- object ansContent = new
- {
- vmName = vmName,
- result = result,
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.ModifyVmNicConfigAnswer);
- }
-
- }
-
- // POST api/HypervResource/GetVmConfigCommand
- [HttpPost]
- [ActionName(CloudStackTypes.GetVmConfigCommand)]
- public JContainer GetVmConfigCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.GetVmConfigCommand + Utils.CleanString(cmd.ToString()));
- bool result = false;
- String vmName = cmd.vmName;
- ComputerSystem vm = wmiCallsV2.GetComputerSystem(vmName);
- List<NicDetails> nicDetails = new List<NicDetails>();
- var nicSettingsViaVm = wmiCallsV2.GetEthernetPortSettings(vm);
- NicDetails nic = null;
- int index = 0;
- int[] nicStates = new int[8];
- int[] nicVlan = new int[8];
- int vlanid = 1;
-
- var ethernetConnections = wmiCallsV2.GetEthernetConnections(vm);
- foreach (EthernetPortAllocationSettingData item in ethernetConnections)
- {
- EthernetSwitchPortVlanSettingData vlanSettings = wmiCallsV2.GetVlanSettings(item);
- if (vlanSettings == null)
- {
- vlanid = -1;
- }
- else
- {
- vlanid = vlanSettings.AccessVlanId;
- }
- nicStates[index] = (Int32)(item.EnabledState);
- nicVlan[index] = vlanid;
- index++;
- }
-
- index = 0;
- foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm)
- {
- nic = new NicDetails(item.Address, nicVlan[index], nicStates[index]);
- index++;
- nicDetails.Add(nic);
- }
-
-
- result = true;
-
- object ansContent = new
- {
- vmName = vmName,
- nics = nicDetails,
- result = result,
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVmConfigAnswer);
- }
- }
-
-
-
- // POST api/HypervResource/GetVmStatsCommand
- [HttpPost]
- [ActionName(CloudStackTypes.GetVmStatsCommand)]
- public JContainer GetVmStatsCommand([FromBody]dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- logger.Info(CloudStackTypes.GetVmStatsCommand + Utils.CleanString(cmd.ToString()));
- bool result = false;
- JArray vmNamesJson = cmd.vmNames;
- string[] vmNames = vmNamesJson.ToObject<string[]>();
- Dictionary<string, VmStatsEntry> vmProcessorInfo = new Dictionary<string, VmStatsEntry>(vmNames.Length);
-
- var vmsToInspect = new List<System.Management.ManagementPath>();
- foreach (var vmName in vmNames)
- {
- var sys = wmiCallsV2.GetComputerSystem(vmName);
- if (sys == null)
- {
- logger.InfoFormat("GetVmStatsCommand requested unknown VM {0}", vmNames);
- continue;
- }
- var sysInfo = wmiCallsV2.GetVmSettings(sys);
- vmsToInspect.Add(sysInfo.Path);
- }
-
- wmiCallsV2.GetSummaryInfo(vmProcessorInfo, vmsToInspect);
-
- // TODO: Network usage comes from Performance Counter API; however it is only available in kb/s, and not in total terms.
- // Curious about these? Use perfmon to inspect them, e.g. http://msdn.microsoft.com/en-us/library/xhcx5a20%28v=vs.100%29.aspx
- // Recent post on these counter at http://blogs.technet.com/b/cedward/archive/2011/07/19/hyper-v-networking-optimizations-part-6-of-6-monitoring-hyper-v-network-consumption.aspx
- result = true;
-
- object ansContent = new
- {
- vmStatsMap = vmProcessorInfo,
- result = result,
- contextMap = contextMap
- };
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVmStatsAnswer);
- }
- }
-
- // POST api/HypervResource/CopyCommand
- [HttpPost]
- [ActionName(CloudStackTypes.CopyCommand)]
- public JContainer CopyCommand(dynamic cmd)
- {
- using (log4net.NDC.Push(Guid.NewGuid().ToString()))
- {
- // Log command *after* we've removed security details from the command.
- logger.Info(CloudStackTypes.CopyCommand + Utils.CleanString(cmd.ToString()));
-
- bool result = false;
- string details = null;
- object newData = null;
- TemplateObjectTO destTemplateObjectTO = null;
- VolumeObjectTO destVolumeObjectTO = null;
- VolumeObjectTO srcVolumeObjectTO = null;
- TemplateObjectTO srcTemplateObjectTO = null;
-
- try
- {
- dynamic timeout = cmd.wait; // TODO: Useful?
-
- srcTemplateObjectTO = TemplateObjectTO.ParseJson(cmd.srcTO);
- destTemplateObjectTO = TemplateObjectTO.ParseJson(cmd.destTO);
- srcVolumeObjectTO = VolumeObjectTO.ParseJson(cmd.srcTO);
- destVolumeObjectTO = VolumeObjectTO.ParseJson(cmd.destTO);
-
- string destFile = null;
- if (destTemplateObjectTO != null)
- {
- if (destTemplateObjectTO.primaryDataStore != null)
- {
- destFile = destTemplateObjectTO.FullFileName;
- }
- else if (destTemplateObjectTO.nfsDataStoreTO != null)
- {
- destFile = destTemplateObjectTO.FullFileName;
- }
- }
-
- // Template already downloaded?
- if (destFile != null && File.Exists(destFile) &&
- !String.IsNullOrEmpty(destTemplateObjectTO.checksum))
+ string details = null;
+ bool result = false;
+
+ try
+ {
+ string vmName = (string)cmd.vmName;
+ var sys = wmiCallsV2.GetComputerSystem(vmName);
+ if (sys == null)
{
- // TODO: checksum fails us, because it is of the compressed image.
- // ASK: should we store the compressed or uncompressed version or is the checksum not calculated correctly?
- logger.Debug(CloudStackTypes.CopyCommand + " calling VerifyChecksum to see if we already have the file at " + destFile);
- result = VerifyChecksum(destFile, destTemplateObjectTO.checksum);
- if (!result)
- {
- result = true;
- logger.Debug(CloudStackTypes.CopyCommand + " existing file has different checksum " + destFile);
- }
+ details = CloudStackTypes.RebootCommand + " requested unknown VM " + vmName;
+ logger.Error(details);
}
-
- // Do we have to create a new one?
- if (!result)
+ else
{
- // Create local copy of a template?
- if (srcTemplateObjectTO != null && destTemplateObjectTO != null)
- {
- // S3 download to primary storage?
- // NFS provider download to primary storage?
- if ((srcTemplateObjectTO.s3DataStoreTO != null || srcTemplateObjectTO.nfsDataStoreTO != null) && destTemplateObjectTO.primaryDataStore != null)
- {
- if (File.Exists(destFile))
- {
- logger.Info("Deleting existing file " + destFile);
- File.Delete(destFile);
- }
-
- if (srcTemplateObjectTO.s3DataStoreTO != null)
- {
- // Download from S3 to destination data storage
- DownloadS3ObjectToFile(srcTemplateObjectTO.path, srcTemplateObjectTO.s3DataStoreTO, destFile);
- }
- else if (srcTemplateObjectTO.nfsDataStoreTO != null)
- {
- // Download from S3 to destination data storage
- Utils.DownloadCifsFileToLocalFile(srcTemplateObjectTO.path, srcTemplateObjectTO.nfsDataStoreTO, destFile);
- }
-
- // Uncompress, as required
- if (srcTemplateObjectTO.path.EndsWith(".bz2"))
- {
- String uncompressedFile = destFile + ".tmp";
- String compressedFile = destFile;
- using (var uncompressedOutStrm = new FileStream(uncompressedFile, FileMode.CreateNew, FileAccess.Write))
- {
- using (var compressedInStrm = new FileStream(destFile, FileMode.Open, FileAccess.Read))
- {
- using (var bz2UncompressorStrm = new Ionic.BZip2.BZip2InputStream(compressedInStrm, true) /* outer 'using' statement will close FileStream*/ )
- {
- int count = 0;
- int bufsize = 1024 * 1024;
- byte[] buf = new byte[bufsize];
-
- // EOF returns -1, see http://dotnetzip.codeplex.com/workitem/16069
- while (0 < (count = bz2UncompressorStrm.Read(buf, 0, bufsize)))
- {
- uncompressedOutStrm.Write(buf, 0, count);
- }
- }
- }
- }
- File.Delete(compressedFile);
- File.Move(uncompressedFile, compressedFile);
- if (File.Exists(uncompressedFile))
- {
- String errMsg = "Extra file left around called " + uncompressedFile + " when creating " + destFile;
- logger.Error(errMsg);
- throw new IOException(errMsg);
- }
- }
-
- // assert
- if (!File.Exists(destFile))
- {
- String errMsg = "Failed to create " + destFile + " , because the file is missing";
- logger.Error(errMsg);
- throw new IOException(errMsg);
- }
-
- newData = cmd.destTO;
- result = true;
- }
- else
- {
- details = "Data store combination not supported";
- }
- }
- // Create volume from a template?
- else if (srcTemplateObjectTO != null && destVolumeObjectTO != null)
- {
- // VolumeObjectTO guesses file extension based on existing files
- // this can be wrong if the previous file had a different file type
- var guessedDestFile = destVolumeObjectTO.FullFileName;
- if (File.Exists(guessedDestFile))
- {
- logger.Info("Deleting existing file " + guessedDestFile);
- File.Delete(guessedDestFile);
- }
-
- destVolumeObjectTO.format = srcTemplateObjectTO.format;
- destFile = destVolumeObjectTO.FullFileName;
- if (File.Exists(destFile))
- {
- logger.Info("Deleting existing file " + destFile);
- File.Delete(destFile);
- }
-
- string srcFile = srcTemplateObjectTO.FullFileName;
- if (!File.Exists(srcFile))
- {
- details = "Local template file missing from " + srcFile;
- }
- else
- {
- // TODO: thin provision instead of copying the full file.
- File.Copy(srcFile, destFile);
- destVolumeObjectTO.path = destVolumeObjectTO.uuid;
- JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, destVolumeObjectTO);
- newData = ansObj;
- result = true;
- }
- }
- else if (srcVolumeObjectTO != null && destVolumeObjectTO != null)
- {
- var guessedDestFile = destVolumeObjectTO.FullFileName;
- if (File.Exists(guessedDestFile))
- {
- logger.Info("Deleting existing file " + guessedDestFile);
- File.Delete(guessedDestFile);
- }
-
- destVolumeObjectTO.format = srcVolumeObjectTO.format;
- destFile = destVolumeObjectTO.FullFileName;
- if (File.Exists(destFile))
- {
- logger.Info("Deleting existing file " + destFile);
- File.Delete(destFile);
- }
-
- string srcFile = srcVolumeObjectTO.FullFileName;
- if (!File.Exists(srcFile))
- {
- details = "Local template file missing from " + srcFile;
- }
- else
- {
- // Create the directory before copying the files. CreateDirectory
- // doesn't do anything if the directory is already present.
- Directory.CreateDirectory(Path.GetDirectoryName(destFile));
- File.Copy(srcFile, destFile);
-
- if (srcVolumeObjectTO.nfsDataStore != null && srcVolumeObjectTO.primaryDataStore == null)
- {
- logger.Info("Copied volume from secondary data store to primary. Path: " + destVolumeObjectTO.path);
- }
- else if (srcVolumeObjectTO.primaryDataStore != null && srcVolumeObjectTO.nfsDataStore == null)
- {
- destVolumeObjectTO.path = destVolumeObjectTO.path + "/" + destVolumeObjectTO.uuid;
- if (destVolumeObjectTO.format != null)
- {
- destVolumeObjectTO.path += "." + destVolumeObjectTO.format.ToLower();
- }
- }
- else
- {
- logger.Error("Destination volume path wasn't set. Unsupported source volume data store.");
- }
-
- // Create volumeto object deserialize and send it
- JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, destVolumeObjectTO);
- newData = ansObj;
- result = true;
- }
- }
- else if (srcVolumeObjectTO != null && destTemplateObjectTO != null)
- {
- var guessedDestFile = destTemplateObjectTO.FullFileName;
- if (File.Exists(guessedDestFile))
- {
- logger.Info("Deleting existing file " + guessedDestFile);
- File.Delete(guessedDestFile);
- }
-
- destTemplateObjectTO.format = srcVolumeObjectTO.format;
- destFile = destTemplateObjectTO.FullFileName;
- if (File.Exists(destFile))
- {
- logger.Info("Deleting existing file " + destFile);
- File.Delete(destFile);
- }
-
- string srcFile = srcVolumeObjectTO.FullFileName;
- if (!File.Exists(srcFile))
- {
- details = "Local template file missing from " + srcFile;
- }
- else
- {
- // Create the directory before copying the files. CreateDirectory
- // doesn't do anything if the directory is already present.
- Directory.CreateDirectory(Path.GetDirectoryName(destFile));
- File.Copy(srcFile, destFile);
-
- FileInfo destFileInfo = new FileInfo(destFile);
- // Write the template.properties file
- PostCreateTemplate(Path.GetDirectoryName(destFile), destTemplateObjectTO.id, destTemplateObjectTO.name,
- destFileInfo.Length.ToString(), srcVolumeObjectTO.size.ToString(), destTemplateObjectTO.format);
-
- TemplateObjectTO destTemplateObject = new TemplateObjectTO();
- destTemplateObject.size = srcVolumeObjectTO.size.ToString();
- destTemplateObject.format = srcVolumeObjectTO.format;
- destTemplateObject.path = destTemplateObjectTO.path + "/" + destTemplateObjectTO.uuid;
- if (destTemplateObject.format != null)
- {
- destTemplateObject.path += "." + destTemplateObject.format.ToLower();
- }
- destTemplateObject.nfsDataStoreTO = destTemplateObjectTO.nfsDataStoreTO;
- destTemplateObject.checksum = destTemplateObjectTO.checksum;
- newData = destTemplateObject;
- JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.TemplateObjectTO, destTemplateObject);
- newData = ansObj;
- result = true;
- }
- }
- else
- {
- details = "Data store combination not supported";
- }
+ wmiCallsV2.SetState(sys, RequiredState.Reset);
+ result = true;
}
}
- catch (Exception ex)
+ catch (Exception sysEx)
{
- // Test by providing wrong key
- details = CloudStackTypes.CopyCommand + " failed on exception, " + ex.Message;
- logger.Error(details, ex);
+ details = CloudStackTypes.RebootCommand + " failed due to " + sysEx.Message;
+ logger.Error(details, sysEx);
}
object ansContent = new
{
result = result,
details = details,
- newData = newData,
contextMap = contextMap
};
- return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CopyCmdAnswer);
- }
- }
-
- private static void PostCreateTemplate(string path, string templateId, string templateUuid, string physicalSize, string virtualSize, string format)
- {
- string templatePropFile = Path.Combine(path, "template.properties");
- using (StreamWriter sw = new StreamWriter(File.Open(templatePropFile, FileMode.Create), Encoding.GetEncoding("iso-8859-1")))
- {
- if (format != null)
- {
- format = format.ToLower();
- }
-
- sw.NewLine = "\n";
- sw.WriteLine("id=" + templateId);
- sw.WriteLine("filename=" + templateUuid + "." + format);
- sw.WriteLine(format + ".filename=" + templateUuid + "." + format);
- sw.WriteLine("uniquename=" + templateUuid);
- sw.WriteLine(format + "=true");
- sw.WriteLine("virtualsize=" + virtualSize);
- sw.WriteLine(format + ".virtualsize=" + virtualSize);
- sw.WriteLine("size=" + physicalSize);
- sw.WriteLine(format + ".size=" + physicalSize);
- sw.WriteLine("public=false");
- }
- }
-
- private static bool VerifyChecksum(string destFile, string checksum)
- {
- string localChecksum = BitConverter.ToString(CalcFileChecksum(destFile)).Replace("-", "").ToLower();
- logger.Debug("Checksum of " + destFile + " is " + checksum);
- if (checksum.Equals(localChecksum))
- {
- return true;
- }
- return false;
- }
-
- /// <summary>
- /// Match implmentation of DownloadManagerImpl.computeCheckSum
- /// </summary>
- /// <param name="destFile"></param>
- /// <returns></returns>
- private static byte[] CalcFileChecksum(string destFile)
- {
- // TODO: Add unit test to verify that checksum algorithm has not changed.
- using (MD5 md5 = MD5.Create())
- {
- using (FileStream stream = File.OpenRead(destFile))
- {
- return md5.ComputeHash(stream);
- }
- }
- }
-
- private static void DownloadS3ObjectToFile(string srcObjectKey, S3TO srcS3TO, string destFile)
- {
- AmazonS3Config S3Config = new AmazonS3Config
- {
- ServiceURL = srcS3TO.endpoint,
- CommunicationProtocol = Amazon.S3.Model.Protocol.HTTP
- };
-
- if (srcS3TO.httpsFlag)
- {
- S3Config.CommunicationProtocol = Protocol.HTTPS;
- }
-
- try
- {
- using (AmazonS3 client = Amazon.AWSClientFactory.CreateAmazonS3Client(srcS3TO.accessKey, srcS3TO.secretKey, S3Config))
- {
- GetObjectRequest getObjectRequest = new GetObjectRequest().WithBucketName(srcS3TO.bucketName).WithKey(srcObjectKey);
- using (S3Response getObjectResponse = client.GetObject(getObjectRequest))
- {
- using (Stream s = getObjectResponse.ResponseStream)
- {
- using (FileStream fs = new FileStream(destFile, FileMode.Create, FileAccess.Write))
- {
- byte[] data = new byte[524288];
- int bytesRead = 0;
- do
- {
- bytesRead = s.Read(data, 0, data.Length);
- fs.Write(data, 0, bytesRead);
- }
- while (bytesRead > 0);
- fs.Flush();
- }
- }
- }
- }
- }
- catch (Exception ex)
- {
- string errMsg = "Download from S3 url" + srcS3TO.endpoint + " said: " + ex.Message;
- logger.Error(errMsg, ex);
- throw new Exception(errMsg, ex);
+ return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.RebootAnswer);
}
}
- // POST api/HypervResource/GetStorageStatsCommand
+ // POST api/HypervResource/DestroyCommand
[HttpPost]
- [ActionName(CloudStackTypes.GetStorageStatsCommand)]
- public JContainer GetStorageStatsCommand([FromBody]dynamic cmd)
+ [ActionName(CloudStackTypes.DestroyCommand)]
+ public JContainer DestroyCommand([FromBody]dynamic cmd)
{
using (log4net.NDC.Push(Guid.NewGuid().ToString()))
{
- logger.Info(CloudStackTypes.GetStorageStatsCommand + Utils.CleanString(cmd.ToString()));
- bool result = false;
+ logger.Info(CloudStackTypes.DestroyCommand + Utils.CleanString(cmd.ToString()));
+
string details = null;
- long capacity = 0;
- long available = 0;
- long used = 0;
+ bool result = false;
+
try
{
- StoragePoolType poolType;
- string poolId = (string)cmd.id;
- string hostPath = null;
- if (!Enum.TryParse<StoragePoolType>((string)cmd.pooltype, out poolType))
- {
- details = "Request to get unsupported pool type: " + ((string)cmd.pooltype == null ? "NULL" : (string)cmd.pooltype) + "in cmd " +
- JsonConvert.SerializeObject(cmd);
- logger.Error(details);
- }
- else if (poolType == StoragePoolType.Filesystem)
+ // Assert
+ String errMsg = "No 'volume' details in " + CloudStackTypes.DestroyCommand + " " + Utils.CleanString(cmd.ToString());
+ if (cmd.volume == null)
{
- hostPath = (string)cmd.localPath;;
- GetCapacityForLocalPath(hostPath, out capacity, out available);
- used = capacity - available;
- result = true;
+ logger.Error(errMsg);
+ throw new ArgumentException(errMsg);
}
- else if (poolType == StoragePoolType.NetworkFilesystem || poolType == StoragePoolType.SMB)
+
+ // Assert
+ errMsg = "No valide path in DestroyCommand in " + CloudStackTypes.DestroyCommand + " " + (String)cmd.ToString();
+ if (cmd.volume.path == null)
{
- string sharePath = config.getPrimaryStorage((string)cmd.id);
- if (sharePath != null)
- {
- hostPath = sharePath;
- Utils.GetShareDetails(sharePath, out capacity, out available);
- used = capacity - available;
- result = true;
- }
+ logger.Error(errMsg);
+ throw new ArgumentException(errMsg);
}
- else
+
+ String path = (string)cmd.volume.path;
+ if (!File.Exists(path))
{
- result = false;
+ logger.Info(CloudStackTypes.DestroyCommand + ", but volume at pass already deleted " + path);
}
- if (result)
+ string vmName = (string)cmd.vmName;
+ if (!string.IsNullOrEmpty(vmName) && File.Exists(path))
{
- logger.Debug(CloudStackTypes.GetStorageStatsCommand + " set used bytes for " + hostPath + " to " + used);
+ // Make sure that this resource is removed from the VM
+ wmiCallsV2.DetachDisk(vmName, path);
}
+
+ File.Delete(path);
+ result = true;
}
- catch (Exception ex)
+ catch (Exception sysEx)
{
- details = CloudStackTypes.GetStorageStatsCommand + " failed on exception" + ex.Message;
- logger.Error(details, ex);
+ details = CloudStackTypes.DestroyCommand + " failed due to " + sysEx.Message;
+ logger.Error(details, sysEx);
}
object ansContent = new
- {
- result = result,
- details = details,
- capacity = capacity,
<TRUNCATED>
[3/3] git commit: updated refs/heads/4.4 to 8fb89cd
Posted by da...@apache.org.
CLOUDSTACK-6504: removed warnings coming in building hyper-v agent code
(cherry picked from commit 66f8e0e1b5c81cbfde926c0c65c4d5969767cab9)
Conflicts:
plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/8fb89cdc
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/8fb89cdc
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/8fb89cdc
Branch: refs/heads/4.4
Commit: 8fb89cdc8e2dff60d49fecd3e51a9bf997061035
Parents: 48f9453
Author: Anshul Gangwar <an...@citrix.com>
Authored: Thu Apr 24 22:30:12 2014 -0700
Committer: Daan Hoogland <da...@onecht.net>
Committed: Mon Jul 28 17:31:03 2014 +0200
----------------------------------------------------------------------
.../HypervResource/CloudStackTypes.cs | 8 +-
.../HypervResource/HypervResourceController.cs | 3558 +++++++++---------
.../ServerResource/HypervResource/Utils.cs | 4 +-
.../ServerResource/HypervResource/WmiCallsV2.cs | 1483 +++++---
4 files changed, 2740 insertions(+), 2313 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8fb89cdc/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 ef24c79..4516191 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
@@ -302,7 +302,7 @@ namespace HypervResource
path = Utils.NormalizePath(path);
if (Directory.Exists(path))
{
- string[] choices = choices = Directory.GetFiles(path, volInfo.uuid + ".vhd*");
+ string[] choices = Directory.GetFiles(path, volInfo.uuid + ".vhd*");
if (choices.Length != 1)
{
String errMsg = "Tried to guess file extension, but cannot find file corresponding to " +
@@ -609,6 +609,7 @@ namespace HypervResource
public struct VolumeInfo
{
+#pragma warning disable 0414
public long id;
public string type;
public string storagePoolType;
@@ -618,6 +619,7 @@ namespace HypervResource
public string path;
long size;
string chainInfo;
+#pragma warning restore 0414
public VolumeInfo(long id, string type, string poolType, String poolUuid, String name, String mountPoint, String path, long size, String chainInfo)
{
@@ -635,10 +637,12 @@ namespace HypervResource
public class VmState
{
+#pragma warning disable 0414
[JsonProperty("state")]
public String state;
[JsonProperty("host")]
String host;
+#pragma warning restore 0414
public VmState() { }
public VmState(String vmState, String host)
{
@@ -649,6 +653,7 @@ namespace HypervResource
public struct StoragePoolInfo
{
+#pragma warning disable 0414
[JsonProperty("uuid")]
public String uuid;
[JsonProperty("host")]
@@ -667,6 +672,7 @@ namespace HypervResource
long availableBytes;
[JsonProperty("details")]
Dictionary<String, String> details;
+#pragma warning restore 0414
public StoragePoolInfo(String uuid, String host, String hostPath,
String localPath, string poolType, long capacityBytes,