Hyper-V replace config files with Service Settings

This commit is contained in:
Alexander Trofimov 2015-05-28 07:24:29 +03:00
parent 60bc7505ca
commit 45bb3c53a8
12 changed files with 673 additions and 194 deletions

View file

@ -12630,4 +12630,59 @@ SET Password = @Password, OneTimePasswordState = 0
WHERE UserID = @UserID WHERE UserID = @UserID
RETURN RETURN
GO GO
-- HyperV for config file
alter table ServiceProperties
alter column PropertyValue nvarchar(MAX) NULL
Go
ALTER PROCEDURE [dbo].[UpdateServiceProperties]
(
@ServiceID int,
@Xml ntext
)
AS
-- delete old properties
BEGIN TRAN
DECLARE @idoc int
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @xml
-- Execute a SELECT statement that uses the OPENXML rowset provider.
DELETE FROM ServiceProperties
WHERE ServiceID = @ServiceID
AND PropertyName COLLATE Latin1_General_CI_AS IN
(
SELECT PropertyName
FROM OPENXML(@idoc, '/properties/property', 1)
WITH (PropertyName nvarchar(50) '@name')
)
INSERT INTO ServiceProperties
(
ServiceID,
PropertyName,
PropertyValue
)
SELECT
@ServiceID,
PropertyName,
PropertyValue
FROM OPENXML(@idoc, '/properties/property',1) WITH
(
PropertyName nvarchar(50) '@name',
PropertyValue nvarchar(MAX) '@value'
) as PV
-- remove document
exec sp_xml_removedocument @idoc
COMMIT TRAN
RETURN
Go

View file

@ -165,12 +165,11 @@ namespace WebsitePanel.EnterpriseServer
{ {
// load service settings // load service settings
StringDictionary settings = ServerController.GetServiceSettings(serviceId); StringDictionary settings = ServerController.GetServiceSettings(serviceId);
string path = settings["OsTemplatesPath"]; string xml = settings["OsTemplates"];
// get proxy var config = new ConfigFile(xml);
VirtualizationServer2012 vs = GetVirtualizationProxy(serviceId);
return vs.GetLibraryItems(path); return config.LibraryItems;
} }
#endregion #endregion
@ -601,10 +600,7 @@ namespace WebsitePanel.EnterpriseServer
private static string GetCorrectTemplateFilePath(string templatesPath, string osTemplateFile) private static string GetCorrectTemplateFilePath(string templatesPath, string osTemplateFile)
{ {
if (osTemplateFile.Trim().EndsWith(".vhdx")) return Path.Combine(templatesPath, osTemplateFile);
return Path.Combine(templatesPath, osTemplateFile);
return Path.Combine(templatesPath, osTemplateFile + ".vhd");
} }
internal static void CreateVirtualMachineInternal(string taskId, VirtualMachine vm, LibraryItem osTemplate, internal static void CreateVirtualMachineInternal(string taskId, VirtualMachine vm, LibraryItem osTemplate,
@ -2159,12 +2155,11 @@ namespace WebsitePanel.EnterpriseServer
// load service settings // load service settings
StringDictionary settings = ServerController.GetServiceSettings(vm.ServiceId); StringDictionary settings = ServerController.GetServiceSettings(vm.ServiceId);
string path = settings["DvdLibraryPath"]; string xml = settings["DvdLibrary"];
// get proxy var config = new ConfigFile(xml);
VirtualizationServer2012 vs = GetVirtualizationProxy(vm.ServiceId);
return vs.GetLibraryItems(path); return config.LibraryItems;
} }
public static ResultObject InsertDvdDisk(int itemId, string isoPath) public static ResultObject InsertDvdDisk(int itemId, string isoPath)

View file

