[gnome-boxes/use-mimetypes: 2/2] media-manager, medias: Use content-type to classify medias




commit 51d656a54e321c8fedd2635f92d45ea5e90458f9
Author: Felipe Borges <felipeborges gnome org>
Date:   Wed Dec 22 13:29:32 2021 +0100

    media-manager, medias: Use content-type to classify medias
    
    Instead of parsing path strings for known extensions, let's query
    for file infos and compare content-types for InstalledMedias and
    InstallerMedias.

 src/installed-media.vala | 45 ++++++++-------------------------
 src/installer-media.vala |  4 +--
 src/libvirt-media.vala   |  4 +--
 src/media-manager.vala   | 65 +++++++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 74 insertions(+), 44 deletions(-)
---
diff --git a/src/installed-media.vala b/src/installed-media.vala
index a76eeca6..349efadf 100644
--- a/src/installed-media.vala
+++ b/src/installed-media.vala
@@ -4,15 +4,6 @@
 using Govf;
 
 private class Boxes.InstalledMedia : Boxes.InstallerMedia {
-    public const string[] supported_extensions = { ".qcow2", ".qcow2.gz",
-                                                   ".qcow", ".qcow.gz",
-                                                   ".img", ".img.gz",
-                                                   ".cow", ".cow.gz",
-                                                   ".ova", ".ova.gz",
-                                                   ".vdi", ".vdi.gz",
-                                                   ".vmdk", ".vmdk.gz",
-                                                   ".vpc", ".vpc.gz",
-                                                   ".cloop", ".cloop.gz" };
     public const string[] supported_architectures = {
         "i686", "i586", "i486", "i386", "x86_64", "amd64"
     };
@@ -39,36 +30,21 @@
         }
     }
 
