Add 'wait' argument to vm.run_service()
It is supported only from dom0, but it's still useful to have, to save on simultaneous vchan connections (only waiting for MSG_DATA_EXIT_CODE). This is especially important for Windows VMs, as qrexec-agent there have pretty low limit on simultaneous connections (about 20). Make qvm-run use it.
This commit is contained in:
parent
bbd0beb830
commit
938fc9348f
@ -310,7 +310,7 @@ class QubesBase(qubesadmin.base.PropertyHolder):
|
|||||||
return self.domains[new_name]
|
return self.domains[new_name]
|
||||||
|
|
||||||
def run_service(self, dest, service, filter_esc=False, user=None,
|
def run_service(self, dest, service, filter_esc=False, user=None,
|
||||||
localcmd=None, **kwargs):
|
localcmd=None, wait=True, **kwargs):
|
||||||
'''Run qrexec service in a given destination
|
'''Run qrexec service in a given destination
|
||||||
|
|
||||||
*kwargs* are passed verbatim to :py:meth:`subprocess.Popen`.
|
*kwargs* are passed verbatim to :py:meth:`subprocess.Popen`.
|
||||||
@ -358,7 +358,7 @@ class QubesLocal(QubesBase):
|
|||||||
return self._parse_qubesd_response(return_data)
|
return self._parse_qubesd_response(return_data)
|
||||||
|
|
||||||
def run_service(self, dest, service, filter_esc=False, user=None,
|
def run_service(self, dest, service, filter_esc=False, user=None,
|
||||||
localcmd=None, **kwargs):
|
localcmd=None, wait=True, **kwargs):
|
||||||
'''Run qrexec service in a given destination
|
'''Run qrexec service in a given destination
|
||||||
|
|
||||||
:param str dest: Destination - may be a VM name or empty
|
:param str dest: Destination - may be a VM name or empty
|
||||||
@ -368,11 +368,14 @@ class QubesLocal(QubesBase):
|
|||||||
emulator
|
emulator
|
||||||
:param str user: username to run service as
|
:param str user: username to run service as
|
||||||
:param str localcmd: Command to connect stdin/stdout to
|
:param str localcmd: Command to connect stdin/stdout to
|
||||||
|
:param bool wait: wait for remote process to finish
|
||||||
:rtype: subprocess.Popen
|
:rtype: subprocess.Popen
|
||||||
'''
|
'''
|
||||||
|
|
||||||
if not dest:
|
if not dest:
|
||||||
raise ValueError('Empty destination name allowed only from a VM')
|
raise ValueError('Empty destination name allowed only from a VM')
|
||||||
|
if not wait and localcmd:
|
||||||
|
raise ValueError('wait=False incompatible with localcmd')
|
||||||
try:
|
try:
|
||||||
self.qubesd_call(dest, 'admin.vm.Start')
|
self.qubesd_call(dest, 'admin.vm.Start')
|
||||||
except qubesadmin.exc.QubesVMNotHaltedError:
|
except qubesadmin.exc.QubesVMNotHaltedError:
|
||||||
@ -384,6 +387,8 @@ class QubesLocal(QubesBase):
|
|||||||
qrexec_opts.extend(['-l', localcmd])
|
qrexec_opts.extend(['-l', localcmd])
|
||||||
if user is None:
|
if user is None:
|
||||||
user = 'DEFAULT'
|
user = 'DEFAULT'
|
||||||
|
if not wait:
|
||||||
|
qrexec_opts.extend(['-e'])
|
||||||
kwargs.setdefault('stdin', subprocess.PIPE)
|
kwargs.setdefault('stdin', subprocess.PIPE)
|
||||||
kwargs.setdefault('stdout', subprocess.PIPE)
|
kwargs.setdefault('stdout', subprocess.PIPE)
|
||||||
kwargs.setdefault('stderr', subprocess.PIPE)
|
kwargs.setdefault('stderr', subprocess.PIPE)
|
||||||
@ -418,7 +423,7 @@ class QubesRemote(QubesBase):
|
|||||||
return self._parse_qubesd_response(stdout)
|
return self._parse_qubesd_response(stdout)
|
||||||
|
|
||||||
def run_service(self, dest, service, filter_esc=False, user=None,
|
def run_service(self, dest, service, filter_esc=False, user=None,
|
||||||
localcmd=None, **kwargs):
|
localcmd=None, wait=True, **kwargs):
|
||||||
'''Run qrexec service in a given destination
|
'''Run qrexec service in a given destination
|
||||||
|
|
||||||
:param str dest: Destination - may be a VM name or empty
|
:param str dest: Destination - may be a VM name or empty
|
||||||
@ -428,6 +433,7 @@ class QubesRemote(QubesBase):
|
|||||||
emulator
|
emulator
|
||||||
:param str user: username to run service as
|
:param str user: username to run service as
|
||||||
:param str localcmd: Command to connect stdin/stdout to
|
:param str localcmd: Command to connect stdin/stdout to
|
||||||
|
:param bool wait: wait for process to finish
|
||||||
:rtype: subprocess.Popen
|
:rtype: subprocess.Popen
|
||||||
'''
|
'''
|
||||||
if filter_esc:
|
if filter_esc:
|
||||||
@ -436,6 +442,18 @@ class QubesRemote(QubesBase):
|
|||||||
if user:
|
if user:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'non-default user not possible for calls from VM')
|
'non-default user not possible for calls from VM')
|
||||||
|
if not wait and localcmd:
|
||||||
|
raise ValueError('wait=False incompatible with localcmd')
|
||||||
|
if not wait:
|
||||||
|
# qrexec-client-vm can only request service calls, which are
|
||||||
|
# started using MSG_EXEC_CMDLINE qrexec protocol message; this
|
||||||
|
# message means "start the process, pipe its stdin/out/err,
|
||||||
|
# and when it terminates, send exit code back".
|
||||||
|
# According to the protocol qrexec-client-vm needs to wait for
|
||||||
|
# MSG_DATA_EXIT_CODE, so implementing wait=False would require
|
||||||
|
# some protocol change (or protocol violation).
|
||||||
|
raise NotImplementedError(
|
||||||
|
'wait=False not implemented for calls from VM')
|
||||||
kwargs.setdefault('stdin', subprocess.PIPE)
|
kwargs.setdefault('stdin', subprocess.PIPE)
|
||||||
kwargs.setdefault('stdout', subprocess.PIPE)
|
kwargs.setdefault('stdout', subprocess.PIPE)
|
||||||
kwargs.setdefault('stderr', subprocess.PIPE)
|
kwargs.setdefault('stderr', subprocess.PIPE)
|
||||||
|
@ -135,6 +135,12 @@ def main(args=None, app=None):
|
|||||||
run_kwargs['stdout'] = None
|
run_kwargs['stdout'] = None
|
||||||
run_kwargs['stderr'] = None
|
run_kwargs['stderr'] = None
|
||||||
|
|
||||||
|
if isinstance(args.app, qubesadmin.app.QubesLocal) and \
|
||||||
|
not args.passio and not args.localcmd:
|
||||||
|
# wait=False works only in dom0; but it's still useful, to save on
|
||||||
|
# simultaneous vchan connections
|
||||||
|
run_kwargs['wait'] = False
|
||||||
|
|
||||||
verbose = args.verbose - args.quiet
|
verbose = args.verbose - args.quiet
|
||||||
if args.passio:
|
if args.passio:
|
||||||
verbose -= 1
|
verbose -= 1
|
||||||
|
Loading…
Reference in New Issue
Block a user