tools: add qvm-run --service
Make it convenient wrapper around qrexec-client{-vm}, which would start a VM, wait for user session etc.
This commit is contained in:
parent
f5e102177c
commit
38abd81ea8
@ -63,6 +63,12 @@ Options
|
||||
Run the command without GUI forwarding enabled. Can be switched back with
|
||||
:option:`--gui`.
|
||||
|
||||
.. option:: --service
|
||||
|
||||
Start RPC service instead of shell command. Specify name of the service in
|
||||
place of *COMMAND* argument. You can also specify service argument, appending
|
||||
it to the service name after `+` character.
|
||||
|
||||
.. option:: --colour-output=COLOUR, --color-output=COLOR
|
||||
|
||||
Mark the qube output with given ANSI colour (ie. "31" for red). The exact
|
||||
|
@ -262,3 +262,35 @@ class TC_00_qvm_run(qubesadmin.tests.QubesTestCase):
|
||||
('test-vm', 'qubes.VMShell', b'command; exit\n')
|
||||
])
|
||||
self.assertAllCalled()
|
||||
|
||||
def test_007_run_service_with_gui(self):
|
||||
self.app.expected_calls[
|
||||
('dom0', 'admin.vm.List', None, None)] = \
|
||||
b'0\x00test-vm class=AppVM state=Running\n'
|
||||
self.app.expected_calls[
|
||||
('test-vm', 'admin.vm.property.Get', 'default_user', None)] = \
|
||||
b'0\x00default=yes type=str user'
|
||||
# self.app.expected_calls[
|
||||
# ('test-vm', 'admin.vm.List', None, None)] = \
|
||||
# b'0\x00test-vm class=AppVM state=Running\n'
|
||||
ret = qubesadmin.tools.qvm_run.main(
|
||||
['--service', 'test-vm', 'service.name'],
|
||||
app=self.app)
|
||||
self.assertEqual(ret, 0)
|
||||
# make sure we have the same instance below
|
||||
self.assertEqual(self.app.service_calls, [
|
||||
('test-vm', 'qubes.WaitForSession', {
|
||||
'stdout': subprocess.DEVNULL,
|
||||
'stderr': subprocess.DEVNULL,
|
||||
}),
|
||||
('test-vm', 'qubes.WaitForSession', b'user'),
|
||||
('test-vm', 'service.name', {
|
||||
'filter_esc': True,
|
||||
'localcmd': None,
|
||||
'stdout': subprocess.DEVNULL,
|
||||
'stderr': subprocess.DEVNULL,
|
||||
'user': None,
|
||||
}),
|
||||
('test-vm', 'service.name', b''),
|
||||
])
|
||||
self.assertAllCalled()
|
||||
|
@ -86,6 +86,10 @@ parser.add_argument('--no-filter-escape-chars',
|
||||
help='do not filter terminal escape sequences; DANGEROUS when output is a'
|
||||
' terminal emulator')
|
||||
|
||||
parser.add_argument('--service',
|
||||
action='store_true', dest='service',
|
||||
help='run a qrexec service (named by COMMAND) instead of shell command')
|
||||
|
||||
parser.add_argument('cmd', metavar='COMMAND',
|
||||
help='command to run')
|
||||
|
||||
@ -136,7 +140,7 @@ def main(args=None, app=None):
|
||||
run_kwargs['stderr'] = None
|
||||
|
||||
if isinstance(args.app, qubesadmin.app.QubesLocal) and \
|
||||
not args.passio and not args.localcmd:
|
||||
not args.passio and not args.localcmd and args.service:
|
||||
# wait=False works only in dom0; but it's still useful, to save on
|
||||
# simultaneous vchan connections
|
||||
run_kwargs['wait'] = False
|
||||
@ -172,13 +176,20 @@ def main(args=None, app=None):
|
||||
if args.passio and not args.localcmd:
|
||||
loop = asyncio.new_event_loop()
|
||||
loop.add_signal_handler(signal.SIGCHLD, loop.stop)
|
||||
proc = vm.run_service('qubes.VMShell',
|
||||
user=args.user,
|
||||
localcmd=args.localcmd,
|
||||
filter_esc=args.filter_esc,
|
||||
**run_kwargs)
|
||||
proc.stdin.write(vm.prepare_input_for_vmshell(args.cmd))
|
||||
proc.stdin.flush()
|
||||
if args.service:
|
||||
proc = vm.run_service(args.cmd,
|
||||
user=args.user,
|
||||
localcmd=args.localcmd,
|
||||
filter_esc=args.filter_esc,
|
||||
**run_kwargs)
|
||||
else:
|
||||
proc = vm.run_service('qubes.VMShell',
|
||||
user=args.user,
|
||||
localcmd=args.localcmd,
|
||||
filter_esc=args.filter_esc,
|
||||
**run_kwargs)
|
||||
proc.stdin.write(vm.prepare_input_for_vmshell(args.cmd))
|
||||
proc.stdin.flush()
|
||||
if args.passio and not args.localcmd:
|
||||
asyncio.ensure_future(loop.connect_read_pipe(
|
||||
functools.partial(DataCopyProtocol, proc.stdin,
|
||||
|
Loading…
Reference in New Issue
Block a user