@ -0,0 +1,141 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
namespace WebsitePanel.Providers.Virtualization
{
public class ConfigFile
{
const string resultTemplate = @"
<?xml version=""1.0""?>
<items>
{0}
</items>";
const string itemTemplate = @"
<item path=""{0}"" legacyNetworkAdapter=""{1}"" remoteDesktop=""{2}"" processVolume=""{3}"">
<name>{4}</name>
<description>{5}</description>
<provisioning>
{6}
<vmconfig computerName=""{7}"" administratorPassword=""{8}"" networkAdapters=""{9}"" />
</provisioning>
</item>";
const string sysprepTemplate = @"<sysprep file=""{0}""/>";
public ConfigFile(string xml)
{
Xml = xml;
Load(xml);
}
public ConfigFile(LibraryItem[] libraryItems)
{
LibraryItems = libraryItems;
Load(libraryItems);
}
public LibraryItem[] LibraryItems { get; private set; }
public string Xml { get; private set; }
private void Load(string xmlText)
{
// create list
List<LibraryItem> items = new List<LibraryItem>();
if (string.IsNullOrEmpty(xmlText))
{
LibraryItems = items.ToArray();
return;
}
// load xml
XmlDocument xml = new XmlDocument();
xml.LoadXml(xmlText);
XmlNodeList nodeItems = xml.SelectNodes("/items/item");
foreach (XmlNode nodeItem in nodeItems)
{
LibraryItem item = new LibraryItem();
item.Path = nodeItem.Attributes["path"].Value;
// optional attributes
if (nodeItem.Attributes["diskSize"] != null)
item.DiskSize = Int32.Parse(nodeItem.Attributes["diskSize"].Value);
if (nodeItem.Attributes["legacyNetworkAdapter"] != null)
item.LegacyNetworkAdapter = Boolean.Parse(nodeItem.Attributes["legacyNetworkAdapter"].Value);
item.ProcessVolume = 0; // process (extend and sysprep) 1st volume by default
if (nodeItem.Attributes["processVolume"] != null)
item.ProcessVolume = Int32.Parse(nodeItem.Attributes["processVolume"].Value);
if (nodeItem.Attributes["remoteDesktop"] != null)
item.RemoteDesktop = Boolean.Parse(nodeItem.Attributes["remoteDesktop"].Value);
// inner nodes
item.Name = nodeItem.SelectSingleNode("name").InnerText;
var descriptionNode = nodeItem.SelectSingleNode("description");
if (descriptionNode != null)
item.Description = descriptionNode.InnerText;
// sysprep files
XmlNodeList nodesSyspep = nodeItem.SelectNodes("provisioning/sysprep");
List<string> sysprepFiles = new List<string>();
foreach (XmlNode nodeSyspep in nodesSyspep)
{
if (nodeSyspep.Attributes["file"] != null)
sysprepFiles.Add(nodeSyspep.Attributes["file"].Value);
}
item.SysprepFiles = sysprepFiles.ToArray();
// vmconfig
XmlNode nodeVmConfig = nodeItem.SelectSingleNode("provisioning/vmconfig");
if (nodeVmConfig != null)
{
if (nodeVmConfig.Attributes["computerName"] != null)
item.ProvisionComputerName = Boolean.Parse(nodeVmConfig.Attributes["computerName"].Value);
if (nodeVmConfig.Attributes["administratorPassword"] != null)
item.ProvisionAdministratorPassword =
Boolean.Parse(nodeVmConfig.Attributes["administratorPassword"].Value);
if (nodeVmConfig.Attributes["networkAdapters"] != null)
item.ProvisionNetworkAdapters = Boolean.Parse(nodeVmConfig.Attributes["networkAdapters"].Value);
}
items.Add(item);
}
LibraryItems = items.ToArray();
}
private void Load(LibraryItem[] libraryItems)
{
List<string> items = new List<string>();
foreach (var libraryItem in libraryItems)
{
var sysprep = "";
if (libraryItem.SysprepFiles != null && libraryItem.SysprepFiles.Any())
sysprep = string.Join("", libraryItem.SysprepFiles.Select(s => string.Format(sysprepTemplate, s)).ToArray());
items.Add(string.Format(itemTemplate, libraryItem.Path, libraryItem.LegacyNetworkAdapter,
libraryItem.RemoteDesktop, libraryItem.ProcessVolume, libraryItem.Name, libraryItem.Description,
sysprep, libraryItem.ProvisionComputerName, libraryItem.ProvisionAdministratorPassword,
libraryItem.ProvisionNetworkAdapters));
}
Xml = string.Format(resultTemplate, string.Join("", items.ToArray()));
}
}
}

View file

@ -77,9 +77,6 @@ namespace WebsitePanel.Providers.Virtualization
JobResult RemoveKVPItems(string vmId, string[] itemNames); JobResult RemoveKVPItems(string vmId, string[] itemNames);
JobResult ModifyKVPItems(string vmId, KvpExchangeDataItem[] items); JobResult ModifyKVPItems(string vmId, KvpExchangeDataItem[] items);
// Library
LibraryItem[] GetLibraryItems(string path);
// Storage // Storage
VirtualHardDiskInfo GetVirtualHardDiskInfo(string vhdPath); VirtualHardDiskInfo GetVirtualHardDiskInfo(string vhdPath);
MountedDiskInfo MountVirtualHardDisk(string vhdPath); MountedDiskInfo MountVirtualHardDisk(string vhdPath);

View file

@ -315,6 +315,7 @@
<Compile Include="Virtualization\ConcreteJobState.cs"> <Compile Include="Virtualization\ConcreteJobState.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Virtualization\Config\ConfigFile.cs" />
<Compile Include="Virtualization\ControllerType.cs" /> <Compile Include="Virtualization\ControllerType.cs" />
<Compile Include="Virtualization\IVirtualizationServer2012.cs" /> <Compile Include="Virtualization\IVirtualizationServer2012.cs" />
<Compile Include="Virtualization\IVirtualizationServer.cs"> <Compile Include="Virtualization\IVirtualizationServer.cs">
@ -325,7 +326,7 @@
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Virtualization\KvpExchangeDataItem.cs" /> <Compile Include="Virtualization\KvpExchangeDataItem.cs" />
<Compile Include="Virtualization\LibraryItem.cs" /> <Compile Include="Virtualization\Config\LibraryItem.cs" />
<Compile Include="Virtualization\LogicalDisk.cs" /> <Compile Include="Virtualization\LogicalDisk.cs" />
<Compile Include="Virtualization\DvdDriveInfo.cs" /> <Compile Include="Virtualization\DvdDriveInfo.cs" />
<Compile Include="Virtualization\MonitoredObjectAlert.cs" /> <Compile Include="Virtualization\MonitoredObjectAlert.cs" />

