qvm-run will unpause paused VMs by defaults
If qvm-run is run with the autostart option (true by default), it will also unpause paused VMs. fixes QubesOS/qubes-issues#5967
This commit is contained in:
parent
a078e1f617
commit
4a6b5dbae2
@ -45,9 +45,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
||||||
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
||||||
# self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
# ('test-vm', 'admin.vm.List', None, None)] = \
|
('test-vm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
# b'0\x00test-vm class=AppVM state=Running\n'
|
b'0\x00power_state=Running'
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['--no-gui', 'test-vm', 'command'],
|
['--no-gui', 'test-vm', 'command'],
|
||||||
app=self.app)
|
app=self.app)
|
||||||
@ -110,6 +110,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
||||||
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
||||||
|
self.app.expected_calls[
|
||||||
|
('test-vm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
|
b'0\x00power_state=Running'
|
||||||
# self.app.expected_calls[
|
# self.app.expected_calls[
|
||||||
# ('test-vm', 'admin.vm.List', None, None)] = \
|
# ('test-vm', 'admin.vm.List', None, None)] = \
|
||||||
# b'0\x00test-vm class=AppVM state=Running\n'
|
# b'0\x00test-vm class=AppVM state=Running\n'
|
||||||
@ -139,9 +142,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('dom0', 'admin.vm.List', None, None)] = \
|
('dom0', 'admin.vm.List', None, None)] = \
|
||||||
b'0\x00test-vm class=AppVM state=Running\n'
|
b'0\x00test-vm class=AppVM state=Running\n'
|
||||||
# self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
# ('test-vm', 'admin.vm.List', None, None)] = \
|
('test-vm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
# b'0\x00test-vm class=AppVM state=Running\n'
|
b'0\x00power_state=Running'
|
||||||
echo = subprocess.Popen(['echo', 'some-data'], stdout=subprocess.PIPE)
|
echo = subprocess.Popen(['echo', 'some-data'], stdout=subprocess.PIPE)
|
||||||
with unittest.mock.patch('sys.stdin', echo.stdout):
|
with unittest.mock.patch('sys.stdin', echo.stdout):
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
@ -276,9 +279,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
||||||
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
||||||
# self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
# ('test-vm', 'admin.vm.List', None, None)] = \
|
('test-vm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
# b'0\x00test-vm class=AppVM state=Running\n'
|
b'0\x00power_state=Running'
|
||||||
mock_popen.return_value.wait.return_value = 0
|
mock_popen.return_value.wait.return_value = 0
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['--no-gui', '--pass-io', '--localcmd', 'local-command',
|
['--no-gui', '--pass-io', '--localcmd', 'local-command',
|
||||||
@ -309,9 +312,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
||||||
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
||||||
# self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
# ('test-vm', 'admin.vm.List', None, None)] = \
|
('test-vm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
# b'0\x00test-vm class=AppVM state=Running\n'
|
b'0\x00power_state=Running'
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['test-vm', 'command'],
|
['test-vm', 'command'],
|
||||||
app=self.app)
|
app=self.app)
|
||||||
@ -339,9 +342,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('test-vm', 'admin.vm.property.Get', 'default_user', None)] = \
|
('test-vm', 'admin.vm.property.Get', 'default_user', None)] = \
|
||||||
b'0\x00default=yes type=str user'
|
b'0\x00default=yes type=str user'
|
||||||
# self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
# ('test-vm', 'admin.vm.List', None, None)] = \
|
('test-vm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
# b'0\x00test-vm class=AppVM state=Running\n'
|
b'0\x00power_state=Running'
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['--service', 'test-vm', 'service.name'],
|
['--service', 'test-vm', 'service.name'],
|
||||||
app=self.app)
|
app=self.app)
|
||||||
@ -363,6 +366,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.assertAllCalled()
|
self.assertAllCalled()
|
||||||
|
|
||||||
def test_008_dispvm_remote(self):
|
def test_008_dispvm_remote(self):
|
||||||
|
self.app.expected_calls[
|
||||||
|
('$dispvm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
|
b'0\x00power_state=Running'
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['--dispvm', '--service', 'test.service'], app=self.app)
|
['--dispvm', '--service', 'test.service'], app=self.app)
|
||||||
self.assertEqual(ret, 0)
|
self.assertEqual(ret, 0)
|
||||||
@ -377,6 +383,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.assertAllCalled()
|
self.assertAllCalled()
|
||||||
|
|
||||||
def test_009_dispvm_remote_specific(self):
|
def test_009_dispvm_remote_specific(self):
|
||||||
|
self.app.expected_calls[
|
||||||
|
('$dispvm:test-vm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
|
b'0\x00power_state=Running'
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['--dispvm=test-vm', '--service', 'test.service'], app=self.app)
|
['--dispvm=test-vm', '--service', 'test.service'], app=self.app)
|
||||||
self.assertEqual(ret, 0)
|
self.assertEqual(ret, 0)
|
||||||
@ -400,6 +409,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('disp123', 'admin.vm.property.Get', 'qrexec_timeout', None)] = \
|
('disp123', 'admin.vm.property.Get', 'qrexec_timeout', None)] = \
|
||||||
b'0\0default=yes type=int 30'
|
b'0\0default=yes type=int 30'
|
||||||
|
self.app.expected_calls[
|
||||||
|
('$dispvm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
|
b'0\x00power_state=Running'
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['--dispvm', '--service', 'test.service'], app=self.app)
|
['--dispvm', '--service', 'test.service'], app=self.app)
|
||||||
self.assertEqual(ret, 0)
|
self.assertEqual(ret, 0)
|
||||||
@ -424,6 +436,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('disp123', 'admin.vm.property.Get', 'qrexec_timeout', None)] = \
|
('disp123', 'admin.vm.property.Get', 'qrexec_timeout', None)] = \
|
||||||
b'0\0default=yes type=int 30'
|
b'0\0default=yes type=int 30'
|
||||||
|
self.app.expected_calls[
|
||||||
|
('$dispvm:test-vm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
|
b'0\x00power_state=Running'
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['--dispvm=test-vm', '--service', 'test.service'], app=self.app)
|
['--dispvm=test-vm', '--service', 'test.service'], app=self.app)
|
||||||
self.assertEqual(ret, 0)
|
self.assertEqual(ret, 0)
|
||||||
@ -496,6 +511,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('disp123', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
('disp123', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
||||||
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
||||||
|
self.app.expected_calls[
|
||||||
|
('$dispvm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
|
b'0\x00power_state=Running'
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['--dispvm', '--', 'test.command'], app=self.app)
|
['--dispvm', '--', 'test.command'], app=self.app)
|
||||||
self.assertEqual(ret, 0)
|
self.assertEqual(ret, 0)
|
||||||
@ -524,6 +542,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('disp123', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
('disp123', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
||||||
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
||||||
|
self.app.expected_calls[
|
||||||
|
('$dispvm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
|
b'0\x00power_state=Running'
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['--dispvm', '--no-gui', 'test.command'], app=self.app)
|
['--dispvm', '--no-gui', 'test.command'], app=self.app)
|
||||||
self.assertEqual(ret, 0)
|
self.assertEqual(ret, 0)
|
||||||
@ -545,9 +566,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
||||||
b'0\x00Windows'
|
b'0\x00Windows'
|
||||||
# self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
# ('test-vm', 'admin.vm.List', None, None)] = \
|
('test-vm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
# b'0\x00test-vm class=AppVM state=Running\n'
|
b'0\x00power_state=Running'
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['--no-gui', 'test-vm', 'command'],
|
['--no-gui', 'test-vm', 'command'],
|
||||||
app=self.app)
|
app=self.app)
|
||||||
@ -572,9 +593,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'vmexec', None)] = \
|
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'vmexec', None)] = \
|
||||||
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'vmexec\' not set\x00'
|
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'vmexec\' not set\x00'
|
||||||
# self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
# ('test-vm', 'admin.vm.List', None, None)] = \
|
('test-vm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
# b'0\x00test-vm class=AppVM state=Running\n'
|
b'0\x00power_state=Running'
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['--no-gui', 'test-vm', 'command', 'arg'],
|
['--no-gui', 'test-vm', 'command', 'arg'],
|
||||||
app=self.app)
|
app=self.app)
|
||||||
@ -597,9 +618,9 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
('test-vm', 'admin.vm.feature.CheckWithTemplate',
|
('test-vm', 'admin.vm.feature.CheckWithTemplate',
|
||||||
'vmexec', None)] = \
|
'vmexec', None)] = \
|
||||||
b'0\x001'
|
b'0\x001'
|
||||||
# self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
# ('test-vm', 'admin.vm.List', None, None)] = \
|
('test-vm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
# b'0\x00test-vm class=AppVM state=Running\n'
|
b'0\x00power_state=Running'
|
||||||
ret = qubesadmin.tools.qvm_run.main(
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
['--no-gui', 'test-vm', 'command', 'arg'],
|
['--no-gui', 'test-vm', 'command', 'arg'],
|
||||||
app=self.app)
|
app=self.app)
|
||||||
@ -613,3 +634,30 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
|||||||
('test-vm', 'qubes.VMExec+command+arg', b'')
|
('test-vm', 'qubes.VMExec+command+arg', b'')
|
||||||
])
|
])
|
||||||
self.assertAllCalled()
|
self.assertAllCalled()
|
||||||
|
|
||||||
|
def test_021_paused_vm(self):
|
||||||
|
self.app.expected_calls[
|
||||||
|
('dom0', 'admin.vm.List', None, None)] = \
|
||||||
|
b'0\x00test-vm class=AppVM state=Paused\n'
|
||||||
|
self.app.expected_calls[
|
||||||
|
('test-vm', 'admin.vm.feature.CheckWithTemplate', 'os', None)] = \
|
||||||
|
b'2\x00QubesFeatureNotFoundError\x00\x00Feature \'os\' not set\x00'
|
||||||
|
self.app.expected_calls[
|
||||||
|
('test-vm', 'admin.vm.CurrentState', None, None)] = \
|
||||||
|
b'0\x00power_state=Paused'
|
||||||
|
self.app.expected_calls[
|
||||||
|
('test-vm', 'admin.vm.Unpause', None, None)] = \
|
||||||
|
b'0\x00'
|
||||||
|
ret = qubesadmin.tools.qvm_run.main(
|
||||||
|
['--no-gui', 'test-vm', 'command'],
|
||||||
|
app=self.app)
|
||||||
|
self.assertEqual(ret, 0)
|
||||||
|
self.assertEqual(self.app.service_calls, [
|
||||||
|
('test-vm', 'qubes.VMShell', {
|
||||||
|
'stdout': subprocess.DEVNULL,
|
||||||
|
'stderr': subprocess.DEVNULL,
|
||||||
|
'user': None,
|
||||||
|
}),
|
||||||
|
('test-vm', 'qubes.VMShell', b'command; exit\n')
|
||||||
|
])
|
||||||
|
self.assertAllCalled()
|
||||||
|
@ -45,7 +45,7 @@ parser.add_argument('--autostart', '--auto', '-a',
|
|||||||
|
|
||||||
parser.add_argument('--no-autostart', '--no-auto', '-n',
|
parser.add_argument('--no-autostart', '--no-auto', '-n',
|
||||||
action='store_false', dest='autostart',
|
action='store_false', dest='autostart',
|
||||||
help='do not autostart qube')
|
help='do not autostart/unpause qube')
|
||||||
|
|
||||||
parser.add_argument('--pass-io', '-p',
|
parser.add_argument('--pass-io', '-p',
|
||||||
action='store_true', dest='passio', default=False,
|
action='store_true', dest='passio', default=False,
|
||||||
@ -270,9 +270,27 @@ def main(args=None, app=None):
|
|||||||
if not args.autostart and not vm.is_running():
|
if not args.autostart and not vm.is_running():
|
||||||
if verbose > 0:
|
if verbose > 0:
|
||||||
print_no_color('Qube \'{}\' not started'.format(vm.name),
|
print_no_color('Qube \'{}\' not started'.format(vm.name),
|
||||||
file=sys.stderr, color=args.color_stderr)
|
file=sys.stderr, color=args.color_stderr)
|
||||||
retcode = max(retcode, 1)
|
retcode = max(retcode, 1)
|
||||||
continue
|
continue
|
||||||
|
if vm.is_paused():
|
||||||
|
if not args.autostart:
|
||||||
|
if verbose > 0:
|
||||||
|
print_no_color(
|
||||||
|
'Qube \'{}\' is paused'.format(vm.name),
|
||||||
|
file=sys.stderr, color=args.color_stderr)
|
||||||
|
retcode = max(retcode, 1)
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
vm.unpause()
|
||||||
|
except qubesadmin.exc.QubesException:
|
||||||
|
if verbose > 0:
|
||||||
|
print_no_color(
|
||||||
|
'Qube \'{}\' cannot be unpaused'.format(
|
||||||
|
vm.name),
|
||||||
|
file=sys.stderr, color=args.color_stderr)
|
||||||
|
retcode = max(retcode, 1)
|
||||||
|
continue
|
||||||
try:
|
try:
|
||||||
if verbose > 0:
|
if verbose > 0:
|
||||||
print_no_color(
|
print_no_color(
|
||||||
|
Loading…
Reference in New Issue
Block a user