-    public InstalledMedia (string path, bool known_qcow2 = false) throws GLib.Error {
-        var supported = false;
+    public InstalledMedia (string path, bool skip_import = false) {
+        this.skip_import = skip_import;
 
-        if (known_qcow2 || path.has_prefix ("/dev/"))
-            supported = true; // Let's assume it's device file in raw format
-        else
-            foreach (var extension in supported_extensions) {
-                supported = path.down ().has_suffix (extension);
-                if (supported)
-                    break;
-            }
-
-        if (!supported)
-            throw new IOError.NOT_SUPPORTED (_("Unsupported disk image format."));
-
-        // FIXME with the proper implementation
-        skip_import = path.down ().has_suffix (".qcow2");
+        if (skip_import)
+            debug ("'%s' doesn't need to be imported", path);
 
+        resources = OSDatabase.get_default_resources ();
         device_file = path;
         from_image = true;
 
         label_setup ();
     }
 
-    public async InstalledMedia.guess_os (string path) throws GLib.Error {
-        this (path);
-
-        resources = OSDatabase.get_default_resources ();
-
-        label_setup ();
+    public async InstalledMedia.for_path (string path, bool skip_import = false) {
+        this (path, skip_import);
     }
 
     // Also converts to native format (QCOW2)
@@ -78,7 +54,7 @@ public async void copy (string destination_path) throws GLib.Error {
 
         string[] argv = { "qemu-img", "convert", "-O", "qcow2", device_file, destination_path };
 
-        var converting = !device_file.has_suffix (".qcow2");
+        var converting = !skip_import;
 
         debug ("Copying '%s' to '%s'%s.",
                device_file,
@@ -131,13 +107,14 @@ private async bool extract_ovf () throws GLib.Error {
     }
 
     private async bool decompress () throws GLib.Error {
-        if (!device_file.has_suffix (".gz"))
+        var media_manager = MediaManager.get_default ();
+        if (!media_manager.path_is_compressed (device_file))
             return false;
 
         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", "");
+        var decompressed_path = Path.get_basename (device_file).concat (".boxes");
         decompressed_path = get_user_pkgcache (decompressed_path);
         var decompressed = File.new_for_path (decompressed_path);
         GLib.OutputStream output_stream = yield decompressed.replace_async (null,
diff --git a/src/installer-media.vala b/src/installer-media.vala
index f991aee5..3990a575 100644
--- a/src/installer-media.vala
+++ b/src/installer-media.vala
@@ -126,8 +126,7 @@
     }
 
     public async InstallerMedia.for_path (string       path,
-                                          MediaManager media_manager,
-                                          Cancellable? cancellable) throws GLib.Error {
+                                          Cancellable? cancellable = null) throws GLib.Error {
         var device_file = yield get_device_file_from_path (path, cancellable);
 #if !FLATPAK
         var device = yield get_device_from_device_file (device_file, media_manager.client);
@@ -137,6 +136,7 @@
         else {
 #endif
             from_image = true;
+            var media_manager = MediaManager.get_default ();
             os_media = yield media_manager.os_db.guess_os_from_install_media_path (device_file, cancellable);
             if (os_media != null)
                 os = os_media.os;
diff --git a/src/libvirt-media.vala b/src/libvirt-media.vala
index f173a497..5654542d 100644
--- a/src/libvirt-media.vala
+++ b/src/libvirt-media.vala
@@ -17,8 +17,8 @@
 
     public Domain domain_config { get; private set; }
 
-    public LibvirtMedia (string path, Domain domain_config, bool known_qcow2 = false) throws GLib.Error {
-        base (path, known_qcow2);
+    public LibvirtMedia (string path, Domain domain_config, bool skip_import = false) throws GLib.Error {
+        base (path, skip_import);
 
         this.domain_config = domain_config;
         label = domain_config.title?? domain_config.name;
diff --git a/src/media-manager.vala b/src/media-manager.vala
index 04915e2b..71521558 100644
--- a/src/media-manager.vala
+++ b/src/media-manager.vala
@@ -22,17 +22,70 @@ public static MediaManager get_default () {
 
     public async InstallerMedia create_installer_media_for_path (string       path,
                                                                  Cancellable? cancellable = null) throws 
GLib.Error {
-        InstallerMedia media;
+        InstallerMedia? media = null;
 
-        try {
-            media = yield new InstalledMedia.guess_os (path);
-        } catch (IOError.NOT_SUPPORTED e) {
-            media = yield new InstallerMedia.for_path (path, this, cancellable);
+        if (path_is_installed_media (path) || path.has_prefix ("/dev/")) {
+            media = new InstalledMedia (path, !path_needs_import (path));
+        } else if (path_is_installer_media (path)) {
+            media = yield new InstallerMedia.for_path (path);
+        }
+
+        if (media == null) {
+            throw new GLib.IOError.NOT_SUPPORTED (_("Media is not supported"));
         }
 
         return create_installer_media_from_media (media);
     }
 
+    private const string[] supported_installed_media_content_types = {
+        "application/x-qemu-disk",
+        "application/octet-stream",
+        "application/x-tar",
+        "application/x-xz",
+        "application/xml",
+    };
+    private bool path_is_installed_media (string path) {
+        return media_matches_content_type (path, supported_installed_media_content_types);
+    }
+
+    private bool path_needs_import (string path) {
+        return !media_matches_content_type (path, {"application/x-qemu-disk"});
+    }
+
+    private const string[] supported_installer_media_content_types = {
+        "application/x-cd-image",
+        "application/x-raw-disk-image",
+    };
+    private bool path_is_installer_media (string path) {
+        return media_matches_content_type (path, supported_installer_media_content_types);
+    }
+
+    private const string[] supported_compression_content_types = {
+        "application/x-tar",
+        "application/x-xz"
+    };
+    public bool path_is_compressed (string path) {
+        return media_matches_content_type (path, supported_compression_content_types);
+    }
+
+    private bool media_matches_content_type (string path, string[] supported_content_types) {
+        File file = File.new_for_path (path);
+
+        try {
+            FileInfo info = file.query_info ("standard::content-type", 0);
+
+            foreach (var content_type in supported_content_types) {
+                if (info.get_content_type () == content_type)
+                    return true;
+            }
+        } catch (GLib.Error error) {
+            warning ("Failed to query file info for '%s': %s", path, error.message);
+        }
+
+        return false;
+
+    }
+
     public async InstallerMedia? create_installer_media_from_config (GVirConfig.Domain config) {
         var path = VMConfigurator.get_source_media_path (config);
         if (path == null)
@@ -40,7 +93,7 @@ public async InstallerMedia create_installer_media_for_path (string       path,
 
         try {
             if (VMConfigurator.is_import_config (config))
-                return yield new InstalledMedia.guess_os (path);
+                return new InstalledMedia (path, !path_needs_import (path));
             else if (VMConfigurator.is_libvirt_system_import_config (config))
                 return new LibvirtMedia (path, config);
             else if (VMConfigurator.is_libvirt_cloning_config (config))


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