View file

@ -877,87 +877,6 @@ namespace WebsitePanel.Providers.Virtualization
} }
#endregion #endregion
#region Library
public LibraryItem[] GetLibraryItems(string path)
{
path = Path.Combine(FileUtils.EvaluateSystemVariables(path), Constants.LIBRARY_INDEX_FILE_NAME);
// convert to UNC if it is a remote computer
path = VdsHelper.ConvertToUNC(ServerNameSettings, path);
if (!File.Exists(path))
{
HostedSolutionLog.LogWarning("The folder does not contain 'index.xml' file: {0}", path);
return null;
}
// create list
List<LibraryItem> items = new List<LibraryItem>();
// load xml
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlNodeList nodeItems = xml.SelectNodes("/items/item");
if (nodeItems.Count == 0)
HostedSolutionLog.LogWarning("index.xml found, but contains 0 items: {0}", path);
foreach (XmlNode nodeItem in nodeItems)
{
LibraryItem item = new LibraryItem();
item.Path = nodeItem.Attributes["path"].Value;
// optional attributes
if (nodeItem.Attributes["diskSize"] != null)
item.DiskSize = Int32.Parse(nodeItem.Attributes["diskSize"].Value);
if (nodeItem.Attributes["legacyNetworkAdapter"] != null)
item.LegacyNetworkAdapter = Boolean.Parse(nodeItem.Attributes["legacyNetworkAdapter"].Value);
item.ProcessVolume = 0; // process (extend and sysprep) 1st volume by default
if (nodeItem.Attributes["processVolume"] != null)
item.ProcessVolume = Int32.Parse(nodeItem.Attributes["processVolume"].Value);
if (nodeItem.Attributes["remoteDesktop"] != null)
item.RemoteDesktop = Boolean.Parse(nodeItem.Attributes["remoteDesktop"].Value);
// inner nodes
item.Name = nodeItem.SelectSingleNode("name").InnerText;
item.Description = nodeItem.SelectSingleNode("description").InnerText;
// sysprep files
XmlNodeList nodesSyspep = nodeItem.SelectNodes("provisioning/sysprep");
List<string> sysprepFiles = new List<string>();
foreach (XmlNode nodeSyspep in nodesSyspep)
{
if (nodeSyspep.Attributes["file"] != null)
sysprepFiles.Add(nodeSyspep.Attributes["file"].Value);
}
item.SysprepFiles = sysprepFiles.ToArray();
// vmconfig
XmlNode nodeVmConfig = nodeItem.SelectSingleNode("provisioning/vmconfig");
if (nodeVmConfig != null)
{
if (nodeVmConfig.Attributes["computerName"] != null)
item.ProvisionComputerName = Boolean.Parse(nodeVmConfig.Attributes["computerName"].Value);
if (nodeVmConfig.Attributes["administratorPassword"] != null)
item.ProvisionAdministratorPassword = Boolean.Parse(nodeVmConfig.Attributes["administratorPassword"].Value);
if (nodeVmConfig.Attributes["networkAdapters"] != null)
item.ProvisionNetworkAdapters = Boolean.Parse(nodeVmConfig.Attributes["networkAdapters"].Value);
}
items.Add(item);
}
return items.ToArray();
}
#endregion
#region KVP #region KVP
public List<KvpExchangeDataItem> GetKVPItems(string vmId) public List<KvpExchangeDataItem> GetKVPItems(string vmId)
{ {

View file

@ -541,25 +541,6 @@ namespace WebsitePanel.Server
} }
#endregion #endregion
#region Library
[WebMethod, SoapHeader("settings")]
public LibraryItem[] GetLibraryItems(string path)
{
try
{
Log.WriteStart("'{0}' GetLibraryItems", ProviderSettings.ProviderName);
LibraryItem[] result = VirtualizationProvider.GetLibraryItems(path);
Log.WriteEnd("'{0}' GetLibraryItems", ProviderSettings.ProviderName);
return result;
}
catch (Exception ex)
{
Log.WriteError(String.Format("'{0}' GetLibraryItems", ProviderSettings.ProviderName), ex);
throw;
}
}
#endregion
#region KVP items #region KVP items
[WebMethod, SoapHeader("settings")] [WebMethod, SoapHeader("settings")]
public List<KvpExchangeDataItem> GetKVPItems(string vmId) public List<KvpExchangeDataItem> GetKVPItems(string vmId)

View file

