[gnome-boxes/wip/system-libvirt-import2] tmp
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-boxes/wip/system-libvirt-import2] tmp
- Date: Fri, 15 Nov 2013 15:56:37 +0000 (UTC)
commit 22190334e719d3ff104aeec0bbd4e41bc687bf1f
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date: Tue Oct 15 20:49:41 2013 -0400
tmp
src/Makefile.am | 3 +
src/app.vala | 2 +
src/libvirt-broker.vala | 8 ++-
src/libvirt-system-importer.vala | 142 +++++++++++++++++++++++++++++++++++
src/libvirt-system-media.vala | 28 +++++++
src/libvirt-system-vm-importer.vala | 50 ++++++++++++
src/vm-configurator.vala | 8 ++
src/vm-importer.vala | 12 ++-
8 files changed, 247 insertions(+), 6 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 12c41db..cbfec97 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -88,6 +88,7 @@ gnome_boxes_SOURCES = \
i-properties-provider.vala \
installer-media.vala \
installed-media.vala \
+ libvirt-system-media.vala \
iso-extractor.vala \
libvirt-broker.vala \
libvirt-machine.vala \
@@ -113,6 +114,8 @@ gnome_boxes_SOURCES = \
vm-configurator.vala \
vm-creator.vala \
vm-importer.vala \
+ libvirt-system-importer.vala \
+ libvirt-system-vm-importer.vala \
vnc-display.vala \
wizard-source.vala \
wizard.vala \
diff --git a/src/app.vala b/src/app.vala
index d835ac2..3d02c8d 100644
--- a/src/app.vala
+++ b/src/app.vala
@@ -82,6 +82,7 @@ private class Boxes.App: Boxes.UI {
public Properties properties;
public DisplayPage display_page;
public EmptyBoxes empty_boxes;
+ public LibvirtSystemImporter system_importer;
public string? uri { get; set; }
public Collection collection;
public CollectionFilter filter;
@@ -572,6 +573,7 @@ private class Boxes.App: Boxes.UI {
wizard = new Wizard ();
properties = new Properties ();
empty_boxes = new EmptyBoxes ();
+ system_importer = new LibvirtSystemImporter ();
var vbox_actor = new Clutter.Actor ();
vbox_actor.name = "top-vbox";
diff --git a/src/libvirt-broker.vala b/src/libvirt-broker.vala
index 2073570..af4adf2 100644
--- a/src/libvirt-broker.vala
+++ b/src/libvirt-broker.vala
@@ -53,12 +53,16 @@ private class Boxes.LibvirtBroker : Boxes.Broker {
var machine = add_domain (source, connection, domain);
var config = machine.domain_config;
+ // These instance will take care of their own lifecycles
if (VMConfigurator.is_install_config (config) || VMConfigurator.is_live_config (config)) {
debug ("Continuing installation/live session for '%s', ..", machine.name);
- new VMCreator.for_install_completion (machine); // This instance will take care of its own
lifecycle
+ new VMCreator.for_install_completion (machine);
} else if (VMConfigurator.is_import_config (config)) {
debug ("Continuing import of '%s', ..", machine.name);
- new VMImporter.for_import_completion (machine); // This instance will take care of its own
lifecycle
+ new VMImporter.for_import_completion (machine);
+ } else if (VMConfigurator.is_libvirt_system_import_config (config)) {
+ debug ("Continuing import of '%s', ..", machine.name);
+ new LibvirtSystemVMImporter.for_import_completion (machine);
}
} catch (GLib.Error error) {
warning ("Failed to create source '%s': %s", source.name, error.message);
diff --git a/src/libvirt-system-importer.vala b/src/libvirt-system-importer.vala
new file mode 100644
index 0000000..0682f74
--- /dev/null
+++ b/src/libvirt-system-importer.vala
@@ -0,0 +1,142 @@
+// This file is part of GNOME Boxes. License: LGPLv2+
+using GVir;
+
+errordomain Boxes.LibvirtSystemImporterError {
+ NO_SUITABLE_DISK
+}
+
+private class Boxes.LibvirtSystemImporter: GLib.Object {
+ public bool import_needed {
+ get {
+ return (domains.length () + pools.length ()) != 0;
+ }
+ }
+
+ private GVir.Connection connection;
+ private GLib.List<GVir.Domain> domains;
+ private GLib.List<GVir.StoragePool> pools;
+
+ public LibvirtSystemImporter () {
+ App.app.call_when_ready (() => {
+ if (App.app.collection.items.length == 0)
+ prepare_import.begin ();
+ });
+ }
+
+ private async void prepare_import () {
+ connection = new GVir.Connection ("qemu+unix:///system");
+
+ try {
+ yield connection.open_read_only_async (null);
+ debug ("Connected to system libvirt, now fetching domains..");
+ yield connection.fetch_domains_async (null);
+ } catch (GLib.Error error) {
+ warning ("Failed to connect to system libvirt: %s", error.message);
+
+ return;
+ }
+
+ domains = connection.get_domains ();
+ debug ("Fetched %u domains from system libvirt.", domains.length ());
+ if (domains.length () == 0)
+ return;
+
+ // Translators: %u here is number of boxes availble for import
+ var msg = _("Do you want to import %u boxes from system broker?").printf (domains.length ());
+ Notificationbar.OKFunc launch_import = () => {
+ import.begin ();
+ };
+
+ App.app.notificationbar.display_for_action (msg, _("Yes"), launch_import);
+ }
+
+ private async void import () {
+ GVirConfig.Domain[] configs = {};
+ string[] disk_paths = {};
+
+ foreach (var domain in domains) {
+ GVirConfig.Domain config;
+ string disk_path;
+
+ try {
+ get_domain_info (domain, out config, out disk_path);
+ configs += config;
+ disk_paths += disk_path;
+ } catch (GLib.Error error) {
+ warning ("%s", error.message);
+ }
+ }
+
+ try {
+ yield ensure_disks_readable (disk_paths);
+ } catch (GLib.Error error) {
+ warning ("Failed to make all libvirt system disks readable: %s", error.message);
+
+ return;
+ }
+
+ for (var i = 0; i < configs.length; i++)
+ import_domain.begin (configs[i], disk_paths[i], null, (obj, result) => {
+ try {
+ import_domain.end (result);
+ } catch (GLib.Error error) {
+ warning ("Failed to import '%s': %s", configs[i].name, error.message);
+ }
+ });
+ }
+
+ private void get_domain_info (Domain domain, out GVirConfig.Domain config, out string disk_path) throws
GLib.Error {
+ debug ("Fetching config for '%s' from system libvirt.", domain.get_name ());
+ config = domain.get_config (DomainXMLFlags.INACTIVE);
+ debug ("Finding a suitable disk to import for '%s' from system libvirt.", domain.get_name ());
+ disk_path = get_disk_path (config);
+ }
+
+ private async void import_domain (GVirConfig.Domain config,
+ string disk_path,
+ Cancellable? cancellable = null) throws GLib.Error {
+ debug ("Importing '%s' from system libvirt..", config.name);
+
+ var media = new LibvirtSystemMedia (disk_path, config);
+ var vm_importer = media.get_vm_creator ();
+ var machine = yield vm_importer.create_vm (cancellable);
+ vm_importer.launch_vm (machine);
+ }
+
+ private string get_disk_path (GVirConfig.Domain config) throws
LibvirtSystemImporterError.NO_SUITABLE_DISK {
+ string disk_path = null;
+
+ var devices = config.get_devices ();
+ foreach (var device in devices) {
+ if (!(device is GVirConfig.DomainDisk))
+ continue;
+
+ var disk = device as GVirConfig.DomainDisk;
+ if (disk.get_guest_device_type () == GVirConfig.DomainDiskGuestDeviceType.DISK) {
+ disk_path = disk.get_source ();
+
+ break;
+ }
+ }
+
+ if (disk_path == null)
+ throw new LibvirtSystemImporterError.NO_SUITABLE_DISK
+ (_("Failed to find suitable disk to import for box '%s'"), config.name);
+
+ return disk_path;
+ }
+
+ private async void ensure_disks_readable (string[] disk_paths) throws GLib.Error {
+ string[] argv = {};
+
+ argv += "pkexec";
+ argv += "chmod";
+ argv += "a+r";
+ foreach (var disk_path in disk_paths)
+ argv += disk_path;
+
+ debug ("Making all libvirt system disks readable..");
+ yield exec (argv, null);
+ debug ("Made all libvirt system disks readable.");
+ }
+}
diff --git a/src/libvirt-system-media.vala b/src/libvirt-system-media.vala
new file mode 100644
index 0000000..030f5d4
--- /dev/null
+++ b/src/libvirt-system-media.vala
@@ -0,0 +1,28 @@
+// This file is part of GNOME Boxes. License: LGPLv2+
+
+using GVirConfig;
+
+private class Boxes.LibvirtSystemMedia : Boxes.InstalledMedia {
+ protected override string? architecture {
+ owned get {
+ return domain_config.get_os ().get_arch ();
+ }
+ }
+
+ public Domain domain_config { get; private set; }
+
+ public LibvirtSystemMedia (string path, Domain domain_config) throws GLib.Error {
+ base (path);
+
+ this.domain_config = domain_config;
+ label = domain_config.title?? domain_config.name;
+
+ // Just initializing for sake for completion (and to avoid crashes). The CPU & RAM config comes from
the
+ // imported domain and storage volume is overwritten as well.
+ resources = OSDatabase.get_default_resources ();
+ }
+
+ public override VMCreator get_vm_creator () {
+ return new LibvirtSystemVMImporter (this);
+ }
+}
diff --git a/src/libvirt-system-vm-importer.vala b/src/libvirt-system-vm-importer.vala
new file mode 100644
index 0000000..6191d3f
--- /dev/null
+++ b/src/libvirt-system-vm-importer.vala
@@ -0,0 +1,50 @@
+// This file is part of GNOME Boxes. License: LGPLv2+
+
+using Osinfo;
+using GVirConfig;
+
+private class Boxes.LibvirtSystemVMImporter : Boxes.VMImporter {
+ public LibvirtSystemVMImporter (InstalledMedia source_media) {
+ base (source_media);
+ start_after_import = false;
+ }
+
+ public LibvirtSystemVMImporter.for_import_completion (LibvirtMachine machine) {
+ base.for_install_completion (machine);
+ start_after_import = false;
+ }
+
+ protected override void create_domain_base_name_and_title (out string base_name, out string base_title) {
+ var media = install_media as LibvirtSystemMedia;
+
+ base_name = media.domain_config.name;
+ base_title = media.domain_config.title?? base_name;
+ }
+
+ protected override async Domain create_domain_config (string name,
+ string title,
+ GVir.StorageVol volume,
+ Cancellable? cancellable) throws GLib.Error {
+ var media = install_media as LibvirtSystemMedia;
+ var config = media.domain_config;
+
+ config.name = name;
+ config.title = title;
+
+ var devices = config.get_devices ();
+ foreach (var device in devices) {
+ if (!(device is DomainDisk))
+ continue;
+
+ var disk = device as DomainDisk;
+ if (disk.get_source () == media.device_file) {
+ disk.set_source (volume.get_path ());
+
+ break;
+ }
+ }
+ config.set_devices (devices);
+
+ return config;
+ }
+}
diff --git a/src/vm-configurator.vala b/src/vm-configurator.vala
index 491a2ec..b1669cd 100644
--- a/src/vm-configurator.vala
+++ b/src/vm-configurator.vala
@@ -14,10 +14,12 @@ private class Boxes.VMConfigurator {
private const string LIVE_STATE = "live";
private const string INSTALLATION_STATE = "installation";
private const string IMPORT_STATE = "importing";
+ private const string LIBVIRT_SYS_IMPORT_STATE = "libvirt-system-importing";
private const string INSTALLED_STATE = "installed";
private const string LIVE_XML = "<os-state>" + LIVE_STATE + "</os-state>";
private const string INSTALLATION_XML = "<os-state>" + INSTALLATION_STATE + "</os-state>";
private const string IMPORT_XML = "<os-state>" + IMPORT_STATE + "</os-state>";
+ private const string LIBVIRT_SYS_IMPORT_XML = "<os-state>" + LIBVIRT_SYS_IMPORT_STATE + "</os-state>";
private const string INSTALLED_XML = "<os-state>" + INSTALLED_STATE + "</os-state>";
private const string OS_ID_XML = "<os-id>%s</os-id>";
@@ -133,6 +135,10 @@ private class Boxes.VMConfigurator {
return get_os_state (domain) == IMPORT_STATE;
}
+ public static bool is_libvirt_system_import_config (Domain domain) {
+ return get_os_state (domain) == LIBVIRT_SYS_IMPORT_STATE;
+ }
+
public static StorageVol create_volume_config (string name, int64 storage) throws GLib.Error {
var volume = new StorageVol ();
volume.set_name (name);
@@ -340,6 +346,8 @@ private class Boxes.VMConfigurator {
custom_xml = INSTALLED_XML;
else if (install_media is InstalledMedia)
custom_xml = IMPORT_XML;
+ else if (install_media is LibvirtSystemMedia)
+ custom_xml = LIBVIRT_SYS_IMPORT_XML;
else
custom_xml = (install_media.live) ? LIVE_XML : INSTALLATION_XML;
diff --git a/src/vm-importer.vala b/src/vm-importer.vala
index 262451a..a53232c 100644
--- a/src/vm-importer.vala
+++ b/src/vm-importer.vala
@@ -6,6 +6,8 @@ using GVir;
private class Boxes.VMImporter : Boxes.VMCreator {
public InstalledMedia source_media { get { return install_media as InstalledMedia; } }
+ protected bool start_after_import = true;
+
public VMImporter (InstalledMedia source_media) {
base (source_media);
}
@@ -56,10 +58,12 @@ private class Boxes.VMImporter : Boxes.VMCreator {
}
set_post_install_config (machine);
- try {
- machine.domain.start (0);
- } catch (GLib.Error error) {
- warning ("Failed to start domain '%s': %s", machine.domain.get_name (), error.message);
+ if (start_after_import) {
+ try {
+ machine.domain.start (0);
+ } catch (GLib.Error error) {
+ warning ("Failed to start domain '%s': %s", machine.domain.get_name (), error.message);
+ }
}
machine.info = null;
machine.vm_creator = null;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]