From c0a8c6528a40312210ba1dd4b962109fbeaa9af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marta=20Marczykowska-G=C3=B3recka?= Date: Tue, 24 Mar 2020 21:12:53 +0100 Subject: [PATCH] Cloning a vm now clones persistent PCI device assignments fixes QubesOS/qubes-issues#4992 --- qubesadmin/app.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/qubesadmin/app.py b/qubesadmin/app.py index 010603d..71d0902 100644 --- a/qubesadmin/app.py +++ b/qubesadmin/app.py @@ -38,6 +38,7 @@ import qubesadmin.storage import qubesadmin.utils import qubesadmin.vm import qubesadmin.config +import qubesadmin.devices class VMCollection(object): @@ -316,7 +317,9 @@ class QubesBase(qubesadmin.base.PropertyHolder): return self.domains[name] def clone_vm(self, src_vm, new_name, new_cls=None, pool=None, pools=None, - ignore_errors=False, ignore_volumes=None): + ignore_errors=False, ignore_volumes=None, + ignore_devices=False): + # pylint: disable=too-many-statements """Clone Virtual Machine Example usage with custom storage pools: @@ -337,6 +340,7 @@ class QubesBase(qubesadmin.base.PropertyHolder): logged, or abort the whole operation? :param list ignore_volumes: do not clone volumes on this list, like 'private' or 'root' + :param bool ignore_devices: if True, do not copy device assignments :return new VM object """ @@ -472,6 +476,22 @@ class QubesBase(qubesadmin.base.PropertyHolder): del self.domains[dst_vm.name] raise + if not ignore_devices: + try: + for devclass in src_vm.devices: + for assignment in src_vm.devices[devclass].assignments( + persistent=True): + new_assignment = qubesadmin.devices.DeviceAssignment( + backend_domain=assignment.backend_domain, + ident=assignment.ident, + options=assignment.options, + persistent=assignment.persistent) + dst_vm.devices[devclass].attach(new_assignment) + except qubesadmin.exc.QubesException: + if not ignore_errors: + del self.domains[dst_vm.name] + raise + return dst_vm def qubesd_call(self, dest, method, arg=None, payload=None,