qubes/vm/dispvm: Add methods for creating and destroying

fixes QubesOS/qubes-issues#866
This commit is contained in:
Wojtek Porczyk 2016-06-02 17:20:13 +02:00
parent a719e0d93d
commit 5a76d0b03b
4 changed files with 63 additions and 0 deletions

View File

@ -30,9 +30,11 @@ import functools
import grp import grp
import logging import logging
import os import os
import random
import sys import sys
import tempfile import tempfile
import time import time
import uuid
import jinja2 import jinja2
import libvirt import libvirt
@ -485,6 +487,16 @@ class VMCollection(object):
raise LookupError("Cannot find unused netid!") raise LookupError("Cannot find unused netid!")
def get_new_unused_dispid(self):
for i in range(qubes.config.max_dispid ** 0.5):
dispid = random.SystemRandom().randrange(qubes.config.max_dispid)
if not any(getattr(vm, 'dispid', None) == dispid for vm in self):
return dispid
raise LookupError((
'https://xkcd.com/221/',
'http://dilbert.com/strip/2001-10-25')[random.randint(0, 1)])
class Qubes(qubes.PropertyHolder): class Qubes(qubes.PropertyHolder):
'''Main Qubes application '''Main Qubes application

View File

@ -111,3 +111,4 @@ defaults = {
max_qid = 254 max_qid = 254
max_netid = 254 max_netid = 254
max_dispid = 10000

View File

@ -3,6 +3,7 @@
import qubes.events import qubes.events
import qubes.vm.qubesvm import qubes.vm.qubesvm
from qubes.config import defaults from qubes.config import defaults

View File

@ -1,6 +1,8 @@
#!/usr/bin/python2 -O #!/usr/bin/python2 -O
# vim: fileencoding=utf-8 # vim: fileencoding=utf-8
import random
import qubes.vm.qubesvm import qubes.vm.qubesvm
import qubes.vm.appvm import qubes.vm.appvm
import qubes.config import qubes.config
@ -44,6 +46,7 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
'volume_type': 'read-only', 'volume_type': 'read-only',
} }
} }
super(DispVM, self).__init__(*args, **kwargs) super(DispVM, self).__init__(*args, **kwargs)
@qubes.events.handler('domain-load') @qubes.events.handler('domain-load')
@ -52,3 +55,49 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
# Some additional checks for template based VM # Some additional checks for template based VM
assert self.template assert self.template
# self.template.appvms.add(self) # XXX # self.template.appvms.add(self) # XXX
@classmethod
def from_appvm(cls, appvm, **kwargs):
'''Create a new instance from given AppVM
:param qubes.vm.appvm.AppVM appvm: template from which the VM should \
be created (could also be name or qid)
:returns: new disposable vm
*kwargs* are passed to the newly created VM
>>> import qubes.vm.dispvm.DispVM
>>> dispvm = qubes.vm.dispvm.DispVM.from_appvm(appvm).start()
>>> dispvm.run_service('qubes.VMShell', input='firefox')
>>> dispvm.cleanup()
This method modifies :file:`qubes.xml` file. In fact, the newly created
vm belongs to other :py:class:`qubes.Qubes` instance than the *app*.
The qube returned is not started.
'''
store = appvm.app.store if isinstance(appvm, qubes.vm.BaseVM) else None
app = qubes.Qubes(store)
dispvm = app.add_new_vm(
cls,
dispid=app.domains.get_new_unused_dispid(),
template=app.domains[appvm],
**kwargs)
dispvm.create_on_disk()
app.save()
return dispvm
def cleanup(self):
'''Clean up after the DispVM
This stops the disposable qube and removes it from the store.
This method modifies :file:`qubes.xml` file.
'''
app = qubes.Qubes(self.app.store)
self = app.domains[self.uuid]
self.force_shutdown()
self.remove_from_disk()
del app.domains[self]
app.save()