[gnome-boxes/wip/image-import: 8/10] Add support for importing gzip-compression images



commit c9103fc037631eb2aaa32ee6fbf3f05a987fd889
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Thu Jun 6 04:47:05 2013 +0300

    Add support for importing gzip-compression images
    
    To reduce download time, images are sometimes compressed by distributors
    (e.g GNOME OSTree images).

 src/installed-media.vala |   40 +++++++++++++++++++++++++++++++++++++++-
 src/wizard-source.vala   |    2 ++
 2 files changed, 41 insertions(+), 1 deletions(-)
---
diff --git a/src/installed-media.vala b/src/installed-media.vala
index 296f4f6..3f0e0a4 100644
--- a/src/installed-media.vala
+++ b/src/installed-media.vala
@@ -31,7 +31,8 @@ private class Boxes.InstalledMedia : Boxes.InstallerMedia {
     private bool converted;
 
     public InstalledMedia (string path) throws GLib.Error {
-        if (!path.has_suffix (".qcow2") && !path.has_suffix (".img"))
+        if (!path.has_suffix (".qcow2") && !path.has_suffix (".qcow2.gz") &&
+            !path.has_suffix (".img") && !path.has_suffix (".img.gz"))
             throw new Boxes.Error.INVALID (_("Only QEMU QCOW Image (v2) and raw formats supported."));
 
         device_file = path;
@@ -45,6 +46,8 @@ private class Boxes.InstalledMedia : Boxes.InstallerMedia {
         if (device_file.has_suffix (".qcow2"))
             return;
 
+        yield decompress ();
+
         var converted_path = get_user_pkgcache (Path.get_basename (device_file) + ".qcow2");
         string[] argv = { "qemu-img", "convert", "-O", "qcow2", device_file, converted_path };
 
@@ -52,6 +55,12 @@ private class Boxes.InstalledMedia : Boxes.InstallerMedia {
         yield exec (argv, null);
         debug ("Finished converting '%s' to 'qcow2' format", device_file);
 
+        if (converted) {
+            // We decompressed into a temporary location
+            var file = File.new_for_path (device_file);
+            delete_file (file);
+        }
+
         device_file = converted_path;
         converted = true;
     }
@@ -89,4 +98,33 @@ private class Boxes.InstalledMedia : Boxes.InstallerMedia {
     public override VMCreator get_vm_creator () {
         return new VMImporter (this);
     }
+
+    private async void decompress () throws GLib.Error {
+        if (!device_file.has_suffix (".gz"))
+            return;
+
+        var compressed = File.new_for_path (device_file);
+        var input_stream = yield compressed.read_async ();
+
+        var decompressed_path = Path.get_basename (device_file).replace (".gz", "");
+        decompressed_path = get_user_pkgcache (decompressed_path);
+        var decompressed = File.new_for_path (decompressed_path);
+        GLib.OutputStream output_stream = yield decompressed.replace_async (null,
+                                                                            false,
+                                                                            
FileCreateFlags.REPLACE_DESTINATION);
+        var decompressor = new ZlibDecompressor (ZlibCompressorFormat.GZIP);
+        output_stream = new ConverterOutputStream (output_stream, decompressor);
+
+        debug ("Decompression '%s'..", device_file);
+        var buffer = new uint8[1048576];
+        ssize_t length = 0;
+        do {
+            length = yield input_stream.read_async (buffer);
+            output_stream.write (buffer[0:length]);
+        } while (length > 0);
+        debug ("Decompressed '%s'.", device_file);
+
+        device_file = decompressed_path;
+        converted = true;
+    }
 }
diff --git a/src/wizard-source.vala b/src/wizard-source.vala
index 36f6043..02e12e3 100644
--- a/src/wizard-source.vala
+++ b/src/wizard-source.vala
@@ -310,7 +310,9 @@ private class Boxes.WizardSource: GLib.Object {
         dialog.filter = new Gtk.FileFilter ();
         dialog.filter.add_mime_type ("application/x-cd-image");
         dialog.filter.add_pattern ("*.img");
+        dialog.filter.add_pattern ("*.img.gz");
         dialog.filter.add_pattern ("*.qcow2");
+        dialog.filter.add_pattern ("*.qcow2.gz");
         var ret = false;
         if (dialog.run () == Gtk.ResponseType.ACCEPT) {
             uri = dialog.get_uri ();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]