[gnome-boxes] unattended-file, archive-writer: Improve initrd-injection support



commit 9f26f63a6f4a783b4cf96d11167a00cd4eb275be
Author: Christophe Fergeau <cfergeau redhat com>
Date:   Mon Feb 18 13:13:15 2019 +0100

    unattended-file,archive-writer: Improve initrd-injection support
    
    Some ubuntu initrds are actually multiple cpio archives concatenated,
    basic use of cpio -id/libarchive are only able to read a single file
    from them, so the approach taken by boxes is not working for them.
    
    virt-install is appending a gzipped single-element cpio archive to the
    initrd instead and this commit changes the initrd-injection to do the
    same.
    
    Reviewed-by: Fabiano FidĂȘncio <fidencio redhat com>

 src/archive-writer.vala  | 12 ++++++++++++
 src/unattended-file.vala | 45 ++++++++++++++++++++++++++++++++++++---------
 2 files changed, 48 insertions(+), 9 deletions(-)
---
diff --git a/src/archive-writer.vala b/src/archive-writer.vala
index 29cf6edf..c2322628 100644
--- a/src/archive-writer.vala
+++ b/src/archive-writer.vala
@@ -19,6 +19,18 @@ public ArchiveWriter (string                     filename,
         execute_libarchive_function (archive, () => { return archive.open_filename (filename); });
     }
 
+    public ArchiveWriter.from_fd (int fd,
+                                  Archive.Format             format,
+                                  GLib.List<Archive.Filter>? filters = null)
+                                  throws GLib.IOError {
+        archive = new Archive.Write ();
+        this.format  = format;
+        this.filters = filters.copy ();
+
+        prepare_archive ();
+        execute_libarchive_function (archive, () => { return archive.open_fd (fd); });
+    }
+
     public ArchiveWriter.from_archive_reader (ArchiveReader archive_reader,
                                               string        filename,
                                               bool          import_contents = true)
diff --git a/src/unattended-file.vala b/src/unattended-file.vala
index 8aa679a8..56a6608d 100644
--- a/src/unattended-file.vala
+++ b/src/unattended-file.vala
@@ -13,24 +13,31 @@
     }
     protected abstract UnattendedInstaller installer { get; set; }
 
-    public async void copy (Cancellable? cancellable) throws GLib.Error {
+    public async virtual void copy (Cancellable? cancellable) throws GLib.Error {
         var source_file = yield get_source_file (cancellable);
+        yield default_copy(disk_file, source_file.get_path (), dest_name);
+    }
 
+    protected static async void default_copy (string       disk_file,
+                                              string       source_file,
+                                              string       dest_name,
+                                              Cancellable? cancellable = null)
+                                              throws GLib.Error {
         debug ("Copying unattended file '%s' into disk drive/image '%s'", dest_name, disk_file);
 
         if (is_libarchive_compatible (disk_file)) {
             yield App.app.async_launcher.launch(() => {
-                copy_with_libarchive (disk_file, source_file.get_path (), dest_name);
+                copy_with_libarchive (disk_file, source_file, dest_name);
             });
         } else
-            yield copy_with_mcopy (disk_file, source_file.get_path (), dest_name, cancellable);
+            yield copy_with_mcopy (disk_file, source_file, dest_name, cancellable);
 
         debug ("Copied unattended file '%s' into disk drive/image '%s'", dest_name, disk_file);
     }
 
     protected abstract async File get_source_file (Cancellable? cancellable)  throws GLib.Error;
 
-    private void copy_with_libarchive (string disk_file, string source_file, string dest_name) throws 
GLib.Error {
+    private static void copy_with_libarchive (string disk_file, string source_file, string dest_name) throws 
GLib.Error {
         var reader = new ArchiveReader (disk_file);
         // write into file~ since we can't write into the file we read from
         var writer = new ArchiveWriter.from_archive_reader (reader, disk_file + "~", false);
@@ -48,11 +55,11 @@ private void copy_with_libarchive (string disk_file, string source_file, string
         src.move (dst, FileCopyFlags.OVERWRITE);
     }
 
-    private async void copy_with_mcopy (string       disk_file,
-                                        string       source_file,
-                                        string       dest_name,
-                                        Cancellable? cancellable = null)
-                                        throws GLib.Error {
+    private static async void copy_with_mcopy (string       disk_file,
+                                               string       source_file,
+                                               string       dest_name,
+                                               Cancellable? cancellable = null)
+                                               throws GLib.Error {
         string[] argv = {"mcopy",
                              "-n",
                              "-o",
@@ -136,6 +143,26 @@ else if (InstallScriptInjectionMethod.INITRD in injection_methods)
             throw new GLib.IOError.NOT_SUPPORTED ("No supported injection method available.");
     }
 
+    public async void copy (Cancellable? cancellable) throws GLib.Error {
+        var source_file = yield get_source_file (cancellable);
+        if (injection_method == InstallScriptInjectionMethod.INITRD) {
+            initrd_append (installer.initrd_file.get_path (), source_file.get_path (), dest_name);
+        } else
+            yield Boxes.UnattendedFile.default_copy(disk_file, source_file.get_path (), dest_name);
+    }
+
+    private static void initrd_append (string disk_file, string source_file, string dest_name) throws 
GLib.Error {
+        debug ("Appending unattended file '%s' to initrd '%s'", dest_name, disk_file);
+        var gzip_filter = new GLib.List<Archive.Filter> ();
+        gzip_filter.append (Archive.Filter.GZIP);
+        var file = FileStream.open (disk_file, "a");
+        if (file == null)
+            throw GLib.IOError.from_errno (errno);
+        var writer = new ArchiveWriter.from_fd (file.fileno (), Archive.Format.CPIO_SVR4_NOCRC, gzip_filter);
+        writer.insert_file (source_file, dest_name);
+        debug ("Appended unattended file '%s' to initrd '%s'", dest_name, disk_file);
+    }
+
     ~UnattendedScriptFile () {
         if (unattended_tmp == null)
             return;


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