From 61cb9887af9f0f3203b121db36e13d012312cbce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Sat, 25 Feb 2017 01:47:13 +0100 Subject: [PATCH] Implement simple VM actions QubesOS/qubes-issues#853 --- qubesmgmt/tests/vm/actions.py | 75 ++++++++++++++++++++++++++++++++ qubesmgmt/tests/vm/properties.py | 1 + qubesmgmt/vm/__init__.py | 70 +++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 qubesmgmt/tests/vm/actions.py diff --git a/qubesmgmt/tests/vm/actions.py b/qubesmgmt/tests/vm/actions.py new file mode 100644 index 0000000..4ff5b97 --- /dev/null +++ b/qubesmgmt/tests/vm/actions.py @@ -0,0 +1,75 @@ +# -*- encoding: utf8 -*- +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2017 Marek Marczykowski-Górecki +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License along +# with this program; if not, see . +import unittest + +import qubesmgmt.tests.vm + + +class TC_00_Actions(qubesmgmt.tests.vm.VMTestCase): + def test_000_start(self): + self.app.expected_calls[ + ('test-vm', 'mgmt.vm.Start', None, None)] = \ + b'0\x00' + self.vm.start() + self.assertAllCalled() + + def test_001_shutdown(self): + self.app.expected_calls[ + ('test-vm', 'mgmt.vm.Shutdown', None, None)] = \ + b'0\x00' + self.vm.shutdown() + self.assertAllCalled() + + def test_002_kill(self): + self.app.expected_calls[ + ('test-vm', 'mgmt.vm.Kill', None, None)] = \ + b'0\x00' + self.vm.kill() + self.assertAllCalled() + + def test_003_pause(self): + self.app.expected_calls[ + ('test-vm', 'mgmt.vm.Pause', None, None)] = \ + b'0\x00' + self.vm.pause() + self.assertAllCalled() + + def test_004_unpause(self): + self.app.expected_calls[ + ('test-vm', 'mgmt.vm.Unpause', None, None)] = \ + b'0\x00' + self.vm.unpause() + self.assertAllCalled() + + @unittest.skip('Not part of the mgmt API yet') + def test_005_suspend(self): + self.app.expected_calls[ + ('test-vm', 'mgmt.vm.Suspend', None, None)] = \ + b'0\x00' + self.vm.suspend() + self.assertAllCalled() + + @unittest.skip('Not part of the mgmt API yet') + def test_006_resume(self): + self.app.expected_calls[ + ('test-vm', 'mgmt.vm.Resume', None, None)] = \ + b'0\x00' + self.vm.resume() + self.assertAllCalled() diff --git a/qubesmgmt/tests/vm/properties.py b/qubesmgmt/tests/vm/properties.py index b4a623e..82d23be 100644 --- a/qubesmgmt/tests/vm/properties.py +++ b/qubesmgmt/tests/vm/properties.py @@ -144,6 +144,7 @@ class TC_01_SpecialCases(qubesmgmt.tests.vm.VMTestCase): ('test-vm', 'mgmt.vm.property.Set', 'name', b'test-vm2')] = \ b'0\x00' self.vm.name = 'test-vm2' + # here should be no separate mgmt.vm.property.Get+name call self.assertEqual(self.vm.name, 'test-vm2') self.assertAllCalled() diff --git a/qubesmgmt/vm/__init__.py b/qubesmgmt/vm/__init__.py index fb2e2ea..95891db 100644 --- a/qubesmgmt/vm/__init__.py +++ b/qubesmgmt/vm/__init__.py @@ -28,6 +28,7 @@ class QubesVM(qubesmgmt.base.PropertyHolder): @property def name(self): + '''Domain name''' return self._method_dest @name.setter @@ -39,3 +40,72 @@ class QubesVM(qubesmgmt.base.PropertyHolder): str(new_value).encode('utf-8')) self._method_dest = new_value self.app.domains.clear_cache() + + def start(self): + ''' + Start domain. + + :return: + ''' + self.qubesd_call(self._method_dest, 'mgmt.vm.Start') + + def shutdown(self): + ''' + Shutdown domain. + + :return: + ''' + # TODO: force parameter + # TODO: wait parameter (using event?) + self.qubesd_call(self._method_dest, 'mgmt.vm.Shutdown') + + def kill(self): + ''' + Kill domain (forcefuly shutdown). + + :return: + ''' + self.qubesd_call(self._method_dest, 'mgmt.vm.Kill') + + def pause(self): + ''' + Pause domain. + + Pause its execution without any prior notification. + + :return: + ''' + self.qubesd_call(self._method_dest, 'mgmt.vm.Pause') + + def unpause(self): + ''' + Unpause domain. + + Opposite to :py:meth:`pause`. + + :return: + ''' + self.qubesd_call(self._method_dest, 'mgmt.vm.Unpause') + + def suspend(self): + ''' + Suspend domain. + + Give domain a chance to prepare for suspend - for example suspend + used PCI devices. + + :return: + ''' + raise NotImplementedError + #self.qubesd_call(self._method_dest, 'mgmt.vm.Suspend') + + def resume(self): + ''' + Resume domain. + + Opposite to :py:meth:`suspend`. + + :return: + ''' + raise NotImplementedError + #self.qubesd_call(self._method_dest, 'mgmt.vm.Resume')