From c437f40284198439a3fa260106e8c57529240dad Mon Sep 17 00:00:00 2001 From: Wojtek Porczyk Date: Mon, 3 Apr 2017 13:11:34 +0200 Subject: [PATCH] qubes/mgmt: lifecycle and class listing - mgmt.vmclass.List - mgmt.vm.Start - mgmt.vm.Shutdown - mgmt.vm.Pause - mgmt.vm.Unpause - mgmt.vm.Kill QubesOS/qubes-issues#2622 --- qubes/app.py | 19 +++++++++++-------- qubes/mgmt.py | 35 +++++++++++++++++++++++++++++++++++ qubes/vm/__init__.py | 1 + 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/qubes/app.py b/qubes/app.py index 8eeeddba..00c7c126 100644 --- a/qubes/app.py +++ b/qubes/app.py @@ -55,13 +55,15 @@ elif os.name == 'nt': else: raise RuntimeError("Qubes works only on POSIX or WinNT systems") - -import qubes # pylint: disable=wrong-import-position -import qubes.ext # pylint: disable=wrong-import-position -import qubes.utils # pylint: disable=wrong-import-position -import qubes.vm.adminvm # pylint: disable=wrong-import-position -import qubes.vm.qubesvm # pylint: disable=wrong-import-position -import qubes.vm.templatevm # pylint: disable=wrong-import-position +# pylint: disable=wrong-import-position +import qubes +import qubes.ext +import qubes.utils +import qubes.vm +import qubes.vm.adminvm +import qubes.vm.qubesvm +import qubes.vm.templatevm +# pylint: enable=wrong-import-position class VirDomainWrapper(object): # pylint: disable=too-few-public-methods @@ -912,7 +914,8 @@ class Qubes(qubes.PropertyHolder): ''' try: - return qubes.utils.get_entry_point_one('qubes.vm', clsname) + return qubes.utils.get_entry_point_one( + qubes.vm.VM_ENTRY_POINT, clsname) except KeyError: raise qubes.exc.QubesException( 'no such VM class: {!r}'.format(clsname)) diff --git a/qubes/mgmt.py b/qubes/mgmt.py index 5d858d21..62aa6c9e 100644 --- a/qubes/mgmt.py +++ b/qubes/mgmt.py @@ -27,6 +27,7 @@ import string import pkg_resources +import qubes.vm import qubes.vm.qubesvm import qubes.storage @@ -157,6 +158,15 @@ class QubesMgmt(AbstractQubesMgmt): https://www.qubes-os.org/doc/mgmt1/ ''' + @api('mgmt.vmclass.List', no_payload=True) + async def vmclass_list(self): + '''List all VM classes''' + assert not self.arg + assert self.dest.name == 'dom0' + + return ''.join('{}\n'.format(ep.name) + for ep in pkg_resources.iter_entry_points(qubes.vm.VM_ENTRY_POINT)) + @api('mgmt.vm.List', no_payload=True) async def vm_list(self): '''List all the domains''' @@ -464,3 +474,28 @@ class QubesMgmt(AbstractQubesMgmt): del self.app.labels[label.index] self.app.save() + + @api('mgmt.vm.Start', no_payload=True) + async def vm_start(self): + assert not self.arg + await self.dest.start() + + @api('mgmt.vm.Shutdown', no_payload=True) + async def vm_shutdown(self): + assert not self.arg + await self.dest.shutdown() + + @api('mgmt.vm.Pause', no_payload=True) + async def vm_pause(self): + assert not self.arg + await self.dest.pause() + + @api('mgmt.vm.Unpause', no_payload=True) + async def vm_unpause(self): + assert not self.arg + await self.dest.unpause() + + @api('mgmt.vm.Kill', no_payload=True) + async def vm_kill(self): + assert not self.arg + await self.dest.kill() diff --git a/qubes/vm/__init__.py b/qubes/vm/__init__.py index 524d5000..90b2362c 100644 --- a/qubes/vm/__init__.py +++ b/qubes/vm/__init__.py @@ -40,6 +40,7 @@ import qubes.events import qubes.log import qubes.tools.qvm_ls +VM_ENTRY_POINT = 'qubes.vm' def validate_name(holder, prop, value): ''' Check if value is syntactically correct VM name '''