[gnome-boxes/drop-system-importer: 3/3] libvirt-machine: Allow to "Import" non-local VMs
- From: Felipe Borges <felipeborges src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-boxes/drop-system-importer: 3/3] libvirt-machine: Allow to "Import" non-local VMs
- Date: Mon, 29 Apr 2019 12:18:13 +0000 (UTC)
commit 6fb713e799ce386d47d59034330ab05b6abab363
Author: Felipe Borges <felipeborges gnome org>
Date: Wed Apr 24 18:45:05 2019 +0200
libvirt-machine: Allow to "Import" non-local VMs
These changes make it possible to "Import" a VM storage volume into
the Boxes internal storage volumes location. We use the same
mechanism than the "clone ()" operation, except we update the
storage volume paths and copy/convert the disks.
src/actions-popover.vala | 8 ++++++--
src/libvirt-machine.vala | 33 ++++++++++++++++++++++++++++-----
src/util-app.vala | 24 ++++++++++++++++++++++++
src/vm-importer.vala | 8 +++++++-
4 files changed, 65 insertions(+), 8 deletions(-)
---
diff --git a/src/actions-popover.vala b/src/actions-popover.vala
index 7d1e0cdd..948abc70 100644
--- a/src/actions-popover.vala
+++ b/src/actions-popover.vala
@@ -71,8 +71,12 @@ public void update_for_item (CollectionItem item) {
}
if (window.ui_state != UIState.DISPLAY) {
- // Clone
- section.append (_("Clone"), "box.clone");
+ var clone_or_import_label = _("Clone");
+ if (machine is LibvirtMachine && !machine.is_local)
+ clone_or_import_label = _("Import");
+
+ // Clone or Import
+ section.append (clone_or_import_label, "box.clone");
var action = action_group.lookup_action ("clone") as GLib.SimpleAction;
action.set_enabled (machine.can_clone);
diff --git a/src/libvirt-machine.vala b/src/libvirt-machine.vala
index 1c8e4830..9022b5b8 100644
--- a/src/libvirt-machine.vala
+++ b/src/libvirt-machine.vala
@@ -51,9 +51,13 @@
public override bool is_local {
get {
- /* get_domain_disk () will return NULL for volumes that aren't managed by Boxes. */
- if (get_domain_disk () != null)
- return true;
+ try {
+ /* get_domain_disk () will return NULL for volumes that aren't managed by Boxes. */
+ if (get_domain_disk () != null)
+ return true;
+ } catch (GLib.Error error) {
+ warning ("Failed to obtain domain disk: %s", error.message);
+ }
return base.is_local;
}
@@ -749,7 +753,24 @@ public override async void clone () {
var config = new GVirConfig.Domain.from_xml (xml);
config.set_uuid (null);
- var media = new LibvirtClonedMedia (storage_volume.get_path (), config);
+ string? device_file = storage_volume.get_path ();
+ var storage_volume_path = is_local ? device_file : get_user_pkgdata (Path.build_filename
("images", name));
+ var media = new LibvirtClonedMedia (storage_volume_path, config);
+
+ if (!is_local) {
+ var devices = config.get_devices ();
+ foreach (var device in devices) {
+ if (!(device is GVirConfig.DomainDisk))
+ continue;
+
+ device_file = (device as GVirConfig.DomainDisk).get_source ();
+ devices.remove (device);
+
+ break;
+ }
+
+ config.set_devices (devices);
+ }
// Recreate network interface so clones won't have the same mac address
var iface= VMConfigurator.create_network_interface (config,
@@ -759,6 +780,7 @@ public override async void clone () {
var vm_cloner = media.get_vm_creator ();
var clone_machine = yield vm_cloner.create_vm (null);
+ (vm_cloner as VMImporter).import_vm (clone_machine, device_file);
vm_cloner.launch_vm (clone_machine, this.config.access_last_time);
ulong under_construct_id = 0;
@@ -771,7 +793,8 @@ public override async void clone () {
}
});
} catch (GLib.Error error) {
- warning ("Failed to clone %s: %s", domain_config.name, error.message);
+ var action = is_local ? "clone" : "import";
+ warning ("Failed to %s %s: %s", action, domain_config.name, error.message);
can_delete = true;
}
}
diff --git a/src/util-app.vala b/src/util-app.vala
index 88a9a1d3..3242de8e 100644
--- a/src/util-app.vala
+++ b/src/util-app.vala
@@ -425,6 +425,30 @@ public async bool check_storage_pool (out string diagnosis) {
return true;
}
+ public async void ensure_disk_is_readable (string disk_path) throws GLib.Error {
+ string[] argv = {};
+
+ argv += "pkexec";
+ argv += "chmod";
+ argv += "a+r";
+
+ var file = File.new_for_path (disk_path);
+ var info = yield file.query_info_async (FileAttribute.ACCESS_CAN_READ,
+ FileQueryInfoFlags.NONE,
+ Priority.DEFAULT,
+ null);
+ if (!info.get_attribute_boolean (FileAttribute.ACCESS_CAN_READ)) {
+ debug ("'%s' not readable, gotta make it readable..", disk_path);
+ argv += disk_path;
+ }
+
+ if (argv.length == 3)
+ return;
+
+ debug ("Making broker's disks readable..");
+ yield exec (argv, null);
+ debug ("Made all broker's disks readable.");
+ }
// FIXME: Better ways to remove alpha more than welcome
private Gdk.Pixbuf remove_alpha (Gdk.Pixbuf pixbuf) {
diff --git a/src/vm-importer.vala b/src/vm-importer.vala
index 8f1c2d57..08544f9d 100644
--- a/src/vm-importer.vala
+++ b/src/vm-importer.vala
@@ -43,10 +43,16 @@ protected virtual async void post_import_setup (LibvirtMachine machine) {
machine.vm_creator = null;
}
- private async void import_vm (LibvirtMachine machine) {
+ public async void import_vm (LibvirtMachine machine, string? custom_source = null) {
try {
var destination_path = machine.storage_volume.get_path ();
+ if (custom_source != null) {
+ yield ensure_disk_is_readable (custom_source);
+
+ source_media.device_file = custom_source;
+ }
+
yield source_media.copy (destination_path);
// Without refreshing the pool, libvirt will not know of changes to volume we just made
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]