@ -443,4 +443,76 @@ The following substitution variables can be used in the pattern:&lt;br/&gt;
<data name="locReplicaServer.Text" xml:space="preserve"> <data name="locReplicaServer.Text" xml:space="preserve">
<value>Replication Server:</value> <value>Replication Server:</value>
</data> </data>
<data name="btnAddDvd.Text" xml:space="preserve">
<value>Add DVD</value>
</data>
<data name="btnAddOsTemplate.Text" xml:space="preserve">
<value>Add OS Template</value>
</data>
<data name="btnRemoveDvd.Text" xml:space="preserve">
<value>Remove</value>
</data>
<data name="btnRemoveOsTemplate.Text" xml:space="preserve">
<value>Remove</value>
</data>
<data name="chkCanSetAdminPass.Text" xml:space="preserve">
<value>Can set an Administrator password</value>
</data>
<data name="chkCanSetComputerName.Text" xml:space="preserve">
<value>Can set a computer name</value>
</data>
<data name="chkCanSetNetwork.Text" xml:space="preserve">
<value>Can set Ip addresses</value>
</data>
<data name="chkLegacyNetworkAdapter.Text" xml:space="preserve">
<value>Use legacy adapter</value>
</data>
<data name="DvdDescriptionValidator.ErrorMessage" xml:space="preserve">
<value>Enter DVD description</value>
</data>
<data name="DvdFileNameValidator.ErrorMessage" xml:space="preserve">
<value>Enter DVD file name</value>
</data>
<data name="DvdNameValidator.ErrorMessage" xml:space="preserve">
<value>Enter DVD name</value>
</data>
<data name="locDvdDescription.Text" xml:space="preserve">
<value>Description:</value>
</data>
<data name="locDvdFileName.Text" xml:space="preserve">
<value>File name (with extension):</value>
</data>
<data name="locDvdLibrary.Text" xml:space="preserve">
<value>DVD Library</value>
</data>
<data name="locDvdName.Text" xml:space="preserve">
<value>Name:</value>
</data>
<data name="locProcessVolume.Text" xml:space="preserve">
<value>Index of the volume to expand:</value>
</data>
<data name="locSysprep.Text" xml:space="preserve">
<value>Sysprep files (separated by ';'):</value>
</data>
<data name="locTemplateFileName.Text" xml:space="preserve">
<value>File name (with extension):</value>
</data>
<data name="locTemplateName.Text" xml:space="preserve">
<value>Name:</value>
</data>
<data name="locTemplates.Text" xml:space="preserve">
<value>OS Templates</value>
</data>
<data name="TemplateFileNameValidator.ErrorMessage" xml:space="preserve">
<value>Enter OS template file name</value>
</data>
<data name="TemplateNameValidator.ErrorMessage" xml:space="preserve">
<value>Enter OS template name</value>
</data>
<data name="valProcessVolume.ErrorMessage" xml:space="preserve">
<value>Enter OS template process volume</value>
</data>
<data name="vcmProcessVolume.ErrorMessage" xml:space="preserve">
<value>Process volume should be a positive number</value>
</data>
</root> </root>

View file

