[gnome-boxes/import-export-vms: 2/2] WIP



commit 22a3f7d96c221eb761d19d7bd81ba496b8ec7db1
Author: Felipe Borges <felipeborges gnome org>
Date:   Tue Nov 26 14:02:11 2019 +0100

    WIP

 src/actions-popover.vala | 23 ++++++++++++++++
 src/meson.build          |  1 +
 src/vm-exporter.vala     | 71 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 95 insertions(+)
---
diff --git a/src/actions-popover.vala b/src/actions-popover.vala
index 7d1e0cdd..283d02d3 100644
--- a/src/actions-popover.vala
+++ b/src/actions-popover.vala
@@ -9,6 +9,7 @@
         {"delete",          delete_activated},
         {"clone",           clone_activated},
         {"properties",      properties_activated},
+        {"export",          export_activated},
         {"restart",         restart_activated},
         {"send_file",       send_file_activated}
 
@@ -95,6 +96,10 @@ public void update_for_item (CollectionItem item) {
         var action = action_group.lookup_action ("properties") as GLib.SimpleAction;
         action.set_enabled (!importing);
 
+        section.append (_("Export"), "box.export");
+        menu.append_section (null, section);
+        // when to enable?
+
         bind_model (menu, null);
         window.current_item = item;
     }
@@ -169,4 +174,22 @@ private void send_file_activated () {
     private void properties_activated () {
         window.show_properties ();
     }
+
+    private void export_activated () {
+        var machine = window.current_item as LibvirtMachine;
+
+        var title = _("Export %s").printf (machine.name);
+        var file_chooser = new Gtk.FileChooserNative (title,
+                                                      window,
+                                                      Gtk.FileChooserAction.SAVE,
+                                                      _("Export"), _("Cancel"));
+        if (file_chooser.run () == Gtk.ResponseType.ACCEPT) {
+            print (title);
+            print (file_chooser.get_filename ());
+
+            var vm_exporter = new VMExporter (machine, file_chooser.get_filename ());
+            vm_exporter.export.begin ();
+        }
+    }
+
 }
diff --git a/src/meson.build b/src/meson.build
index c78b8fbd..4a4c4fa6 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -102,6 +102,7 @@ vala_sources = [
   'vm-configurator.vala',
   'vm-creator.vala',
   'vm-importer.vala',
+  'vm-exporter.vala',
   'libvirt-system-importer.vala',
   'libvirt-vm-cloner.vala',
   'libvirt-vm-importer.vala',
diff --git a/src/vm-exporter.vala b/src/vm-exporter.vala
new file mode 100644
index 00000000..38a4e98d
--- /dev/null
+++ b/src/vm-exporter.vala
@@ -0,0 +1,71 @@
+// This file is part of GNOME Boxes. License: LGPLv2+
+
+private class Boxes.VMExporter : GLib.Object {
+    private LibvirtMachine machine;
+    private string destination;
+
+    public VMExporter (LibvirtMachine machine, string destination) {
+        this.machine = machine;
+
+    }
+
+    public async void export () {
+        var xml = machine.domain_config.to_xml ();
+
+        print (xml);
+
+        string? device_file = null;
+        foreach (var device in machine.domain_config.get_devices ()) {
+            if (device is GVirConfig.DomainDisk) {
+                device_file = (device as GVirConfig.DomainDisk).get_source ();
+
+                break;
+            }
+        }
+
+        if (device_file != null) {
+
+            print ("device_file %s\n", device_file);
+            Archive.Write archive = new Archive.Write ();
+            archive.add_filter_gzip ();
+            archive.set_format_pax_restricted ();
+            archive.open_filename (destination);
+
+            GLib.File file = GLib.File.new_for_path (device_file);
+            GLib.File parent_dir = GLib.File.new_for_path (".");
+            try {
+                GLib.FileInfo file_info = file.query_info (GLib.FileAttribute.STANDARD_SIZE, 
GLib.FileQueryInfoFlags.NONE);
+                FileInputStream input_stream = file.read ();
+                DataInputStream data_input_stream = new DataInputStream (input_stream);
+
+                Archive.Entry entry = new Archive.Entry ();
+                entry.set_pathname (parent_dir.get_relative_path (file));
+                entry.set_size ((Archive.int64_t)file_info.get_size ());
+                entry.set_filetype ((Archive.FileType) Posix.S_IFREG);
+                entry.set_perm(0644);
+
+                if (archive.write_header (entry) != Archive.Result.OK) {
+                    critical ("Error writing '%s': %s (%d)", file.get_path (), archive.error_string (), 
archive.errno ());
+
+                    return;
+                }
+
+                size_t bytes_read;
+                uint8[] buffer = new uint8[64];
+                while (data_input_stream.read_all (buffer, out bytes_read)) {
+                    if (bytes_read <= 0) {
+                        break;
+                    }
+
+                    archive.write_data_block (buffer, bytes_read);
+                }
+            } catch (GLib.Error e) {
+                critical (e.message);
+            }
+
+            if (archive.close () != Archive.Result.OK) {
+                error ("Error : %s (%d)", archive.error_string (), archive.errno ());
+            }
+        }
+    }
+}


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