diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/BiosInfo.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/BiosInfo.cs
new file mode 100644
index 00000000..f7fd4a59
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/BiosInfo.cs
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, Outercurve Foundation.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// - Neither the name of the Outercurve Foundation nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WebsitePanel.Providers.Virtualization
+{
+ public class BiosInfo
+ {
+ public bool NumLockEnabled { get; set; }
+ public string[] StartupOrder { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/ControllerType.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/ControllerType.cs
new file mode 100644
index 00000000..afe85d2a
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/ControllerType.cs
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, Outercurve Foundation.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// - Neither the name of the Outercurve Foundation nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WebsitePanel.Providers.Virtualization
+{
+ public enum ControllerType
+ {
+ IDE = 0,
+ SCSI = 1
+ }
+}
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/MemoryInfo.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/MemoryInfo.cs
new file mode 100644
index 00000000..0fe02369
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/MemoryInfo.cs
@@ -0,0 +1,44 @@
+// Copyright (c) 2014, Outercurve Foundation.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// - Neither the name of the Outercurve Foundation nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WebsitePanel.Providers.Virtualization
+{
+ public class MemoryInfo
+ {
+ public bool DynamicMemoryEnabled { get; set; }
+ public Int32 Startup { get; set; }
+ public Int32 Minimum { get; set; }
+ public Int32 Maximum { get; set; }
+ public int Buffer { get; set; }
+ public int Priority { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualHardDiskInfo.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualHardDiskInfo.cs
index 906b3969..9881f717 100644
--- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualHardDiskInfo.cs
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualHardDiskInfo.cs
@@ -40,5 +40,15 @@ namespace WebsitePanel.Providers.Virtualization
public long MaxInternalSize { get; set; }
public string ParentPath { get; set; }
public VirtualHardDiskType DiskType { get; set; }
+ public bool SupportPersistentReservations { get; set; }
+ public long MaximumIOPS { get; set; }
+ public long MinimumIOPS { get; set; }
+ public ControllerType VHDControllerType { get; set; }
+ public int ControllerNumber { get; set; }
+ public int ControllerLocation { get; set; }
+ public string Name { get; set; }
+ public string Path { get; set; }
+ public VirtualHardDiskFormat DiskFormat { get; set; }
+ public bool Attached { get; set; }
}
}
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachine.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachine.cs
index f8be508c..41ed3494 100644
--- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachine.cs
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachine.cs
@@ -124,6 +124,9 @@ namespace WebsitePanel.Providers.Virtualization
// for GetVirtualMachineEx used in import method
public VirtualMachineNetworkAdapter[] Adapters { get; set; }
+ [Persistent]
+ public VirtualHardDiskInfo[] Disks { get; set; }
+
[Persistent]
public string Status { get; set; }
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/WebsitePanel.Providers.Base.csproj b/WebsitePanel/Sources/WebsitePanel.Providers.Base/WebsitePanel.Providers.Base.csproj
index 2ab48c12..fa659087 100644
--- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/WebsitePanel.Providers.Base.csproj
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/WebsitePanel.Providers.Base.csproj
@@ -268,6 +268,7 @@
+
Code
@@ -278,6 +279,7 @@
Code
+
Code
@@ -288,6 +290,7 @@
+
@@ -302,6 +305,7 @@
Code
+
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs
index 15199ad5..6aa31177 100644
--- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs
@@ -143,7 +143,7 @@ namespace WebsitePanel.Providers.Virtualization
return GetVirtualMachineInternal( vmId, false);
}
- public VirtualMachine GetVirtualMachineInternal(string vmId, bool extended)
+ public VirtualMachine GetVirtualMachineInternal(string vmId, bool extendedInfo)
{
HostedSolutionLog.LogStart("GetVirtualMachine");
@@ -171,26 +171,41 @@ namespace WebsitePanel.Providers.Virtualization
vm.ReplicationState = GetPSObjectProperty(result[0], "ReplicationState").ToString();
vm.Heartbeat = GetVMHeartBeatStatus(runSpace, vm.Name);
-
-
- //vm.CreatedDate = null;
- // HDD
- /*
- if (vmKvp.Name == KVP_HDD_SUMMARY_KEY)
+ vm.CreatedDate = DateTime.Now;
+
+ if (extendedInfo)
{
- string[] disksArray = vmKvp.Data.Split(';');
- vm.HddLogicalDisks = new LogicalDisk[disksArray.Length];
- for (int i = 0; i < disksArray.Length; i++)
+ vm.CpuCores = GetVMProcessors(runSpace, vm.Name);
+
+ MemoryInfo memoryInfo = GetVMMemory(runSpace, vm.Name);
+ vm.RamSize = memoryInfo.Startup;
+
+ BiosInfo biosInfo = GetVMBios(runSpace, vm.Name);
+ vm.NumLockEnabled = biosInfo.NumLockEnabled;
+
+ vm.BootFromCD = false;
+ if ((biosInfo.StartupOrder != null) && (biosInfo.StartupOrder.Length > 0))
+ vm.BootFromCD = (biosInfo.StartupOrder[0] == "CD");
+
+ cmd = new Command("Get-VMDvdDrive");
+ cmd.Parameters.Add("VMName", vm.Name);
+
+ result = ExecuteShellCommand(runSpace, cmd, false);
+ vm.DvdDriveInstalled = (result != null && result.Count > 0);
+
+ vm.Disks = GetVirtualHardDisks(runSpace, vm.Name);
+
+ if ((vm.Disks != null) & (vm.Disks.GetLength(0) > 0))
{
- string[] disk = disksArray[i].Split(':');
- vm.HddLogicalDisks[i] = new LogicalDisk();
- vm.HddLogicalDisks[i].DriveLetter = disk[0];
- vm.HddLogicalDisks[i].FreeSpace = Int32.Parse(disk[1]);
- vm.HddLogicalDisks[i].Size = Int32.Parse(disk[2]);
+ vm.VirtualHardDrivePath = vm.Disks[0].Path;
+ vm.HddSize = Convert.ToInt32(vm.Disks[0].FileSize);
}
+
+
+
}
- */
+
}
}
catch (Exception ex)
@@ -213,7 +228,6 @@ namespace WebsitePanel.Providers.Virtualization
OperationalStatus status = OperationalStatus.None;
- runSpace = OpenRunspace();
Command cmd = new Command("Get-VMIntegrationService");
cmd.Parameters.Add("VMName", name);
@@ -224,8 +238,6 @@ namespace WebsitePanel.Providers.Virtualization
{
status = (OperationalStatus)Enum.Parse(typeof(OperationalStatus), GetPSObjectProperty(result[0], "PrimaryOperationalStatus").ToString());
}
-
-
return status;
}
@@ -234,56 +246,123 @@ namespace WebsitePanel.Providers.Virtualization
return GetVirtualMachineInternal( vmId, true);
}
+
+ internal int GetVMProcessors(Runspace runSpace, string name)
+ {
+
+ int procs = 0;
+
+ Command cmd = new Command("Get-VMProcessor");
+
+ cmd.Parameters.Add("VMName", name);
+
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if (result != null && result.Count > 0)
+ {
+ procs = Convert.ToInt32(GetPSObjectProperty(result[0], "Count"));
+
+ }
+ return procs;
+ }
+
+ internal MemoryInfo GetVMMemory(Runspace runSpace, string name)
+ {
+
+ MemoryInfo info = new MemoryInfo();
+
+ Command cmd = new Command("Get-VMMemory");
+
+ cmd.Parameters.Add("VMName", name);
+
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if (result != null && result.Count > 0)
+ {
+ info.DynamicMemoryEnabled = Convert.ToBoolean(GetPSObjectProperty(result[0], "DynamicMemoryEnabled"));
+ info.Startup = Convert.ToInt32(GetPSObjectProperty(result[0], "Startup"));
+ info.Minimum = Convert.ToInt32(GetPSObjectProperty(result[0], "Minimum"));
+ info.Maximum = Convert.ToInt32(GetPSObjectProperty(result[0], "Maximum"));
+ info.Buffer = Convert.ToInt16(GetPSObjectProperty(result[0], "Buffer"));
+ info.Priority = Convert.ToInt16(GetPSObjectProperty(result[0], "Prioriy"));
+ }
+ return info;
+ }
+
+ internal BiosInfo GetVMBios(Runspace runSpace, string name)
+ {
+
+ BiosInfo info = new BiosInfo();
+
+ Command cmd = new Command("Get-VMBios");
+
+ cmd.Parameters.Add("VMName", name);
+
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if (result != null && result.Count > 0)
+ {
+ info.NumLockEnabled = Convert.ToBoolean(GetPSObjectProperty(result[0], "NumLockEnabled"));
+ info.StartupOrder = (string[])GetPSObjectProperty(result[0], "StartupOrder");
+ }
+ return info;
+ }
+
+ internal VirtualHardDiskInfo[] GetVirtualHardDisks(Runspace runSpace, string name)
+ {
+
+ List disks = new List();
+
+ Command cmd = new Command("Get-VMHardDiskDrive");
+ cmd.Parameters.Add("VMName", name);
+
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if (result != null && result.Count > 0)
+ {
+ foreach(PSObject d in result)
+ {
+ VirtualHardDiskInfo disk = new VirtualHardDiskInfo();
+
+ disk.SupportPersistentReservations = Convert.ToBoolean(GetPSObjectProperty(d, "SupportPersistentReservations"));
+ disk.MaximumIOPS= Convert.ToInt32(GetPSObjectProperty(d, "MaximumIOPS"));
+ disk.MinimumIOPS= Convert.ToInt32(GetPSObjectProperty(d, "MinimumIOPS"));
+ disk.VHDControllerType = (ControllerType)Enum.Parse(typeof(ControllerType), GetPSObjectProperty(d, "ControllerType").ToString());
+ disk.ControllerNumber = Convert.ToInt16(GetPSObjectProperty(d, "ControllerNumber"));
+ disk.ControllerLocation = Convert.ToInt16(GetPSObjectProperty(d, "ControllerLocation"));
+ disk.Path = GetPSObjectProperty(d, "Path").ToString();
+ disk.Name = GetPSObjectProperty(d, "Name").ToString();
+
+ GetVirtualHardDiskDetail(runSpace, disk.Path, ref disk);
+
+ disks.Add(disk);
+ }
+ }
+ return disks.ToArray();
+ }
+
+ internal void GetVirtualHardDiskDetail(Runspace runSpace, string path, ref VirtualHardDiskInfo disk)
+ {
+ if (!string.IsNullOrEmpty(path))
+ {
+ Command cmd = new Command("Get-VHD");
+ cmd.Parameters.Add("Path", path);
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if (result != null && result.Count > 0)
+ {
+ disk.DiskFormat = (VirtualHardDiskFormat)Enum.Parse(typeof(VirtualHardDiskFormat), GetPSObjectProperty(result[0], "VhdFormat").ToString());
+ disk.DiskType = (VirtualHardDiskType)Enum.Parse(typeof(VirtualHardDiskType), GetPSObjectProperty(result[0], "Type").ToString());
+ disk.ParentPath = GetPSObjectProperty(result[0], "ParentPath").ToString();
+ disk.MaxInternalSize = Convert.ToInt32(GetPSObjectProperty(result[0], "Size")) / Size1G;
+ disk.FileSize = Convert.ToInt32(GetPSObjectProperty(result[0], "FileSize")) / Size1G;
+ disk.Attached = Convert.ToBoolean(GetPSObjectProperty(result[0], "Attached"));
+ }
+ }
+ }
+
+
/*
public VirtualMachine GetVirtualMachineExInternal(runSpace, string vmId)
{
- ManagementObject objVm = wmi.GetWmiObject("msvm_ComputerSystem", "Name = '{0}'", vmId);
- if (objVm == null)
- return null;
+
- // general settings
- VirtualMachine vm = CreateVirtualMachineFromWmiObject(objVm);
-
- // CPU
- ManagementObject objCpu = wmi.GetWmiObject("Msvm_ProcessorSettingData", "InstanceID Like 'Microsoft:{0}%'", vmId);
- vm.CpuCores = Convert.ToInt32(objCpu["VirtualQuantity"]);
-
- // RAM
- ManagementObject objRam = wmi.GetWmiObject("Msvm_MemorySettingData", "InstanceID Like 'Microsoft:{0}%'", vmId);
- vm.RamSize = Convert.ToInt32(objRam["VirtualQuantity"]);
-
- // other settings
- ManagementObject objSettings = GetVirtualMachineSettingsObject(vmId);
-
- // BIOS (num lock)
- vm.NumLockEnabled = Convert.ToBoolean(objSettings["BIOSNumLock"]);
-
- // BIOS (boot order)
- // BootOrder = 0 - Boot from floppy, 1 - Boot from CD, 2 - Boot from disk, 3 - PXE Boot
- UInt16[] bootOrder = (UInt16[])objSettings["BootOrder"];
- vm.BootFromCD = (bootOrder[0] == 1);
-
- // DVD drive
- ManagementObject objDvd = wmi.GetWmiObject(
- "Msvm_ResourceAllocationSettingData", "ResourceSubType = 'Microsoft Synthetic DVD Drive'"
- + " and InstanceID Like 'Microsoft:{0}%'", vmId);
- vm.DvdDriveInstalled = (objDvd != null);
-
- // HDD
- ManagementObject objVhd = wmi.GetWmiObject(
- "Msvm_ResourceAllocationSettingData", "ResourceSubType = 'Microsoft Virtual Hard Disk'"
- + " and InstanceID like 'Microsoft:{0}%'", vmId);
-
- if (objVhd != null)
- {
- vm.VirtualHardDrivePath = ((string[])objVhd["Connection"])[0];
-
- // get VHD size
- VirtualHardDiskInfo vhdInfo = GetVirtualHardDiskInfo(vm.VirtualHardDrivePath);
- if (vhdInfo != null)
- vm.HddSize = Convert.ToInt32(vhdInfo.MaxInternalSize / Size1G);
- }
// network adapters
List nics = new List();
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VpsDetailsGeneral.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VpsDetailsGeneral.ascx.cs
index 050186fd..39fa7a08 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VpsDetailsGeneral.ascx.cs
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VpsDetailsGeneral.ascx.cs
@@ -155,7 +155,7 @@ namespace WebsitePanel.Portal.VPS
|| vm.State == VirtualMachineState.Saved))
buttons.Add(CreateActionButton("Start", "start.png"));
- if (vm.State == VirtualMachineState.Started)
+ if (vm.State == VirtualMachineState.Running)
{
if(vmi.RebootAllowed)
buttons.Add(CreateActionButton("Reboot", "reboot.png"));
@@ -165,12 +165,12 @@ namespace WebsitePanel.Portal.VPS
}
if (vmi.StartTurnOffAllowed
- && (vm.State == VirtualMachineState.Started
+ && (vm.State == VirtualMachineState.Running
|| vm.State == VirtualMachineState.Paused))
buttons.Add(CreateActionButton("TurnOff", "turnoff.png"));
if (vmi.PauseResumeAllowed
- && vm.State == VirtualMachineState.Started)
+ && vm.State == VirtualMachineState.Running)
buttons.Add(CreateActionButton("Pause", "pause.png"));
if (vmi.PauseResumeAllowed
@@ -178,7 +178,7 @@ namespace WebsitePanel.Portal.VPS
buttons.Add(CreateActionButton("Resume", "start2.png"));
if (vmi.ResetAllowed
- && (vm.State == VirtualMachineState.Started
+ && (vm.State == VirtualMachineState.Running
|| vm.State == VirtualMachineState.Paused))
buttons.Add(CreateActionButton("Reset", "reset2.png"));