private void ExtractFile()
        {
            ArchiveIterator iterator = null;

            try
            {
                using (Stream stream = new FileStream(outFileName, FileMode.Open, FileAccess.Read))
                {
                    iterator = ArchiveFactory.Reader(ArchiveFactory.Type.Zip, stream);
                    DotNetZipZipIterator zipIterator = iterator as DotNetZipZipIterator;
                    if (zipIterator != null)
                    {
                        zipIterator.CurrentFileExtractProgressChanged +=
                            archiveIterator_CurrentFileExtractProgressChanged;
                    }

                    while (iterator.HasNext())
                    {
                        if (Path.GetExtension(iterator.CurrentFileName()) == ".xsupdate")
                        {
                            string path = Path.Combine(Path.GetDirectoryName(outFileName), iterator.CurrentFileName());

                            using (Stream outputStream = new FileStream(path, FileMode.Create))
                            {
                                iterator.ExtractCurrentFile(outputStream);
                                PatchPath = path;
                                break;
                            }
                        }
                    }

                    if (zipIterator != null)
                    {
                        zipIterator.CurrentFileExtractProgressChanged -=
                            archiveIterator_CurrentFileExtractProgressChanged;
                    }
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("Exception occurred when extracting downloaded archive: {0}", e.Message);
                throw new Exception(Messages.DOWNLOAD_AND_EXTRACT_ACTION_EXTRACTING_ERROR);
            }
            finally
            {
                if (iterator != null)
                {
                    iterator.Dispose();
                }
                File.Delete(outFileName);
            }

            if (string.IsNullOrEmpty(PatchPath))
            {
                MarkCompleted(new Exception(Messages.DOWNLOAD_AND_EXTRACT_ACTION_FILE_NOT_FOUND));
                log.DebugFormat("File '{0}{1}' could not be located in downloaded archive", updateName, ".xsupdate");
            }
        }
Пример #2
0
 private string GetXmlStringFromTarXVA()
 {
     using (Stream stream = new FileStream(textBoxFile.Text, FileMode.Open, FileAccess.Read)) {
         ArchiveIterator iterator = ArchiveFactory.Reader(ArchiveFactory.Type.Tar, stream);
         if (iterator.HasNext())
         {
             Stream ofs = new MemoryStream();
             iterator.ExtractCurrentFile(ofs);
             ofs.Position = 0;
             return(new StreamReader(ofs).ReadToEnd());
         }
         return(String.Empty);
     }
 }
Пример #3
0
        public void TestValidReaderGeneration()
        {
            Dictionary <ArchiveFactory.Type, Type> validIterators = new Dictionary <ArchiveFactory.Type, Type>()
            {
                { ArchiveFactory.Type.Tar, typeof(SharpZipTarArchiveIterator) },
                { ArchiveFactory.Type.TarGz, typeof(SharpZipTarArchiveIterator) },
                { ArchiveFactory.Type.TarBz2, typeof(SharpZipTarArchiveIterator) }
            };

            foreach (KeyValuePair <ArchiveFactory.Type, Type> pair in validIterators)
            {
                string target = Path.Combine(Directory.GetCurrentDirectory(), @"XenAdminTests\TestResources\emptyfile.bz2");
                using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(target)))
                {
                    ArchiveIterator providedStream = ArchiveFactory.Reader(pair.Key, ms);
                    Assert.AreEqual(providedStream.GetType(), pair.Value);
                }
            }
        }
        private void ExtractFile()
        {
            ArchiveIterator iterator = null;

            try
            {
                using (Stream stream = new FileStream(outputFileName, FileMode.Open, FileAccess.Read))
                {
                    iterator = ArchiveFactory.Reader(ArchiveFactory.Type.Zip, stream);
                    DotNetZipZipIterator zipIterator = iterator as DotNetZipZipIterator;
                    if (zipIterator != null)
                    {
                        zipIterator.CurrentFileExtractProgressChanged +=
                            archiveIterator_CurrentFileExtractProgressChanged;
                    }

                    while (iterator.HasNext())
                    {
                        string currentExtension = Path.GetExtension(iterator.CurrentFileName());

                        if (updateFileSuffixes.Any(item => item == currentExtension))
                        {
                            string path = downloadUpdate
                                ? Path.Combine(Path.GetDirectoryName(outputFileName), iterator.CurrentFileName())
                                : Path.Combine(Path.GetTempPath(), iterator.CurrentFileName());

                            log.InfoFormat(
                                "Found '{0}' in the downloaded archive when looking for a '{1}' file. Extracting...",
                                iterator.CurrentFileName(), currentExtension);

                            using (Stream outputStream = new FileStream(path, FileMode.Create))
                            {
                                iterator.ExtractCurrentFile(outputStream);
                                PatchPath = path;

                                log.InfoFormat("Update file extracted to '{0}'", path);

                                break;
                            }
                        }
                    }

                    if (zipIterator != null)
                    {
                        zipIterator.CurrentFileExtractProgressChanged -=
                            archiveIterator_CurrentFileExtractProgressChanged;
                    }
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("Exception occurred when extracting downloaded archive: {0}", e.Message);
                throw new Exception(Messages.DOWNLOAD_AND_EXTRACT_ACTION_EXTRACTING_ERROR);
            }
            finally
            {
                if (iterator != null)
                {
                    iterator.Dispose();
                }

                if (downloadUpdate)
                {
                    try { File.Delete(outputFileName); }
                    catch { }
                }
            }

            if (string.IsNullOrEmpty(PatchPath) && downloadUpdate)
            {
                MarkCompleted(new Exception(Messages.DOWNLOAD_AND_EXTRACT_ACTION_FILE_NOT_FOUND));
                log.InfoFormat(
                    "The downloaded archive does not contain a file with any of the following extensions: {0}",
                    string.Join(", ", updateFileSuffixes));
            }
        }
Пример #5
0
        protected override void Run()
        {
            SafeToExit  = false;
            Description = Messages.ACTION_EXPORT_DESCRIPTION_IN_PROGRESS;

            RelatedTask = XenAPI.Task.create(Session,
                                             string.Format(Messages.ACTION_EXPORT_TASK_NAME, VM.Name),
                                             string.Format(Messages.ACTION_EXPORT_TASK_DESCRIPTION, VM.Name));

            UriBuilder uriBuilder = new UriBuilder(this.Session.Url);

            uriBuilder.Path  = "export";
            uriBuilder.Query = string.Format("session_id={0}&uuid={1}&task_id={2}",
                                             Uri.EscapeDataString(this.Session.uuid),
                                             Uri.EscapeDataString(this.VM.uuid),
                                             Uri.EscapeDataString(this.RelatedTask.opaque_ref));

            log.DebugFormat("Exporting {0} from {1} to {2}", VM.Name, uriBuilder.ToString(), _filename);

            // The DownloadFile call will block, so we need a separate thread to poll for task status.
            Thread taskThread = new Thread((ThreadStart)progressPoll);

            taskThread.Name         = "Progress polling thread for ExportVmAction for " + VM.Name.Ellipsise(20);
            taskThread.IsBackground = true;
            taskThread.Start();

            // Create the file with a temporary name till it is fully downloaded
            String tmpFile = _filename + ".tmp";

            try
            {
                HttpGet(tmpFile, uriBuilder.Uri);
            }
            catch (Exception e)
            {
                if (XenAPI.Task.get_status(this.Session, this.RelatedTask.opaque_ref) == XenAPI.task_status_type.pending &&
                    XenAPI.Task.get_progress(this.Session, this.RelatedTask.opaque_ref) == 0)
                {
                    // If task is pending and has zero progress, it probably hasn't been started,
                    // which probably means there was an exception in the GUI code before the
                    // action got going. Kill the task so that we don't block forever on
                    // taskThread.Join(). Brought to light by CA-11100.
                    XenAPI.Task.destroy(this.Session, this.RelatedTask.opaque_ref);
                }
                // Test for null: don't overwrite a previous exception
                if (_exception == null)
                {
                    _exception = e;
                }
            }

            taskThread.Join();

            using (FileStream fs = new FileStream(tmpFile, FileMode.Append))
            {
                // Flush written data to disk
                if (!Win32.FlushFileBuffers(fs.SafeFileHandle))
                {
                    Win32Exception exn = new Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error());
                    log.ErrorFormat("FlushFileBuffers failed in ExportVmAction.\nNativeErrorCode={0}\nMessage={1}\nToString={2}",
                                    exn.NativeErrorCode, exn.Message, exn.ToString());
                }
            }

            if (verify && _exception == null)
            {
                long read     = 0;
                int  i        = 0;
                long filesize = new FileInfo(tmpFile).Length / 50; //Div by 50 to save doing the * 50 in the callback

                Export.verifyCallback callback = new Export.verifyCallback(delegate(uint size)
                {
                    read += size;
                    i++;

                    //divide number of updates by 10, so as not to spend all out time redrawing the control
                    //but try and send an update every second to keep the timer ticking
                    if (i > 10)
                    {
                        PercentComplete = 50 + (int)(read / filesize);
                        i = 0;
                    }
                });

                try
                {
                    using (FileStream fs = new FileStream(tmpFile, FileMode.Open, FileAccess.Read))
                    {
                        log.DebugFormat("Verifying export of {0} in {1}", VM.Name, _filename);
                        this.Description = Messages.ACTION_EXPORT_VERIFY;

                        export = new Export();
                        export.verify(fs, null, (Export.cancellingCallback) delegate() { return(Cancelling); }, callback);
                    }
                }
                catch (Exception e)
                {
                    if (_exception == null)
                    {
                        _exception = e;
                    }
                }
            }

            if (Cancelling || _exception is CancelledException)
            {
                log.InfoFormat("Export of VM {0} cancelled", VM.Name);
                this.Description = Messages.ACTION_EXPORT_DESCRIPTION_CANCELLED;

                log.DebugFormat("Deleting {0}", tmpFile);
                File.Delete(tmpFile);
                throw new CancelledException();
            }
            else if (_exception != null)
            {
                log.Warn(string.Format("Export of VM {0} failed", VM.Name), _exception);

                if (_exception is HeaderChecksumFailed || _exception is FormatException)
                {
                    this.Description = Messages.ACTION_EXPORT_DESCRIPTION_HEADER_CHECKSUM_FAILED;
                }
                else if (_exception is BlockChecksumFailed)
                {
                    this.Description = Messages.ACTION_EXPORT_DESCRIPTION_BLOCK_CHECKSUM_FAILED;
                }
                else if (_exception is IOException && Win32.GetHResult(_exception) == Win32.ERROR_DISK_FULL)
                {
                    this.Description = Messages.ACTION_EXPORT_DESCRIPTION_DISK_FULL;
                }
                else if (_exception is Failure && ((Failure)_exception).ErrorDescription[0] == Failure.VDI_IN_USE)
                {
                    this.Description = Messages.ACTION_EXPORT_DESCRIPTION_VDI_IN_USE;
                }
                else
                {
                    this.Description = Messages.ACTION_EXPORT_DESCRIPTION_FAILED;
                }

                var fi = new FileInfo(tmpFile);
                log.DebugFormat("Progress of the action until exception: {0}", PercentComplete);
                log.DebugFormat("Size file exported until exception: {0}", fi.Length);
                try
                {
                    using (Stream stream = new FileStream(tmpFile, FileMode.Open, FileAccess.Read))
                    {
                        ArchiveIterator iterator = ArchiveFactory.Reader(ArchiveFactory.Type.Tar,
                                                                         stream);
                        while (iterator.HasNext())
                        {
                            log.DebugFormat("Tar entry: {0} {1}", iterator.CurrentFileName(), iterator.CurrentFileSize());
                        }
                    }
                }
                catch (Exception)
                {}
                log.DebugFormat("Deleting {0}", tmpFile);
                File.Delete(tmpFile);
                throw new Exception(Description);
            }
            else
            {
                log.InfoFormat("Export of VM {0} successful", VM.Name);
                this.Description = Messages.ACTION_EXPORT_DESCRIPTION_SUCCESSFUL;

                log.DebugFormat("Renaming {0} to {1}", tmpFile, _filename);
                if (File.Exists(_filename))
                {
                    File.Delete(_filename);
                }
                File.Move(tmpFile, _filename);
            }
        }
