wsp-10323 Convert the VSP provider into one utilizing PowerShell. Step 4 Snapshots
This commit is contained in:
parent
6a1efab8d5
commit
8f6b035e89
8 changed files with 377 additions and 181 deletions
|
@ -136,5 +136,11 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
[Persistent]
|
[Persistent]
|
||||||
public int Generation { get; set; }
|
public int Generation { get; set; }
|
||||||
|
|
||||||
|
[Persistent]
|
||||||
|
public int ProcessorCount { get; set; }
|
||||||
|
|
||||||
|
[Persistent]
|
||||||
|
public string ParentSnapshotId { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string CheckPointId { get; set; }
|
public string CheckPointId { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
public string VMName { get; set; }
|
||||||
public string ParentId { get; set; }
|
public string ParentId { get; set; }
|
||||||
public DateTime Created { get; set; }
|
public DateTime Created { get; set; }
|
||||||
public bool IsCurrent { get; set; }
|
public bool IsCurrent { get; set; }
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Management;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -9,6 +10,8 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
{
|
{
|
||||||
static class PSObjectExtension
|
static class PSObjectExtension
|
||||||
{
|
{
|
||||||
|
#region Properties
|
||||||
|
|
||||||
public static object GetProperty(this PSObject obj, string name)
|
public static object GetProperty(this PSObject obj, string name)
|
||||||
{
|
{
|
||||||
return obj.Members[name].Value;
|
return obj.Members[name].Value;
|
||||||
|
@ -33,5 +36,27 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
{
|
{
|
||||||
return obj.Members[name].Value == null ? "" : obj.Members[name].Value.ToString();
|
return obj.Members[name].Value == null ? "" : obj.Members[name].Value.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public static ManagementObject Invoke(this PSObject obj, string name, object argument)
|
||||||
|
{
|
||||||
|
return obj.Invoke(name, new[] {argument});
|
||||||
|
}
|
||||||
|
public static ManagementObject Invoke(this PSObject obj, string name, params object[] arguments)
|
||||||
|
{
|
||||||
|
var results = (ManagementObjectCollection)obj.Methods[name].Invoke(arguments);
|
||||||
|
|
||||||
|
foreach (var result in results)
|
||||||
|
{
|
||||||
|
return (ManagementObject) result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
{
|
{
|
||||||
public static class BiosHelper
|
public static class BiosHelper
|
||||||
{
|
{
|
||||||
public static BiosInfo GetVMBios(PowerShellManager powerShell, string name, int generation)
|
public static BiosInfo Get(PowerShellManager powerShell, string name, int generation)
|
||||||
{
|
{
|
||||||
BiosInfo info = new BiosInfo();
|
BiosInfo info = new BiosInfo();
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateBios(PowerShellManager powerShell, VirtualMachine vm, bool bootFromCD, bool numLockEnabled)
|
public static void Update(PowerShellManager powerShell, VirtualMachine vm, bool bootFromCD, bool numLockEnabled)
|
||||||
{
|
{
|
||||||
// for Win2012R2+ and Win8.1+
|
// for Win2012R2+ and Win8.1+
|
||||||
if (vm.Generation == 2)
|
if (vm.Generation == 2)
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Management.Automation;
|
||||||
|
using System.Management.Automation.Runspaces;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WebsitePanel.Providers.Virtualization
|
||||||
|
{
|
||||||
|
public static class JobHelper
|
||||||
|
{
|
||||||
|
public static JobResult CreateSuccessResult(ReturnCode returnCode = ReturnCode.OK)
|
||||||
|
{
|
||||||
|
return new JobResult
|
||||||
|
{
|
||||||
|
Job = new ConcreteJob {JobState = ConcreteJobState.Completed},
|
||||||
|
ReturnValue = returnCode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JobResult CreateResultFromPSResults(Collection<PSObject> objJob)
|
||||||
|
{
|
||||||
|
if (objJob == null || objJob.Count == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
JobResult result = new JobResult();
|
||||||
|
|
||||||
|
result.Job = CreateFromPSObject(objJob);
|
||||||
|
result.ReturnValue = ReturnCode.JobStarted;
|
||||||
|
|
||||||
|
switch (result.Job.JobState)
|
||||||
|
{
|
||||||
|
case ConcreteJobState.Failed:
|
||||||
|
result.ReturnValue = ReturnCode.Failed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConcreteJob CreateFromPSObject(Collection<PSObject> objJob)
|
||||||
|
{
|
||||||
|
if (objJob == null || objJob.Count == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
ConcreteJob job = new ConcreteJob();
|
||||||
|
job.Id = objJob[0].GetProperty<int>("Id").ToString();
|
||||||
|
job.JobState = objJob[0].GetEnum<ConcreteJobState>("JobStateInfo");
|
||||||
|
job.Caption = objJob[0].GetProperty<string>("Name");
|
||||||
|
job.Description = objJob[0].GetProperty<string>("Command");
|
||||||
|
job.StartTime = objJob[0].GetProperty<DateTime>("PSBeginTime");
|
||||||
|
job.ElapsedTime = objJob[0].GetProperty<DateTime?>("PSEndTime") ?? DateTime.Now;
|
||||||
|
|
||||||
|
// PercentComplete
|
||||||
|
job.PercentComplete = 0;
|
||||||
|
var progress = (PSDataCollection<ProgressRecord>)objJob[0].GetProperty("Progress");
|
||||||
|
if (progress != null && progress.Count > 0)
|
||||||
|
job.PercentComplete = progress[0].PercentComplete;
|
||||||
|
|
||||||
|
// Errors
|
||||||
|
var errors = (PSDataCollection<ErrorRecord>)objJob[0].GetProperty("Error");
|
||||||
|
if (errors != null && errors.Count > 0)
|
||||||
|
{
|
||||||
|
job.ErrorDescription = errors[0].ErrorDetails.Message + ". " + errors[0].ErrorDetails.RecommendedAction;
|
||||||
|
job.ErrorCode = errors[0].Exception != null ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Management;
|
||||||
|
using System.Management.Automation;
|
||||||
|
using System.Management.Automation.Runspaces;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WebsitePanel.Providers.Virtualization
|
||||||
|
{
|
||||||
|
public static class SnapshotHelper
|
||||||
|
{
|
||||||
|
public static VirtualMachineSnapshot GetFromPS(PSObject psObject, string runningSnapshotId = null)
|
||||||
|
{
|
||||||
|
var snapshot = new VirtualMachineSnapshot
|
||||||
|
{
|
||||||
|
Id = psObject.GetString("Id"),
|
||||||
|
Name = psObject.GetString("Name"),
|
||||||
|
VMName = psObject.GetString("VMName"),
|
||||||
|
ParentId = psObject.GetString("ParentSnapshotId"),
|
||||||
|
Created = psObject.GetProperty<DateTime>("CreationTime")
|
||||||
|
};
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(snapshot.ParentId))
|
||||||
|
snapshot.ParentId = null; // for capability
|
||||||
|
|
||||||
|
if (!String.IsNullOrEmpty(runningSnapshotId))
|
||||||
|
snapshot.IsCurrent = snapshot.Id == runningSnapshotId;
|
||||||
|
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VirtualMachineSnapshot GetFromWmi(ManagementBaseObject objSnapshot)
|
||||||
|
{
|
||||||
|
if (objSnapshot == null || objSnapshot.Properties.Count == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
VirtualMachineSnapshot snapshot = new VirtualMachineSnapshot();
|
||||||
|
snapshot.Id = (string)objSnapshot["InstanceID"];
|
||||||
|
snapshot.Name = (string)objSnapshot["ElementName"];
|
||||||
|
|
||||||
|
string parentId = (string)objSnapshot["Parent"];
|
||||||
|
if (!String.IsNullOrEmpty(parentId))
|
||||||
|
{
|
||||||
|
int idx = parentId.IndexOf("Microsoft:");
|
||||||
|
snapshot.ParentId = parentId.Substring(idx, parentId.Length - idx - 1);
|
||||||
|
snapshot.ParentId = snapshot.ParentId.ToLower().Replace("microsoft:", "");
|
||||||
|
}
|
||||||
|
if (!String.IsNullOrEmpty(snapshot.Id))
|
||||||
|
{
|
||||||
|
snapshot.Id = snapshot.Id.ToLower().Replace("microsoft:", "");
|
||||||
|
}
|
||||||
|
snapshot.Created = Wmi.ToDateTime((string)objSnapshot["CreationTime"]);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(snapshot.ParentId))
|
||||||
|
snapshot.ParentId = null; // for capability
|
||||||
|
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Delete(PowerShellManager powerShell, VirtualMachineSnapshot snapshot, bool includeChilds)
|
||||||
|
{
|
||||||
|
Command cmd = new Command("Remove-VMSnapshot");
|
||||||
|
cmd.Parameters.Add("VMName", snapshot.VMName);
|
||||||
|
cmd.Parameters.Add("Name", snapshot.Name);
|
||||||
|
if (includeChilds) cmd.Parameters.Add("IncludeAllChildSnapshots", true);
|
||||||
|
|
||||||
|
powerShell.Execute(cmd, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -59,7 +59,7 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
{
|
{
|
||||||
#region Constants
|
#region Constants
|
||||||
private const string CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG = "WebsitePanel.HyperV.UseDiskPartClearReadOnlyFlag";
|
private const string CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG = "WebsitePanel.HyperV.UseDiskPartClearReadOnlyFlag";
|
||||||
private const string WMI_VIRTUALIZATION_NAMESPACE = @"root\virtualization";
|
private const string WMI_VIRTUALIZATION_NAMESPACE = @"root\virtualization\v2";
|
||||||
private const string WMI_CIMV2_NAMESPACE = @"root\cimv2";
|
private const string WMI_CIMV2_NAMESPACE = @"root\cimv2";
|
||||||
|
|
||||||
private const int SWITCH_PORTS_NUMBER = 1024;
|
private const int SWITCH_PORTS_NUMBER = 1024;
|
||||||
|
@ -174,6 +174,8 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
vm.Status = result[0].GetProperty("Status").ToString();
|
vm.Status = result[0].GetProperty("Status").ToString();
|
||||||
vm.ReplicationState = result[0].GetProperty("ReplicationState").ToString();
|
vm.ReplicationState = result[0].GetProperty("ReplicationState").ToString();
|
||||||
vm.Generation = result[0].GetInt("Generation");
|
vm.Generation = result[0].GetInt("Generation");
|
||||||
|
vm.ProcessorCount = result[0].GetInt("ProcessorCount");
|
||||||
|
vm.ParentSnapshotId = result[0].GetString("ParentSnapshotId");
|
||||||
|
|
||||||
vm.Heartbeat = VirtualMachineHelper.GetVMHeartBeatStatus(PowerShell, vm.Name);
|
vm.Heartbeat = VirtualMachineHelper.GetVMHeartBeatStatus(PowerShell, vm.Name);
|
||||||
|
|
||||||
|
@ -187,7 +189,7 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
vm.RamSize = memoryInfo.Startup;
|
vm.RamSize = memoryInfo.Startup;
|
||||||
|
|
||||||
// BIOS
|
// BIOS
|
||||||
BiosInfo biosInfo = BiosHelper.GetVMBios(PowerShell, vm.Name, vm.Generation);
|
BiosInfo biosInfo = BiosHelper.Get(PowerShell, vm.Name, vm.Generation);
|
||||||
vm.NumLockEnabled = biosInfo.NumLockEnabled;
|
vm.NumLockEnabled = biosInfo.NumLockEnabled;
|
||||||
vm.BootFromCD = biosInfo.BootFromCD;
|
vm.BootFromCD = biosInfo.BootFromCD;
|
||||||
|
|
||||||
|
@ -219,6 +221,7 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
return vm;
|
return vm;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<VirtualMachine> GetVirtualMachines()
|
public List<VirtualMachine> GetVirtualMachines()
|
||||||
{
|
{
|
||||||
HostedSolutionLog.LogStart("GetVirtualMachines");
|
HostedSolutionLog.LogStart("GetVirtualMachines");
|
||||||
|
@ -255,11 +258,10 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
|
|
||||||
public byte[] GetVirtualMachineThumbnailImage(string vmId, ThumbnailSize size)
|
public byte[] GetVirtualMachineThumbnailImage(string vmId, ThumbnailSize size)
|
||||||
{
|
{
|
||||||
//ManagementBaseObject objSummary = GetVirtualMachineSummaryInformation(vmId, (SummaryInformationRequest)size);
|
ManagementBaseObject objSummary = GetVirtualMachineSummaryInformation(vmId, (SummaryInformationRequest)size);
|
||||||
//wmi.Dump(objSummary);
|
wmi.Dump(objSummary);
|
||||||
//return GetTumbnailFromSummaryInformation(objSummary, size);
|
return GetTumbnailFromSummaryInformation(objSummary, size);
|
||||||
// TODO:
|
//return (byte[]) (new ImageConverter()).ConvertTo(new Bitmap(80, 60), typeof (byte[]));
|
||||||
return (byte[]) (new ImageConverter()).ConvertTo(new Bitmap(80, 60), typeof (byte[]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] GetTumbnailFromSummaryInformation(ManagementBaseObject objSummary, ThumbnailSize size)
|
private byte[] GetTumbnailFromSummaryInformation(ManagementBaseObject objSummary, ThumbnailSize size)
|
||||||
|
@ -436,7 +438,7 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
var realVm = GetVirtualMachineEx(vm.VirtualMachineId);
|
var realVm = GetVirtualMachineEx(vm.VirtualMachineId);
|
||||||
|
|
||||||
DvdDriveHelper.Update(PowerShell, realVm, vm.DvdDriveInstalled); // Dvd should be before bios because bios sets boot order
|
DvdDriveHelper.Update(PowerShell, realVm, vm.DvdDriveInstalled); // Dvd should be before bios because bios sets boot order
|
||||||
BiosHelper.UpdateBios(PowerShell, realVm, vm.BootFromCD, vm.NumLockEnabled);
|
BiosHelper.Update(PowerShell, realVm, vm.BootFromCD, vm.NumLockEnabled);
|
||||||
VirtualMachineHelper.UpdateProcessors(PowerShell, realVm, vm.CpuCores, CpuLimitSettings, CpuReserveSettings, CpuWeightSettings);
|
VirtualMachineHelper.UpdateProcessors(PowerShell, realVm, vm.CpuCores, CpuLimitSettings, CpuReserveSettings, CpuWeightSettings);
|
||||||
VirtualMachineHelper.UpdateMemory(PowerShell, realVm, vm.RamSize);
|
VirtualMachineHelper.UpdateMemory(PowerShell, realVm, vm.RamSize);
|
||||||
NetworkAdapterHelper.Update(PowerShell, vm);
|
NetworkAdapterHelper.Update(PowerShell, vm);
|
||||||
|
@ -661,7 +663,7 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
paramList.ForEach(p => cmd.Parameters.Add(p));
|
paramList.ForEach(p => cmd.Parameters.Add(p));
|
||||||
|
|
||||||
PowerShell.Execute(cmd, false);
|
PowerShell.Execute(cmd, false);
|
||||||
jobResult = CreateSuccessJobResult();
|
jobResult = JobHelper.CreateSuccessResult();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -852,130 +854,148 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Snapshots
|
#region Snapshots
|
||||||
|
|
||||||
public List<VirtualMachineSnapshot> GetVirtualMachineSnapshots(string vmId)
|
public List<VirtualMachineSnapshot> GetVirtualMachineSnapshots(string vmId)
|
||||||
{
|
{
|
||||||
// get all VM setting objects
|
|
||||||
ManagementObject objVmSettings = GetVirtualMachineSettingsObject(vmId);
|
|
||||||
VirtualMachineSnapshot runningSnapshot = CreateSnapshotFromWmiObject(objVmSettings);
|
|
||||||
|
|
||||||
// load snapshots
|
|
||||||
ManagementBaseObject objSummary = GetVirtualMachineSummaryInformation(vmId, SummaryInformationRequest.Snapshots);
|
|
||||||
ManagementBaseObject[] objSnapshots = (ManagementBaseObject[])objSummary["Snapshots"];
|
|
||||||
|
|
||||||
List<VirtualMachineSnapshot> snapshots = new List<VirtualMachineSnapshot>();
|
List<VirtualMachineSnapshot> snapshots = new List<VirtualMachineSnapshot>();
|
||||||
|
|
||||||
if (objSnapshots != null)
|
try
|
||||||
{
|
{
|
||||||
foreach (ManagementBaseObject objSnapshot in objSnapshots)
|
var vm = GetVirtualMachine(vmId);
|
||||||
|
|
||||||
|
Command cmd = new Command("Get-VMSnapshot");
|
||||||
|
cmd.Parameters.Add("VMName", vm.Name);
|
||||||
|
|
||||||
|
Collection<PSObject> result = PowerShell.Execute(cmd, false);
|
||||||
|
if (result != null && result.Count > 0)
|
||||||
{
|
{
|
||||||
VirtualMachineSnapshot snapshot = CreateSnapshotFromWmiObject(objSnapshot);
|
foreach (PSObject psSnapshot in result)
|
||||||
snapshot.IsCurrent = (runningSnapshot.ParentId == snapshot.Id);
|
{
|
||||||
snapshots.Add(snapshot);
|
snapshots.Add(SnapshotHelper.GetFromPS(psSnapshot, vm.ParentSnapshotId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
HostedSolutionLog.LogError("GetVirtualMachineSnapshots", ex);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
return snapshots;
|
return snapshots;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VirtualMachineSnapshot GetSnapshot(string snapshotId)
|
public VirtualMachineSnapshot GetSnapshot(string snapshotId)
|
||||||
{
|
{
|
||||||
// load snapshot
|
try
|
||||||
ManagementObject objSnapshot = GetSnapshotObject(snapshotId);
|
{
|
||||||
return CreateSnapshotFromWmiObject(objSnapshot);
|
Command cmd = new Command("Get-VMSnapshot");
|
||||||
|
cmd.Parameters.Add("Id", snapshotId);
|
||||||
|
|
||||||
|
Collection<PSObject> result = PowerShell.Execute(cmd, false);
|
||||||
|
if (result != null && result.Count > 0)
|
||||||
|
{
|
||||||
|
return SnapshotHelper.GetFromPS(result[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
HostedSolutionLog.LogError("GetSnapshot", ex);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JobResult CreateSnapshot(string vmId)
|
public JobResult CreateSnapshot(string vmId)
|
||||||
{
|
{
|
||||||
// get VM management service
|
try
|
||||||
ManagementObject objVmsvc = GetVirtualSystemManagementService();
|
{
|
||||||
|
var vm = GetVirtualMachine(vmId);
|
||||||
|
|
||||||
// load virtual machine
|
Command cmd = new Command("Checkpoint-VM");
|
||||||
ManagementObject objVm = GetVirtualMachineObject(vmId);
|
cmd.Parameters.Add("Name", vm.Name);
|
||||||
|
|
||||||
// get method params
|
PowerShell.Execute(cmd, false);
|
||||||
ManagementBaseObject inParams = objVmsvc.GetMethodParameters("CreateVirtualSystemSnapshot");
|
return JobHelper.CreateSuccessResult(ReturnCode.JobStarted);
|
||||||
inParams["SourceSystem"] = objVm;
|
}
|
||||||
|
catch (Exception ex)
|
||||||
// invoke method
|
{
|
||||||
ManagementBaseObject outParams = objVmsvc.InvokeMethod("CreateVirtualSystemSnapshot", inParams, null);
|
HostedSolutionLog.LogError("CreateSnapshot", ex);
|
||||||
return CreateJobResultFromWmiMethodResults(outParams);
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public JobResult RenameSnapshot(string vmId, string snapshotId, string name)
|
public JobResult RenameSnapshot(string vmId, string snapshotId, string name)
|
||||||
{
|
{
|
||||||
// load virtual machine
|
try
|
||||||
ManagementObject objVm = GetVirtualMachineObject(vmId);
|
{
|
||||||
|
var vm = GetVirtualMachine(vmId);
|
||||||
|
var snapshot = GetSnapshot(snapshotId);
|
||||||
|
|
||||||
// load snapshot
|
Command cmd = new Command("Rename-VMSnapshot");
|
||||||
ManagementObject objSnapshot = GetSnapshotObject(snapshotId);
|
cmd.Parameters.Add("VMName", vm.Name);
|
||||||
|
cmd.Parameters.Add("Name", snapshot.Name);
|
||||||
|
cmd.Parameters.Add("NewName", name);
|
||||||
|
|
||||||
// rename snapshot
|
PowerShell.Execute(cmd, false);
|
||||||
objSnapshot["ElementName"] = name;
|
return JobHelper.CreateSuccessResult();
|
||||||
|
}
|
||||||
// save
|
catch (Exception ex)
|
||||||
ManagementObject objVmsvc = GetVirtualSystemManagementService();
|
{
|
||||||
ManagementBaseObject inParams = objVmsvc.GetMethodParameters("ModifyVirtualSystem");
|
HostedSolutionLog.LogError("RenameSnapshot", ex);
|
||||||
inParams["ComputerSystem"] = objVm.Path.Path;
|
throw;
|
||||||
inParams["SystemSettingData"] = objSnapshot.GetText(TextFormat.CimDtd20);
|
}
|
||||||
ManagementBaseObject outParams = objVmsvc.InvokeMethod("ModifyVirtualSystem", inParams, null);
|
|
||||||
return CreateJobResultFromWmiMethodResults(outParams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public JobResult ApplySnapshot(string vmId, string snapshotId)
|
public JobResult ApplySnapshot(string vmId, string snapshotId)
|
||||||
{
|
{
|
||||||
// get VM management service
|
try
|
||||||
ManagementObject objVmsvc = GetVirtualSystemManagementService();
|
{
|
||||||
|
var vm = GetVirtualMachine(vmId);
|
||||||
|
var snapshot = GetSnapshot(snapshotId);
|
||||||
|
|
||||||
// load virtual machine
|
Command cmd = new Command("Restore-VMSnapshot");
|
||||||
ManagementObject objVm = GetVirtualMachineObject(vmId);
|
cmd.Parameters.Add("VMName", vm.Name);
|
||||||
|
cmd.Parameters.Add("Name", snapshot.Name);
|
||||||
|
|
||||||
// load snapshot
|
PowerShell.Execute(cmd, false);
|
||||||
ManagementObject objSnapshot = GetSnapshotObject(snapshotId);
|
return JobHelper.CreateSuccessResult();
|
||||||
|
}
|
||||||
ManagementObjectCollection objRelated = objVm.GetRelated("Msvm_SettingsDefineState");
|
catch (Exception ex)
|
||||||
|
{
|
||||||
// get method params
|
HostedSolutionLog.LogError("ApplySnapshot", ex);
|
||||||
ManagementBaseObject inParams = objVmsvc.GetMethodParameters("ApplyVirtualSystemSnapshot");
|
throw;
|
||||||
inParams["ComputerSystem"] = objVm.Path.Path;
|
}
|
||||||
inParams["SnapshotSettingData"] = objSnapshot.Path.Path;
|
|
||||||
|
|
||||||
// invoke method
|
|
||||||
ManagementBaseObject outParams = objVmsvc.InvokeMethod("ApplyVirtualSystemSnapshot", inParams, null);
|
|
||||||
return CreateJobResultFromWmiMethodResults(outParams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public JobResult DeleteSnapshot(string snapshotId)
|
public JobResult DeleteSnapshot(string snapshotId)
|
||||||
{
|
{
|
||||||
// get VM management service
|
try
|
||||||
ManagementObject objVmsvc = GetVirtualSystemManagementService();
|
{
|
||||||
|
var snapshot = GetSnapshot(snapshotId);
|
||||||
// load snapshot object
|
SnapshotHelper.Delete(PowerShell, snapshot, false);
|
||||||
ManagementObject objSnapshot = GetSnapshotObject(snapshotId);
|
return JobHelper.CreateSuccessResult(ReturnCode.JobStarted);
|
||||||
|
}
|
||||||
// get method params
|
catch (Exception ex)
|
||||||
ManagementBaseObject inParams = objVmsvc.GetMethodParameters("RemoveVirtualSystemSnapshot");
|
{
|
||||||
inParams["SnapshotSettingData"] = objSnapshot.Path.Path;
|
HostedSolutionLog.LogError("DeleteSnapshot", ex);
|
||||||
|
throw;
|
||||||
// invoke method
|
}
|
||||||
ManagementBaseObject outParams = objVmsvc.InvokeMethod("RemoveVirtualSystemSnapshot", inParams, null);
|
|
||||||
return CreateJobResultFromWmiMethodResults(outParams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public JobResult DeleteSnapshotSubtree(string snapshotId)
|
public JobResult DeleteSnapshotSubtree(string snapshotId)
|
||||||
{
|
{
|
||||||
// get VM management service
|
try
|
||||||
ManagementObject objVmsvc = GetVirtualSystemManagementService();
|
{
|
||||||
|
var snapshot = GetSnapshot(snapshotId);
|
||||||
// load snapshot object
|
SnapshotHelper.Delete(PowerShell, snapshot, true);
|
||||||
ManagementObject objSnapshot = GetSnapshotObject(snapshotId);
|
return JobHelper.CreateSuccessResult(ReturnCode.JobStarted);
|
||||||
|
}
|
||||||
// get method params
|
catch (Exception ex)
|
||||||
ManagementBaseObject inParams = objVmsvc.GetMethodParameters("RemoveVirtualSystemSnapshotTree");
|
{
|
||||||
inParams["SnapshotSettingData"] = objSnapshot.Path.Path;
|
HostedSolutionLog.LogError("DeleteSnapshot", ex);
|
||||||
|
throw;
|
||||||
// invoke method
|
}
|
||||||
ManagementBaseObject outParams = objVmsvc.InvokeMethod("RemoveVirtualSystemSnapshotTree", inParams, null);
|
|
||||||
return CreateJobResultFromWmiMethodResults(outParams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetSnapshotThumbnailImage(string snapshotId, ThumbnailSize size)
|
public byte[] GetSnapshotThumbnailImage(string snapshotId, ThumbnailSize size)
|
||||||
|
@ -983,6 +1003,7 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
ManagementBaseObject objSummary = GetSnapshotSummaryInformation(snapshotId, (SummaryInformationRequest)size);
|
ManagementBaseObject objSummary = GetSnapshotSummaryInformation(snapshotId, (SummaryInformationRequest)size);
|
||||||
return GetTumbnailFromSummaryInformation(objSummary, size);
|
return GetTumbnailFromSummaryInformation(objSummary, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region DVD operations
|
#region DVD operations
|
||||||
|
@ -1029,7 +1050,7 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
}
|
}
|
||||||
|
|
||||||
HostedSolutionLog.LogEnd("InsertDVD");
|
HostedSolutionLog.LogEnd("InsertDVD");
|
||||||
return CreateSuccessJobResult();
|
return JobHelper.CreateSuccessResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JobResult EjectDVD(string vmId)
|
public JobResult EjectDVD(string vmId)
|
||||||
|
@ -1049,7 +1070,7 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
}
|
}
|
||||||
|
|
||||||
HostedSolutionLog.LogEnd("InsertDVD");
|
HostedSolutionLog.LogEnd("InsertDVD");
|
||||||
return CreateSuccessJobResult();
|
return JobHelper.CreateSuccessResult();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -1276,8 +1297,7 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// TODO
|
HostedSolutionLog.LogError("GetKVPItems", new Exception("msvm_KvpExchangeComponent"));
|
||||||
// add logging...
|
|
||||||
|
|
||||||
return pairs;
|
return pairs;
|
||||||
}
|
}
|
||||||
|
@ -1307,6 +1327,70 @@ namespace WebsitePanel.Providers.Virtualization
|
||||||
}
|
}
|
||||||
|
|
||||||
return pairs;
|
return pairs;
|
||||||
|
|
||||||
|
//HostedSolutionLog.LogStart("GetKVPItems");
|
||||||
|
//HostedSolutionLog.DebugInfo("Virtual Machine: {0}", vmId);
|
||||||
|
//HostedSolutionLog.DebugInfo("exchangeItemsName: {0}", exchangeItemsName);
|
||||||
|
|
||||||
|
//List<KvpExchangeDataItem> pairs = new List<KvpExchangeDataItem>();
|
||||||
|
|
||||||
|
//try
|
||||||
|
//{
|
||||||
|
// var vm = GetVirtualMachine(vmId);
|
||||||
|
|
||||||
|
// Command cmdGetVm = new Command("Get-WmiObject");
|
||||||
|
|
||||||
|
// cmdGetVm.Parameters.Add("Namespace", WMI_VIRTUALIZATION_NAMESPACE);
|
||||||
|
// cmdGetVm.Parameters.Add("Class", "Msvm_ComputerSystem");
|
||||||
|
// cmdGetVm.Parameters.Add("Filter", "ElementName = '" + vm.Name + "'");
|
||||||
|
|
||||||
|
// Collection<PSObject> result = PowerShell.Execute(cmdGetVm, false);
|
||||||
|
|
||||||
|
// if (result != null && result.Count > 0)
|
||||||
|
// {
|
||||||
|
// dynamic resultDynamic = result[0];//.Invoke();
|
||||||
|
// var kvp = resultDynamic.GetRelated("Msvm_KvpExchangeComponent");
|
||||||
|
|
||||||
|
// // return XML pairs
|
||||||
|
// string[] xmlPairs = null;
|
||||||
|
|
||||||
|
// foreach (dynamic a in kvp)
|
||||||
|
// {
|
||||||
|
// xmlPairs = a[exchangeItemsName];
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (xmlPairs == null)
|
||||||
|
// return pairs;
|
||||||
|
|
||||||
|
// // join all pairs
|
||||||
|
// StringBuilder sb = new StringBuilder();
|
||||||
|
// sb.Append("<result>");
|
||||||
|
// foreach (string xmlPair in xmlPairs)
|
||||||
|
// sb.Append(xmlPair);
|
||||||
|
// sb.Append("</result>");
|
||||||
|
|
||||||
|
// // parse pairs
|
||||||
|
// XmlDocument doc = new XmlDocument();
|
||||||
|
// doc.LoadXml(sb.ToString());
|
||||||
|
|
||||||
|
// foreach (XmlNode nodeName in doc.SelectNodes("/result/INSTANCE/PROPERTY[@NAME='Name']/VALUE"))
|
||||||
|
// {
|
||||||
|
// string name = nodeName.InnerText;
|
||||||
|
// string data = nodeName.ParentNode.ParentNode.SelectSingleNode("PROPERTY[@NAME='Data']/VALUE").InnerText;
|
||||||
|
// pairs.Add(new KvpExchangeDataItem(name, data));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//catch (Exception ex)
|
||||||
|
//{
|
||||||
|
// HostedSolutionLog.LogError("GetKVPItems", ex);
|
||||||
|
// throw;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//HostedSolutionLog.LogEnd("GetKVPItems");
|
||||||
|
|
||||||
|
//return pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JobResult AddKVPItems(string vmId, KvpExchangeDataItem[] items)
|
public JobResult AddKVPItems(string vmId, KvpExchangeDataItem[] items)
|
||||||
|
@ -1832,13 +1916,12 @@ exit", Convert.ToInt32(objDisk["Index"])));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
Command cmd = new Command("Get-Job");
|
Command cmd = new Command("Get-Job");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(jobId)) cmd.Parameters.Add("Id", jobId);
|
if (!string.IsNullOrEmpty(jobId)) cmd.Parameters.Add("Id", jobId);
|
||||||
|
|
||||||
Collection<PSObject> result = PowerShell.Execute( cmd, false);
|
Collection<PSObject> result = PowerShell.Execute( cmd, false);
|
||||||
job = CreateJobFromPSObject(result);
|
job = JobHelper.CreateFromPSObject(result);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -2124,34 +2207,14 @@ exit", Convert.ToInt32(objDisk["Index"])));
|
||||||
return value == null ? 0 : Convert.ToInt64(value);
|
return value == null ? 0 : Convert.ToInt64(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JobResult CreateSuccessJobResult()
|
//protected VirtualMachineSnapshot GetSnapshotById(string id)
|
||||||
{
|
//{
|
||||||
JobResult result = new JobResult();
|
// var vms = GetVirtualMachines();
|
||||||
|
// var allSnapshots = vms.SelectMany(vm => GetVirtualMachineSnapshots(vm.Id.ToString()));
|
||||||
|
|
||||||
result.Job = new ConcreteJob(){JobState = ConcreteJobState.Completed};
|
// return allSnapshots.FirstOrDefault(s => s.Id == id);
|
||||||
result.ReturnValue = ReturnCode.OK;
|
//}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
protected JobResult CreateJobResultFromPSResults(Collection<PSObject> objJob)
|
|
||||||
{
|
|
||||||
if (objJob == null || objJob.Count == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
JobResult result = new JobResult();
|
|
||||||
|
|
||||||
result.Job = CreateJobFromPSObject(objJob);
|
|
||||||
|
|
||||||
result.ReturnValue = ReturnCode.JobStarted;
|
|
||||||
switch (result.Job.JobState)
|
|
||||||
{
|
|
||||||
case ConcreteJobState.Failed:
|
|
||||||
result.ReturnValue = ReturnCode.Failed;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected JobResult CreateJobResultFromWmiMethodResults(ManagementBaseObject outParams)
|
protected JobResult CreateJobResultFromWmiMethodResults(ManagementBaseObject outParams)
|
||||||
{
|
{
|
||||||
|
@ -2201,29 +2264,12 @@ exit", Convert.ToInt32(objDisk["Index"])));
|
||||||
|
|
||||||
private ManagementObject GetSnapshotObject(string snapshotId)
|
private ManagementObject GetSnapshotObject(string snapshotId)
|
||||||
{
|
{
|
||||||
return wmi.GetWmiObject("Msvm_VirtualSystemSettingData", "InstanceID = '{0}'", snapshotId);
|
return wmi.GetWmiObject("Msvm_VirtualSystemSettingData", "InstanceID = '{0}'", snapshotId) ??
|
||||||
|
wmi.GetWmiObject("Msvm_VirtualSystemSettingData", "InstanceID = '{0}'", "Microsoft:" + snapshotId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private VirtualMachineSnapshot CreateSnapshotFromWmiObject(ManagementBaseObject objSnapshot)
|
|
||||||
{
|
|
||||||
if (objSnapshot == null || objSnapshot.Properties.Count == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
VirtualMachineSnapshot snapshot = new VirtualMachineSnapshot();
|
|
||||||
snapshot.Id = (string)objSnapshot["InstanceID"];
|
|
||||||
snapshot.Name = (string)objSnapshot["ElementName"];
|
|
||||||
|
|
||||||
string parentId = (string)objSnapshot["Parent"];
|
|
||||||
if (!String.IsNullOrEmpty(parentId))
|
|
||||||
{
|
|
||||||
int idx = parentId.IndexOf("Microsoft:");
|
|
||||||
snapshot.ParentId = parentId.Substring(idx, parentId.Length - idx - 1);
|
|
||||||
}
|
|
||||||
snapshot.Created = wmi.ToDateTime((string)objSnapshot["CreationTime"]);
|
|
||||||
|
|
||||||
return snapshot;
|
|
||||||
}
|
|
||||||
|
|
||||||
private VirtualSwitch CreateSwitchFromWmiObject(ManagementObject objSwitch)
|
private VirtualSwitch CreateSwitchFromWmiObject(ManagementObject objSwitch)
|
||||||
{
|
{
|
||||||
|
@ -2236,36 +2282,6 @@ exit", Convert.ToInt32(objDisk["Index"])));
|
||||||
return sw;
|
return sw;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConcreteJob CreateJobFromPSObject(Collection<PSObject> objJob)
|
|
||||||
{
|
|
||||||
if (objJob == null || objJob.Count == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
ConcreteJob job = new ConcreteJob();
|
|
||||||
job.Id = objJob[0].GetProperty<int>("Id").ToString();
|
|
||||||
job.JobState = objJob[0].GetEnum<ConcreteJobState>("JobStateInfo");
|
|
||||||
job.Caption = objJob[0].GetProperty<string>("Name");
|
|
||||||
job.Description = objJob[0].GetProperty<string>("Command");
|
|
||||||
job.StartTime = objJob[0].GetProperty<DateTime>("PSBeginTime");
|
|
||||||
job.ElapsedTime = objJob[0].GetProperty<DateTime?>("PSEndTime") ?? DateTime.Now;
|
|
||||||
|
|
||||||
// PercentComplete
|
|
||||||
job.PercentComplete = 0;
|
|
||||||
var progress = (PSDataCollection<ProgressRecord>)objJob[0].GetProperty("Progress");
|
|
||||||
if (progress != null && progress.Count > 0)
|
|
||||||
job.PercentComplete = progress[0].PercentComplete;
|
|
||||||
|
|
||||||
// Errors
|
|
||||||
var errors = (PSDataCollection<ErrorRecord>)objJob[0].GetProperty("Error");
|
|
||||||
if (errors != null && errors.Count > 0)
|
|
||||||
{
|
|
||||||
job.ErrorDescription = errors[0].ErrorDetails.Message + ". " + errors[0].ErrorDetails.RecommendedAction;
|
|
||||||
job.ErrorCode = errors[0].Exception != null ? -1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return job;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConcreteJob CreateJobFromWmiObject(ManagementBaseObject objJob)
|
private ConcreteJob CreateJobFromWmiObject(ManagementBaseObject objJob)
|
||||||
{
|
{
|
||||||
if (objJob == null || objJob.Properties.Count == 0)
|
if (objJob == null || objJob.Properties.Count == 0)
|
||||||
|
@ -2276,7 +2292,7 @@ exit", Convert.ToInt32(objDisk["Index"])));
|
||||||
job.JobState = (ConcreteJobState)Convert.ToInt32(objJob["JobState"]);
|
job.JobState = (ConcreteJobState)Convert.ToInt32(objJob["JobState"]);
|
||||||
job.Caption = (string)objJob["Caption"];
|
job.Caption = (string)objJob["Caption"];
|
||||||
job.Description = (string)objJob["Description"];
|
job.Description = (string)objJob["Description"];
|
||||||
job.StartTime = wmi.ToDateTime((string)objJob["StartTime"]);
|
job.StartTime = Wmi.ToDateTime((string)objJob["StartTime"]);
|
||||||
// TODO proper parsing of WMI time spans, e.g. 00000000000001.325247:000
|
// TODO proper parsing of WMI time spans, e.g. 00000000000001.325247:000
|
||||||
job.ElapsedTime = DateTime.Now; //wmi.ToDateTime((string)objJob["ElapsedTime"]);
|
job.ElapsedTime = DateTime.Now; //wmi.ToDateTime((string)objJob["ElapsedTime"]);
|
||||||
job.ErrorCode = Convert.ToInt32(objJob["ErrorCode"]);
|
job.ErrorCode = Convert.ToInt32(objJob["ErrorCode"]);
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
<Compile Include="Helpers\BiosHelper.cs" />
|
<Compile Include="Helpers\BiosHelper.cs" />
|
||||||
<Compile Include="Helpers\NetworkAdapterHelper.cs" />
|
<Compile Include="Helpers\NetworkAdapterHelper.cs" />
|
||||||
<Compile Include="Helpers\DvdDriveHelper.cs" />
|
<Compile Include="Helpers\DvdDriveHelper.cs" />
|
||||||
|
<Compile Include="Helpers\JobHelper.cs" />
|
||||||
|
<Compile Include="Helpers\SnapshotHelper.cs" />
|
||||||
<Compile Include="PowerShellManager.cs" />
|
<Compile Include="PowerShellManager.cs" />
|
||||||
<Compile Include="HyperV2012R2.cs" />
|
<Compile Include="HyperV2012R2.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue