[gnome-boxes] Revert "express: No need for floppy image"



commit 12b120fded5ca91468c6ac0ab6e03ca247da2cee
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Mon Feb 6 20:31:21 2012 +0100

    Revert "express: No need for floppy image"
    
    This reverts commit bc806277b17856543bfeb5f07c7de66c3db5012d.
    
    Turns out that this really breaks against qemu builds in fedora at
    least. So reverting this for now.

 configure.ac                  |    2 +-
 data/Makefile.am              |    4 +
 data/disk.img                 |  Bin 0 -> 1474560 bytes
 src/fedora-installer.vala     |   22 ++++++-
 src/unattended-installer.vala |  134 +++++++++++++++++++++++++++++++++++++----
 src/util.vala                 |   44 -------------
 6 files changed, 145 insertions(+), 61 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 7d26d9d..bf08f98 100644
--- a/configure.ac
+++ b/configure.ac
@@ -46,7 +46,7 @@ GOBJECT_INTROSPECTION_MIN_VERSION=0.9.6
 GTK_MIN_VERSION=3.3.5
 GTK_VNC_MIN_VERSION=0.4.4
 LIBVIRT_GLIB_MIN_VERSION=0.0.4
-LIBVIRT_GCONFIG_MIN_VERSION=0.0.5
+LIBVIRT_GCONFIG_MIN_VERSION=0.0.4
 LIBXML2_MIN_VERSION=2.7.8
 SPICE_GTK_MIN_VERSION=0.7.98
 GUDEV_MIN_VERSION=147
diff --git a/data/Makefile.am b/data/Makefile.am
index a92dce1..03e1447 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -25,8 +25,12 @@ unattended_DATA = fedora.ks			\
 		  winxp.sif 			\
 		  win2k.sif 			\
 		  win2k3.sif 			\
+		  disk.img			\
 		  $(NULL)
 
+disk.img:
+	rm -f disk.img && qemu-img create -f raw disk.img 1440k && mkfs.msdos -s 1 disk.img
+
 EXTRA_DIST =					\
 	gnome-boxes.desktop.in			\
 	org.gnome.boxes.gschema.xml.in		\
diff --git a/data/disk.img b/data/disk.img
new file mode 100644
index 0000000..f7eb640
Binary files /dev/null and b/data/disk.img differ
diff --git a/src/fedora-installer.vala b/src/fedora-installer.vala
index de8ad68..357991f 100644
--- a/src/fedora-installer.vala
+++ b/src/fedora-installer.vala
@@ -22,7 +22,7 @@ private class Boxes.FedoraInstaller: UnattendedInstaller {
 
         os.set_kernel (kernel_path);
         os.set_ramdisk (initrd_path);
-        os.set_cmdline ("ks=hd:sdb1:" + unattended_dest_name);
+        os.set_cmdline ("ks=hd:sdb:" + unattended_dest_name);
     }
 
     protected override async void prepare_direct_boot (Cancellable? cancellable) throws GLib.Error {
@@ -36,10 +36,26 @@ private class Boxes.FedoraInstaller: UnattendedInstaller {
 
         yield extract_boot_files (cancellable);
 
-        yield clean_up (cancellable);
+        yield normal_clean_up (cancellable);
     }
 
-    private async void clean_up (Cancellable? cancellable) throws GLib.Error {
+    protected override void clean_up () throws GLib.Error {
+        base.clean_up ();
+
+        if (kernel_file != null) {
+            debug ("Removing '%s'..", kernel_path);
+            kernel_file.delete ();
+            debug ("Removed '%s'.", kernel_path);
+        }
+
+        if (initrd_file != null) {
+            debug ("Removing '%s'..", initrd_path);
+            initrd_file.delete ();
+            debug ("Removed '%s'.", initrd_path);
+        }
+    }
+
+    private async void normal_clean_up (Cancellable? cancellable) throws GLib.Error {
         if (!mounted)
             return;
 
diff --git a/src/unattended-installer.vala b/src/unattended-installer.vala
index 6c4cc4d..55f0010 100644
--- a/src/unattended-installer.vala
+++ b/src/unattended-installer.vala
@@ -32,6 +32,8 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
 
     protected string disk_path;
 
+    private bool created_disk;
+
     protected Gtk.Table setup_table;
     protected Gtk.Label setup_label;
     protected Gtk.HBox setup_hbox;
@@ -72,8 +74,7 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
         from_image = media.from_image;
         mount_point = media.mount_point;
 
-        disk_path = get_pkgcache (os.short_id + "-unattended");
-        ensure_directory (disk_path);
+        disk_path = get_pkgcache (os.short_id + "-unattended.img");
         this.unattended_src_path = unattended_src_path;
         this.unattended_dest_name = unattended_dest_name;
         newline_type = DataStreamNewlineType.LF;
@@ -99,8 +100,19 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
             return;
         }
 
-        yield create_unattended_file (cancellable);
-        yield prepare_direct_boot (cancellable);
+        try {
+            if (yield unattended_disk_exists (cancellable))
+                debug ("Found previously created unattended disk image for '%s', re-using..", os.short_id);
+            else
+                yield create_disk_image (cancellable);
+
+            yield copy_unattended_file (cancellable);
+            yield prepare_direct_boot (cancellable);
+        } catch (GLib.Error error) {
+            clean_up ();
+
+            throw error;
+        }
     }
 
     public virtual void populate_setup_vbox (Gtk.VBox setup_vbox) {
@@ -115,13 +127,12 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
             return null;
 
         var disk = new DomainDisk ();
-        disk.set_type (DomainDiskType.DIR);
+        disk.set_type (DomainDiskType.FILE);
         disk.set_guest_device_type (DomainDiskGuestDeviceType.DISK);
         disk.set_driver_name ("qemu");
-        disk.set_driver_type ("fat");
+        disk.set_driver_type ("raw");
         disk.set_source (disk_path);
         disk.set_target_dev ("sdb");
-        disk.set_readonly (true);
 
         return disk;
     }
@@ -201,6 +212,17 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
                 express_toggle.bind_property ("active", child, "sensitive", 0);
     }
 
+    protected virtual void clean_up () throws GLib.Error {
+        if (!created_disk)
+            return;
+
+        var disk_file = File.new_for_path (disk_path);
+
+        disk_file.delete ();
+
+        debug ("Removed '%s'.", disk_path);
+    }
+
     protected virtual string fill_unattended_data (string data) throws RegexError {
         var str = username_regex.replace (data, data.length, 0, username_entry.text);
         str = password_regex.replace (str, str.length, 0, password_entry.text);
@@ -213,12 +235,71 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
 
     protected virtual async void prepare_direct_boot (Cancellable? cancellable) throws GLib.Error {}
 
-    private async void create_unattended_file (Cancellable? cancellable)  throws GLib.Error {
-        var source = File.new_for_path (unattended_src_path);
-        var destination_path = Path.build_filename (disk_path, unattended_dest_name);
-        var destination = File.new_for_path (destination_path);
+    protected async void exec (string[] argv, Cancellable? cancellable) throws GLib.Error {
+        SourceFunc continuation = exec.callback;
+        GLib.Error error = null;
+        var context = MainContext.get_thread_default ();
+
+        g_io_scheduler_push_job ((job) => {
+            try {
+                exec_sync (argv);
+            } catch (GLib.Error err) {
+                error = err;
+            }
+
+            var source = new IdleSource ();
+            source.set_callback (() => {
+                continuation ();
+
+                return false;
+            });
+            source.attach (context);
 
-        debug ("Creating unattended file at '%s'..", destination_path);
+            return false;
+        });
+
+        yield;
+
+        if (error != null)
+            throw error;
+    }
+
+    private async void create_disk_image (Cancellable? cancellable) throws GLib.Error {
+        var disk_file = File.new_for_path (disk_path);
+        var template_path = get_unattended_dir ("disk.img");
+        var template_file = File.new_for_path (template_path);
+
+        debug ("Creating disk image for unattended installation at '%s'..", disk_path);
+        yield template_file.copy_async (disk_file, 0, Priority.DEFAULT, cancellable);
+        debug ("Floppy image for unattended installation created at '%s'", disk_path);
+
+        created_disk = true;
+    }
+
+    private async void copy_unattended_file (Cancellable? cancellable) throws GLib.Error {
+        var unattended_src = File.new_for_path (unattended_src_path);
+        var unattended_tmp_path = get_user_unattended_dir (unattended_dest_name);
+        var unattended_tmp = File.new_for_path (unattended_tmp_path);
+
+        yield create_unattended_file (unattended_src, unattended_tmp, cancellable);
+
+        debug ("Copying unattended file '%s' into disk drive/image '%s'", unattended_dest_name, disk_path);
+        // FIXME: Perhaps we should use libarchive for this?
+        string[] argv = { "mcopy", "-n", "-o", "-i", disk_path,
+                                   unattended_tmp_path,
+                                   "::" + unattended_dest_name };
+        yield exec (argv, cancellable);
+        debug ("Copied unattended file '%s' into disk drive/image '%s'", unattended_dest_name, disk_path);
+
+        debug ("Deleting temporary file '%s'", unattended_tmp_path);
+        unattended_tmp.delete (cancellable);
+        debug ("Deleted temporary file '%s'", unattended_tmp_path);
+    }
+
+    private async void create_unattended_file (File         source,
+                                               File         destination,
+                                               Cancellable? cancellable)  throws GLib.Error {
+        debug ("Creating unattended file at '%s'..", destination.get_path ());
         var input_stream = yield source.read_async (Priority.DEFAULT, cancellable);
         var output_stream = yield destination.replace_async (null,
                                                              false,
@@ -236,6 +317,33 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
             yield output_stream.write_async (str.data, Priority.DEFAULT, cancellable);
         }
         yield output_stream.close_async (Priority.DEFAULT, cancellable);
-        debug ("Created unattended file at '%s'.", destination_path);
+        debug ("Created unattended file at '%s'..", destination.get_path ());
+    }
+
+    private async bool unattended_disk_exists (Cancellable? cancellable) {
+        var file = File.new_for_path (disk_path);
+
+        try {
+            yield file.read_async (Priority.DEFAULT, cancellable);
+        } catch (IOError.NOT_FOUND not_found_error) {
+            return false;
+        } catch (GLib.Error error) {}
+
+        return true;
+    }
+
+    private void exec_sync (string[] argv) throws GLib.Error {
+        int exit_status = -1;
+
+        Process.spawn_sync (null,
+                            argv,
+                            null,
+                            SpawnFlags.SEARCH_PATH,
+                            null,
+                            null,
+                            null,
+                            out exit_status);
+        if (exit_status != 0)
+            throw new UnattendedInstallerError.COMMAND_FAILED ("Failed to execute: %s", string.joinv (" ", argv));
     }
 }
diff --git a/src/util.vala b/src/util.vala
index a749005..e4fe160 100644
--- a/src/util.vala
+++ b/src/util.vala
@@ -278,50 +278,6 @@ namespace Boxes {
         return val.value;
     }
 
-    public async void exec (string[] argv, Cancellable? cancellable) throws GLib.Error {
-        SourceFunc continuation = exec.callback;
-        GLib.Error error = null;
-        var context = MainContext.get_thread_default ();
-
-        g_io_scheduler_push_job ((job) => {
-            try {
-                exec_sync (argv);
-            } catch (GLib.Error err) {
-                error = err;
-            }
-
-            var source = new IdleSource ();
-            source.set_callback (() => {
-                continuation ();
-
-                return false;
-            });
-            source.attach (context);
-
-            return false;
-        });
-
-        yield;
-
-        if (error != null)
-            throw error;
-    }
-
-    private void exec_sync (string[] argv) throws GLib.Error {
-        int exit_status = -1;
-
-        Process.spawn_sync (null,
-                            argv,
-                            null,
-                            SpawnFlags.SEARCH_PATH,
-                            null,
-                            null,
-                            null,
-                            out exit_status);
-        if (exit_status != 0)
-            throw new UnattendedInstallerError.COMMAND_FAILED ("Failed to execute: %s", string.joinv (" ", argv));
-    }
-
     public class Pair<T1,T2> {
         public T1 first;
         public T2 second;



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