vm: add DispVMWrapper for calling a single service in new DispVM
This is a wrapper to use `$dispvm` target of qrexec call, just like any other service call in qubesadmin module - using vm.run_service(). When running in dom0, qrexec-client-vm is not available, so DispVM needs to be created "manually", using appropriate Admin API call (admin.vm.CreateDisposable). QubesOS/qubes-issues#2974
This commit is contained in:
parent
50bd9f5fab
commit
9bb59cdd20
@ -346,7 +346,50 @@ class TemplateVM(QubesVM):
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
class DispVMWrapper(QubesVM):
|
||||
'''Wrapper class for new DispVM, supporting only service call
|
||||
|
||||
Note that when running in dom0, one need to manually kill the DispVM after
|
||||
service call ends.
|
||||
'''
|
||||
|
||||
def run_service(self, service, **kwargs):
|
||||
if self.app.qubesd_connection_type == 'socket':
|
||||
# create dispvm at service call
|
||||
if self._method_dest.startswith('$dispvm'):
|
||||
if self._method_dest.startswith('$dispvm:'):
|
||||
method_dest = self._method_dest[len('$dispvm:'):]
|
||||
else:
|
||||
method_dest = 'dom0'
|
||||
dispvm = self.app.qubesd_call(method_dest,
|
||||
'admin.vm.CreateDisposable')
|
||||
dispvm = dispvm.decode('ascii')
|
||||
self._method_dest = dispvm
|
||||
return super(DispVMWrapper, self).run_service(service, **kwargs)
|
||||
|
||||
def cleanup(self):
|
||||
'''Cleanup after DispVM usage'''
|
||||
# in 'remote' case nothing is needed, as DispVM is cleaned up
|
||||
# automatically
|
||||
if self.app.qubesd_connection_type == 'socket':
|
||||
try:
|
||||
self.kill()
|
||||
except qubesadmin.exc.QubesVMNotRunningError:
|
||||
pass
|
||||
|
||||
|
||||
class DispVM(QubesVM):
|
||||
'''Disposable VM'''
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def from_appvm(cls, app, appvm):
|
||||
'''Returns a wrapper for calling service in a new DispVM based on given
|
||||
AppVM. If *appvm* is none, use default DispVM template'''
|
||||
|
||||
if appvm:
|
||||
method_dest = '$dispvm:' + str(appvm)
|
||||
else:
|
||||
method_dest = '$dispvm'
|
||||
|
||||
wrapper = DispVMWrapper(app, method_dest)
|
||||
return wrapper
|
||||
|
Loading…
Reference in New Issue
Block a user