internal List<XenRef<VDI>> ImportFile(Session xenSession, string vmname, string pathToOvf, string filename, string compression, string version, string passcode, string sruuid, string description, string vdiuuid) { List<XenRef<VDI>> vdiRef = new List<XenRef<VDI>>(); // Get the disk transport method from the configuration in XenOvfTransport.Properties.Settings.TransferType. TransferType useTransport = (TransferType)Enum.Parse(typeof(TransferType), Properties.Settings.Default.TransferType, true); TransferMethod useTransferMethod = TransferMethod.Image; string sourcefile = filename; string encryptfilename = null; string uncompressedfilename = null; string destinationPath = Properties.Settings.Default.xenISOMount; string StartPath = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(pathToOvf); Stream dataStream = null; long dataCapacity = 0; #region SET UP TRANSPORT if (filename != null) { if (IsKnownURIType(filename)) { Uri fileUri = new Uri(filename); filename = DownloadFileAsync(fileUri, 0); sourcefile = filename; } if (File.Exists(filename)) { string ext = Path.GetExtension(filename); try { encryptfilename = "enc_" + filename; uncompressedfilename = "unc_" + filename; // OK.. lets see is the file encrypted? #region ENCRYPTION if (passcode != null) { var statusMessage = string.Format(Messages.START_FILE_DECRYPTION, filename); OnUpdate(new XenOvfTranportEventArgs(XenOvfTranportEventType.MarqueeOn, "Security", statusMessage)); log.Debug(statusMessage); OVF.DecryptToTempFile(EncryptionClass, filename, version, passcode, encryptfilename); sourcefile = encryptfilename; statusMessage += Messages.COMPLETE; OnUpdate(new XenOvfTranportEventArgs(XenOvfTranportEventType.MarqueeOff, "Security", statusMessage)); } #endregion #region COMPRESSION // Identity == no compression, it is meant when a URL is used to identify the compression during transport. if (compression != null && !compression.ToLower().Equals("none") && !compression.ToLower().Equals("identity")) { // gz is the only understood 'compressed' format, strip it.. // the OVF is marked with "compressed=gzip" therefor it will get decompress // correctly and use with its disk extension (vmdk/vhd/vdi)... if (ext.ToLower().EndsWith(".gz")) { string newfilename = Path.GetFileNameWithoutExtension(uncompressedfilename); uncompressedfilename = newfilename; ext = Path.GetExtension(uncompressedfilename); } var statusMessage = string.Format(Messages.START_FILE_EXPANSION, filename); OnUpdate(new XenOvfTranportEventArgs(XenOvfTranportEventType.MarqueeOn, "Compression", statusMessage)); var ovfCompressor = new OvfCompressor(); ovfCompressor.UncompressFile(sourcefile, uncompressedfilename, compression); if (File.Exists(encryptfilename)) { File.Delete(encryptfilename); } sourcefile = uncompressedfilename; statusMessage += Messages.COMPLETE; OnUpdate(new XenOvfTranportEventArgs(XenOvfTranportEventType.MarqueeOff, "Compression", statusMessage)); } #endregion #region DISK SELECTION bool knownDisk = false; foreach (string diskext in VirtualDisk.SupportedDiskFormats) { if (ext.ToLower().Contains(diskext.ToLower())) { knownDisk = true; break; } } if (knownDisk) { log.DebugFormat("Found file {0} using {1} Stream", filename, ext); vhdDisk = VirtualDisk.OpenDisk(sourcefile, FileAccess.Read); dataStream = vhdDisk.Content; dataCapacity = vhdDisk.Capacity; } else if (ext.ToLower().Contains("wim")) { log.WarnFormat("EXPERIMENTAL CODE: Found file {0} using WIM file structure", filename); wimDisk = new DiscUtils.Wim.WimFile(new FileStream(sourcefile, FileMode.Open, FileAccess.Read)); //wimFS = wimDisk.GetImage(wimDisk.BootImage); dataStream = null; string manifest = wimDisk.Manifest; Wim_Manifest wimManifest = (Wim_Manifest)Tools.Deserialize(manifest, typeof(Wim_Manifest)); ulong imagesize = wimManifest.Image[wimDisk.BootImage].TotalBytes; // <----<<< Image data size wimFileCount = wimManifest.Image[wimDisk.BootImage].FileCount; dataCapacity = (long)(imagesize + AdditionalSpace); useTransferMethod = TransferMethod.Files; } else if (ext.ToLower().Contains("xva")) { log.WarnFormat("EXPERIMENTAL CODE: Found file {0} using XVA Stream (DISK {1} is being imported).", filename, xvadisk); DiscUtils.Xva.VirtualMachine vm = new DiscUtils.Xva.VirtualMachine(new FileStream(sourcefile, FileMode.Open, FileAccess.Read)); int i = 0; foreach (DiscUtils.Xva.Disk d in vm.Disks) { if (i == xvadisk) { vhdDisk = d; break; } } dataStream = vhdDisk.Content; dataCapacity = vhdDisk.Capacity; } else if (ext.ToLower().EndsWith("iso")) { if (string.IsNullOrEmpty(sruuid)) { useTransport = TransferType.Skip; } else { //DiscUtils.Iso9660.CDReader cdr = new DiscUtils.Iso9660.CDReader(File.OpenRead(filename), true); dataStream = File.OpenRead(filename); dataCapacity = dataStream.Length + (512 * KB); // Xen does 512KB rounding this is to ensure it doesn't round down below size. } } #endregion } catch (Exception ex) { log.Error(Messages.ISCSI_ERROR_CANNOT_OPEN_DISK); throw new Exception(Messages.ISCSI_ERROR_CANNOT_OPEN_DISK, ex); } } else { throw new FileNotFoundException(string.Format(Messages.FILE_MISSING, filename)); } } else { log.Error(Messages.ERROR_FILE_NAME_NULL); throw new InvalidDataException(Messages.ERROR_FILE_NAME_NULL); } #endregion try { #region SEE IF TARGET SR HAS ENOUGH SPACE if (useTransport == TransferType.UploadRawVDI || useTransport == TransferType.iSCSI) { long freespace; string contenttype = string.Empty; if(vdiuuid != null) { XenRef<VDI> vdiLookup = VDI.get_by_uuid(xenSession, vdiuuid); freespace = VDI.get_virtual_size(xenSession, vdiLookup); } else { XenRef<SR> srRef = SR.get_by_uuid(xenSession, sruuid); long size = SR.get_physical_size(xenSession, srRef); long usage = SR.get_physical_utilisation(xenSession, srRef); contenttype = SR.get_content_type(xenSession, srRef); freespace = size - usage; } if (freespace <= dataCapacity) { string message = string.Format(Messages.NOT_ENOUGH_SPACE_IN_SR, sruuid, Convert.ToString(vhdDisk.Capacity), filename); log.Error(message); throw new IOException(message); } } #endregion #region UPLOAD FILE switch (useTransport) { case TransferType.UploadRawVDI: { vdiRef.Add(UploadRawVDI(xenSession, sruuid, vmname, dataStream, dataCapacity, description)); break; } case TransferType.iSCSI: { if (useTransferMethod == TransferMethod.Image) { vdiRef.Add(UploadiSCSI(xenSession, sruuid, vmname, dataStream, dataCapacity, description, vdiuuid)); } else { for (int i = 0; i < wimDisk.ImageCount; i++) { Wim_Manifest wimManifest = (Wim_Manifest)Tools.Deserialize(wimDisk.Manifest, typeof(Wim_Manifest)); wimFileCount = wimManifest.Image[i].FileCount; int wimArch = wimManifest.Image[i].Windows.Architecture; vdiRef.Add(UploadiSCSIbyWimFile(xenSession, sruuid, vmname, wimDisk, i, dataCapacity, wimFileCount, wimArch, "")); } } break; } case TransferType.Skip: { log.Info("ImportFile: Upload Skipped"); break; } default: { log.Error(Messages.UNSUPPORTED_TRANSPORT); throw new InvalidDataException(Messages.UNSUPPORTED_TRANSPORT); } } #endregion } catch (Exception ex) { if (ex is OperationCanceledException) throw; throw new Exception(Messages.FILE_TRANSPORT_FAILED, ex); } finally { if (vhdDisk != null) { vhdDisk.Dispose(); vhdDisk = null; } if (wimDisk != null) { wimDisk = null; } if (File.Exists(encryptfilename)) { File.Delete(encryptfilename); } if (File.Exists(uncompressedfilename)) { File.Delete(uncompressedfilename); } } Directory.SetCurrentDirectory(StartPath); log.DebugFormat("OVF.Import.ImportFile leave: created {0} VDIs", vdiRef.Count); return vdiRef; }
protected override void Run() { base.Run(); var session = Connection.Session; var url = session.Url; Uri uri = new Uri(url); var appFolder = Path.Combine(m_applianceDirectory, m_applianceFileName); var appFile = string.Format("{0}.ovf", m_applianceFileName); if (!Directory.Exists(appFolder)) Directory.CreateDirectory(appFolder); PercentComplete = 5; Description = Messages.EXPORTING_VMS; EnvelopeType env; try { m_transportAction = new XenOvfTransport.Export(uri, session) { UpdateHandler = UpdateHandler, ShouldVerifyDisks = m_shouldVerify, Cancel = Cancelling //in case the Cancel button has already been pressed }; m_transportAction.SetTvmNetwork(m_networkUuid, m_isTvmIpStatic, m_tvmIpAddress, m_tvmSubnetMask, m_tvmGateway); env = (m_transportAction as XenOvfTransport.Export).Process(appFolder, m_applianceFileName, (from VM vm in m_vmsToExport select vm.uuid).ToArray()); PercentComplete = 60; } catch (OperationCanceledException) { throw new CancelledException(); } foreach (var eula in m_eulas) { if (Cancelling) throw new CancelledException(); Description = Messages.ADDING_EULAS; OVF.AddEula(env, eula); } if (Cancelling) throw new CancelledException(); var ovfPath = Path.Combine(appFolder, appFile); Description = String.Format(Messages.CREATING_FILE, appFile); OVF.SaveAs(env, ovfPath); PercentComplete = 70; if (Cancelling) throw new CancelledException(); if (m_signAppliance) { Description = Messages.SIGNING_APPLIANCE; OVF.Sign(m_certificate, appFolder, appFile); } else if (m_createManifest) { Description = Messages.CREATING_MANIFEST; OVF.Manifest(appFolder, appFile); } PercentComplete = 90; if (Cancelling) throw new CancelledException(); if (m_createOVA) { Description = String.Format(Messages.CREATING_FILE, String.Format("{0}.ova", m_applianceFileName)); OVF.ConvertOVFtoOVA(appFolder, appFile, m_compressOVFfiles); } else if (m_compressOVFfiles) { Description = Messages.COMPRESSING_FILES; m_compressor = new OvfCompressor { CancelCompression = Cancelling }; //in case the Cancel button has already been pressed} try { m_compressor.CompressOvfFiles(ovfPath, "GZip"); } catch (OperationCanceledException) { throw new CancelledException(); } } PercentComplete = 100; Description = Messages.COMPLETED; }