api/admin: add 'wait' parameter to admin.vm.Shutdown
Add support for blocking shutdown call. This adds a symmetry to admin.vm.Start call which is blocking. Since the admin.vm.Shutdown has established semantic already, add a 'wait' parameter. It can be combined with 'force' as 'force+wait' (or the other way around).
This commit is contained in:
parent
d3d6b9de2b
commit
6d11388807
@ -899,9 +899,15 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI):
|
|||||||
scope='local', execute=True)
|
scope='local', execute=True)
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def vm_shutdown(self):
|
def vm_shutdown(self):
|
||||||
force = (self.arg == 'force')
|
if self.arg:
|
||||||
self.fire_event_for_permission(force=force)
|
args = self.arg.split('+')
|
||||||
yield from self.dest.shutdown(force=force)
|
else:
|
||||||
|
args = []
|
||||||
|
self.enforce(all(arg in ('force', 'wait') for arg in args))
|
||||||
|
force = ('force' in args)
|
||||||
|
wait = ('wait' in args)
|
||||||
|
self.fire_event_for_permission(force=force, wait=wait)
|
||||||
|
yield from self.dest.shutdown(force=force, wait=wait)
|
||||||
|
|
||||||
@qubes.api.method('admin.vm.Pause', no_payload=True,
|
@qubes.api.method('admin.vm.Pause', no_payload=True,
|
||||||
scope='local', execute=True)
|
scope='local', execute=True)
|
||||||
|
@ -1030,7 +1030,7 @@ netvm default=True type=vm \n'''
|
|||||||
self.vm.shutdown = coroutine_mock
|
self.vm.shutdown = coroutine_mock
|
||||||
value = self.call_mgmt_func(b'admin.vm.Shutdown', b'test-vm1')
|
value = self.call_mgmt_func(b'admin.vm.Shutdown', b'test-vm1')
|
||||||
self.assertIsNone(value)
|
self.assertIsNone(value)
|
||||||
func_mock.assert_called_once_with(force=False)
|
func_mock.assert_called_once_with(force=False, wait=False)
|
||||||
|
|
||||||
def test_231_shutdown_force(self):
|
def test_231_shutdown_force(self):
|
||||||
func_mock = unittest.mock.Mock()
|
func_mock = unittest.mock.Mock()
|
||||||
@ -1041,7 +1041,51 @@ netvm default=True type=vm \n'''
|
|||||||
self.vm.shutdown = coroutine_mock
|
self.vm.shutdown = coroutine_mock
|
||||||
value = self.call_mgmt_func(b'admin.vm.Shutdown', b'test-vm1', b'force')
|
value = self.call_mgmt_func(b'admin.vm.Shutdown', b'test-vm1', b'force')
|
||||||
self.assertIsNone(value)
|
self.assertIsNone(value)
|
||||||
func_mock.assert_called_once_with(force=True)
|
func_mock.assert_called_once_with(force=True, wait=False)
|
||||||
|
|
||||||
|
def test_232_shutdown_wait(self):
|
||||||
|
func_mock = unittest.mock.Mock()
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def coroutine_mock(*args, **kwargs):
|
||||||
|
return func_mock(*args, **kwargs)
|
||||||
|
self.vm.shutdown = coroutine_mock
|
||||||
|
value = self.call_mgmt_func(b'admin.vm.Shutdown', b'test-vm1', b'wait')
|
||||||
|
self.assertIsNone(value)
|
||||||
|
func_mock.assert_called_once_with(force=False, wait=True)
|
||||||
|
|
||||||
|
def test_233_shutdown_wait_force(self):
|
||||||
|
func_mock = unittest.mock.Mock()
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def coroutine_mock(*args, **kwargs):
|
||||||
|
return func_mock(*args, **kwargs)
|
||||||
|
self.vm.shutdown = coroutine_mock
|
||||||
|
value = self.call_mgmt_func(b'admin.vm.Shutdown', b'test-vm1', b'wait+force')
|
||||||
|
self.assertIsNone(value)
|
||||||
|
func_mock.assert_called_once_with(force=True, wait=True)
|
||||||
|
|
||||||
|
def test_234_shutdown_force_wait(self):
|
||||||
|
func_mock = unittest.mock.Mock()
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def coroutine_mock(*args, **kwargs):
|
||||||
|
return func_mock(*args, **kwargs)
|
||||||
|
self.vm.shutdown = coroutine_mock
|
||||||
|
value = self.call_mgmt_func(b'admin.vm.Shutdown', b'test-vm1', b'force+wait')
|
||||||
|
self.assertIsNone(value)
|
||||||
|
func_mock.assert_called_once_with(force=True, wait=True)
|
||||||
|
|
||||||
|
def test_234_shutdown_force_wait_invalid(self):
|
||||||
|
func_mock = unittest.mock.Mock()
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def coroutine_mock(*args, **kwargs):
|
||||||
|
return func_mock(*args, **kwargs)
|
||||||
|
self.vm.shutdown = coroutine_mock
|
||||||
|
with self.assertRaises(qubes.api.PermissionDenied):
|
||||||
|
self.call_mgmt_func(b'admin.vm.Shutdown', b'test-vm1', b'forcewait')
|
||||||
|
func_mock.assert_not_called()
|
||||||
|
|
||||||
def test_240_pause(self):
|
def test_240_pause(self):
|
||||||
func_mock = unittest.mock.Mock()
|
func_mock = unittest.mock.Mock()
|
||||||
|
Loading…
Reference in New Issue
Block a user