From 8b3332e3c70fb6c5061c1caa6d4fea80e6d938f5 Mon Sep 17 00:00:00 2001 From: AlexanderTr Date: Fri, 20 Mar 2015 21:24:07 +0300 Subject: [PATCH 1/8] wsp-10323 Convert the VSP provider into one utilizing PowerShell. Step 6 Create\Delete\Export --- .../Helpers/BiosHelper.cs | 8 +- .../Helpers/DvdDriveHelper.cs | 8 +- .../Helpers/HardDriveHelper.cs | 6 +- .../Helpers/NetworkAdapterHelper.cs | 12 +- .../Helpers/SnapshotHelper.cs | 2 +- .../Helpers/VirtualMachineHelper.cs | 10 +- .../HyperV2012R2.cs | 403 ++++-------------- .../PowerShellManager.cs | 73 +--- 8 files changed, 121 insertions(+), 401 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/BiosHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/BiosHelper.cs index 21dafb52..fdb71f50 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/BiosHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/BiosHelper.cs @@ -23,7 +23,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { info.NumLockEnabled = true; @@ -56,7 +56,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { info.NumLockEnabled = Convert.ToBoolean(result[0].GetProperty("NumLockEnabled")); @@ -89,7 +89,7 @@ namespace WebsitePanel.Providers.Virtualization else cmd.Parameters.Add("FirstBootDevice", HardDriveHelper.GetPS(powerShell, vm.Name).FirstOrDefault()); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } // for others win and linux else @@ -102,7 +102,7 @@ namespace WebsitePanel.Providers.Virtualization : new[] { "IDE", "CD", "LegacyNetworkAdapter", "Floppy" }; cmd.Parameters.Add("StartupOrder", bootOrder); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/DvdDriveHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/DvdDriveHelper.cs index 012232ee..ce039f0c 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/DvdDriveHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/DvdDriveHelper.cs @@ -36,7 +36,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", vmName); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { @@ -57,7 +57,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("ControllerNumber", dvd.ControllerNumber); cmd.Parameters.Add("ControllerLocation", dvd.ControllerLocation); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } public static void Update(PowerShellManager powerShell, VirtualMachine vm, bool dvdDriveShouldBeInstalled) @@ -74,7 +74,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", vmName); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } public static void Remove(PowerShellManager powerShell, string vmName) @@ -87,7 +87,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("ControllerNumber", dvd.ControllerNumber); cmd.Parameters.Add("ControllerLocation", dvd.ControllerLocation); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/HardDriveHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/HardDriveHelper.cs index c8a951d6..b2e90e90 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/HardDriveHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/HardDriveHelper.cs @@ -47,7 +47,7 @@ namespace WebsitePanel.Providers.Virtualization // Command cmd = new Command("Get-VM"); - // Collection result = powerShell.Execute(cmd, false); + // Collection result = powerShell.Execute(cmd, true); // if (result == null || result.Count == 0) // return null; @@ -63,7 +63,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Get-VMHardDiskDrive"); cmd.Parameters.Add("VMName", vmname); - return powerShell.Execute(cmd, false); + return powerShell.Execute(cmd, true); } public static void GetVirtualHardDiskDetail(PowerShellManager powerShell, string path, ref VirtualHardDiskInfo disk) @@ -72,7 +72,7 @@ namespace WebsitePanel.Providers.Virtualization { Command cmd = new Command("Get-VHD"); cmd.Parameters.Add("Path", path); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { disk.DiskFormat = result[0].GetEnum("VhdFormat"); diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/NetworkAdapterHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/NetworkAdapterHelper.cs index bd6f9b37..f14f8f97 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/NetworkAdapterHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/NetworkAdapterHelper.cs @@ -26,7 +26,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Get-VMNetworkAdapter"); if (!string.IsNullOrEmpty(vmName)) cmd.Parameters.Add("VMName", vmName); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { foreach (PSObject psAdapter in result) @@ -89,8 +89,9 @@ namespace WebsitePanel.Providers.Virtualization else cmd.Parameters.Add("StaticMacAddress", macAddress); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } + public static void Delete(PowerShellManager powerShell, string vmName, string macAddress) { var networkAdapter = Get(powerShell, vmName, macAddress); @@ -98,12 +99,17 @@ namespace WebsitePanel.Providers.Virtualization if (networkAdapter == null) return; + Delete(powerShell, vmName, networkAdapter); + } + + public static void Delete(PowerShellManager powerShell, string vmName, VirtualMachineNetworkAdapter networkAdapter) + { Command cmd = new Command("Remove-VMNetworkAdapter"); cmd.Parameters.Add("VMName", vmName); cmd.Parameters.Add("Name", networkAdapter.Name); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/SnapshotHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/SnapshotHelper.cs index b5dee5c2..fa738ce0 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/SnapshotHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/SnapshotHelper.cs @@ -66,7 +66,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("Name", snapshot.Name); if (includeChilds) cmd.Parameters.Add("IncludeAllChildSnapshots", true); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/VirtualMachineHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/VirtualMachineHelper.cs index e7d05288..bd1291a1 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/VirtualMachineHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/VirtualMachineHelper.cs @@ -21,7 +21,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); cmd.Parameters.Add("Name", "HeartBeat"); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { var statusString = result[0].GetProperty("PrimaryOperationalStatus"); @@ -41,7 +41,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { procs = Convert.ToInt32(result[0].GetProperty("Count")); @@ -58,7 +58,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { info.DynamicMemoryEnabled = Convert.ToBoolean(result[0].GetProperty("DynamicMemoryEnabled")); @@ -81,7 +81,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("Reserve", Convert.ToInt64(cpuReserveSettings * 1000)); cmd.Parameters.Add("RelativeWeight", cpuWeightSettings); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } public static void UpdateMemory(PowerShellManager powerShell, VirtualMachine vm, long ramMB) @@ -91,7 +91,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", vm.Name); cmd.Parameters.Add("StartupBytes", ramMB * Constants.Size1M); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs index 7b1801ea..b8ad22ab 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs @@ -163,7 +163,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("Id", vmId); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); if (result != null && result.Count > 0) { vm.Name = result[0].GetProperty("Name").ToString(); @@ -232,7 +232,7 @@ namespace WebsitePanel.Providers.Virtualization { Command cmd = new Command("Get-VM"); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); foreach (PSObject current in result) { VirtualMachine vm = new VirtualMachine @@ -332,8 +332,9 @@ namespace WebsitePanel.Providers.Virtualization // Add new VM Command cmdNew = new Command("New-VM"); cmdNew.Parameters.Add("Name", vm.Name); + cmdNew.Parameters.Add("Generation", vm.Generation > 1 ? vm.Generation : 1); cmdNew.Parameters.Add("VHDPath", vm.VirtualHardDrivePath); - PowerShell.Execute(cmdNew, false); + PowerShell.Execute(cmdNew, true); // Set VM Command cmdSet = new Command("Set-VM"); @@ -350,7 +351,7 @@ namespace WebsitePanel.Providers.Virtualization } if (autoStopAction != AutomaticStopAction.Undefined) cmdSet.Parameters.Add("AutomaticStopAction", autoStopAction.ToString()); - PowerShell.Execute(cmdSet, false); + PowerShell.Execute(cmdSet, true); // Get created machine Id var createdMachine = GetVirtualMachines().FirstOrDefault(m => m.Name == vm.Name); @@ -396,168 +397,6 @@ namespace WebsitePanel.Providers.Virtualization return vm; } - - private void AddVirtualMachineDvdDrive(string vmId, ManagementObject objVM) - { - // load IDE 1 controller - ManagementObject objIDE1 = wmi.GetWmiObject( - "Msvm_ResourceAllocationSettingData", "ResourceSubType = 'Microsoft Emulated IDE Controller'" - + " and InstanceID Like 'Microsoft:{0}%' and Address = 1", vmId); - - // load default hard disk drive - ManagementObject objDefaultDvd = wmi.GetWmiObject( - "Msvm_ResourceAllocationSettingData", "ResourceSubType = 'Microsoft Synthetic DVD Drive'" - + " and InstanceID like '%Default'"); - ManagementObject objDvd = (ManagementObject)objDefaultDvd.Clone(); - objDvd["Parent"] = objIDE1.Path; - objDvd["Address"] = 0; - - // add DVD drive to VM resources - AddVirtualMachineResources(objVM, objDvd); - } - - private void AddNetworkAdapter(ManagementObject objVm, string switchId, string portName, string macAddress, string adapterName, bool legacyAdapter) - { - string nicClassName = GetNetworkAdapterClassName(legacyAdapter); - - string vmId = (string)objVm["Name"]; - - // check if already exists - ManagementObject objNic = wmi.GetWmiObject( - nicClassName, "InstanceID like 'Microsoft:{0}%' and Address = '{1}'", vmId, macAddress); - - if (objNic != null) - return; // exists - exit - - portName = String.Format("{0} - {1}", - portName, (adapterName == EXTERNAL_NETWORK_ADAPTER_NAME) ? "External" : "Private"); - - // Network service - ManagementObject objNetworkSvc = GetVirtualSwitchManagementService(); - - // default NIC - ManagementObject objDefaultNic = wmi.GetWmiObject(nicClassName, "InstanceID like '%Default'"); - - // find switch - ManagementObject objSwitch = wmi.GetWmiObject("msvm_VirtualSwitch", "Name = '{0}'", switchId); - - // create switch port - ManagementBaseObject inParams = objNetworkSvc.GetMethodParameters("CreateSwitchPort"); - inParams["VirtualSwitch"] = objSwitch; - inParams["Name"] = portName; - inParams["FriendlyName"] = portName; - inParams["ScopeOfResidence"] = ""; - - // invoke method - ManagementBaseObject outParams = objNetworkSvc.InvokeMethod("CreateSwitchPort", inParams, null); - - // process output parameters - ReturnCode code = (ReturnCode)Convert.ToInt32(outParams["ReturnValue"]); - if (code == ReturnCode.OK) - { - // created port - ManagementObject objPort = wmi.GetWmiObjectByPath((string)outParams["CreatedSwitchPort"]); - - // create NIC - ManagementObject objExtNic = (ManagementObject)objDefaultNic.Clone(); - objExtNic["Connection"] = new string[] { objPort.Path.Path }; - - if (!String.IsNullOrEmpty(macAddress)) - { - objExtNic["StaticMacAddress"] = true; - objExtNic["Address"] = macAddress; - } - else - { - objExtNic["StaticMacAddress"] = false; - } - objExtNic["ElementName"] = adapterName; - - if (!legacyAdapter) - objExtNic["VirtualSystemIdentifiers"] = new string[] { Guid.NewGuid().ToString("B") }; - - // add NIC - ManagementObject objCreatedExtNic = AddVirtualMachineResources(objVm, objExtNic); - } - } - - private string GetNetworkAdapterClassName(bool legacy) - { - return legacy ? "Msvm_EmulatedEthernetPortSettingData" : "Msvm_SyntheticEthernetPortSettingData"; - } - - private ManagementObject AddVirtualMachineResources(ManagementObject objVm, ManagementObject resource) - { - if (resource == null) - return resource; - - // request management service - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // add resources - string txtResource = resource.GetText(TextFormat.CimDtd20); - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("AddVirtualSystemResources"); - inParams["TargetSystem"] = objVm; - inParams["ResourceSettingData"] = new string[] { txtResource }; - ManagementBaseObject outParams = objVmsvc.InvokeMethod("AddVirtualSystemResources", inParams, null); - JobResult result = CreateJobResultFromWmiMethodResults(outParams); - - if (result.ReturnValue == ReturnCode.OK) - { - string[] wmiPaths = (string[])outParams["NewResources"]; - return wmi.GetWmiObjectByPath(wmiPaths[0]); - } - else if (result.ReturnValue == ReturnCode.JobStarted) - { - if (JobCompleted(result.Job)) - { - string[] wmiPaths = (string[])outParams["NewResources"]; - return wmi.GetWmiObjectByPath(wmiPaths[0]); - } - else - { - throw new Exception("Cannot add virtual machine resources"); - } - } - else - { - throw new Exception("Cannot add virtual machine resources: " + txtResource); - } - } - - private JobResult RemoveVirtualMachineResources(ManagementObject objVm, ManagementObject resource) - { - if (resource == null) - return null; - - // request management service - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // remove resources - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("RemoveVirtualSystemResources"); - inParams["TargetSystem"] = objVm; - inParams["ResourceSettingData"] = new string[] { resource.Path.Path }; - ManagementBaseObject outParams = objVmsvc.InvokeMethod("RemoveVirtualSystemResources", inParams, null); - JobResult result = CreateJobResultFromWmiMethodResults(outParams); - if (result.ReturnValue == ReturnCode.OK) - { - return result; - } - else if (result.ReturnValue == ReturnCode.JobStarted) - { - if (!JobCompleted(result.Job)) - { - throw new Exception("Cannot remove virtual machine resources"); - } - } - else - { - throw new Exception("Cannot remove virtual machine resources: " + resource.Path.Path); - } - - return result; - } - public JobResult ChangeVirtualMachineState(string vmId, VirtualMachineRequestedState newState) { HostedSolutionLog.LogStart("ChangeVirtualMachineState"); @@ -604,8 +443,8 @@ namespace WebsitePanel.Providers.Virtualization //cmd.Parameters.Add("AsJob"); paramList.ForEach(p => cmd.Parameters.Add(p)); - PowerShell.Execute(cmd, false); - jobResult = JobHelper.CreateSuccessResult(); + PowerShell.Execute(cmd, true); + jobResult = JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } catch (Exception ex) { @@ -633,7 +472,7 @@ namespace WebsitePanel.Providers.Virtualization if (force) cmd.Parameters.Add("Force"); //if (!string.IsNullOrEmpty(reason)) cmd.Parameters.Add("Reason", reason); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); } catch (Exception ex) { @@ -665,133 +504,58 @@ namespace WebsitePanel.Providers.Virtualization public JobResult RenameVirtualMachine(string vmId, string name) { - // load virtual machine - ManagementObject objVm = GetVirtualMachineObject(vmId); + var vm = GetVirtualMachine(vmId); - // load machine settings - ManagementObject objVmSettings = GetVirtualMachineSettingsObject(vmId); + Command cmdSet = new Command("Rename-VM"); + cmdSet.Parameters.Add("Name", vm.Name); + cmdSet.Parameters.Add("NewName", name); + PowerShell.Execute(cmdSet, true); - // rename machine - objVmSettings["ElementName"] = name; - - // save - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("ModifyVirtualSystem"); - inParams["ComputerSystem"] = objVm.Path.Path; - inParams["SystemSettingData"] = objVmSettings.GetText(TextFormat.CimDtd20); - ManagementBaseObject outParams = objVmsvc.InvokeMethod("ModifyVirtualSystem", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); + return JobHelper.CreateSuccessResult(); } public JobResult DeleteVirtualMachine(string vmId) { - // load virtual machine object - ManagementObject objVm = GetVirtualMachineObject(vmId); - - // check state - VirtualMachine vm = GetVirtualMachine(vmId); + var vm = GetVirtualMachineEx(vmId); // The virtual computer system must be in the powered off or saved state prior to calling this method. - if (vm.State == VirtualMachineState.Saved - || vm.State == VirtualMachineState.Off) - { - // delete network adapters and ports - DeleteNetworkAdapters(objVm); - - // destroy machine - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // get method - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("DestroyVirtualSystem"); - inParams["ComputerSystem"] = objVm; - - // invoke method - ManagementBaseObject outParams = objVmsvc.InvokeMethod("DestroyVirtualSystem", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); - } - else - { + if (vm.State != VirtualMachineState.Saved && vm.State != VirtualMachineState.Off) throw new Exception("The virtual computer system must be in the powered off or saved state prior to calling Destroy method."); + + // Delete network adapters and network switchesw + foreach (var networkAdapter in vm.Adapters) + { + NetworkAdapterHelper.Delete(PowerShell, vm.Name, networkAdapter); + + if (!string.IsNullOrEmpty(networkAdapter.SwitchName)) + DeleteSwitch(networkAdapter.SwitchName); } - } - private void DeleteNetworkAdapters(ManagementObject objVM) - { - string vmId = (string)objVM["Name"]; + object[] errors; - // delete synthetic adapters - foreach (ManagementObject objNic in wmi.GetWmiObjects("Msvm_SyntheticEthernetPortSettingData", "InstanceID like 'Microsoft:{0}%'", vmId)) - DeleteNetworkAdapter(objVM, objNic); + Command cmdSet = new Command("Remove-VM"); + cmdSet.Parameters.Add("Name", vm.Name); + cmdSet.Parameters.Add("Force"); + PowerShell.Execute(cmdSet, false, out errors); - // delete legacy adapters - foreach (ManagementObject objNic in wmi.GetWmiObjects("Msvm_EmulatedEthernetPortSettingData", "InstanceID like 'Microsoft:{0}%'", vmId)) - DeleteNetworkAdapter(objVM, objNic); - } + PowerShellManager.ExceptionIfErrors(errors); - private void DeleteNetworkAdapter(ManagementObject objVM, string macAddress) - { - // locate network adapter - ManagementObject objNic = wmi.GetWmiObject("CIM_ResourceAllocationSettingData", "Address = '{0}'", macAddress); - - // delete adapter - DeleteNetworkAdapter(objVM, objNic); - } - - private void DeleteNetworkAdapter(ManagementObject objVM, ManagementObject objNic) - { - if (objNic == null) - return; - - // delete corresponding switch port - string[] conn = (string[])objNic["Connection"]; - if (conn != null && conn.Length > 0) - DeleteSwitchPort(conn[0]); - - // delete adapter - RemoveVirtualMachineResources(objVM, objNic); - } - - private void DeleteSwitchPort(string portPath) - { - // Network service - ManagementObject objNetworkSvc = GetVirtualSwitchManagementService(); - - // create switch port - ManagementBaseObject inParams = objNetworkSvc.GetMethodParameters("DeleteSwitchPort"); - inParams["SwitchPort"] = portPath; - - // invoke method - objNetworkSvc.InvokeMethod("DeleteSwitchPort", inParams, null); + return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } public JobResult ExportVirtualMachine(string vmId, string exportPath) { - // load virtual machine object - ManagementObject objVm = GetVirtualMachineObject(vmId); - - // check state - VirtualMachine vm = GetVirtualMachine(vmId); + var vm = GetVirtualMachine(vmId); // The virtual computer system must be in the powered off or saved state prior to calling this method. - if (vm.State == VirtualMachineState.Off) - { - // export machine - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // get method - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("ExportVirtualSystem"); - inParams["ComputerSystem"] = objVm; - inParams["CopyVmState"] = true; - inParams["ExportDirectory"] = FileUtils.EvaluateSystemVariables(exportPath); - - // invoke method - ManagementBaseObject outParams = objVmsvc.InvokeMethod("ExportVirtualSystem", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); - } - else - { + if (vm.State != VirtualMachineState.Off) throw new Exception("The virtual computer system must be in the powered off or saved state prior to calling Export method."); - } + + Command cmdSet = new Command("Export-VM"); + cmdSet.Parameters.Add("Name", vm.Name); + cmdSet.Parameters.Add("Path", FileUtils.EvaluateSystemVariables(exportPath)); + PowerShell.Execute(cmdSet, true); + return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } #endregion @@ -808,7 +572,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Get-VMSnapshot"); cmd.Parameters.Add("VMName", vm.Name); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); if (result != null && result.Count > 0) { foreach (PSObject psSnapshot in result) @@ -833,7 +597,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Get-VMSnapshot"); cmd.Parameters.Add("Id", snapshotId); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); if (result != null && result.Count > 0) { return SnapshotHelper.GetFromPS(result[0]); @@ -857,7 +621,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Checkpoint-VM"); cmd.Parameters.Add("Name", vm.Name); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } catch (Exception ex) @@ -879,7 +643,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("Name", snapshot.Name); cmd.Parameters.Add("NewName", name); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); return JobHelper.CreateSuccessResult(); } catch (Exception ex) @@ -900,7 +664,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", vm.Name); cmd.Parameters.Add("Name", snapshot.Name); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); return JobHelper.CreateSuccessResult(); } catch (Exception ex) @@ -1042,7 +806,10 @@ namespace WebsitePanel.Providers.Virtualization if (!string.IsNullOrEmpty(computerName)) cmd.Parameters.Add("ComputerName", computerName); if (!string.IsNullOrEmpty(type)) cmd.Parameters.Add("SwitchType", type); - Collection result = PowerShell.Execute(cmd,false); + object[] errors; + Collection result = PowerShell.Execute(cmd, false, out errors); + PowerShellManager.ExceptionIfErrors(errors); + foreach (PSObject current in result) { VirtualSwitch sw = new VirtualSwitch(); @@ -1083,7 +850,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("SwitchType", "Private"); cmd.Parameters.Add("Name", name); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); if (result != null && result.Count > 0) { virtualSwitch = new VirtualSwitch(); @@ -1102,7 +869,7 @@ namespace WebsitePanel.Providers.Virtualization return virtualSwitch; } - public ReturnCode DeleteSwitch(string switchId) + public ReturnCode DeleteSwitch(string switchId) // switchId is SwitchName { HostedSolutionLog.LogStart("DeleteSwitch"); HostedSolutionLog.DebugInfo("switchId: {0}", switchId); @@ -1111,7 +878,8 @@ namespace WebsitePanel.Providers.Virtualization { Command cmd = new Command("Remove-VMSwitch"); cmd.Parameters.Add("Name", switchId); - PowerShell.Execute(cmd, false); + cmd.Parameters.Add("Force"); + PowerShell.Execute(cmd, true); } catch (Exception ex) { @@ -1438,13 +1206,6 @@ namespace WebsitePanel.Providers.Virtualization } } - private string GetPropertyValue(string propertyName, XmlDocument doc) - { - string xpath = string.Format(@"//PROPERTY[@NAME = '{0}']/VALUE/child::text()", propertyName); - XmlNode node = doc.SelectSingleNode(xpath); - return node != null ? node.Value : null; - } - public MountedDiskInfo MountVirtualHardDisk(string vhdPath) { ManagementObject objImgSvc = GetImageManagementService(); @@ -1687,7 +1448,7 @@ exit", Convert.ToInt32(objDisk["Index"]))); cmd.Parameters.Add("DestinationPath", destinationPath); cmd.Parameters.Add("VHDType", diskType.ToString()); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } catch (Exception ex) @@ -1840,53 +1601,41 @@ exit", Convert.ToInt32(objDisk["Index"]))); #region Jobs public ConcreteJob GetJob(string jobId) { - HostedSolutionLog.LogStart("GetJob"); - HostedSolutionLog.DebugInfo("jobId: {0}", jobId); + throw new NotImplementedException(); - Runspace runSpace = null; - ConcreteJob job; + //HostedSolutionLog.LogStart("GetJob"); + //HostedSolutionLog.DebugInfo("jobId: {0}", jobId); - try - { - Command cmd = new Command("Get-Job"); + //Runspace runSpace = null; + //ConcreteJob job; - if (!string.IsNullOrEmpty(jobId)) cmd.Parameters.Add("Id", jobId); + //try + //{ + // Command cmd = new Command("Get-Job"); - Collection result = PowerShell.Execute( cmd, false); - job = JobHelper.CreateFromPSObject(result); - } - catch (Exception ex) - { - HostedSolutionLog.LogError("GetJob", ex); - throw; - } + // if (!string.IsNullOrEmpty(jobId)) cmd.Parameters.Add("Id", jobId); - HostedSolutionLog.LogEnd("GetJob"); - return job; + // Collection result = PowerShell.Execute(cmd, true); + // job = JobHelper.CreateFromPSObject(result); + //} + //catch (Exception ex) + //{ + // HostedSolutionLog.LogError("GetJob", ex); + // throw; + //} + + //HostedSolutionLog.LogEnd("GetJob"); + //return job; } public List GetAllJobs() { - List jobs = new List(); - - ManagementObjectCollection objJobs = wmi.GetWmiObjects("CIM_ConcreteJob"); - foreach (ManagementObject objJob in objJobs) - jobs.Add(CreateJobFromWmiObject(objJob)); - - return jobs; + throw new NotImplementedException(); } public ChangeJobStateReturnCode ChangeJobState(string jobId, ConcreteJobRequestedState newState) { - ManagementObject objJob = GetJobWmiObject(jobId); - - // get method - ManagementBaseObject inParams = objJob.GetMethodParameters("RequestStateChange"); - inParams["RequestedState"] = (Int32)newState; - - // invoke method - ManagementBaseObject outParams = objJob.InvokeMethod("RequestStateChange", inParams, null); - return (ChangeJobStateReturnCode)Convert.ToInt32(outParams["ReturnValue"]); + throw new NotImplementedException(); } #endregion @@ -2504,7 +2253,7 @@ exit", Convert.ToInt32(objDisk["Index"]))); private PowerShellManager _powerShell; protected PowerShellManager PowerShell { - get { return _powerShell ?? (_powerShell = new PowerShellManager()); } + get { return _powerShell ?? (_powerShell = new PowerShellManager(ServerNameSettings)); } } #endregion diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/PowerShellManager.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/PowerShellManager.cs index 949b08bd..74298da0 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/PowerShellManager.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/PowerShellManager.cs @@ -12,12 +12,14 @@ namespace WebsitePanel.Providers.Virtualization { public class PowerShellManager : IDisposable { + private readonly string _remoteComputerName; protected static InitialSessionState session = null; protected Runspace RunSpace { get; set; } - public PowerShellManager() + public PowerShellManager(string remoteComputerName) { + _remoteComputerName = remoteComputerName; OpenRunspace(); } @@ -61,24 +63,27 @@ namespace WebsitePanel.Providers.Virtualization return Execute(cmd, true); } - public Collection Execute(Command cmd, bool useDomainController) + public Collection Execute(Command cmd, bool addComputerNameParameter) { object[] errors; - return Execute(cmd, useDomainController, out errors); + return Execute(cmd, addComputerNameParameter, out errors); } - public Collection Execute(Command cmd, out object[] errors) - { - return Execute(cmd, true, out errors); - } - - public Collection Execute(Command cmd, bool useDomainController, out object[] errors) + public Collection Execute(Command cmd, bool addComputerNameParameter, out object[] errors) { HostedSolutionLog.LogStart("Execute"); List errorList = new List(); HostedSolutionLog.DebugCommand(cmd); Collection results = null; + + // Add computerName parameter to command if it is remote server + if (addComputerNameParameter) + { + if (!string.IsNullOrEmpty(_remoteComputerName)) + cmd.Parameters.Add("ComputerName", _remoteComputerName); + } + // Create a pipeline Pipeline pipeLine = RunSpace.CreatePipeline(); using (pipeLine) @@ -88,6 +93,8 @@ namespace WebsitePanel.Providers.Virtualization // Execute the pipeline and save the objects returned. results = pipeLine.Invoke(); + // Only non-terminating errors are delivered here. + // Terminating errors raise exceptions instead. // Log out any errors in the pipeline execution // NOTE: These errors are NOT thrown as exceptions! // Be sure to check this to ensure that no errors @@ -108,52 +115,10 @@ namespace WebsitePanel.Providers.Virtualization return results; } - - /// - /// Returns the identity of the object from the shell execution result - /// - /// - /// - public static string GetResultObjectIdentity(Collection result) + public static void ExceptionIfErrors(object[] errors) { - HostedSolutionLog.LogStart("GetResultObjectIdentity"); - if (result == null) - throw new ArgumentNullException("result", "Execution result is not specified"); - - if (result.Count < 1) - throw new ArgumentException("Execution result is empty", "result"); - - if (result.Count > 1) - throw new ArgumentException("Execution result contains more than one object", "result"); - - PSMemberInfo info = result[0].Members["Identity"]; - if (info == null) - throw new ArgumentException("Execution result does not contain Identity property", "result"); - - string ret = info.Value.ToString(); - HostedSolutionLog.LogEnd("GetResultObjectIdentity"); - return ret; - } - - public static string GetResultObjectDN(Collection result) - { - HostedSolutionLog.LogStart("GetResultObjectDN"); - if (result == null) - throw new ArgumentNullException("result", "Execution result is not specified"); - - if (result.Count < 1) - throw new ArgumentException("Execution result does not contain any object"); - - if (result.Count > 1) - throw new ArgumentException("Execution result contains more than one object"); - - PSMemberInfo info = result[0].Members["DistinguishedName"]; - if (info == null) - throw new ArgumentException("Execution result does not contain DistinguishedName property", "result"); - - string ret = info.Value.ToString(); - HostedSolutionLog.LogEnd("GetResultObjectDN"); - return ret; + if (errors != null && errors.Length > 0) + throw new Exception("Invoke error: " + string.Join("; ", errors.Select(e => e.ToString()))); } } } From e96a2195b0aecc38769ccb58b925a55905474b91 Mon Sep 17 00:00:00 2001 From: AlexanderTr Date: Sun, 22 Mar 2015 07:35:09 +0300 Subject: [PATCH 2/8] wsp-10323 Convert the VSP provider into one utilizing PowerShell. Step 7 --- .../Constants.cs | 10 ++ .../Helpers/NetworkAdapterHelper.cs | 14 +- .../HyperV2012R2.cs | 168 +++++++----------- 3 files changed, 80 insertions(+), 112 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Constants.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Constants.cs index 7821a6fd..b487d4cf 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Constants.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Constants.cs @@ -8,6 +8,16 @@ namespace WebsitePanel.Providers.Virtualization { public static class Constants { + public const string CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG = "WebsitePanel.HyperV.UseDiskPartClearReadOnlyFlag"; + public const string WMI_VIRTUALIZATION_NAMESPACE = @"root\virtualization\v2"; + public const string WMI_CIMV2_NAMESPACE = @"root\cimv2"; + + public const string LIBRARY_INDEX_FILE_NAME = "index.xml"; + + public const string EXTERNAL_NETWORK_ADAPTER_NAME = "External Network Adapter"; + public const string PRIVATE_NETWORK_ADAPTER_NAME = "Private Network Adapter"; + public const string MANAGEMENT_NETWORK_ADAPTER_NAME = "Management Network Adapter"; + public const Int64 Size1G = 0x40000000; public const Int64 Size1M = 0x100000; } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/NetworkAdapterHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/NetworkAdapterHelper.cs index f14f8f97..f2c99ce5 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/NetworkAdapterHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/NetworkAdapterHelper.cs @@ -10,15 +10,7 @@ using System.Threading.Tasks; namespace WebsitePanel.Providers.Virtualization { public static class NetworkAdapterHelper - { - #region Constants - - private const string EXTERNAL_NETWORK_ADAPTER_NAME = "External Network Adapter"; - private const string PRIVATE_NETWORK_ADAPTER_NAME = "Private Network Adapter"; - private const string MANAGEMENT_NETWORK_ADAPTER_NAME = "Management Network Adapter"; - - #endregion - + { public static VirtualMachineNetworkAdapter[] Get(PowerShellManager powerShell, string vmName) { List adapters = new List(); @@ -60,7 +52,7 @@ namespace WebsitePanel.Providers.Virtualization else if (vm.ExternalNetworkEnabled && !String.IsNullOrEmpty(vm.ExternalNicMacAddress) && Get(powerShell,vm.Name,vm.ExternalNicMacAddress) == null) { - Add(powerShell, vm.Name, vm.ExternalSwitchId, vm.ExternalNicMacAddress, EXTERNAL_NETWORK_ADAPTER_NAME, vm.LegacyNetworkAdapter); + Add(powerShell, vm.Name, vm.ExternalSwitchId, vm.ExternalNicMacAddress, Constants.EXTERNAL_NETWORK_ADAPTER_NAME, vm.LegacyNetworkAdapter); } // Private NIC @@ -72,7 +64,7 @@ namespace WebsitePanel.Providers.Virtualization else if (vm.PrivateNetworkEnabled && !String.IsNullOrEmpty(vm.PrivateNicMacAddress) && Get(powerShell, vm.Name, vm.PrivateNicMacAddress) == null) { - Add(powerShell, vm.Name, vm.PrivateSwitchId, vm.PrivateNicMacAddress, PRIVATE_NETWORK_ADAPTER_NAME, vm.LegacyNetworkAdapter); + Add(powerShell, vm.Name, vm.PrivateSwitchId, vm.PrivateNicMacAddress, Constants.PRIVATE_NETWORK_ADAPTER_NAME, vm.LegacyNetworkAdapter); } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs index b8ad22ab..8d8d9cdf 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs @@ -57,25 +57,6 @@ namespace WebsitePanel.Providers.Virtualization { public class HyperV2012R2 : HostingServiceProviderBase, IVirtualizationServer { - #region Constants - private const string CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG = "WebsitePanel.HyperV.UseDiskPartClearReadOnlyFlag"; - private const string WMI_VIRTUALIZATION_NAMESPACE = @"root\virtualization\v2"; - private const string WMI_CIMV2_NAMESPACE = @"root\cimv2"; - - private const int SWITCH_PORTS_NUMBER = 1024; - private const string LIBRARY_INDEX_FILE_NAME = "index.xml"; - private const string EXTERNAL_NETWORK_ADAPTER_NAME = "External Network Adapter"; - private const string PRIVATE_NETWORK_ADAPTER_NAME = "Private Network Adapter"; - private const string MANAGEMENT_NETWORK_ADAPTER_NAME = "Management Network Adapter"; - - private const string KVP_RAM_SUMMARY_KEY = "VM-RAM-Summary"; - private const string KVP_HDD_SUMMARY_KEY = "VM-HDD-Summary"; - - private const Int64 Size1G = 0x40000000; - private const Int64 Size1M = 0x100000; - - #endregion - #region Provider Settings protected string ServerNameSettings { @@ -119,16 +100,17 @@ namespace WebsitePanel.Providers.Virtualization #endregion #region Fields - private Wmi _wmi = null; + private PowerShellManager _powerShell; + protected PowerShellManager PowerShell + { + get { return _powerShell ?? (_powerShell = new PowerShellManager(ServerNameSettings)); } + } + + private Wmi _wmi; private Wmi wmi { - get - { - if (_wmi == null) - _wmi = new Wmi(ServerNameSettings, WMI_VIRTUALIZATION_NAMESPACE); - return _wmi; - } + get { return _wmi ?? (_wmi = new Wmi(ServerNameSettings, Constants.WMI_VIRTUALIZATION_NAMESPACE)); } } #endregion @@ -169,7 +151,7 @@ namespace WebsitePanel.Providers.Virtualization vm.Name = result[0].GetProperty("Name").ToString(); vm.State = result[0].GetEnum("State"); vm.CpuUsage = ConvertNullableToInt32(result[0].GetProperty("CpuUsage")); - vm.RamUsage = ConvertNullableToInt64(result[0].GetProperty("MemoryAssigned")) / Size1M; + vm.RamUsage = ConvertNullableToInt64(result[0].GetProperty("MemoryAssigned")) / Constants.Size1M; vm.Uptime = Convert.ToInt64(result[0].GetProperty("UpTime").TotalMilliseconds); vm.Status = result[0].GetProperty("Status").ToString(); vm.ReplicationState = result[0].GetProperty("ReplicationState").ToString(); @@ -203,7 +185,7 @@ namespace WebsitePanel.Providers.Virtualization if (vm.Disks != null && vm.Disks.GetLength(0) > 0) { vm.VirtualHardDrivePath = vm.Disks[0].Path; - vm.HddSize = Convert.ToInt32(vm.Disks[0].FileSize / Size1G); + vm.HddSize = Convert.ToInt32(vm.Disks[0].FileSize / Constants.Size1G); } // network adapters @@ -219,7 +201,6 @@ namespace WebsitePanel.Providers.Virtualization HostedSolutionLog.LogEnd("GetVirtualMachine"); return vm; - } public List GetVirtualMachines() @@ -557,6 +538,7 @@ namespace WebsitePanel.Providers.Virtualization PowerShell.Execute(cmdSet, true); return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } + #endregion #region Snapshots @@ -895,7 +877,7 @@ namespace WebsitePanel.Providers.Virtualization #region Library public LibraryItem[] GetLibraryItems(string path) { - path = Path.Combine(FileUtils.EvaluateSystemVariables(path), LIBRARY_INDEX_FILE_NAME); + path = Path.Combine(FileUtils.EvaluateSystemVariables(path), Constants.LIBRARY_INDEX_FILE_NAME); // convert to UNC if it is a remote computer path = ConvertToUNC(path); @@ -971,14 +953,6 @@ namespace WebsitePanel.Providers.Virtualization return items.ToArray(); } - private string ConvertToUNC(string path) - { - if (String.IsNullOrEmpty(ServerNameSettings) - || path.StartsWith(@"\\")) - return path; - - return String.Format(@"\\{0}\{1}", ServerNameSettings, path.Replace(":", "$")); - } #endregion #region KVP @@ -1208,6 +1182,39 @@ namespace WebsitePanel.Providers.Virtualization public MountedDiskInfo MountVirtualHardDisk(string vhdPath) { + //MountedDiskInfo diskInfo = new MountedDiskInfo(); + //vhdPath = FileUtils.EvaluateSystemVariables(vhdPath); + + //// Mount disk + //Command cmd = new Command("Mount-VHD"); + + //cmd.Parameters.Add("Path", vhdPath); + //cmd.Parameters.Add("PassThru"); + + //// Get disk address + //var result = PowerShell.Execute(cmd, true); + + //try + //{ + // if (result == null || result.Count == 0) + // throw new Exception("Failed to mount disk"); + + // diskInfo.DiskAddress = result[0].GetString("DiskNumber"); + + // // Get disk volumes + + //} + //catch (Exception ex) + //{ + // // unmount disk + // UnmountVirtualHardDisk(vhdPath); + + // // throw error + // throw ex; + //} + + //return diskInfo; + ManagementObject objImgSvc = GetImageManagementService(); // get method params @@ -1264,11 +1271,11 @@ namespace WebsitePanel.Providers.Virtualization // check if DiskPart must be used to bring disk online and clear read-only flag bool useDiskPartToClearReadOnly = false; - if (ConfigurationManager.AppSettings[CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG] != null) - useDiskPartToClearReadOnly = Boolean.Parse(ConfigurationManager.AppSettings[CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG]); + if (ConfigurationManager.AppSettings[Constants.CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG] != null) + useDiskPartToClearReadOnly = Boolean.Parse(ConfigurationManager.AppSettings[Constants.CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG]); // determine disk index for DiskPart - Wmi cimv2 = new Wmi(ServerNameSettings, WMI_CIMV2_NAMESPACE); + Wmi cimv2 = new Wmi(ServerNameSettings, Constants.WMI_CIMV2_NAMESPACE); ManagementObject objDisk = cimv2.GetWmiObject("win32_diskdrive", "Model='Msft Virtual Disk SCSI Disk Device' and ScsiTargetID={0} and ScsiLogicalUnit={1} and scsiPort={2}", targetId, lun, portNumber); @@ -1401,29 +1408,23 @@ exit", Convert.ToInt32(objDisk["Index"]))); public ReturnCode UnmountVirtualHardDisk(string vhdPath) { - ManagementObject objImgSvc = GetImageManagementService(); + Command cmd = new Command("Dismount-VHD"); - // get method params - ManagementBaseObject inParams = objImgSvc.GetMethodParameters("Unmount"); - inParams["Path"] = FileUtils.EvaluateSystemVariables(vhdPath); + cmd.Parameters.Add("Path", FileUtils.EvaluateSystemVariables(vhdPath)); - ManagementBaseObject outParams = (ManagementBaseObject)objImgSvc.InvokeMethod("Unmount", inParams, null); - return (ReturnCode)Convert.ToInt32(outParams["ReturnValue"]); + PowerShell.Execute(cmd, true); + return ReturnCode.OK; } public JobResult ExpandVirtualHardDisk(string vhdPath, UInt64 sizeGB) { - const UInt64 Size1G = 0x40000000; + Command cmd = new Command("Resize-VHD"); - ManagementObject objImgSvc = GetImageManagementService(); + cmd.Parameters.Add("Path", FileUtils.EvaluateSystemVariables(vhdPath)); + cmd.Parameters.Add("SizeBytes", sizeGB * Constants.Size1G); - // get method params - ManagementBaseObject inParams = objImgSvc.GetMethodParameters("ExpandVirtualHardDisk"); - inParams["Path"] = FileUtils.EvaluateSystemVariables(vhdPath); - inParams["MaxInternalSize"] = sizeGB * Size1G; - - ManagementBaseObject outParams = (ManagementBaseObject)objImgSvc.InvokeMethod("ExpandVirtualHardDisk", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); + PowerShell.Execute(cmd, true); + return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } public JobResult ConvertVirtualHardDisk(string sourcePath, string destinationPath, VirtualHardDiskType diskType) @@ -1888,15 +1889,6 @@ exit", Convert.ToInt32(objDisk["Index"]))); return value == null ? 0 : Convert.ToInt64(value); } - //protected VirtualMachineSnapshot GetSnapshotById(string id) - //{ - // var vms = GetVirtualMachines(); - // var allSnapshots = vms.SelectMany(vm => GetVirtualMachineSnapshots(vm.Id.ToString())); - - // return allSnapshots.FirstOrDefault(s => s.Id == id); - //} - - protected JobResult CreateJobResultFromWmiMethodResults(ManagementBaseObject outParams) { JobResult result = new JobResult(); @@ -1918,21 +1910,11 @@ exit", Convert.ToInt32(objDisk["Index"]))); return result; } - private ManagementObject GetJobWmiObject(string id) - { - return wmi.GetWmiObject("msvm_ConcreteJob", "InstanceID = '{0}'", id); - } - private ManagementObject GetVirtualSystemManagementService() { return wmi.GetWmiObject("msvm_VirtualSystemManagementService"); } - private ManagementObject GetVirtualSwitchManagementService() - { - return wmi.GetWmiObject("msvm_VirtualSwitchManagementService"); - } - protected ManagementObject GetImageManagementService() { return wmi.GetWmiObject("msvm_ImageManagementService"); @@ -1949,18 +1931,13 @@ exit", Convert.ToInt32(objDisk["Index"]))); wmi.GetWmiObject("Msvm_VirtualSystemSettingData", "InstanceID = '{0}'", "Microsoft:" + snapshotId); } - - - - private VirtualSwitch CreateSwitchFromWmiObject(ManagementObject objSwitch) + private string ConvertToUNC(string path) { - if (objSwitch == null || objSwitch.Properties.Count == 0) - return null; + if (String.IsNullOrEmpty(ServerNameSettings) + || path.StartsWith(@"\\")) + return path; - VirtualSwitch sw = new VirtualSwitch(); - sw.SwitchId = (string)objSwitch["Name"]; - sw.Name = (string)objSwitch["ElementName"]; - return sw; + return String.Format(@"\\{0}\{1}", ServerNameSettings, path.Replace(":", "$")); } private ConcreteJob CreateJobFromWmiObject(ManagementBaseObject objJob) @@ -2061,7 +2038,7 @@ exit", Convert.ToInt32(objDisk["Index"]))); return File.Exists(path); else { - Wmi cimv2 = new Wmi(ServerNameSettings, WMI_CIMV2_NAMESPACE); + Wmi cimv2 = new Wmi(ServerNameSettings, Constants.WMI_CIMV2_NAMESPACE); ManagementObject objFile = cimv2.GetWmiObject("CIM_Datafile", "Name='{0}'", path.Replace("\\", "\\\\")); return (objFile != null); } @@ -2073,7 +2050,7 @@ exit", Convert.ToInt32(objDisk["Index"]))); return Directory.Exists(path); else { - Wmi cimv2 = new Wmi(ServerNameSettings, WMI_CIMV2_NAMESPACE); + Wmi cimv2 = new Wmi(ServerNameSettings, Constants.WMI_CIMV2_NAMESPACE); ManagementObject objDir = cimv2.GetWmiObject("Win32_Directory", "Name='{0}'", path.Replace("\\", "\\\\")); return (objDir != null); } @@ -2097,7 +2074,7 @@ exit", Convert.ToInt32(objDisk["Index"]))); return false; // copy using WMI - Wmi cimv2 = new Wmi(ServerNameSettings, WMI_CIMV2_NAMESPACE); + Wmi cimv2 = new Wmi(ServerNameSettings, Constants.WMI_CIMV2_NAMESPACE); ManagementObject objFile = cimv2.GetWmiObject("CIM_Datafile", "Name='{0}'", sourceFileName.Replace("\\", "\\\\")); if (objFile == null) throw new Exception("Source file does not exists: " + sourceFileName); @@ -2247,17 +2224,6 @@ exit", Convert.ToInt32(objDisk["Index"]))); return !String.IsNullOrEmpty(connString); } #endregion Hyper-V Cloud - - #region PowerShell integration - - private PowerShellManager _powerShell; - protected PowerShellManager PowerShell - { - get { return _powerShell ?? (_powerShell = new PowerShellManager(ServerNameSettings)); } - } - - #endregion - - + } -} +} \ No newline at end of file From a26a67cbf7f81ea3a7e6183782e1e428a9c7fa02 Mon Sep 17 00:00:00 2001 From: me Date: Mon, 23 Mar 2015 09:12:14 +0400 Subject: [PATCH 3/8] wsp-10323 bugfix + Step 8 --- .../VirtualizationServerProxy.cs | 79 +-- .../esVirtualizationServer.asmx.cs | 7 +- .../Virtualization/MemoryInfo.cs | 6 +- .../Virtualization/VirtualMachine.cs | 4 +- .../Helpers/VirtualMachineHelper.cs | 16 +- .../HyperV2012R2.cs | 569 +++++------------- .../IVirtualMachineCreateControl.cs | 52 ++ .../WebsitePanel/UserControls/Gauge.ascx.cs | 10 +- .../UserControls/QuotaViewer.ascx.cs | 2 +- .../WebsitePanel/VPS/VdcCreateServer.ascx | 2 + .../WebsitePanel/VPS/VdcCreateServer.ascx.cs | 38 ++ .../VPS/VdcCreateServer.ascx.designer.cs | 49 +- .../WebsitePanel.Portal.Modules.csproj | 1 + 13 files changed, 297 insertions(+), 538 deletions(-) create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Code/ProviderControls/IVirtualMachineCreateControl.cs diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/VirtualizationServerProxy.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/VirtualizationServerProxy.cs index a206a34d..26699aa8 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/VirtualizationServerProxy.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/VirtualizationServerProxy.cs @@ -29,7 +29,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.3074 +// Runtime Version:2.0.50727.5466 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -40,7 +40,6 @@ // This source code was auto-generated by wsdl, Version=2.0.50727.42. // namespace WebsitePanel.EnterpriseServer { - using System.Xml.Serialization; using System.Web.Services; using System.ComponentModel; @@ -50,7 +49,7 @@ namespace WebsitePanel.EnterpriseServer { using WebsitePanel.Providers; using WebsitePanel.Providers.Common; using WebsitePanel.Providers.Virtualization; - using WebsitePanel.Providers.ResultObjects; + using WebsitePanel.Providers.ResultObjects; /// [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")] @@ -171,9 +170,11 @@ namespace WebsitePanel.EnterpriseServer { private System.Threading.SendOrPostCallback SendVirtualMachineSummaryLetterOperationCompleted; /// - public esVirtualizationServer() { + public esVirtualizationServer() + { this.Url = "http://127.0.0.1:9002/esVirtualizationServer.asmx"; } + /// public event GetVirtualMachinesCompletedEventHandler GetVirtualMachinesCompleted; @@ -339,7 +340,7 @@ namespace WebsitePanel.EnterpriseServer { /// public event SendVirtualMachineSummaryLetterCompletedEventHandler SendVirtualMachineSummaryLetterCompleted; - + /// [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/GetVirtualMachines", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public VirtualMachineMetaItemsPaged GetVirtualMachines(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows, bool recursive) { @@ -949,8 +950,8 @@ namespace WebsitePanel.EnterpriseServer { } /// - [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/GetOperatingSystemTemplatesByServi" + - "ceId", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/GetOperatingSystemTemplatesByService" + + "Id", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public LibraryItem[] GetOperatingSystemTemplatesByServiceId(int serviceId) { object[] results = this.Invoke("GetOperatingSystemTemplatesByServiceId", new object[] { serviceId}); @@ -1133,6 +1134,7 @@ namespace WebsitePanel.EnterpriseServer { string osTemplateFile, string password, string summaryLetterEmail, + int generation, int cpuCores, int ramMB, int hddGB, @@ -1159,6 +1161,7 @@ namespace WebsitePanel.EnterpriseServer { osTemplateFile, password, summaryLetterEmail, + generation, cpuCores, ramMB, hddGB, @@ -1189,6 +1192,7 @@ namespace WebsitePanel.EnterpriseServer { string osTemplateFile, string password, string summaryLetterEmail, + int generation, int cpuCores, int ramMB, int hddGB, @@ -1217,6 +1221,7 @@ namespace WebsitePanel.EnterpriseServer { osTemplateFile, password, summaryLetterEmail, + generation, cpuCores, ramMB, hddGB, @@ -1252,6 +1257,7 @@ namespace WebsitePanel.EnterpriseServer { string osTemplateFile, string password, string summaryLetterEmail, + int generation, int cpuCores, int ramMB, int hddGB, @@ -1272,7 +1278,7 @@ namespace WebsitePanel.EnterpriseServer { int privateAddressesNumber, bool randomPrivateAddresses, string[] privateAddresses) { - this.CreateVirtualMachineAsync(packageId, hostname, osTemplateFile, password, summaryLetterEmail, cpuCores, ramMB, hddGB, snapshots, dvdInstalled, bootFromCD, numLock, startShutdownAllowed, pauseResumeAllowed, rebootAllowed, resetAllowed, reinstallAllowed, externalNetworkEnabled, externalAddressesNumber, randomExternalAddresses, externalAddresses, privateNetworkEnabled, privateAddressesNumber, randomPrivateAddresses, privateAddresses, null); + this.CreateVirtualMachineAsync(packageId, hostname, osTemplateFile, password, summaryLetterEmail, generation, cpuCores, ramMB, hddGB, snapshots, dvdInstalled, bootFromCD, numLock, startShutdownAllowed, pauseResumeAllowed, rebootAllowed, resetAllowed, reinstallAllowed, externalNetworkEnabled, externalAddressesNumber, randomExternalAddresses, externalAddresses, privateNetworkEnabled, privateAddressesNumber, randomPrivateAddresses, privateAddresses, null); } /// @@ -1282,6 +1288,7 @@ namespace WebsitePanel.EnterpriseServer { string osTemplateFile, string password, string summaryLetterEmail, + int generation, int cpuCores, int ramMB, int hddGB, @@ -1312,6 +1319,7 @@ namespace WebsitePanel.EnterpriseServer { osTemplateFile, password, summaryLetterEmail, + generation, cpuCores, ramMB, hddGB, @@ -2462,8 +2470,8 @@ namespace WebsitePanel.EnterpriseServer { } /// - [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/AddVirtualMachineExternalIPAddress" + - "es", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/AddVirtualMachineExternalIPAddresses" + + "", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public ResultObject AddVirtualMachineExternalIPAddresses(int itemId, bool selectRandom, int addressesNumber, int[] addressId) { object[] results = this.Invoke("AddVirtualMachineExternalIPAddresses", new object[] { itemId, @@ -2513,8 +2521,8 @@ namespace WebsitePanel.EnterpriseServer { } /// - [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/SetVirtualMachinePrimaryExternalIP" + - "Address", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/SetVirtualMachinePrimaryExternalIPAd" + + "dress", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public ResultObject SetVirtualMachinePrimaryExternalIPAddress(int itemId, int addressId) { object[] results = this.Invoke("SetVirtualMachinePrimaryExternalIPAddress", new object[] { itemId, @@ -2558,8 +2566,8 @@ namespace WebsitePanel.EnterpriseServer { } /// - [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/DeleteVirtualMachineExternalIPAddr" + - "esses", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/DeleteVirtualMachineExternalIPAddres" + + "ses", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public ResultObject DeleteVirtualMachineExternalIPAddresses(int itemId, int[] addressId) { object[] results = this.Invoke("DeleteVirtualMachineExternalIPAddresses", new object[] { itemId, @@ -2644,8 +2652,7 @@ namespace WebsitePanel.EnterpriseServer { } /// - [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/AddVirtualMachinePrivateIPAddresse" + - "s", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/AddVirtualMachinePrivateIPAddresses", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public ResultObject AddVirtualMachinePrivateIPAddresses(int itemId, bool selectRandom, int addressesNumber, string[] addresses) { object[] results = this.Invoke("AddVirtualMachinePrivateIPAddresses", new object[] { itemId, @@ -2695,8 +2702,8 @@ namespace WebsitePanel.EnterpriseServer { } /// - [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/SetVirtualMachinePrimaryPrivateIPA" + - "ddress", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/SetVirtualMachinePrimaryPrivateIPAdd" + + "ress", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public ResultObject SetVirtualMachinePrimaryPrivateIPAddress(int itemId, int addressId) { object[] results = this.Invoke("SetVirtualMachinePrimaryPrivateIPAddress", new object[] { itemId, @@ -2740,8 +2747,8 @@ namespace WebsitePanel.EnterpriseServer { } /// - [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/DeleteVirtualMachinePrivateIPAddre" + - "sses", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/DeleteVirtualMachinePrivateIPAddress" + + "es", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public ResultObject DeleteVirtualMachinePrivateIPAddresses(int itemId, int[] addressId) { object[] results = this.Invoke("DeleteVirtualMachinePrivateIPAddresses", new object[] { itemId, @@ -2826,8 +2833,7 @@ namespace WebsitePanel.EnterpriseServer { } /// - [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/UpdateVirtualMachineUserPermission" + - "s", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/UpdateVirtualMachineUserPermissions", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public int UpdateVirtualMachineUserPermissions(int itemId, VirtualMachinePermission[] permissions) { object[] results = this.Invoke("UpdateVirtualMachineUserPermissions", new object[] { itemId, @@ -3112,36 +3118,8 @@ namespace WebsitePanel.EnterpriseServer { public new void CancelAsync(object userState) { base.CancelAsync(userState); } - } - - - - - - - - - - - - - - - - - - - - - - - - - - - /// [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")] public delegate void GetVirtualMachinesCompletedEventHandler(object sender, GetVirtualMachinesCompletedEventArgs e); @@ -4602,5 +4580,4 @@ namespace WebsitePanel.EnterpriseServer { } } } - } diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esVirtualizationServer.asmx.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esVirtualizationServer.asmx.cs index cb5e7677..5ad2523e 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esVirtualizationServer.asmx.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esVirtualizationServer.asmx.cs @@ -37,7 +37,10 @@ using System.ComponentModel; using WebsitePanel.Providers.Common; using WebsitePanel.Providers.ResultObjects; using Microsoft.Web.Services3; - +using WebsitePanel.Providers; +using WebsitePanel.Providers.Common; +using WebsitePanel.Providers.Virtualization; +using WebsitePanel.Providers.ResultObjects; using WebsitePanel.Providers.Virtualization; namespace WebsitePanel.EnterpriseServer @@ -183,7 +186,7 @@ namespace WebsitePanel.EnterpriseServer [WebMethod] public IntResult CreateVirtualMachine(int packageId, string hostname, string osTemplateFile, string password, string summaryLetterEmail, - int cpuCores, int ramMB, int hddGB, int snapshots, bool dvdInstalled, bool bootFromCD, bool numLock, + int generation, int cpuCores, int ramMB, int hddGB, int snapshots, bool dvdInstalled, bool bootFromCD, bool numLock, bool startShutdownAllowed, bool pauseResumeAllowed, bool rebootAllowed, bool resetAllowed, bool reinstallAllowed, bool externalNetworkEnabled, int externalAddressesNumber, bool randomExternalAddresses, int[] externalAddresses, bool privateNetworkEnabled, int privateAddressesNumber, bool randomPrivateAddresses, string[] privateAddresses) diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/MemoryInfo.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/MemoryInfo.cs index 7e79088a..e25a0173 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/MemoryInfo.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/MemoryInfo.cs @@ -35,9 +35,9 @@ namespace WebsitePanel.Providers.Virtualization public class MemoryInfo { public bool DynamicMemoryEnabled { get; set; } - public Int64 Startup { get; set; } - public Int64 Minimum { get; set; } - public Int64 Maximum { get; set; } + public int Startup { get; set; } + public int Minimum { get; set; } + public int Maximum { get; set; } public int Buffer { get; set; } public int Priority { get; set; } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachine.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachine.cs index 11da6676..aa659526 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachine.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachine.cs @@ -69,8 +69,8 @@ namespace WebsitePanel.Providers.Virtualization public int CpuUsage { get; set; } [Persistent] - public long RamSize { get; set; } - public long RamUsage { get; set; } + public int RamSize { get; set; } + public int RamUsage { get; set; } [Persistent] public int HddSize { get; set; } public LogicalDisk[] HddLogicalDisks { get; set; } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/VirtualMachineHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/VirtualMachineHelper.cs index e7d05288..30aad925 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/VirtualMachineHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/VirtualMachineHelper.cs @@ -21,7 +21,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); cmd.Parameters.Add("Name", "HeartBeat"); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { var statusString = result[0].GetProperty("PrimaryOperationalStatus"); @@ -41,7 +41,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { procs = Convert.ToInt32(result[0].GetProperty("Count")); @@ -58,13 +58,13 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { info.DynamicMemoryEnabled = Convert.ToBoolean(result[0].GetProperty("DynamicMemoryEnabled")); - info.Startup = Convert.ToInt64(result[0].GetProperty("Startup")) / Constants.Size1M; - info.Minimum = Convert.ToInt64(result[0].GetProperty("Minimum")) / Constants.Size1M; - info.Maximum = Convert.ToInt64(result[0].GetProperty("Maximum")) / Constants.Size1M; + info.Startup = Convert.ToInt32(Convert.ToInt64(result[0].GetProperty("Startup")) / Constants.Size1M); + info.Minimum = Convert.ToInt32(Convert.ToInt64(result[0].GetProperty("Minimum")) / Constants.Size1M); + info.Maximum = Convert.ToInt32(Convert.ToInt64(result[0].GetProperty("Maximum")) / Constants.Size1M); info.Buffer = Convert.ToInt32(result[0].GetProperty("Buffer")); info.Priority = Convert.ToInt32(result[0].GetProperty("Priority")); } @@ -81,7 +81,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("Reserve", Convert.ToInt64(cpuReserveSettings * 1000)); cmd.Parameters.Add("RelativeWeight", cpuWeightSettings); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } public static void UpdateMemory(PowerShellManager powerShell, VirtualMachine vm, long ramMB) @@ -91,7 +91,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", vm.Name); cmd.Parameters.Add("StartupBytes", ramMB * Constants.Size1M); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs index 7b1801ea..b86d832a 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs @@ -57,25 +57,6 @@ namespace WebsitePanel.Providers.Virtualization { public class HyperV2012R2 : HostingServiceProviderBase, IVirtualizationServer { - #region Constants - private const string CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG = "WebsitePanel.HyperV.UseDiskPartClearReadOnlyFlag"; - private const string WMI_VIRTUALIZATION_NAMESPACE = @"root\virtualization\v2"; - private const string WMI_CIMV2_NAMESPACE = @"root\cimv2"; - - private const int SWITCH_PORTS_NUMBER = 1024; - private const string LIBRARY_INDEX_FILE_NAME = "index.xml"; - private const string EXTERNAL_NETWORK_ADAPTER_NAME = "External Network Adapter"; - private const string PRIVATE_NETWORK_ADAPTER_NAME = "Private Network Adapter"; - private const string MANAGEMENT_NETWORK_ADAPTER_NAME = "Management Network Adapter"; - - private const string KVP_RAM_SUMMARY_KEY = "VM-RAM-Summary"; - private const string KVP_HDD_SUMMARY_KEY = "VM-HDD-Summary"; - - private const Int64 Size1G = 0x40000000; - private const Int64 Size1M = 0x100000; - - #endregion - #region Provider Settings protected string ServerNameSettings { @@ -119,16 +100,17 @@ namespace WebsitePanel.Providers.Virtualization #endregion #region Fields - private Wmi _wmi = null; + private PowerShellManager _powerShell; + protected PowerShellManager PowerShell + { + get { return _powerShell ?? (_powerShell = new PowerShellManager(ServerNameSettings)); } + } + + private Wmi _wmi; private Wmi wmi { - get - { - if (_wmi == null) - _wmi = new Wmi(ServerNameSettings, WMI_VIRTUALIZATION_NAMESPACE); - return _wmi; - } + get { return _wmi ?? (_wmi = new Wmi(ServerNameSettings, Constants.WMI_VIRTUALIZATION_NAMESPACE)); } } #endregion @@ -163,13 +145,13 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("Id", vmId); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); if (result != null && result.Count > 0) { vm.Name = result[0].GetProperty("Name").ToString(); vm.State = result[0].GetEnum("State"); vm.CpuUsage = ConvertNullableToInt32(result[0].GetProperty("CpuUsage")); - vm.RamUsage = ConvertNullableToInt64(result[0].GetProperty("MemoryAssigned")) / Size1M; + vm.RamUsage = Convert.ToInt32(ConvertNullableToInt64(result[0].GetProperty("MemoryAssigned")) / Constants.Size1M); vm.Uptime = Convert.ToInt64(result[0].GetProperty("UpTime").TotalMilliseconds); vm.Status = result[0].GetProperty("Status").ToString(); vm.ReplicationState = result[0].GetProperty("ReplicationState").ToString(); @@ -203,7 +185,7 @@ namespace WebsitePanel.Providers.Virtualization if (vm.Disks != null && vm.Disks.GetLength(0) > 0) { vm.VirtualHardDrivePath = vm.Disks[0].Path; - vm.HddSize = Convert.ToInt32(vm.Disks[0].FileSize / Size1G); + vm.HddSize = Convert.ToInt32(vm.Disks[0].FileSize / Constants.Size1G); } // network adapters @@ -219,7 +201,6 @@ namespace WebsitePanel.Providers.Virtualization HostedSolutionLog.LogEnd("GetVirtualMachine"); return vm; - } public List GetVirtualMachines() @@ -232,7 +213,7 @@ namespace WebsitePanel.Providers.Virtualization { Command cmd = new Command("Get-VM"); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); foreach (PSObject current in result) { VirtualMachine vm = new VirtualMachine @@ -332,8 +313,9 @@ namespace WebsitePanel.Providers.Virtualization // Add new VM Command cmdNew = new Command("New-VM"); cmdNew.Parameters.Add("Name", vm.Name); + cmdNew.Parameters.Add("Generation", vm.Generation > 1 ? vm.Generation : 1); cmdNew.Parameters.Add("VHDPath", vm.VirtualHardDrivePath); - PowerShell.Execute(cmdNew, false); + PowerShell.Execute(cmdNew, true); // Set VM Command cmdSet = new Command("Set-VM"); @@ -350,7 +332,7 @@ namespace WebsitePanel.Providers.Virtualization } if (autoStopAction != AutomaticStopAction.Undefined) cmdSet.Parameters.Add("AutomaticStopAction", autoStopAction.ToString()); - PowerShell.Execute(cmdSet, false); + PowerShell.Execute(cmdSet, true); // Get created machine Id var createdMachine = GetVirtualMachines().FirstOrDefault(m => m.Name == vm.Name); @@ -396,168 +378,6 @@ namespace WebsitePanel.Providers.Virtualization return vm; } - - private void AddVirtualMachineDvdDrive(string vmId, ManagementObject objVM) - { - // load IDE 1 controller - ManagementObject objIDE1 = wmi.GetWmiObject( - "Msvm_ResourceAllocationSettingData", "ResourceSubType = 'Microsoft Emulated IDE Controller'" - + " and InstanceID Like 'Microsoft:{0}%' and Address = 1", vmId); - - // load default hard disk drive - ManagementObject objDefaultDvd = wmi.GetWmiObject( - "Msvm_ResourceAllocationSettingData", "ResourceSubType = 'Microsoft Synthetic DVD Drive'" - + " and InstanceID like '%Default'"); - ManagementObject objDvd = (ManagementObject)objDefaultDvd.Clone(); - objDvd["Parent"] = objIDE1.Path; - objDvd["Address"] = 0; - - // add DVD drive to VM resources - AddVirtualMachineResources(objVM, objDvd); - } - - private void AddNetworkAdapter(ManagementObject objVm, string switchId, string portName, string macAddress, string adapterName, bool legacyAdapter) - { - string nicClassName = GetNetworkAdapterClassName(legacyAdapter); - - string vmId = (string)objVm["Name"]; - - // check if already exists - ManagementObject objNic = wmi.GetWmiObject( - nicClassName, "InstanceID like 'Microsoft:{0}%' and Address = '{1}'", vmId, macAddress); - - if (objNic != null) - return; // exists - exit - - portName = String.Format("{0} - {1}", - portName, (adapterName == EXTERNAL_NETWORK_ADAPTER_NAME) ? "External" : "Private"); - - // Network service - ManagementObject objNetworkSvc = GetVirtualSwitchManagementService(); - - // default NIC - ManagementObject objDefaultNic = wmi.GetWmiObject(nicClassName, "InstanceID like '%Default'"); - - // find switch - ManagementObject objSwitch = wmi.GetWmiObject("msvm_VirtualSwitch", "Name = '{0}'", switchId); - - // create switch port - ManagementBaseObject inParams = objNetworkSvc.GetMethodParameters("CreateSwitchPort"); - inParams["VirtualSwitch"] = objSwitch; - inParams["Name"] = portName; - inParams["FriendlyName"] = portName; - inParams["ScopeOfResidence"] = ""; - - // invoke method - ManagementBaseObject outParams = objNetworkSvc.InvokeMethod("CreateSwitchPort", inParams, null); - - // process output parameters - ReturnCode code = (ReturnCode)Convert.ToInt32(outParams["ReturnValue"]); - if (code == ReturnCode.OK) - { - // created port - ManagementObject objPort = wmi.GetWmiObjectByPath((string)outParams["CreatedSwitchPort"]); - - // create NIC - ManagementObject objExtNic = (ManagementObject)objDefaultNic.Clone(); - objExtNic["Connection"] = new string[] { objPort.Path.Path }; - - if (!String.IsNullOrEmpty(macAddress)) - { - objExtNic["StaticMacAddress"] = true; - objExtNic["Address"] = macAddress; - } - else - { - objExtNic["StaticMacAddress"] = false; - } - objExtNic["ElementName"] = adapterName; - - if (!legacyAdapter) - objExtNic["VirtualSystemIdentifiers"] = new string[] { Guid.NewGuid().ToString("B") }; - - // add NIC - ManagementObject objCreatedExtNic = AddVirtualMachineResources(objVm, objExtNic); - } - } - - private string GetNetworkAdapterClassName(bool legacy) - { - return legacy ? "Msvm_EmulatedEthernetPortSettingData" : "Msvm_SyntheticEthernetPortSettingData"; - } - - private ManagementObject AddVirtualMachineResources(ManagementObject objVm, ManagementObject resource) - { - if (resource == null) - return resource; - - // request management service - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // add resources - string txtResource = resource.GetText(TextFormat.CimDtd20); - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("AddVirtualSystemResources"); - inParams["TargetSystem"] = objVm; - inParams["ResourceSettingData"] = new string[] { txtResource }; - ManagementBaseObject outParams = objVmsvc.InvokeMethod("AddVirtualSystemResources", inParams, null); - JobResult result = CreateJobResultFromWmiMethodResults(outParams); - - if (result.ReturnValue == ReturnCode.OK) - { - string[] wmiPaths = (string[])outParams["NewResources"]; - return wmi.GetWmiObjectByPath(wmiPaths[0]); - } - else if (result.ReturnValue == ReturnCode.JobStarted) - { - if (JobCompleted(result.Job)) - { - string[] wmiPaths = (string[])outParams["NewResources"]; - return wmi.GetWmiObjectByPath(wmiPaths[0]); - } - else - { - throw new Exception("Cannot add virtual machine resources"); - } - } - else - { - throw new Exception("Cannot add virtual machine resources: " + txtResource); - } - } - - private JobResult RemoveVirtualMachineResources(ManagementObject objVm, ManagementObject resource) - { - if (resource == null) - return null; - - // request management service - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // remove resources - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("RemoveVirtualSystemResources"); - inParams["TargetSystem"] = objVm; - inParams["ResourceSettingData"] = new string[] { resource.Path.Path }; - ManagementBaseObject outParams = objVmsvc.InvokeMethod("RemoveVirtualSystemResources", inParams, null); - JobResult result = CreateJobResultFromWmiMethodResults(outParams); - if (result.ReturnValue == ReturnCode.OK) - { - return result; - } - else if (result.ReturnValue == ReturnCode.JobStarted) - { - if (!JobCompleted(result.Job)) - { - throw new Exception("Cannot remove virtual machine resources"); - } - } - else - { - throw new Exception("Cannot remove virtual machine resources: " + resource.Path.Path); - } - - return result; - } - public JobResult ChangeVirtualMachineState(string vmId, VirtualMachineRequestedState newState) { HostedSolutionLog.LogStart("ChangeVirtualMachineState"); @@ -604,8 +424,8 @@ namespace WebsitePanel.Providers.Virtualization //cmd.Parameters.Add("AsJob"); paramList.ForEach(p => cmd.Parameters.Add(p)); - PowerShell.Execute(cmd, false); - jobResult = JobHelper.CreateSuccessResult(); + PowerShell.Execute(cmd, true); + jobResult = JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } catch (Exception ex) { @@ -633,7 +453,7 @@ namespace WebsitePanel.Providers.Virtualization if (force) cmd.Parameters.Add("Force"); //if (!string.IsNullOrEmpty(reason)) cmd.Parameters.Add("Reason", reason); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); } catch (Exception ex) { @@ -665,134 +485,60 @@ namespace WebsitePanel.Providers.Virtualization public JobResult RenameVirtualMachine(string vmId, string name) { - // load virtual machine - ManagementObject objVm = GetVirtualMachineObject(vmId); + var vm = GetVirtualMachine(vmId); - // load machine settings - ManagementObject objVmSettings = GetVirtualMachineSettingsObject(vmId); + Command cmdSet = new Command("Rename-VM"); + cmdSet.Parameters.Add("Name", vm.Name); + cmdSet.Parameters.Add("NewName", name); + PowerShell.Execute(cmdSet, true); - // rename machine - objVmSettings["ElementName"] = name; - - // save - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("ModifyVirtualSystem"); - inParams["ComputerSystem"] = objVm.Path.Path; - inParams["SystemSettingData"] = objVmSettings.GetText(TextFormat.CimDtd20); - ManagementBaseObject outParams = objVmsvc.InvokeMethod("ModifyVirtualSystem", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); + return JobHelper.CreateSuccessResult(); } public JobResult DeleteVirtualMachine(string vmId) { - // load virtual machine object - ManagementObject objVm = GetVirtualMachineObject(vmId); - - // check state - VirtualMachine vm = GetVirtualMachine(vmId); + var vm = GetVirtualMachineEx(vmId); // The virtual computer system must be in the powered off or saved state prior to calling this method. - if (vm.State == VirtualMachineState.Saved - || vm.State == VirtualMachineState.Off) - { - // delete network adapters and ports - DeleteNetworkAdapters(objVm); - - // destroy machine - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // get method - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("DestroyVirtualSystem"); - inParams["ComputerSystem"] = objVm; - - // invoke method - ManagementBaseObject outParams = objVmsvc.InvokeMethod("DestroyVirtualSystem", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); - } - else - { + if (vm.State != VirtualMachineState.Saved && vm.State != VirtualMachineState.Off) throw new Exception("The virtual computer system must be in the powered off or saved state prior to calling Destroy method."); + + // Delete network adapters and network switchesw + foreach (var networkAdapter in vm.Adapters) + { + NetworkAdapterHelper.Delete(PowerShell, vm.Name, networkAdapter); + + if (!string.IsNullOrEmpty(networkAdapter.SwitchName)) + DeleteSwitch(networkAdapter.SwitchName); } - } - private void DeleteNetworkAdapters(ManagementObject objVM) - { - string vmId = (string)objVM["Name"]; + object[] errors; - // delete synthetic adapters - foreach (ManagementObject objNic in wmi.GetWmiObjects("Msvm_SyntheticEthernetPortSettingData", "InstanceID like 'Microsoft:{0}%'", vmId)) - DeleteNetworkAdapter(objVM, objNic); + Command cmdSet = new Command("Remove-VM"); + cmdSet.Parameters.Add("Name", vm.Name); + cmdSet.Parameters.Add("Force"); + PowerShell.Execute(cmdSet, false, out errors); - // delete legacy adapters - foreach (ManagementObject objNic in wmi.GetWmiObjects("Msvm_EmulatedEthernetPortSettingData", "InstanceID like 'Microsoft:{0}%'", vmId)) - DeleteNetworkAdapter(objVM, objNic); - } + PowerShellManager.ExceptionIfErrors(errors); - private void DeleteNetworkAdapter(ManagementObject objVM, string macAddress) - { - // locate network adapter - ManagementObject objNic = wmi.GetWmiObject("CIM_ResourceAllocationSettingData", "Address = '{0}'", macAddress); - - // delete adapter - DeleteNetworkAdapter(objVM, objNic); - } - - private void DeleteNetworkAdapter(ManagementObject objVM, ManagementObject objNic) - { - if (objNic == null) - return; - - // delete corresponding switch port - string[] conn = (string[])objNic["Connection"]; - if (conn != null && conn.Length > 0) - DeleteSwitchPort(conn[0]); - - // delete adapter - RemoveVirtualMachineResources(objVM, objNic); - } - - private void DeleteSwitchPort(string portPath) - { - // Network service - ManagementObject objNetworkSvc = GetVirtualSwitchManagementService(); - - // create switch port - ManagementBaseObject inParams = objNetworkSvc.GetMethodParameters("DeleteSwitchPort"); - inParams["SwitchPort"] = portPath; - - // invoke method - objNetworkSvc.InvokeMethod("DeleteSwitchPort", inParams, null); + return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } public JobResult ExportVirtualMachine(string vmId, string exportPath) { - // load virtual machine object - ManagementObject objVm = GetVirtualMachineObject(vmId); - - // check state - VirtualMachine vm = GetVirtualMachine(vmId); + var vm = GetVirtualMachine(vmId); // The virtual computer system must be in the powered off or saved state prior to calling this method. - if (vm.State == VirtualMachineState.Off) - { - // export machine - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // get method - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("ExportVirtualSystem"); - inParams["ComputerSystem"] = objVm; - inParams["CopyVmState"] = true; - inParams["ExportDirectory"] = FileUtils.EvaluateSystemVariables(exportPath); - - // invoke method - ManagementBaseObject outParams = objVmsvc.InvokeMethod("ExportVirtualSystem", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); - } - else - { + if (vm.State != VirtualMachineState.Off) throw new Exception("The virtual computer system must be in the powered off or saved state prior to calling Export method."); - } + + Command cmdSet = new Command("Export-VM"); + cmdSet.Parameters.Add("Name", vm.Name); + cmdSet.Parameters.Add("Path", FileUtils.EvaluateSystemVariables(exportPath)); + PowerShell.Execute(cmdSet, true); + return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } + #endregion #region Snapshots @@ -808,7 +554,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Get-VMSnapshot"); cmd.Parameters.Add("VMName", vm.Name); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); if (result != null && result.Count > 0) { foreach (PSObject psSnapshot in result) @@ -833,7 +579,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Get-VMSnapshot"); cmd.Parameters.Add("Id", snapshotId); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); if (result != null && result.Count > 0) { return SnapshotHelper.GetFromPS(result[0]); @@ -857,7 +603,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Checkpoint-VM"); cmd.Parameters.Add("Name", vm.Name); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } catch (Exception ex) @@ -879,7 +625,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("Name", snapshot.Name); cmd.Parameters.Add("NewName", name); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); return JobHelper.CreateSuccessResult(); } catch (Exception ex) @@ -900,7 +646,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", vm.Name); cmd.Parameters.Add("Name", snapshot.Name); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); return JobHelper.CreateSuccessResult(); } catch (Exception ex) @@ -1042,7 +788,10 @@ namespace WebsitePanel.Providers.Virtualization if (!string.IsNullOrEmpty(computerName)) cmd.Parameters.Add("ComputerName", computerName); if (!string.IsNullOrEmpty(type)) cmd.Parameters.Add("SwitchType", type); - Collection result = PowerShell.Execute(cmd,false); + object[] errors; + Collection result = PowerShell.Execute(cmd, false, out errors); + PowerShellManager.ExceptionIfErrors(errors); + foreach (PSObject current in result) { VirtualSwitch sw = new VirtualSwitch(); @@ -1083,7 +832,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("SwitchType", "Private"); cmd.Parameters.Add("Name", name); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); if (result != null && result.Count > 0) { virtualSwitch = new VirtualSwitch(); @@ -1102,7 +851,7 @@ namespace WebsitePanel.Providers.Virtualization return virtualSwitch; } - public ReturnCode DeleteSwitch(string switchId) + public ReturnCode DeleteSwitch(string switchId) // switchId is SwitchName { HostedSolutionLog.LogStart("DeleteSwitch"); HostedSolutionLog.DebugInfo("switchId: {0}", switchId); @@ -1111,7 +860,8 @@ namespace WebsitePanel.Providers.Virtualization { Command cmd = new Command("Remove-VMSwitch"); cmd.Parameters.Add("Name", switchId); - PowerShell.Execute(cmd, false); + cmd.Parameters.Add("Force"); + PowerShell.Execute(cmd, true); } catch (Exception ex) { @@ -1127,7 +877,7 @@ namespace WebsitePanel.Providers.Virtualization #region Library public LibraryItem[] GetLibraryItems(string path) { - path = Path.Combine(FileUtils.EvaluateSystemVariables(path), LIBRARY_INDEX_FILE_NAME); + path = Path.Combine(FileUtils.EvaluateSystemVariables(path), Constants.LIBRARY_INDEX_FILE_NAME); // convert to UNC if it is a remote computer path = ConvertToUNC(path); @@ -1203,14 +953,6 @@ namespace WebsitePanel.Providers.Virtualization return items.ToArray(); } - private string ConvertToUNC(string path) - { - if (String.IsNullOrEmpty(ServerNameSettings) - || path.StartsWith(@"\\")) - return path; - - return String.Format(@"\\{0}\{1}", ServerNameSettings, path.Replace(":", "$")); - } #endregion #region KVP @@ -1438,15 +1180,41 @@ namespace WebsitePanel.Providers.Virtualization } } - private string GetPropertyValue(string propertyName, XmlDocument doc) - { - string xpath = string.Format(@"//PROPERTY[@NAME = '{0}']/VALUE/child::text()", propertyName); - XmlNode node = doc.SelectSingleNode(xpath); - return node != null ? node.Value : null; - } - public MountedDiskInfo MountVirtualHardDisk(string vhdPath) { + //MountedDiskInfo diskInfo = new MountedDiskInfo(); + //vhdPath = FileUtils.EvaluateSystemVariables(vhdPath); + + //// Mount disk + //Command cmd = new Command("Mount-VHD"); + + //cmd.Parameters.Add("Path", vhdPath); + //cmd.Parameters.Add("PassThru"); + + //// Get disk address + //var result = PowerShell.Execute(cmd, true); + + //try + //{ + // if (result == null || result.Count == 0) + // throw new Exception("Failed to mount disk"); + + // diskInfo.DiskAddress = result[0].GetString("DiskNumber"); + + // // Get disk volumes + + //} + //catch (Exception ex) + //{ + // // unmount disk + // UnmountVirtualHardDisk(vhdPath); + + // // throw error + // throw ex; + //} + + //return diskInfo; + ManagementObject objImgSvc = GetImageManagementService(); // get method params @@ -1503,11 +1271,11 @@ namespace WebsitePanel.Providers.Virtualization // check if DiskPart must be used to bring disk online and clear read-only flag bool useDiskPartToClearReadOnly = false; - if (ConfigurationManager.AppSettings[CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG] != null) - useDiskPartToClearReadOnly = Boolean.Parse(ConfigurationManager.AppSettings[CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG]); + if (ConfigurationManager.AppSettings[Constants.CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG] != null) + useDiskPartToClearReadOnly = Boolean.Parse(ConfigurationManager.AppSettings[Constants.CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG]); // determine disk index for DiskPart - Wmi cimv2 = new Wmi(ServerNameSettings, WMI_CIMV2_NAMESPACE); + Wmi cimv2 = new Wmi(ServerNameSettings, Constants.WMI_CIMV2_NAMESPACE); ManagementObject objDisk = cimv2.GetWmiObject("win32_diskdrive", "Model='Msft Virtual Disk SCSI Disk Device' and ScsiTargetID={0} and ScsiLogicalUnit={1} and scsiPort={2}", targetId, lun, portNumber); @@ -1640,29 +1408,23 @@ exit", Convert.ToInt32(objDisk["Index"]))); public ReturnCode UnmountVirtualHardDisk(string vhdPath) { - ManagementObject objImgSvc = GetImageManagementService(); + Command cmd = new Command("Dismount-VHD"); - // get method params - ManagementBaseObject inParams = objImgSvc.GetMethodParameters("Unmount"); - inParams["Path"] = FileUtils.EvaluateSystemVariables(vhdPath); + cmd.Parameters.Add("Path", FileUtils.EvaluateSystemVariables(vhdPath)); - ManagementBaseObject outParams = (ManagementBaseObject)objImgSvc.InvokeMethod("Unmount", inParams, null); - return (ReturnCode)Convert.ToInt32(outParams["ReturnValue"]); + PowerShell.Execute(cmd, true); + return ReturnCode.OK; } public JobResult ExpandVirtualHardDisk(string vhdPath, UInt64 sizeGB) { - const UInt64 Size1G = 0x40000000; + Command cmd = new Command("Resize-VHD"); - ManagementObject objImgSvc = GetImageManagementService(); + cmd.Parameters.Add("Path", FileUtils.EvaluateSystemVariables(vhdPath)); + cmd.Parameters.Add("SizeBytes", sizeGB * Constants.Size1G); - // get method params - ManagementBaseObject inParams = objImgSvc.GetMethodParameters("ExpandVirtualHardDisk"); - inParams["Path"] = FileUtils.EvaluateSystemVariables(vhdPath); - inParams["MaxInternalSize"] = sizeGB * Size1G; - - ManagementBaseObject outParams = (ManagementBaseObject)objImgSvc.InvokeMethod("ExpandVirtualHardDisk", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); + PowerShell.Execute(cmd, true); + return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } public JobResult ConvertVirtualHardDisk(string sourcePath, string destinationPath, VirtualHardDiskType diskType) @@ -1687,7 +1449,7 @@ exit", Convert.ToInt32(objDisk["Index"]))); cmd.Parameters.Add("DestinationPath", destinationPath); cmd.Parameters.Add("VHDType", diskType.ToString()); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } catch (Exception ex) @@ -1840,53 +1602,41 @@ exit", Convert.ToInt32(objDisk["Index"]))); #region Jobs public ConcreteJob GetJob(string jobId) { - HostedSolutionLog.LogStart("GetJob"); - HostedSolutionLog.DebugInfo("jobId: {0}", jobId); + throw new NotImplementedException(); - Runspace runSpace = null; - ConcreteJob job; + //HostedSolutionLog.LogStart("GetJob"); + //HostedSolutionLog.DebugInfo("jobId: {0}", jobId); - try - { - Command cmd = new Command("Get-Job"); + //Runspace runSpace = null; + //ConcreteJob job; - if (!string.IsNullOrEmpty(jobId)) cmd.Parameters.Add("Id", jobId); + //try + //{ + // Command cmd = new Command("Get-Job"); - Collection result = PowerShell.Execute( cmd, false); - job = JobHelper.CreateFromPSObject(result); - } - catch (Exception ex) - { - HostedSolutionLog.LogError("GetJob", ex); - throw; - } + // if (!string.IsNullOrEmpty(jobId)) cmd.Parameters.Add("Id", jobId); - HostedSolutionLog.LogEnd("GetJob"); - return job; + // Collection result = PowerShell.Execute(cmd, true); + // job = JobHelper.CreateFromPSObject(result); + //} + //catch (Exception ex) + //{ + // HostedSolutionLog.LogError("GetJob", ex); + // throw; + //} + + //HostedSolutionLog.LogEnd("GetJob"); + //return job; } public List GetAllJobs() { - List jobs = new List(); - - ManagementObjectCollection objJobs = wmi.GetWmiObjects("CIM_ConcreteJob"); - foreach (ManagementObject objJob in objJobs) - jobs.Add(CreateJobFromWmiObject(objJob)); - - return jobs; + throw new NotImplementedException(); } public ChangeJobStateReturnCode ChangeJobState(string jobId, ConcreteJobRequestedState newState) { - ManagementObject objJob = GetJobWmiObject(jobId); - - // get method - ManagementBaseObject inParams = objJob.GetMethodParameters("RequestStateChange"); - inParams["RequestedState"] = (Int32)newState; - - // invoke method - ManagementBaseObject outParams = objJob.InvokeMethod("RequestStateChange", inParams, null); - return (ChangeJobStateReturnCode)Convert.ToInt32(outParams["ReturnValue"]); + throw new NotImplementedException(); } #endregion @@ -2139,15 +1889,6 @@ exit", Convert.ToInt32(objDisk["Index"]))); return value == null ? 0 : Convert.ToInt64(value); } - //protected VirtualMachineSnapshot GetSnapshotById(string id) - //{ - // var vms = GetVirtualMachines(); - // var allSnapshots = vms.SelectMany(vm => GetVirtualMachineSnapshots(vm.Id.ToString())); - - // return allSnapshots.FirstOrDefault(s => s.Id == id); - //} - - protected JobResult CreateJobResultFromWmiMethodResults(ManagementBaseObject outParams) { JobResult result = new JobResult(); @@ -2169,21 +1910,11 @@ exit", Convert.ToInt32(objDisk["Index"]))); return result; } - private ManagementObject GetJobWmiObject(string id) - { - return wmi.GetWmiObject("msvm_ConcreteJob", "InstanceID = '{0}'", id); - } - private ManagementObject GetVirtualSystemManagementService() { return wmi.GetWmiObject("msvm_VirtualSystemManagementService"); } - private ManagementObject GetVirtualSwitchManagementService() - { - return wmi.GetWmiObject("msvm_VirtualSwitchManagementService"); - } - protected ManagementObject GetImageManagementService() { return wmi.GetWmiObject("msvm_ImageManagementService"); @@ -2200,18 +1931,13 @@ exit", Convert.ToInt32(objDisk["Index"]))); wmi.GetWmiObject("Msvm_VirtualSystemSettingData", "InstanceID = '{0}'", "Microsoft:" + snapshotId); } - - - - private VirtualSwitch CreateSwitchFromWmiObject(ManagementObject objSwitch) + private string ConvertToUNC(string path) { - if (objSwitch == null || objSwitch.Properties.Count == 0) - return null; + if (String.IsNullOrEmpty(ServerNameSettings) + || path.StartsWith(@"\\")) + return path; - VirtualSwitch sw = new VirtualSwitch(); - sw.SwitchId = (string)objSwitch["Name"]; - sw.Name = (string)objSwitch["ElementName"]; - return sw; + return String.Format(@"\\{0}\{1}", ServerNameSettings, path.Replace(":", "$")); } private ConcreteJob CreateJobFromWmiObject(ManagementBaseObject objJob) @@ -2312,7 +2038,7 @@ exit", Convert.ToInt32(objDisk["Index"]))); return File.Exists(path); else { - Wmi cimv2 = new Wmi(ServerNameSettings, WMI_CIMV2_NAMESPACE); + Wmi cimv2 = new Wmi(ServerNameSettings, Constants.WMI_CIMV2_NAMESPACE); ManagementObject objFile = cimv2.GetWmiObject("CIM_Datafile", "Name='{0}'", path.Replace("\\", "\\\\")); return (objFile != null); } @@ -2324,7 +2050,7 @@ exit", Convert.ToInt32(objDisk["Index"]))); return Directory.Exists(path); else { - Wmi cimv2 = new Wmi(ServerNameSettings, WMI_CIMV2_NAMESPACE); + Wmi cimv2 = new Wmi(ServerNameSettings, Constants.WMI_CIMV2_NAMESPACE); ManagementObject objDir = cimv2.GetWmiObject("Win32_Directory", "Name='{0}'", path.Replace("\\", "\\\\")); return (objDir != null); } @@ -2348,7 +2074,7 @@ exit", Convert.ToInt32(objDisk["Index"]))); return false; // copy using WMI - Wmi cimv2 = new Wmi(ServerNameSettings, WMI_CIMV2_NAMESPACE); + Wmi cimv2 = new Wmi(ServerNameSettings, Constants.WMI_CIMV2_NAMESPACE); ManagementObject objFile = cimv2.GetWmiObject("CIM_Datafile", "Name='{0}'", sourceFileName.Replace("\\", "\\\\")); if (objFile == null) throw new Exception("Source file does not exists: " + sourceFileName); @@ -2498,17 +2224,6 @@ exit", Convert.ToInt32(objDisk["Index"]))); return !String.IsNullOrEmpty(connString); } #endregion Hyper-V Cloud - - #region PowerShell integration - - private PowerShellManager _powerShell; - protected PowerShellManager PowerShell - { - get { return _powerShell ?? (_powerShell = new PowerShellManager()); } - } - - #endregion - - + } -} +} \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Code/ProviderControls/IVirtualMachineCreateControl.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Code/ProviderControls/IVirtualMachineCreateControl.cs new file mode 100644 index 00000000..7ffcba0b --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Code/ProviderControls/IVirtualMachineCreateControl.cs @@ -0,0 +1,52 @@ +// Copyright (c) 2015, 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.Data; +using System.Configuration; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; + +using WebsitePanel.Providers.Mail; +using WebsitePanel.Providers.Virtualization; + +namespace WebsitePanel.Portal +{ + /// + /// Summary description for IVirtualMachineCreateControl + /// + public interface IVirtualMachineCreateControl + { + void BindItem(VirtualMachine item); + void SaveItem(VirtualMachine item); + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserControls/Gauge.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserControls/Gauge.ascx.cs index 9a7d4440..6d80d876 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserControls/Gauge.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserControls/Gauge.ascx.cs @@ -56,15 +56,15 @@ namespace WebsitePanel.Portal set { ViewState["DisplayText"] = value; } } - public long Progress + public int Progress { - get { return (ViewState["Progress"] != null) ? (long)ViewState["Progress"] : 0; } + get { return (ViewState["Progress"] != null) ? (int)ViewState["Progress"] : 0; } set { ViewState["Progress"] = value; } } - public long Total + public int Total { - get { return (ViewState["Total"] != null) ? (long)ViewState["Total"] : 0; } + get { return (ViewState["Total"] != null) ? (int)ViewState["Total"] : 0; } set { ViewState["Total"] = value; } } @@ -101,7 +101,7 @@ namespace WebsitePanel.Portal string bkgSrc = Page.ResolveUrl(PortalUtils.GetThemedImage("gauge_bkg.gif")); // calculate the width of the gauge - long fTotal = Total; + int fTotal = Total; int percent = (fTotal > 0) ? Convert.ToInt32(Math.Round((double)Progress / (double)fTotal * 100)) : 0; double fFilledWidth = (fTotal > 0) ? ((double)Progress / (double)fTotal * Width) : 0; diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserControls/QuotaViewer.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserControls/QuotaViewer.ascx.cs index 83bdf399..2ee49ac3 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserControls/QuotaViewer.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserControls/QuotaViewer.ascx.cs @@ -92,7 +92,7 @@ namespace WebsitePanel.Portal private void UpdateControl() { - long total = gauge.Total; + int total = gauge.Total; if (QuotaTypeId == 1) { litValue.Text = (total == 0) ? GetLocalizedString("Text.Disabled") : GetLocalizedString("Text.Enabled"); diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx index c7913290..c864299e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx @@ -189,6 +189,8 @@ + + diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx.cs index 207cc239..45d7380e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx.cs @@ -42,6 +42,8 @@ namespace WebsitePanel.Portal.VPS { protected void Page_Load(object sender, EventArgs e) { + LoadCustomProviderControl(); + if (!IsPostBack) { BindFormControls(); @@ -54,6 +56,26 @@ namespace WebsitePanel.Portal.VPS ToggleControls(); } + private void LoadCustomProviderControl() + { + try + { + LoadProviderControl(PanelSecurity.PackageId, "VPS", providerControl, "Create.ascx"); + } + catch { /* skip */ } + } + + private IVirtualMachineCreateControl CustomProviderControl + { + get + { + if (providerControl.Controls.Count == 0) + return null; + + return (IVirtualMachineCreateControl)providerControl.Controls[0]; + } + } + private void ToggleWizardSteps() { // external network @@ -113,6 +135,13 @@ namespace WebsitePanel.Portal.VPS ddlCpu.SelectedIndex = ddlCpu.Items.Count - 1; // select last (maximum) item + // the custom provider control + if (CustomProviderControl != null) + { + IVirtualMachineCreateControl ctrl = (IVirtualMachineCreateControl)providerControl.Controls[0]; + ctrl.BindItem(new VirtualMachine()); + } + // external network details if (PackagesHelper.IsQuotaEnabled(PanelSecurity.PackageId, Quotas.VPS_EXTERNAL_NETWORK_ENABLED)) { @@ -287,6 +316,15 @@ namespace WebsitePanel.Portal.VPS try { + VirtualMachine virtualMachine = new VirtualMachine(); + + // the custom provider control + if (CustomProviderControl != null) + { + IVirtualMachineCreateControl ctrl = (IVirtualMachineCreateControl)providerControl.Controls[0]; + ctrl.SaveItem(virtualMachine); + } + // collect and prepare data string hostname = String.Format("{0}.{1}", txtHostname.Text.Trim(), txtDomain.Text.Trim()); diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx.designer.cs index 7f1bb24f..c179bdcf 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx.designer.cs @@ -1,38 +1,9 @@ -// Copyright (c) 2015, 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. - //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.3053 // // Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -401,6 +372,15 @@ namespace WebsitePanel.Portal.VPS { /// protected global::System.Web.UI.WebControls.Localize locGB; + /// + /// providerControl control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.PlaceHolder providerControl; + /// /// secSnapshots control. /// @@ -1354,14 +1334,5 @@ namespace WebsitePanel.Portal.VPS { /// To modify move field declaration from designer file to code-behind file. /// protected global::System.Web.UI.WebControls.Literal litPrivateAddressesList; - - /// - /// FormComments control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Localize FormComments; } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/WebsitePanel.Portal.Modules.csproj b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/WebsitePanel.Portal.Modules.csproj index d7218b57..f80d41bc 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/WebsitePanel.Portal.Modules.csproj +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/WebsitePanel.Portal.Modules.csproj @@ -195,6 +195,7 @@ + From d31c1210400713542331a95281130df2bfb28e15 Mon Sep 17 00:00:00 2001 From: me Date: Mon, 23 Mar 2015 09:39:13 +0400 Subject: [PATCH 4/8] wsp-10323 Step 8 --- WebsitePanel/Database/update_db.sql | 8 ++++++-- .../WebsitePanel/VPS/VdcCreateServer.ascx.cs | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql index 802718bc..deda7025 100644 --- a/WebsitePanel/Database/update_db.sql +++ b/WebsitePanel/Database/update_db.sql @@ -8860,10 +8860,14 @@ AND ((@GroupName IS NULL) OR (@GroupName IS NOT NULL AND RG.GroupName = @GroupNa RETURN GO --- Hyper-V 2012 R2 +-- Hyper-V 2012 R2 Provider IF NOT EXISTS (SELECT * FROM [dbo].[Providers] WHERE [ProviderName] = 'HyperV2012R2') BEGIN -INSERT [dbo].[Providers] ([ProviderID], [GroupID], [ProviderName], [DisplayName], [ProviderType], [EditorControl], [DisableAutoDiscovery]) VALUES (350, 30, N'HyperV2012R2', N'Microsoft Hyper-V 2012 R2', N'WebsitePanel.Providers.Virtualization.HyperV2012R2, WebsitePanel.Providers.Virtualization.HyperV2012R2', N'HyperV', 1) +INSERT [dbo].[Providers] ([ProviderID], [GroupID], [ProviderName], [DisplayName], [ProviderType], [EditorControl], [DisableAutoDiscovery]) VALUES (350, 30, N'HyperV2012R2', N'Microsoft Hyper-V 2012 R2', N'WebsitePanel.Providers.Virtualization.HyperV2012R2, WebsitePanel.Providers.Virtualization.HyperV2012R2', N'HyperV2012R2', 1) +END +ELSE +BEGIN +UPDATE [dbo].[Providers] SET [EditorControl] = N'HyperV2012R2' WHERE [ProviderName] = 'HyperV2012R2' END GO diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx.cs index 45d7380e..4fb5436e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/VPS/VdcCreateServer.ascx.cs @@ -343,7 +343,7 @@ namespace WebsitePanel.Portal.VPS // create virtual machine IntResult res = ES.Services.VPS.CreateVirtualMachine(PanelSecurity.PackageId, hostname, listOperatingSystems.SelectedValue, adminPassword, summaryEmail, - Utils.ParseInt(ddlCpu.SelectedValue), Utils.ParseInt(txtRam.Text.Trim()), + virtualMachine.Generation, Utils.ParseInt(ddlCpu.SelectedValue), Utils.ParseInt(txtRam.Text.Trim()), Utils.ParseInt(txtHdd.Text.Trim()), Utils.ParseInt(txtSnapshots.Text.Trim()), chkDvdInstalled.Checked, chkBootFromCd.Checked, chkNumLock.Checked, chkStartShutdown.Checked, chkPauseResume.Checked, chkReboot.Checked, chkReset.Checked, chkReinstall.Checked, From 8158c5369c8abbd1102de0c515839ff9028949f9 Mon Sep 17 00:00:00 2001 From: McMak Date: Mon, 23 Mar 2015 10:55:18 +0200 Subject: [PATCH 5/8] Fix empty grid after double click on lync users form. --- .../DesktopModules/WebsitePanel/Lync/LyncUsers.ascx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Lync/LyncUsers.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Lync/LyncUsers.ascx index 926b8780..0535046a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Lync/LyncUsers.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Lync/LyncUsers.ascx @@ -67,7 +67,7 @@ - + From 8729a7f5a956162d37c8711246fe9bfba19cc763 Mon Sep 17 00:00:00 2001 From: McMak Date: Mon, 23 Mar 2015 11:31:27 +0200 Subject: [PATCH 6/8] Fix crash when attempting to sort a grid on lync users form. --- WebsitePanel/Database/update_db.sql | 134 ++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql index f3cb07d2..ca90e3a3 100644 --- a/WebsitePanel/Database/update_db.sql +++ b/WebsitePanel/Database/update_db.sql @@ -9133,3 +9133,137 @@ BEGIN INSERT INTO [dbo].[Quotas] (QuotaID, GroupID, QuotaOrder, QuotaName, QuotaDescription, QuotaTypeID, ServiceQuota) VALUES (552, @group_id, 3, 'HostedSharePointServer.UseSharedSSL', 'Use shared SSL Root', 1, 0) END + +GO + +IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'GetLyncUsers') +DROP PROCEDURE GetLyncUsers +GO + +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER OFF +GO + +CREATE PROCEDURE [dbo].[GetLyncUsers] +( + @ItemID int, + @SortColumn nvarchar(40), + @SortDirection nvarchar(20), + @StartRow int, + @Count int +) +AS + +CREATE TABLE #TempLyncUsers +( + [ID] [int] IDENTITY(1,1) NOT NULL, + [AccountID] [int], + [ItemID] [int] NOT NULL, + [AccountName] [nvarchar](300) NOT NULL, + [DisplayName] [nvarchar](300) NOT NULL, + [UserPrincipalName] [nvarchar](300) NULL, + [SipAddress] [nvarchar](300) NULL, + [SamAccountName] [nvarchar](100) NULL, + [LyncUserPlanId] [int] NOT NULL, + [LyncUserPlanName] [nvarchar] (300) NOT NULL, +) + +DECLARE @condition nvarchar(700) +SET @condition = '' + +IF (@SortColumn = 'DisplayName') +BEGIN + SET @condition = 'ORDER BY ea.DisplayName' +END + +IF (@SortColumn = 'UserPrincipalName') +BEGIN + SET @condition = 'ORDER BY ea.UserPrincipalName' +END + +IF (@SortColumn = 'SipAddress') +BEGIN + SET @condition = 'ORDER BY ou.SipAddress' +END + +IF (@SortColumn = 'LyncUserPlanName') +BEGIN + SET @condition = 'ORDER BY lp.LyncUserPlanName' +END + +DECLARE @sql nvarchar(3500) + +set @sql = ' + INSERT INTO + #TempLyncUsers + SELECT + ea.AccountID, + ea.ItemID, + ea.AccountName, + ea.DisplayName, + ea.UserPrincipalName, + ou.SipAddress, + ea.SamAccountName, + ou.LyncUserPlanId, + lp.LyncUserPlanName + FROM + ExchangeAccounts ea + INNER JOIN + LyncUsers ou + INNER JOIN + LyncUserPlans lp + ON + ou.LyncUserPlanId = lp.LyncUserPlanId + ON + ea.AccountID = ou.AccountID + WHERE + ea.ItemID = @ItemID ' + @condition + +exec sp_executesql @sql, N'@ItemID int',@ItemID + +DECLARE @RetCount int +SELECT @RetCount = COUNT(ID) FROM #TempLyncUsers + +IF (@SortDirection = 'ASC') +BEGIN + SELECT * FROM #TempLyncUsers + WHERE ID > @StartRow AND ID <= (@StartRow + @Count) +END +ELSE +BEGIN + IF @SortColumn <> '' AND @SortColumn IS NOT NULL + BEGIN + IF (@SortColumn = 'DisplayName') + BEGIN + SELECT * FROM #TempLyncUsers + WHERE ID >@RetCount - @Count - @StartRow AND ID <= @RetCount- @StartRow ORDER BY DisplayName DESC + END + IF (@SortColumn = 'UserPrincipalName') + BEGIN + SELECT * FROM #TempLyncUsers + WHERE ID >@RetCount - @Count - @StartRow AND ID <= @RetCount- @StartRow ORDER BY UserPrincipalName DESC + END + + IF (@SortColumn = 'SipAddress') + BEGIN + SELECT * FROM #TempLyncUsers + WHERE ID >@RetCount - @Count - @StartRow AND ID <= @RetCount- @StartRow ORDER BY SipAddress DESC + END + + IF (@SortColumn = 'LyncUserPlanName') + BEGIN + SELECT * FROM #TempLyncUsers + WHERE ID >@RetCount - @Count - @StartRow AND ID <= @RetCount- @StartRow ORDER BY LyncUserPlanName DESC + END + END + ELSE + BEGIN + SELECT * FROM #TempLyncUsers + WHERE ID >@RetCount - @Count - @StartRow AND ID <= @RetCount- @StartRow ORDER BY UserPrincipalName DESC + END +END + +DROP TABLE #TempLyncUsers + +GO From ad092e2fc60f8675d79d89fc03e82af33f695746 Mon Sep 17 00:00:00 2001 From: McMak Date: Mon, 23 Mar 2015 11:43:09 +0200 Subject: [PATCH 7/8] Fix HO users popup and Organizations.SearchAccounts now populates a IsLyncUser property in OrganizationUser. --- WebsitePanel/Database/update_db.sql | 67 +++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql index ca90e3a3..d5bccec6 100644 --- a/WebsitePanel/Database/update_db.sql +++ b/WebsitePanel/Database/update_db.sql @@ -9267,3 +9267,70 @@ END DROP TABLE #TempLyncUsers GO + +IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'SearchOrganizationAccounts') +DROP PROCEDURE SearchOrganizationAccounts +GO +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER OFF +GO + +CREATE PROCEDURE [dbo].[SearchOrganizationAccounts] +( + @ActorID int, + @ItemID int, + @FilterColumn nvarchar(50) = '', + @FilterValue nvarchar(50) = '', + @SortColumn nvarchar(50), + @IncludeMailboxes bit +) +AS +DECLARE @PackageID int +SELECT @PackageID = PackageID FROM ServiceItems +WHERE ItemID = @ItemID + +-- check rights +IF dbo.CheckActorPackageRights(@ActorID, @PackageID) = 0 +RAISERROR('You are not allowed to access this package', 16, 1) + +-- start +DECLARE @condition nvarchar(700) +SET @condition = ' +(EA.AccountType = 7 OR (EA.AccountType = 1 AND @IncludeMailboxes = 1) ) +AND EA.ItemID = @ItemID +' + +IF @FilterColumn <> '' AND @FilterColumn IS NOT NULL +AND @FilterValue <> '' AND @FilterValue IS NOT NULL +SET @condition = @condition + ' AND ' + @FilterColumn + ' LIKE ''' + @FilterValue + '''' + +IF @SortColumn IS NULL OR @SortColumn = '' +SET @SortColumn = 'EA.DisplayName ASC' + +DECLARE @sql nvarchar(3500) + +set @sql = ' +SELECT + EA.AccountID, + EA.ItemID, + EA.AccountType, + EA.AccountName, + EA.DisplayName, + EA.PrimaryEmailAddress, + EA.SubscriberNumber, + EA.UserPrincipalName, + (CASE WHEN LU.AccountID IS NULL THEN ''false'' ELSE ''true'' END) as IsLyncUser +FROM ExchangeAccounts AS EA +LEFT JOIN LyncUsers AS LU +ON LU.AccountID = EA.AccountID +WHERE ' + @condition + +print @sql + +exec sp_executesql @sql, N'@ItemID int, @IncludeMailboxes bit', +@ItemID, @IncludeMailboxes + +RETURN + +GO From d5b510aa3cfb2eb96c41cdef7cbec293991792a3 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Mon, 23 Mar 2015 06:51:21 -0400 Subject: [PATCH 8/8] Added tag build-2.1.0.621 for changeset 648933cdf289