@ -62,16 +62,7 @@
<br /> <br />
</td> </td>
</tr> </tr>
<tr>
<td class="SubHead">
<asp:Localize ID="locOSTemplatesPath" runat="server" meta:resourcekey="locOSTemplatesPath" Text="OS Templates path:"></asp:Localize>
</td>
<td>
<asp:TextBox Width="300px" CssClass="NormalTextBox" Runat="server" ID="txtOSTemplatesPath"></asp:TextBox>
<asp:RequiredFieldValidator ID="TemplatesPathValidator" runat="server" ControlToValidate="txtOSTemplatesPath"
Text="*" meta:resourcekey="TemplatesPathValidator" Display="Dynamic" SetFocusOnError="true" />
</td>
</tr>
<tr> <tr>
<td class="SubHead"> <td class="SubHead">
<asp:Localize ID="locExportedVpsPath" runat="server" meta:resourcekey="locExportedVpsPath" Text="Exported VPS path:"></asp:Localize> <asp:Localize ID="locExportedVpsPath" runat="server" meta:resourcekey="locExportedVpsPath" Text="Exported VPS path:"></asp:Localize>
@ -82,16 +73,6 @@
Text="*" meta:resourcekey="ExportedVpsPathValidator" Display="Dynamic" SetFocusOnError="true" /> Text="*" meta:resourcekey="ExportedVpsPathValidator" Display="Dynamic" SetFocusOnError="true" />
</td> </td>
</tr> </tr>
<tr>
<td class="SubHead" style="width:200px;">
<asp:Localize ID="locDvdIsoPath" runat="server" meta:resourcekey="locDvdIsoPath" Text="Path to DVD ISO files:"></asp:Localize>
</td>
<td>
<asp:TextBox Width="300px" CssClass="NormalTextBox" Runat="server" ID="txtDvdLibraryPath"></asp:TextBox>
<asp:RequiredFieldValidator ID="DvdLibraryPathValidator" runat="server" ControlToValidate="txtDvdLibraryPath"
Text="*" meta:resourcekey="DvdLibraryPathValidator" Display="Dynamic" SetFocusOnError="true" />
</td>
</tr>
</table> </table>
</fieldset> </fieldset>
<br /> <br />
@ -137,6 +118,165 @@
</fieldset> </fieldset>
<br /> <br />
<fieldset>
<legend>
<asp:Localize ID="locTemplates" runat="server" meta:resourcekey="locTemplates" Text="OS Templates"></asp:Localize>
</legend>
<table cellpadding="2" cellspacing="0" width="100%" style="margin: 10px;">
<tr>
<td class="SubHead">
<asp:Localize ID="locOSTemplatesPath" runat="server" meta:resourcekey="locOSTemplatesPath" Text="OS Templates path:"></asp:Localize>
</td>
<td>
<asp:TextBox Width="300px" CssClass="NormalTextBox" Runat="server" ID="txtOSTemplatesPath"></asp:TextBox>
<asp:RequiredFieldValidator ID="TemplatesPathValidator" runat="server" ControlToValidate="txtOSTemplatesPath"
Text="*" meta:resourcekey="TemplatesPathValidator" Display="Dynamic" SetFocusOnError="true" />
</td>
</tr>
</table>
<div style="margin-top: 15px;margin-bottom: 25px;margin-left: 10px;">
<asp:Button ID="btnAddOsTemplate" runat="server" meta:resourcekey="btnAddOsTemplate"
CssClass="Button1" Text="Add OS Template" CausesValidation="false"
OnClick="btnAddOsTemplate_Click" />
</div>
<asp:Repeater ID="repOsTemplates" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<table cellpadding="2" cellspacing="0" width="100%" style="margin: 10px;">
<tr>
<td class="SubHead" style="width: 200px;">
<asp:Localize ID="locTemplateName" runat="server" meta:resourcekey="locTemplateName" Text="Name:"></asp:Localize>
</td>
<td>
<asp:TextBox CssClass="NormalTextBox" runat="server" ID="txtTemplateName" Text='<%# Eval("Name") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="TemplateNameValidator" runat="server" ControlToValidate="txtTemplateName"
Text="*" meta:resourcekey="TemplateNameValidator" Display="Dynamic" SetFocusOnError="true" />
</td>
<td rowspan="3">
<asp:CheckBox ID="chkLegacyNetworkAdapter" runat="server" Checked='<%# Eval("LegacyNetworkAdapter") %>' meta:resourcekey="chkLegacyNetworkAdapter" Text="Use legacy adapter" /><br />
<%--<asp:CheckBox ID="chkRemoteDesktop" runat="server" Checked='<%# Eval("RemoteDesktop") %>' meta:resourcekey="chkRemoteDesktop" Text="Remote desktop" /><br/>--%>
<asp:CheckBox ID="chkCanSetComputerName" runat="server" Checked='<%# Eval("ProvisionComputerName") %>' meta:resourcekey="chkCanSetComputerName" Text="Can set a computer name" /><br />
<asp:CheckBox ID="chkCanSetAdminPass" runat="server" Checked='<%# Eval("ProvisionAdministratorPassword") %>' meta:resourcekey="chkCanSetAdminPass" Text="Can set an Administrator password" /><br />
<asp:CheckBox ID="chkCanSetNetwork" runat="server" Checked='<%# Eval("ProvisionNetworkAdapters") %>' meta:resourcekey="chkCanSetNetwork" Text="Can set Ip addresses" /><br />
</td>
<td rowspan="3">
<asp:Button ID="btnRemoveOsTemplate" runat="server" meta:resourcekey="btnRemoveOsTemplate"
CssClass="Button1" Text="Remove" CausesValidation="false"
CommandName="Remove" CommandArgument="<%# Container.ItemIndex %>" OnCommand="btnRemoveOsTemplate_OnCommand" />
</td>
</tr>
<tr>
<td class="SubHead">
<asp:Localize ID="locTemplateFileName" runat="server" meta:resourcekey="locTemplateFileName" Text="File name (with extension):"></asp:Localize>
</td>
<td>
<asp:TextBox CssClass="NormalTextBox" runat="server" ID="txtTemplateFileName" Text='<%# Eval("Path") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="TemplateFileNameValidator" runat="server" ControlToValidate="txtTemplateFileName"
Text="*" meta:resourcekey="TemplateFileNameValidator" Display="Dynamic" SetFocusOnError="true" />
</td>
</tr>
<tr>
<td class="SubHead">
<asp:Localize ID="locProcessVolume" runat="server" meta:resourcekey="locProcessVolume" Text="Index of the volume to expand:"></asp:Localize>
</td>
<td>
<asp:TextBox CssClass="NormalTextBox" runat="server" ID="txtProcessVolume" Text='<%# Eval("ProcessVolume") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="valProcessVolume" runat="server" ControlToValidate="txtProcessVolume"
Text="*" meta:resourcekey="valProcessVolume" Display="Dynamic" SetFocusOnError="true" />
<asp:CompareValidator runat="server" ID="vcmProcessVolume" ControlToValidate="txtProcessVolume"
Type="Integer" Operator="GreaterThanEqual" Display="Dynamic" ValueToCompare="0" meta:resourcekey="vcmProcessVolume" />
</td>
</tr>
<tr>
<td class="SubHead">
<asp:Localize ID="locSysprep" runat="server" meta:resourcekey="locSysprep" Text="Sysprep files:"></asp:Localize>
</td>
<td colspan="2">
<asp:TextBox Width="470px" CssClass="NormalTextBox" runat="server" ID="txtSysprep" Text='<%# string.Join(";", (string[])Eval("SysprepFiles")) %>'></asp:TextBox>
</td>
</tr>
</table>
</ItemTemplate>
<SeparatorTemplate>
<br/>
<%--<hr style="margin-bottom: 20px; margin-top: 10px; margin-left: 10px; margin-right: 10px;"/>--%>
</SeparatorTemplate>
</asp:Repeater>
</fieldset>
<br />
<fieldset>
<legend>
<asp:Localize ID="locDvdLibrary" runat="server" meta:resourcekey="locDvdLibrary" Text="DVD Library"></asp:Localize>
</legend>
<table cellpadding="2" cellspacing="0" width="100%" style="margin: 10px;">
<tr>
<td class="SubHead" style="width: 200px;">
<asp:Localize ID="locDvdIsoPath" runat="server" meta:resourcekey="locDvdIsoPath" Text="Path to DVD ISO files:"></asp:Localize>
</td>
<td>
<asp:TextBox Width="300px" CssClass="NormalTextBox" runat="server" ID="txtDvdLibraryPath"></asp:TextBox>
<asp:RequiredFieldValidator ID="DvdLibraryPathValidator" runat="server" ControlToValidate="txtDvdLibraryPath"
Text="*" meta:resourcekey="DvdLibraryPathValidator" Display="Dynamic" SetFocusOnError="true" />
</td>
</tr>
</table>
<div style="margin-top: 15px;margin-bottom: 25px;margin-left: 10px;">
<asp:Button ID="btnAddDvd" runat="server" meta:resourcekey="btnAddDvd"
CssClass="Button1" Text="Add DVD" CausesValidation="false"
OnClick="btnAddDvd_Click" />
</div>
<asp:Repeater ID="repDvdLibrary" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<table cellpadding="2" cellspacing="0" width="100%" style="margin: 10px;">
<tr>
<td class="SubHead" style="width: 200px;">
<asp:Localize ID="locDvdName" runat="server" meta:resourcekey="locDvdName" Text="Name:"></asp:Localize>
</td>
<td>
<asp:TextBox CssClass="NormalTextBox" runat="server" ID="txtDvdName" Text='<%# Eval("Name") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="DvdNameValidator" runat="server" ControlToValidate="txtDvdName"
Text="*" meta:resourcekey="DvdNameValidator" Display="Dynamic" SetFocusOnError="true" />
</td>
<td rowspan="3">
<asp:Button ID="btnRemoveDvd" runat="server" meta:resourcekey="btnRemoveDvd"
CssClass="Button1" Text="Remove" CausesValidation="false"
CommandName="Remove" CommandArgument="<%# Container.ItemIndex %>" OnCommand="btnRemoveDvd_OnCommand" />
</td>
</tr>
<tr>
<td class="SubHead">
<asp:Localize ID="locDvdDescription" runat="server" meta:resourcekey="locDvdDescription" Text="Description:"></asp:Localize>
</td>
<td>
<asp:TextBox CssClass="NormalTextBox" runat="server" ID="txtDvdDescription" Text='<%# Eval("Description") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="DvdDescriptionValidator" runat="server" ControlToValidate="txtDvdDescription"
Text="*" meta:resourcekey="DvdDescriptionValidator" Display="Dynamic" SetFocusOnError="true" />
</td>
</tr>
<tr>
<td class="SubHead">
<asp:Localize ID="locDvdFileName" runat="server" meta:resourcekey="locDvdFileName" Text="File name (with extension):"></asp:Localize>
</td>
<td>
<asp:TextBox CssClass="NormalTextBox" runat="server" ID="txtDvdFileName" Text='<%# Eval("Path") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="DvdFileNameValidator" runat="server" ControlToValidate="txtDvdFileName"
Text="*" meta:resourcekey="DvdFileNameValidator" Display="Dynamic" SetFocusOnError="true" />
</td>
</tr>
</table>
</ItemTemplate>
<SeparatorTemplate>
<br/>
<%--<hr style="margin-bottom: 20px; margin-top: 10px; margin-left: 10px; margin-right: 10px;"/>--%>
</SeparatorTemplate>
</asp:Repeater>
</fieldset>
<br />
<fieldset> <fieldset>
<legend> <legend>
<asp:Localize ID="locReplication" runat="server" meta:resourcekey="locReplication" Text="Replication"></asp:Localize> <asp:Localize ID="locReplication" runat="server" meta:resourcekey="locReplication" Text="Replication"></asp:Localize>