Пример #6
0
 /// <summary>
 /// Always remember to call Close after having used the opened package,
 /// usually in a try-finally block
 /// </summary>
 private void Open()
 {
     _tarStream       = File.OpenRead(PackageSourceFile);
     _archiveIterator = ArchiveFactory.Reader(_tarType, _tarStream);
 }
Пример #7
0
        protected override void Run()
        {
            // The directory in which we assemble the log files from the server before repackaging them
            // in a single zip file.
            string extractTempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

            try
            {
                // Calculate total bytes to save
                long bytesToExtract = 1, bytesExtracted = 0;
                foreach (string inputFile in Directory.GetFiles(_inputTempFolder))
                {
                    bytesToExtract += new FileInfo(inputFile).Length;
                }

                // Create temp dir for extracted stuff
                if (Directory.Exists(extractTempDir))
                {
                    Directory.Delete(extractTempDir);
                }
                Directory.CreateDirectory(extractTempDir);

                // Extract each of the raw server files to the temp extraction directory
                foreach (string inputFile in Directory.GetFiles(_inputTempFolder))
                {
                    if (inputFile.ToLowerInvariant().EndsWith(".tar"))
                    {
                        // Un-tar it. SharpZipLib doesn't account for illegal filenames or characters in
                        // filenames (e.g. ':'in Windows), so first we stream the tar to a new tar,
                        // sanitizing any bad filenames as we go.

                        // We also need to record the modification times of all the files, so that we can
                        // restore them into the final zip.

                        string outFilename = inputFile.Substring(0, inputFile.Length - 4);
                        if (outFilename.Length == 0)
                        {
                            outFilename = Path.GetRandomFileName();
                        }
                        string outputDir = Path.Combine(extractTempDir, Path.GetFileName(outFilename));

                        string sanitizedTar = Path.GetTempFileName();

                        using (ArchiveIterator tarIterator = ArchiveFactory.Reader(ArchiveFactory.Type.Tar, File.OpenRead(inputFile)))
                        {
                            using (ArchiveWriter tarWriter = ArchiveFactory.Writer(ArchiveFactory.Type.Tar, File.OpenWrite(sanitizedTar)))
                            {
                                Dictionary <string, string> usedNames = new Dictionary <string, string>();
                                while (tarIterator.HasNext())
                                {
                                    if (Cancelling)
                                    {
                                        throw new CancelledException();
                                    }

                                    using (MemoryStream ms = new MemoryStream())
                                    {
                                        tarIterator.ExtractCurrentFile(ms);
                                        string saneName = SanitizeTarName(tarIterator.CurrentFileName(), usedNames);
                                        tarWriter.Add(ms, saneName);
                                        ModTimes[Path.Combine(outputDir, saneName)] = tarIterator.CurrentFileModificationTime();
                                    }
                                }
                            }
                        }

                        // Now extract the sanitized tar
                        using (FileStream fs = File.OpenRead(sanitizedTar))
                        {
                            using (ArchiveIterator tarIterator = ArchiveFactory.Reader(ArchiveFactory.Type.Tar, fs))
                            {
                                Directory.CreateDirectory(outputDir);
                                tarIterator.ExtractAllContents(outputDir);
                                bytesToCompress += Core.Helpers.GetDirSize(new DirectoryInfo(outputDir));
                            }
                        }
                    }
                    else
                    {
                        // Just copy vanilla input files unmodified to the temp directory
                        string outputFile = Path.Combine(extractTempDir, Path.GetFileName(inputFile));
                        File.Copy(inputFile, outputFile);
                        ModTimes[outputFile] = new FileInfo(inputFile).LastWriteTimeUtc;
                        bytesToCompress     += new FileInfo(outputFile).Length;
                    }

                    bytesExtracted += new FileInfo(inputFile).Length;
                    File.Delete(inputFile);
                    this.PercentComplete = (int)(50.0 * bytesExtracted / bytesToExtract);

                    if (Cancelling)
                    {
                        throw new CancelledException();
                    }
                }

                // Now zip up all the temporarily extracted files into a single zip file for the user
                log.DebugFormat("Packing {0} of bug report files into zip file {1}",
                                Util.DiskSizeString(bytesToCompress), _destFile);

                LogDescriptionChanges = false;
                try
                {
                    ZipToOutputFile(extractTempDir);
                    PercentComplete = 100;

                    // Only cleanup files if it succeeded (or cancelled)
                    CleanupFiles(extractTempDir);
                }
                finally
                {
                    LogDescriptionChanges = true;
                }

                if (Cancelling)
                {
                    throw new CancelledException();
                }
            }
            catch (CancelledException)
            {
                CleanupFiles(extractTempDir, true);

                throw;
            }
            catch (Exception exn)
            {
                ZipToOutputFile(_inputTempFolder);
                PercentComplete = 100;
                log.ErrorFormat("An exception was trapped while creating a server status report: " + exn.Message);
                throw new Exception(Messages.STATUS_REPORT_ZIP_FAILED);
            }
        }
