/* Copyright (c) Citrix Systems, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Management;
using System.Reflection;
using System.Resources;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using XenOvf.Definitions;
using XenOvf.Utilities;
using XenCenterLib.Archive;
using XenCenterLib.Compression;
namespace XenOvf
{
public partial class OVF
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly log4net.ILog auditLog = log4net.LogManager.GetLogger("Audit");
private static readonly log4net.ILog traceLog = log4net.LogManager.GetLogger("Trace");
///
/// Event Registration of changes in Ovf state.
///
public static event Action Changed;
///
/// Protected method call for eventing.
///
/// OvfEventArgs
private static void OnChanged(OvfEventArgs e)
{
if (Changed != null)
{
Changed(e);
}
}
private const long KB = 1024;
private const long MB = (KB * 1024);
private const long GB = (MB * 1024);
private static int _processId = 0;
private static string _touchFile;
private static bool _promptForEula = true;
internal static ResourceManager _rm = new ResourceManager("XenOvf.Messages", Assembly.GetExecutingAssembly());
internal static ResourceManager _ovfrm = new ResourceManager("XenOvf.Content", Assembly.GetExecutingAssembly());
#region PUBLIC
public OVF()
{
UnLoad();
}
#region PROPERTIES
public static object AlgorithmMap(string key)
{
return Properties.Settings.Default[key];
}
public bool PromptForEula
{
get { return _promptForEula; }
set { _promptForEula = value; }
}
#endregion
#region LOAD OVF
///
/// Load an OVF XML File into OVF class context
///
///
///
public static EnvelopeType Load(string filename)
{
return Tools.LoadOvfXml(filename);
}
#endregion
#region SAVE OVF
public static void SaveAs(EnvelopeType ovfEnv, string filename)
{
SaveAs(ToXml(ovfEnv), filename);
}
public static void SaveAs(string OvfXml, string filename)
{
log.DebugFormat("OVF.SaveAs: {0}", filename);
if (OvfXml == null)
{
log.Error("SaveAs: cannot save NULL string OvfXml");
throw new ArgumentNullException();
}
if (filename == null)
{
log.Error("SaveAs: cannot save OvfXml. Filename was NULL");
throw new ArgumentNullException();
}
string oldfile = string.Format(@"{0}_ovf.old", Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename)));
try
{
if (File.Exists(filename))
{
if (File.Exists(oldfile))
{
File.Delete(oldfile);
}
File.Move(filename, oldfile);
}
}
catch (Exception ex)
{
log.ErrorFormat("File handling error. {0}", ex.Message);
}
FileStream fs = null;
StreamWriter sw = null;
try
{
fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
sw = new StreamWriter(fs);
sw.Write(OvfXml);
sw.Flush();
}
catch (Exception ex)
{
log.ErrorFormat("SaveAs FAILED: {0} with {1}", filename, ex.Message);
throw;
}
finally
{
if (sw != null) sw.Close();
if (fs != null) fs.Close();
}
if (File.Exists(oldfile)) { File.Delete(oldfile); }
log.Debug("OVF.SaveAs completed");
}
#endregion
#region UNLOAD OVF
///
/// Clears memory and resets to defaults.
///
public void UnLoad()
{
mappings.Clear();
Win32_ComputerSystem = null;
Win32_Processor.Clear();
Win32_CDROMDrive.Clear();
Win32_DiskDrive.Clear();
Win32_NetworkAdapter.Clear();
Win32_IDEController.Clear();
Win32_SCSIController.Clear();
Win32_IDEControllerDevice.Clear();
Win32_SCSIControllerDevice.Clear();
Win32_DiskPartition.Clear();
Win32_DiskDriveToDiskPartition.Clear();
}
#endregion
#region CHECK FOR FILE(S) METHODs (and HAS methods)
public static bool HasDeploymentOptions(EnvelopeType ovfObj)
{
DeploymentOptionSection_Type[] dos = FindSections(ovfObj);
if (dos != null && dos.Length > 0)
{
return true;
}
return false;
}
public static bool HasEula(EnvelopeType ovfObj)
{
EulaSection_Type[] eulas = FindSections(ovfObj);
if (eulas != null && eulas.Length > 0)
{
return true;
}
return false;
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope",
Justification = "Streams are used in embedded streams and are disposed appropriately.")]
private static bool CheckForFileExt(string filename, string extension)
{
string ovfpath = Path.GetDirectoryName(filename);
string ovfname = Path.GetFileNameWithoutExtension(filename);
string findfile = Path.Combine(ovfpath, string.Format("{0}.{1}", ovfname, extension));
string ext = Path.GetExtension(filename);
bool foundfile = false;
if (ext.ToLower().EndsWith("gz") || ext.ToLower().EndsWith("bz2"))
{
ovfname = Path.GetFileNameWithoutExtension(ovfname);
}
if (ext.ToLower().EndsWith("ovf"))
{
if (File.Exists(findfile))
{
log.InfoFormat("File: OVF: {0} found file with (.{1}) extension", filename, extension);
foundfile = true;
}
else
{
log.InfoFormat("File: OVF: {0} did not find file with (.{1}) extension", filename, extension);
foundfile = false;
}
}
else if (ext.ToLower().EndsWith("ova") ||
ext.ToLower().EndsWith("gz") ||
ext.ToLower().EndsWith("bz2"))
{
string origDir = Directory.GetCurrentDirectory();
Directory.SetCurrentDirectory(ovfpath);
Stream inputStream = null; // new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None);
#region DECOMPRESSION STREAM
try
{
if (ext.ToLower().EndsWith("gz") || ext.ToLower().EndsWith("bz2")) // need to decompress.
{
log.Info("OVA is compressed, de-compression stream inserted");
string ovaext = Path.GetExtension(ovfname);
if (ovaext.ToLower().EndsWith("ova"))
{
FileStream fsStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None);
if (Properties.Settings.Default.useGZip)
{
inputStream = CompressionFactory.Reader(CompressionFactory.Type.Gz, fsStream);
}
else
{
inputStream = CompressionFactory.Reader(CompressionFactory.Type.Bz2, fsStream);
}
}
else
{
throw new ArgumentException(Messages.OVF_COMPRESSED_OVA_INVALID);
}
}
else
{
inputStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None);
}
}
catch
{
if (inputStream != null)
{
inputStream.Dispose();
}
throw;
}
#endregion
if (inputStream == null)
{
throw new IOException(string.Format(Messages.OVF_COULD_NOT_OPEN_STREAM, filename));
}
ArchiveIterator tar = ArchiveFactory.Reader(ArchiveFactory.Type.Tar, inputStream);
try
{
while(tar.HasNext())
{
string ovaext = Path.GetExtension(tar.CurrentFileName());
log.DebugFormat("OVA: File: {0}", tar.CurrentFileName());
if (tar.CurrentFileName() != null && ovaext.ToLower().Contains(extension.ToLower()))
{
log.InfoFormat("OVF: File: {0} found file with (.{1}) extension", tar.CurrentFileName(), extension);
foundfile = true;
break;
}
if (tar.CurrentFileName() != null &&
!(Path.GetExtension(tar.CurrentFileName()).EndsWith(Properties.Settings.Default.ovfFileExtension)) &&
!(Path.GetExtension(tar.CurrentFileName()).EndsWith(Properties.Settings.Default.manifestFileExtension)) &&
!(Path.GetExtension(tar.CurrentFileName()).EndsWith(Properties.Settings.Default.certificateFileExtension)))
{
foundfile = false;
break;
}
}
}
catch (Exception ex)
{
log.ErrorFormat("OVA search FAILED with {0}", ex.Message);
throw;
}
finally
{
if (inputStream != null) inputStream.Dispose();
if (tar != null) tar.Dispose();
Directory.SetCurrentDirectory(origDir);
}
return foundfile;
}
else
{
log.InfoFormat("Unknown extension {0}", ext);
foundfile = false;
}
return foundfile;
}
#endregion
#region ADDs
public string AddAnnotation(EnvelopeType ovfObj, string vsId, string info, string annotation)
{
return AddAnnotation(ovfObj, vsId, Properties.Settings.Default.Language, info, annotation);
}
public string AddAnnotation(EnvelopeType ovfObj, string vsId, string lang, string info, string annotation)
{
VirtualSystem_Type vs = FindVirtualSystemById(ovfObj, vsId);
List sections = new List();
sections.AddRange(vs.Items);
AnnotationSection_Type annotate = new AnnotationSection_Type();
annotate.Id = Guid.NewGuid().ToString();
annotate.Info = new Msg_Type(AddToStringSection(ovfObj, lang, info), info);
annotate.Annotation = new Msg_Type(AddToStringSection(ovfObj, lang, info), info);
sections.Add(annotate);
vs.Items = sections.ToArray();
return annotate.Id;
}
public static string AddCDROM(EnvelopeType ovfObj, string vsId, string cdId, string caption, string description)
{
return AddCDROM(ovfObj, vsId, Properties.Settings.Default.Language, cdId, caption, description);
}
///
/// Add a CD/DVD Drive
///
/// EnvelopeType
/// Virtual System Identifier
/// InstanceID
/// string short description
/// string longer description
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands",
Justification = "Logging mechanism")]
public static string AddCDROM(EnvelopeType ovfObj, string vsId, string lang, string cdId, string caption, string description)
{
RASD_Type rasd = new RASD_Type();
rasd.required = false;
rasd.AllocationUnits = new cimString(_ovfrm.GetString("RASD_16_ALLOCATIONUNITS"));
rasd.AutomaticAllocation = new cimBoolean();
rasd.AutomaticAllocation.Value = true;
rasd.ConsumerVisibility = new ConsumerVisibility();
rasd.ConsumerVisibility.Value = 3; //From MS.
rasd.Caption = new Caption(caption);
rasd.Description = new cimString(description);
rasd.ElementName = new cimString(_ovfrm.GetString("RASD_16_ELEMENTNAME"));
rasd.InstanceID = new cimString(cdId);
rasd.Limit = new cimUnsignedLong();
rasd.Limit.Value = 1; // From MS;
rasd.MappingBehavior = new MappingBehavior();
rasd.MappingBehavior.Value = 0; // From MS.
rasd.ResourceType = new ResourceType();
rasd.ResourceType.Value = 16; // DVD Drive
rasd.VirtualQuantity = new cimUnsignedLong();
rasd.VirtualQuantity.Value = 1;
rasd.Weight = new cimUnsignedInt();
rasd.Weight.Value = 0; // From MS.
AddRasdToAllVHS(ovfObj, vsId, rasd);
log.Debug("OVF.AddCDDrive completed");
return rasd.InstanceID.Value;
}
public void AddController(EnvelopeType ovfObj, string vsId, DeviceType type, string deviceId, int iteration)
{
AddController(ovfObj, vsId, Properties.Settings.Default.Language, type, deviceId, iteration);
}
///
/// Add a controller to the mix.
///
/// object of type EnvelopeType
/// System Instance ID
/// Resource Type: 5 = IDE, 6 = SCSI
/// String identifying the device to match to the controller
/// which controller 0 = first, 1, 2, 3... (per type)
/// InstanceID of Controller
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands",
Justification = "Logging mechanism")]
public void AddController(EnvelopeType ovfObj, string vsId, string lang, DeviceType type, string deviceId, int iteration)
{
VirtualHardwareSection_Type[] vhsArray = FindVirtualHardwareSection(ovfObj, vsId);
foreach (VirtualHardwareSection_Type vhs in vhsArray)
{
AddControllerToVHS(vhs, lang, type, deviceId, iteration);
}
log.Debug("OVF.AddController completed");
}
///
/// Add a controller to the mix.
///
/// object of type EnvelopeType
/// System Instance ID
/// Resource Type: 5 = IDE, 6 = SCSI
/// String identifying the device to match to the controller
/// which controller 0 = first, 1, 2, 3... (per type)
/// InstanceID of Controller
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands",
Justification = "Logging mechanism")]
public void AddControllerToVHS(object vhsObj, string lang, DeviceType type, string deviceId, int iteration)
{
VirtualHardwareSection_Type vhs = (VirtualHardwareSection_Type)vhsObj;
RASD_Type rasd = new RASD_Type();
string controllername = _ovfrm.GetString("RASD_CONTROLLER_UNKNOWN");
switch (type)
{
case DeviceType.IDE: { controllername = _ovfrm.GetString("RASD_CONTROLLER_IDE"); break; }
case DeviceType.SCSI: { controllername = _ovfrm.GetString("RASD_CONTROLLER_SCSI"); break; }
default: { controllername = _ovfrm.GetString("RASD_CONTROLLER_OTHER"); break; }
}
string caption = string.Format("{0} {1}", controllername, iteration);
rasd.required = false; // as default change to FALSE, if we make a connection, it'll change to true.
rasd.Address = new cimString(Convert.ToString(iteration));
rasd.AllocationUnits = new cimString("Controllers");
rasd.Caption = new Caption(caption);
rasd.ConsumerVisibility = new ConsumerVisibility();
rasd.ConsumerVisibility.Value = 3;
rasd.Description = new cimString(string.Format(_ovfrm.GetString("RASD_CONTROLLER_DESCRIPTION"), controllername));
rasd.ElementName = new cimString(string.Format(_ovfrm.GetString("RASD_CONTROLLER_ELEMENTNAME"), controllername, iteration));
rasd.InstanceID = new cimString(deviceId);
if (type == DeviceType.SCSI)
{
rasd.ResourceSubType = new cimString(_ovfrm.GetString("RASD_CONTROLLER_SCSI_SUBTYPE"));
}
rasd.Limit = new cimUnsignedLong();
rasd.Limit.Value = 2;
rasd.ResourceType = new ResourceType();
rasd.ResourceType.Value = (ushort)type;
rasd.VirtualQuantity = new cimUnsignedLong();
rasd.VirtualQuantity.Value = 1;
rasd.Weight = new cimUnsignedInt();
rasd.Weight.Value = 0;
List rasds = new List();
rasds.Add(rasd);
if (vhs.Item != null && vhs.Item.Length > 0)
{
rasds.AddRange(vhs.Item);
}
vhs.Item = rasds.ToArray();
log.Debug("OVF.AddController completed");
}
public string AddDeploymentOption(EnvelopeType ovfObj, string label, string description, bool isdefault)
{
return AddDeploymentOption(ovfObj, Properties.Settings.Default.Language, label, description, isdefault);
}
public string AddDeploymentOption(EnvelopeType env, string lang, string label, string description, bool isdefault)
{
DeploymentOptionSection_Type dos = null;
List sections = new List();
Section_Type[] sectionArray = null;
if (env.Sections != null)
{
sectionArray = env.Sections;
}
foreach (Section_Type sect in sectionArray)
{
if (sect is DeploymentOptionSection_Type)
{
dos = (DeploymentOptionSection_Type)sect;
}
else
{
sections.Add(sect);
}
}
if (dos == null)
{
dos = new DeploymentOptionSection_Type();
dos.Id = Guid.NewGuid().ToString();
}
DeploymentOptionSection_TypeConfiguration conf = new DeploymentOptionSection_TypeConfiguration();
conf.@default = isdefault;
conf.Description = new Msg_Type(AddToStringSection(env, lang, description), description);
conf.Label = new Msg_Type(AddToStringSection(env, lang, label), label);
conf.id = Guid.NewGuid().ToString();
List confs = new List();
if (dos.Configuration != null && dos.Configuration.Length > 0)
{
confs.AddRange(dos.Configuration);
}
confs.Add(conf);
dos.Configuration = confs.ToArray();
sections.Add(dos);
env.Sections = sections.ToArray();
return conf.id;
}
public void AddDeviceToController(EnvelopeType ovfObj, string vsId, string deviceInstanceId, string controllerInstanceId, string AddressOnController)
{
AddDeviceToController(ovfObj, vsId, Properties.Settings.Default.Language, deviceInstanceId, controllerInstanceId, AddressOnController);
}
///
/// Connect a Disk (VHD) to a Controller ie: IDE or SCSI and where on controller it should exist.
///
/// EnvelopeType
/// string Virtual System Identifier
/// instance ID of device
/// instance ID of controller
/// where on controller 0...
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands",
Justification = "Logging mechanism")]
public void AddDeviceToController(EnvelopeType ovfObj, string vsId, string lang, string deviceInstanceId, string controllerInstanceId, string AddressOnController)
{
VirtualHardwareSection_Type[] vhsArray = FindVirtualHardwareSection(ovfObj, vsId);
foreach (VirtualHardwareSection_Type vhs in vhsArray)
{
foreach (RASD_Type rasd in vhs.Item)
{
if (rasd.InstanceID.Value.Equals(deviceInstanceId))
{
rasd.Parent = new cimString(controllerInstanceId);
rasd.AddressOnParent = new cimString(AddressOnController);
}
else if (rasd.InstanceID.Value.Equals(controllerInstanceId))
{
rasd.required = true;
}
}
}
log.Debug("OVF.AddDeviceToController completed");
return;
}
public static void AddDisk(EnvelopeType ovfObj, string vsId, string diskId, string vhdFileName, bool bootable, string name, string description, ulong filesize, ulong capacity)
{
AddDisk(ovfObj, vsId, diskId, Properties.Settings.Default.Language, vhdFileName, bootable, name, description, filesize, capacity);
}
///
/// Add a VHD to the VM
///
/// EnvelopeType
/// Which VM to apply to
/// The RASDs InstanceID
/// File Name of VHD (needs to be in the same directory as OVF
/// Is this disk bootable
/// Short string describing disk
/// Description of VHD
/// physical file size
/// capacity of disk
/// amount of free space
/// System Index in OVF to set memory value (0 = first VM)
/// Section Index in Virtual Hardware Section (1 = VHS index)
/// Instance ID of Disk
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands",
Justification = "Logging mechanism")]
public static void AddDisk(EnvelopeType ovfEnv, string vsId, string diskId, string lang, string vhdFileName, bool bootable, string name, string description, ulong filesize, ulong capacity)
{
List files = new List();
List sections = new List();
List disks = new List();
DiskSection_Type disksection = null;
if (ovfEnv.References.File != null && ovfEnv.References.File.Length > 0)
{
foreach (File_Type fi in ovfEnv.References.File)
{
files.Add(fi);
}
}
if (ovfEnv.Sections != null && ovfEnv.Sections.Length > 0)
{
foreach (Section_Type sect in ovfEnv.Sections)
{
if (sect is DiskSection_Type)
{
DiskSection_Type ds = (DiskSection_Type)sect;
if (ds.Disk != null && ds.Disk.Length > 0)
{
foreach (VirtualDiskDesc_Type vd in ds.Disk)
{
disks.Add(vd);
}
}
}
else
{
sections.Add(sect);
}
}
}
disksection = new DiskSection_Type();
string info = _ovfrm.GetString("SECTION_DISK_INFO");
disksection.Info = new Msg_Type(AddToStringSection(ovfEnv, lang, info), info);
VirtualDiskDesc_Type vdisk = new VirtualDiskDesc_Type();
File_Type filet = new File_Type();
RASD_Type rasd = new RASD_Type();
vdisk.capacity = Convert.ToString(capacity);
vdisk.isBootable = bootable;
vdisk.format = Properties.Settings.Default.winFileFormatURI;
vdisk.fileRef = diskId;
vdisk.diskId = vdisk.fileRef;
disks.Add(vdisk);
filet.id = vdisk.diskId;
if (filesize > 0)
{
filet.size = filesize;
filet.sizeSpecified = true;
}
filet.href = string.Format(Properties.Settings.Default.FileURI, vhdFileName);
files.Add(filet);
rasd.AllocationUnits = new cimString(_ovfrm.GetString("RASD_19_ALLOCATIONUNITS"));
rasd.AutomaticAllocation = new cimBoolean();
rasd.AutomaticAllocation.Value = true;
// Other code depends on the value of caption.
rasd.Caption = new Caption(_ovfrm.GetString("RASD_19_CAPTION"));
rasd.ConsumerVisibility = new ConsumerVisibility();
rasd.ConsumerVisibility.Value = 3; //From MS.
rasd.Connection = new cimString[] { new cimString(diskId) };
rasd.HostResource = new cimString[] { new cimString(string.Format(Properties.Settings.Default.hostresource, diskId)) };
rasd.Description = new cimString(description);
rasd.ElementName = new cimString(name);
rasd.InstanceID = new cimString(diskId);
rasd.Limit = new cimUnsignedLong();
rasd.Limit.Value = 1; // From MS;
rasd.MappingBehavior = new MappingBehavior();
rasd.MappingBehavior.Value = 0; // From MS.
rasd.ResourceSubType = new cimString(_ovfrm.GetString("RASD_19_RESOURCESUBTYPE"));
rasd.ResourceType = new ResourceType();
rasd.ResourceType.Value = 19; // Hard Disk Image
rasd.VirtualQuantity = new cimUnsignedLong();
rasd.VirtualQuantity.Value = 1;
rasd.Weight = new cimUnsignedInt();
rasd.Weight.Value = 100; // From MS.
AddRasdToAllVHS(ovfEnv, vsId, rasd);
disksection.Disk = disks.ToArray();
sections.Add(disksection);
ovfEnv.Sections = sections.ToArray();
ovfEnv.References.File = files.ToArray();
log.Debug("OVF.AddDisk completed");
}
public static string AddEula(EnvelopeType ovfObj, string eulafilename)
{
return AddEula(ovfObj, Properties.Settings.Default.Language, eulafilename);
}
///
/// Add a EULA to the OVF
///
public static string AddEula(EnvelopeType ovfEnv, string lang, string eulafilename)
{
EulaSection_Type eulaSection = null;
if (eulafilename != null)
{
FileStream fs = null;
try
{
fs = new FileStream(eulafilename, FileMode.Open, FileAccess.Read, FileShare.Read);
StreamReader sw = new StreamReader(fs);
eulaSection = new EulaSection_Type();
eulaSection.Id = Guid.NewGuid().ToString();
string info = _ovfrm.GetString("SECTION_EULA_INFO");
eulaSection.Info = new Msg_Type(AddToStringSection(ovfEnv, lang, info), info);
string agreement = sw.ReadToEnd();
eulaSection.License = new Msg_Type(AddToStringSection(ovfEnv, lang, agreement), agreement);
}
catch (Exception ex)
{
eulaSection = null;
throw new Exception("Export Halted: Cannot read EULA", ex);
}
finally
{
if (fs != null) { fs.Close(); }
}
}
if (eulaSection != null)
{
List sections = new List();
if (ovfEnv.Item != null)
{
if (ovfEnv.Item.Items != null)
{
sections.AddRange(ovfEnv.Item.Items);
}
}
else
{
throw new Exception("Cannot add EULA no VirtualSystem or VirtualSystemCollection available.");
}
sections.Add(eulaSection);
ovfEnv.Item.Items = sections.ToArray();
}
return eulaSection.Id;
}
///
/// Add an external file
///
/// EnvelopeType
/// Filename
public static void AddExternalFile(EnvelopeType ovfObj, string filename, string id)
{
File_Type ft = new File_Type();
if (id == null || id.Length <= 0)
{
id = Guid.NewGuid().ToString();
}
ft.id = id;
ft.href = Path.GetFileName(filename);
List ftList = new List();
if (ovfObj.References.File != null)
{
ftList.AddRange(ovfObj.References.File);
}
ftList.Add(ft);
ovfObj.References.File = ftList.ToArray();
}
public void AddFileReference(EnvelopeType ovfObj, string filename, string id, ulong capacity, string format)
{
AddFileReference(ovfObj, Properties.Settings.Default.Language, filename, id, capacity, format);
}
///
/// Add an Disk Reference file
///
/// EnvelopeType
/// Filename
public static void AddFileReference(EnvelopeType env, string lang, string filename, string id, ulong capacity, string format)
{
DiskSection_Type ds = null;
List vdisks = new List();
List sections = new List();
if (env.Sections != null)
{
foreach (Section_Type section in env.Sections)
{
if (section is DiskSection_Type)
{
ds = (DiskSection_Type)section;
}
else
{
sections.Add(section);
}
}
}
if (ds == null)
{
ds = new DiskSection_Type();
string info = _ovfrm.GetString("SECTION_DISK_INFO");
ds.Info = new Msg_Type(AddToStringSection(env, lang, info), info);
}
VirtualDiskDesc_Type vdisk = new VirtualDiskDesc_Type();
vdisk.format = format;
vdisk.diskId = id;
vdisk.fileRef = id;
if (capacity != 0)
{
vdisk.capacity = Convert.ToString(capacity);
}
AddExternalFile(env, filename, id);
if (ds.Disk != null)
{
foreach (VirtualDiskDesc_Type vd in ds.Disk)
{
vdisks.Add(vd);
}
}
vdisks.Add(vdisk);
ds.Disk = vdisks.ToArray();
sections.Add(ds);
env.Sections = sections.ToArray();
}
public static InstallSection_Type AddInstallSection(EnvelopeType ovfObj, string vsId, ushort bootStopDelay, string lang, string info)
{
VirtualSystem_Type vSystem = FindVirtualSystemById(ovfObj, vsId);
InstallSection_Type installSection = null;
List sections = new List();
foreach (Section_Type section in vSystem.Items)
{
if (section is InstallSection_Type)
{
installSection = (InstallSection_Type)section;
}
else
{
sections.Add(section);
}
}
if (installSection == null)
{
installSection = new InstallSection_Type();
installSection.Id = Guid.NewGuid().ToString();
}
installSection.initialBootStopDelay = bootStopDelay;
installSection.Info = new Msg_Type(AddToStringSection(ovfObj, lang, info), info);
sections.Add(installSection);
vSystem.Items = sections.ToArray();
return installSection;
}
public static void AddNetwork(EnvelopeType ovfObj, string vsId, string netId, string netName, string networkDescription, string macAddress)
{
AddNetwork(ovfObj, vsId, Properties.Settings.Default.Language, netId, netName, networkDescription, macAddress);
}
///
/// Add a Network to the VM
///
/// EnvelopeType
/// Virtual System Identifier
/// null = unset, value sets MAC Address
public static void AddNetwork(EnvelopeType ovfEnv, string vsId, string lang, string netId, string netName, string networkDescription, string macAddress)
{
List ns = new List();
NetworkSection_TypeNetwork attached = null;
List rasds = new List();
NetworkSection_Type netsection = new NetworkSection_Type();
string info = _ovfrm.GetString("SECTION_NETWORK_INFO");
netsection.Info = new Msg_Type(AddToStringSection(ovfEnv, lang, info), info);
List sections = new List();
if (ovfEnv.Sections != null && ovfEnv.Sections.Length > 0)
{
foreach (Section_Type sect in ovfEnv.Sections)
{
if (sect is NetworkSection_Type)
{
netsection = (NetworkSection_Type)sect;
}
else
{
sections.Add(sect);
}
}
}
if (netsection.Network != null && netsection.Network.Length > 0)
{
foreach (NetworkSection_TypeNetwork lns in netsection.Network)
{
ns.Add(lns);
if (lns.name.Equals(netId))
{
attached = lns;
}
}
}
RASD_Type rasd = new RASD_Type();
if (!string.IsNullOrEmpty(macAddress))
{
rasd.Address = new cimString(macAddress);
}
rasd.AllocationUnits = new cimString(_ovfrm.GetString("RASD_10_ALLOCATIONUNITS"));
rasd.AutomaticAllocation = new cimBoolean();
rasd.AutomaticAllocation.Value = true;
rasd.Caption = new Caption(_ovfrm.GetString("RASD_10_CAPTION"));
rasd.ConsumerVisibility = new ConsumerVisibility();
rasd.ConsumerVisibility.Value = 3;
if (!string.IsNullOrEmpty(networkDescription))
{
rasd.Description = new cimString(networkDescription);
}
else
{
rasd.Description = new cimString(_ovfrm.GetString("RASD_10_DESCRIPTION"));
}
rasd.ElementName = new cimString(netName);
rasd.InstanceID = new cimString(Guid.NewGuid().ToString());
rasd.Connection = new cimString[1];
rasd.Connection[0] = new cimString(netId);
rasd.Limit = new cimUnsignedLong();
rasd.Limit.Value = 1;
rasd.MappingBehavior = new MappingBehavior();
rasd.MappingBehavior.Value = 0;
rasd.ResourceType = new ResourceType();
rasd.ResourceType.Value = 10;
rasd.VirtualQuantity = new cimUnsignedLong();
rasd.VirtualQuantity.Value = 1;
rasd.Weight = new cimUnsignedInt();
rasd.Weight.Value = 0;
if (attached == null)
{
attached = new NetworkSection_TypeNetwork();
attached.name = netId;
attached.Description = new Msg_Type(AddToStringSection(ovfEnv, lang, rasd.Description.Value), rasd.Description.Value);
ns.Add(attached);
}
AddRasdToAllVHS(ovfEnv, vsId, rasd);
netsection.Network = ns.ToArray();
sections.Add(netsection);
ovfEnv.Sections = sections.ToArray();
log.Debug("OVF.AddNetwork completed");
}
public void AddOperatingSystemSection(EnvelopeType ovfObj, string vsId, string description, string osInfo)
{
AddOperatingSystemSection(ovfObj, vsId, Properties.Settings.Default.Language, description, osInfo, 0);
}
public static void AddOperatingSystemSection(EnvelopeType ovfObj, string vsId, string lang, string description, string osInfo)
{
AddOperatingSystemSection(ovfObj, vsId, lang, description, osInfo, 0);
}
///
/// Add the Operating System Section
///
/// Ovf:EnvelopeType
/// Virtual System Identifier
/// Language
/// Description
/// OS Information
/// ushort identifying the OS from CIM_OperatingSystem ValueMap
public void AddOperatingSystemSection(EnvelopeType ovfObj, string vsId, string description, string osInfo, ushort osid)
{
AddOperatingSystemSection(ovfObj, vsId, Properties.Settings.Default.Language, description, osInfo, osid);
}
///
/// Add the Operating System Section
///
/// Ovf:EnvelopeType
/// Virtual System Identifier
/// Language
/// Description
/// OS Information
/// ushort identifying the OS from CIM_OperatingSystem ValueMap
public static void AddOperatingSystemSection(EnvelopeType ovfEnv, string vsId, string lang, string description, string osInfo, ushort osid)
{
OperatingSystemSection_Type oss = new OperatingSystemSection_Type();
oss.id = osid;
string info = null;
if (!string.IsNullOrEmpty(description))
{
oss.Description = new Msg_Type(AddToStringSection(ovfEnv, lang, description), description);
}
else
{
info = _ovfrm.GetString("SECTION_OPERATINGSYSTEM_DESCRIPTION");
oss.Description = new Msg_Type(AddToStringSection(ovfEnv, lang, info), info);
}
if (!string.IsNullOrEmpty(osInfo))
{
oss.Info = new Msg_Type(AddToStringSection(ovfEnv, lang, osInfo), osInfo);
}
else
{
info = _ovfrm.GetString("SECTION_OPERATINGSYSTEM_INFO");
oss.Info = new Msg_Type(AddToStringSection(ovfEnv, lang, info), info);
}
if (ovfEnv.Item == null || ((VirtualSystemCollection_Type)ovfEnv.Item).Content == null)
{
throw new ArgumentNullException(Messages.FAILED_TO_ADD_OS_SECTION);
}
AddContent((VirtualSystemCollection_Type)ovfEnv.Item, vsId, oss);
log.DebugFormat("OVF.AddOperatingSystemSection completed {0}", vsId);
}
public static string AddOtherSystemSettingData(EnvelopeType ovfObj, string vsId, string name, string value, string description, bool permitMultiple=false)
{
return AddOtherSystemSettingData(ovfObj, vsId, Properties.Settings.Default.Language, name, value, description, permitMultiple);
}
///
/// Add XEN Specific configuration Items.
///
/// EnvelopeType
/// Virtual System Identifier
/// Name of Parameter: is: HVM-boot-policy (case sensitive)
/// value for the parameter
/// Description of parameter
/// Whether the setting data permit multiple values, default false
public static string AddOtherSystemSettingData(EnvelopeType ovfObj, string vsId, string lang, string name, string value, string description, bool permitMultiple=false)
{
VirtualHardwareSection_Type[] vhsArray = FindVirtualHardwareSection(ovfObj, vsId);
VirtualHardwareSection_Type vhs = null;
foreach (VirtualHardwareSection_Type _vhs in vhsArray)
{
if (_vhs.System != null && _vhs.System.VirtualSystemType != null &&
!(string.IsNullOrEmpty(_vhs.System.VirtualSystemType.Value)) &&
(_vhs.System.VirtualSystemType.Value.ToLower().StartsWith("xen") ||
_vhs.System.VirtualSystemType.Value.ToLower().StartsWith("hvm")))
{
vhs = _vhs;
break;
}
}
if (vhs == null)
{
log.Warn("OVF.AddOtherSystemSettingData: could not find 'xen' or 'hvm' system type VHS, skipping.");
return null;
}
List xencfg = new List();
if (vhs.VirtualSystemOtherConfigurationData != null && vhs.VirtualSystemOtherConfigurationData.Length > 0)
{
foreach (Xen_ConfigurationSettingData_Type xencsd in vhs.VirtualSystemOtherConfigurationData)
{
// If permitMultiple, the old items are kept, and the new item will be added later,
// otherwise, the old item is skipped here and will be overridden by the new one
if (permitMultiple || xencsd.Name.ToLower() != name.ToLower())
{
xencfg.Add(xencsd);
}
}
}
Xen_ConfigurationSettingData_Type xenother = new Xen_ConfigurationSettingData_Type();
xenother.id = Guid.NewGuid().ToString();
xenother.Name = name;
xenother.Value = new cimString(value);
xenother.Info = new Msg_Type(AddToStringSection(ovfObj, lang, description), description);
xencfg.Add(xenother);
vhs.VirtualSystemOtherConfigurationData = xencfg.ToArray();
log.Debug("OVF.AddOtherSystemSettingData completed");
return xenother.id;
}
public static string AddPostInstallOperation(EnvelopeType ovfObj, string vsId, string lang, string message)
{
VirtualSystem_Type vSystem = FindVirtualSystemById(ovfObj, vsId);
InstallSection_Type installSection = null;
foreach (Section_Type sec in vSystem.Items)
{
if (sec is InstallSection_Type)
{
installSection = (InstallSection_Type)sec;
break;
}
}
if (installSection == null)
installSection = AddInstallSection(ovfObj, vsId, 600, Properties.Settings.Default.Language, "ConfigureForXenServer");
Xen_PostInstallOperation_Type XenPostInstall = new Xen_PostInstallOperation_Type();
XenPostInstall.required = false;
XenPostInstall.requiredSpecified = true;
XenPostInstall.id = Guid.NewGuid().ToString();
XenPostInstall.Info = new Msg_Type(AddToStringSection(ovfObj, lang, message), message);
installSection.PostInstallOperations = XenPostInstall;
return XenPostInstall.id;
}
public string AddProductSection(EnvelopeType ovfObj, string nameSpace, string info, string product, string vendor, string version, string producturl, string vendorurl)
{
return AddProductSection(ovfObj, Properties.Settings.Default.Language, nameSpace, info, product, vendor, version, producturl, vendorurl);
}
public string AddProductSection(EnvelopeType env, string lang, string nameSpace, string info, string product, string vendor, string version, string producturl, string vendorurl)
{
string psId = Guid.NewGuid().ToString();
ProductSection_Type ps = new ProductSection_Type();
ps.@class = nameSpace;
ps.instance = psId;
ps.Product = new Msg_Type(AddToStringSection(env, lang, product), product);
ps.ProductUrl = new cimString(producturl);
ps.Vendor = new Msg_Type(AddToStringSection(env, lang, vendor), vendor);
ps.Version = new cimString(version);
ps.VendorUrl = new cimString(vendorurl);
List sections = new List();
Section_Type[] sectionArray = null;
if (env.Item != null)
{
if (env.Item is VirtualSystemCollection_Type)
{
sectionArray = ((VirtualSystemCollection_Type)env.Item).Content[0].Items;
}
else
{
sectionArray = env.Item.Items;
}
}
else
{
sectionArray = env.Sections;
}
foreach (Section_Type section in sectionArray)
{
if (!(section is ProductSection_Type))
{
sections.Add(section);
}
}
sections.Add(ps);
if (env.Item is VirtualSystemCollection_Type)
{
((VirtualSystemCollection_Type)env.Item).Content[0].Items = sections.ToArray();
}
else
{
env.Item.Items = sections.ToArray();
}
return psId;
}
public string AddProductSectionProperty(EnvelopeType ovfObj, string psId, string category, string key, string type, bool userConfig, string label, string description)
{
return AddProductSectionProperty(ovfObj, psId, Properties.Settings.Default.Language, category, key, type, userConfig, label, description);
}
public string AddProductSectionProperty(EnvelopeType env, string psId, string lang, string category, string key, string type, bool userConfig, string label, string description)
{
Msg_Type msgCategory = new Msg_Type(AddToStringSection(env, lang, category), category);
ProductSection_TypeProperty pst = new ProductSection_TypeProperty();
pst.id = Guid.NewGuid().ToString();
pst.key = key;
pst.type = type;
pst.userConfigurable = userConfig;
pst.Label = new Msg_Type(AddToStringSection(env, lang, label), label);
pst.Description = new Msg_Type(AddToStringSection(env, lang, description), description);
ProductSection_Type productsection = null;
List sections = new List();
Section_Type[] sectionArray = null;
if (env.Item is VirtualSystemCollection_Type)
{
sectionArray = ((VirtualSystemCollection_Type)env.Item).Content[0].Items;
}
else
{
sectionArray = env.Item.Items;
}
foreach (Section_Type section in sectionArray)
{
if (section is ProductSection_Type)
{
productsection = (ProductSection_Type)section;
if (productsection.instance == psId)
{
break;
}
productsection = null;
}
sections.Add(section);
}
if (productsection == null)
throw new InvalidDataException(string.Format(Messages.OVF_PRODUCT_SECTION_MISSING, psId));
List