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:
|
except AttributeError:
|
||||||
pass
|
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):
|
class DispVM(QubesVM):
|
||||||
'''Disposable VM'''
|
'''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