View file

@ -61,7 +61,6 @@ namespace WebsitePanel.Portal.ProviderControls
// general settings // general settings
txtVpsRootFolder.Text = settings["RootFolder"]; txtVpsRootFolder.Text = settings["RootFolder"];
txtOSTemplatesPath.Text = settings["OsTemplatesPath"];
txtExportedVpsPath.Text = settings["ExportedVpsPath"]; txtExportedVpsPath.Text = settings["ExportedVpsPath"];
// CPU // CPU
@ -69,8 +68,15 @@ namespace WebsitePanel.Portal.ProviderControls
txtCpuReserve.Text = settings["CpuReserve"]; txtCpuReserve.Text = settings["CpuReserve"];
txtCpuWeight.Text = settings["CpuWeight"]; txtCpuWeight.Text = settings["CpuWeight"];
// OS Templates
txtOSTemplatesPath.Text = settings["OsTemplatesPath"];
repOsTemplates.DataSource = new ConfigFile(settings["OsTemplates"]).LibraryItems; //ES.Services.VPS2012.GetOperatingSystemTemplatesByServiceId(PanelRequest.ServiceId).ToList();
repOsTemplates.DataBind();
// DVD library // DVD library
txtDvdLibraryPath.Text = settings["DvdLibraryPath"]; txtDvdLibraryPath.Text = settings["DvdLibraryPath"];
repDvdLibrary.DataSource = new ConfigFile(settings["DvdLibrary"]).LibraryItems;
repDvdLibrary.DataBind();
// VHD type // VHD type
radioVirtualDiskType.SelectedValue = settings["VirtualDiskType"]; radioVirtualDiskType.SelectedValue = settings["VirtualDiskType"];
@ -132,7 +138,6 @@ namespace WebsitePanel.Portal.ProviderControls
// general settings // general settings
settings["RootFolder"] = txtVpsRootFolder.Text.Trim(); settings["RootFolder"] = txtVpsRootFolder.Text.Trim();
settings["OsTemplatesPath"] = txtOSTemplatesPath.Text.Trim();
settings["ExportedVpsPath"] = txtExportedVpsPath.Text.Trim(); settings["ExportedVpsPath"] = txtExportedVpsPath.Text.Trim();
// CPU // CPU
@ -140,7 +145,12 @@ namespace WebsitePanel.Portal.ProviderControls
settings["CpuReserve"] = txtCpuReserve.Text.Trim(); settings["CpuReserve"] = txtCpuReserve.Text.Trim();
settings["CpuWeight"] = txtCpuWeight.Text.Trim(); settings["CpuWeight"] = txtCpuWeight.Text.Trim();
// OS Templates
settings["OsTemplates"] = GetConfigXml(GetOsTemplates());
settings["OsTemplatesPath"] = txtOSTemplatesPath.Text.Trim();
// DVD library // DVD library
settings["DvdLibrary"] = GetConfigXml(GetDvds());
settings["DvdLibraryPath"] = txtDvdLibraryPath.Text.Trim(); settings["DvdLibraryPath"] = txtDvdLibraryPath.Text.Trim();
// VHD type // VHD type
@ -301,7 +311,7 @@ namespace WebsitePanel.Portal.ProviderControls
ReplicaPathErrorTr.Visible = ReplicaErrorTr.Visible = false; ReplicaPathErrorTr.Visible = ReplicaErrorTr.Visible = false;
if (IsReplicaServer) BindCertificates(); if (IsReplicaServer) BindCertificates();
if (EnabledReplica) BindReplicaServices(); if (EnabledReplica) BindReplicaServices();
} }
protected void radioServer_SelectedIndexChanged(object sender, EventArgs e) protected void radioServer_SelectedIndexChanged(object sender, EventArgs e)
{ {
@ -334,6 +344,7 @@ namespace WebsitePanel.Portal.ProviderControls
SetUnsetReplication(); SetUnsetReplication();
} }
private void SetUnsetReplication() private void SetUnsetReplication()
{ {
if (!IsReplicaServer) if (!IsReplicaServer)
@ -354,5 +365,118 @@ namespace WebsitePanel.Portal.ProviderControls
if (!result.IsSuccess) if (!result.IsSuccess)
ReplicaErrorTr.Visible = true; ReplicaErrorTr.Visible = true;
} }
// OS Templates
protected void btnAddOsTemplate_Click(object sender, EventArgs e)
{
var templates = GetOsTemplates();
templates.Add(new LibraryItem());
RebindOsTemplate(templates);
}
protected void btnRemoveOsTemplate_OnCommand(object sender, CommandEventArgs e)
{
var templates = GetOsTemplates();
templates.RemoveAt(Convert.ToInt32(e.CommandArgument));
RebindOsTemplate(templates);
}
private List<LibraryItem> GetOsTemplates()
{
var result = new List<LibraryItem>();
foreach (RepeaterItem item in repOsTemplates.Items)
{
var template = new LibraryItem();
int processVolume;
template.Name = GetTextBoxText(item, "txtTemplateName");
template.Path = GetTextBoxText(item, "txtTemplateFileName");
int.TryParse(GetTextBoxText(item, "txtProcessVolume"), out processVolume);
template.ProcessVolume = processVolume;
template.LegacyNetworkAdapter = GetCheckBoxValue(item, "chkLegacyNetworkAdapter");
template.RemoteDesktop = true; // obsolete
template.ProvisionComputerName = GetCheckBoxValue(item, "chkCanSetComputerName");
template.ProvisionAdministratorPassword = GetCheckBoxValue(item, "chkCanSetAdminPass");
template.ProvisionNetworkAdapters = GetCheckBoxValue(item, "chkCanSetNetwork");
var syspreps = GetTextBoxText(item, "txtSysprep").Split(new[] {";"}, StringSplitOptions.RemoveEmptyEntries);
template.SysprepFiles = syspreps.Select(s=>s.Trim()).ToArray();
result.Add(template);
}
return result;
}
private void RebindOsTemplate(List<LibraryItem> templates)
{
repOsTemplates.DataSource = templates;
repOsTemplates.DataBind();
}
private string GetConfigXml(List<LibraryItem> items)
{
var templates = items.ToArray();
return new ConfigFile(templates).Xml;
}
private string GetTextBoxText(RepeaterItem item, string name)
{
return (item.FindControl(name) as TextBox).Text;
}
private bool GetCheckBoxValue(RepeaterItem item, string name)
{
return (item.FindControl(name) as CheckBox).Checked;
}
// DVD Library
protected void btnAddDvd_Click(object sender, EventArgs e)
{
var dvds = GetDvds();
dvds.Add(new LibraryItem());
RebindDvds(dvds);
}
protected void btnRemoveDvd_OnCommand(object sender, CommandEventArgs e)
{
var dvds = GetDvds();
dvds.RemoveAt(Convert.ToInt32(e.CommandArgument));
RebindDvds(dvds);
}
private List<LibraryItem> GetDvds()
{
var result = new List<LibraryItem>();
foreach (RepeaterItem item in repDvdLibrary.Items)
{
var dvd = new LibraryItem();
dvd.Name = GetTextBoxText(item, "txtDvdName");
dvd.Description = GetTextBoxText(item, "txtDvdDescription");
dvd.Path = GetTextBoxText(item, "txtDvdFileName");
result.Add(dvd);
}
return result;
}
private void RebindDvds(List<LibraryItem> dvds)
{
repDvdLibrary.DataSource = dvds;
repDvdLibrary.DataBind();
}
} }
} }