Пример #8
0
        protected override void Run()
        {
            do
            {
                _extractTempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            } while (Directory.Exists(_extractTempDir));

            Directory.CreateDirectory(_extractTempDir);

            try
            {
                // Calculate total bytes to save
                long bytesToCompress = 0, bytesToExtract = 0, bytesExtracted = 0;

                var files = Directory.GetFiles(_inputTempFolder);

                foreach (string inputFile in files)
                {
                    bytesToExtract += new FileInfo(inputFile).Length;
                }

                foreach (string inputFile in files)
                {
                    if (inputFile.ToLowerInvariant().EndsWith(".tar"))
                    {
                        // Sanitize and un-tar each of the raw server tars to the temp extraction directory

                        string outFilename = inputFile.Substring(0, inputFile.Length - 4);
                        if (outFilename.Length == 0)
                        {
                            outFilename = Path.GetRandomFileName();
                        }
                        string outputDir = Path.Combine(_extractTempDir, Path.GetFileName(outFilename));

                        string sanitizedTar = Path.GetTempFileName();
                        TarSanitization.SanitizeTarForWindows(inputFile, sanitizedTar, CheckCancellation);

                        using (FileStream fs = File.OpenRead(sanitizedTar))
                            using (ArchiveIterator tarIterator = ArchiveFactory.Reader(ArchiveFactory.Type.Tar, fs))
                            {
                                Directory.CreateDirectory(outputDir);
                                tarIterator.ExtractAllContents(outputDir);
                                bytesToCompress += Core.Helpers.GetDirSize(new DirectoryInfo(outputDir));
                            }

                        try
                        {
                            File.Delete(sanitizedTar);
                        }
                        catch
                        {
                        }
                    }
                    else
                    {
                        // Just copy vanilla input files unmodified to the temp directory
                        string outputFile = Path.Combine(_extractTempDir, Path.GetFileName(inputFile));
                        File.Copy(inputFile, outputFile);
                        bytesToCompress += new FileInfo(outputFile).Length;
                    }

                    bytesExtracted += new FileInfo(inputFile).Length;
                    File.Delete(inputFile);
                    PercentComplete = (int)(50.0 * bytesExtracted / bytesToExtract);
                    CheckCancellation();
                }

                // Now zip up all the temporarily extracted files into a single zip file for the user
                log.DebugFormat("Packing {0} of bug report files into zip file {1}",
                                Util.DiskSizeString(bytesToCompress), _destFile);

                ZipToOutputFile(_extractTempDir, CheckCancellation, p => PercentComplete = 50 + p / 2);
                CleanupFiles();
                PercentComplete = 100;
            }
            catch (CancelledException)
            {
                CleanupFiles(true);
                throw;
            }
            catch (Exception exn)
            {
                try
                {
                    log.Error("Failed to package sanitized server status report: ", exn);
                    log.Debug("Attempting to package raw downloaded server files.");
                    ZipToOutputFile(_inputTempFolder, CheckCancellation);
                }
                catch (CancelledException)
                {
                    CleanupFiles(true);
                    throw;
                }
                catch
                {
                    log.Debug("Failed to package raw downloaded server files.");
                }

                throw new Exception(Messages.STATUS_REPORT_ZIP_FAILED);
            }
        }