View file

@ -147,33 +147,6 @@ namespace WebsitePanel.Portal.ProviderControls {
/// </remarks> /// </remarks>
protected global::System.Web.UI.WebControls.Localize locFolderVariables; protected global::System.Web.UI.WebControls.Localize locFolderVariables;
/// <summary>
/// locOSTemplatesPath control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize locOSTemplatesPath;
/// <summary>
/// txtOSTemplatesPath control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtOSTemplatesPath;
/// <summary>
/// TemplatesPathValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator TemplatesPathValidator;
/// <summary> /// <summary>
/// locExportedVpsPath control. /// locExportedVpsPath control.
/// </summary> /// </summary>
@ -201,33 +174,6 @@ namespace WebsitePanel.Portal.ProviderControls {
/// </remarks> /// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator ExportedVpsPathValidator; protected global::System.Web.UI.WebControls.RequiredFieldValidator ExportedVpsPathValidator;
/// <summary>
/// locDvdIsoPath control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize locDvdIsoPath;
/// <summary>
/// txtDvdLibraryPath control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtDvdLibraryPath;
/// <summary>
/// DvdLibraryPathValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator DvdLibraryPathValidator;
/// <summary> /// <summary>
/// locProcessorSettings control. /// locProcessorSettings control.
/// </summary> /// </summary>
@ -318,6 +264,114 @@ namespace WebsitePanel.Portal.ProviderControls {
/// </remarks> /// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator CpuWeightValidator; protected global::System.Web.UI.WebControls.RequiredFieldValidator CpuWeightValidator;
/// <summary>
/// locTemplates control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize locTemplates;
/// <summary>
/// locOSTemplatesPath control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize locOSTemplatesPath;
/// <summary>
/// txtOSTemplatesPath control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtOSTemplatesPath;
/// <summary>
/// TemplatesPathValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator TemplatesPathValidator;
/// <summary>
/// btnAddOsTemplate control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button btnAddOsTemplate;
/// <summary>
/// repOsTemplates control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Repeater repOsTemplates;
/// <summary>
/// locDvdLibrary control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize locDvdLibrary;
/// <summary>
/// locDvdIsoPath control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize locDvdIsoPath;
/// <summary>
/// txtDvdLibraryPath control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtDvdLibraryPath;
/// <summary>
/// DvdLibraryPathValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator DvdLibraryPathValidator;
/// <summary>
/// btnAddDvd control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button btnAddDvd;
/// <summary>
/// repDvdLibrary control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Repeater repDvdLibrary;
/// <summary> /// <summary>
/// locReplication control. /// locReplication control.
/// </summary> /// </summary>