diff --git a/qubes/app.py b/qubes/app.py index 805a64f4..2df571e2 100644 --- a/qubes/app.py +++ b/qubes/app.py @@ -415,7 +415,6 @@ class VMCollection(object): return value - def __getitem__(self, key): if isinstance(key, int): return self._dict[key] @@ -858,7 +857,6 @@ class Qubes(qubes.PropertyHolder): 'no such VM class: {!r}'.format(clsname)) # don't catch TypeError - def add_new_vm(self, cls, qid=None, **kwargs): '''Add new Virtual Machine to colletion @@ -871,10 +869,11 @@ class Qubes(qubes.PropertyHolder): # override it with default template) if 'template' not in kwargs and hasattr(cls, 'template'): kwargs['template'] = self.default_template + elif 'template' in kwargs and isinstance(kwargs['template'], str): + kwargs['template'] = self.domains[kwargs['template']] return self.domains.add(cls(self, None, qid=qid, **kwargs)) - def get_label(self, label): '''Get label as identified by index or name diff --git a/qubes/vm/appvm.py b/qubes/vm/appvm.py index f567213a..de6d30f1 100644 --- a/qubes/vm/appvm.py +++ b/qubes/vm/appvm.py @@ -21,12 +21,12 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # - ''' This module contains the AppVM implementation ''' +import copy + import qubes.events import qubes.vm.qubesvm - from qubes.config import defaults @@ -39,36 +39,75 @@ class AppVM(qubes.vm.qubesvm.QubesVM): ls_width=31, doc='Template, on which this AppVM is based.') - def __init__(self, *args, **kwargs): + def __init__(self, app, xml, template=None, **kwargs): self.volume_config = { 'root': { 'name': 'root', 'pool': 'default', - 'volume_type': 'snapshot', + 'snap_on_start': True, + 'save_on_stop': False, + 'rw': False, 'internal': True }, 'private': { 'name': 'private', 'pool': 'default', - 'volume_type': 'origin', + 'snap_on_start': False, + 'save_on_stop': True, + 'rw': True, + 'source': None, 'size': defaults['private_img_size'], 'internal': True }, 'volatile': { 'name': 'volatile', 'pool': 'default', - 'volume_type': 'volatile', 'size': defaults['root_img_size'], - 'internal': True + 'internal': True, + 'rw': True, }, 'kernel': { 'name': 'kernel', 'pool': 'linux-kernel', - 'volume_type': 'read-only', + 'snap_on_start': True, + 'rw': False, 'internal': True } } - super(AppVM, self).__init__(*args, **kwargs) + + if template is not None: + # template is only passed if the AppVM is created, in other cases we + # don't need to patch the volume_config because the config is + # coming from XML, already as we need it + + for name, conf in self.volume_config.items(): + tpl_volume = template.volumes[name] + + conf['size'] = tpl_volume.size + conf['pool'] = tpl_volume.pool + + has_source = ('source' in conf and conf['source'] is not None) + is_snapshot = 'snap_on_start' in conf and conf['snap_on_start'] + if is_snapshot and not has_source: + if tpl_volume.source is not None: + conf['source'] = tpl_volume.source + else: + conf['source'] = tpl_volume.vid + + for name, config in template.volume_config.items(): + # in case the template vm has more volumes add them to own + # config + if name not in self.volume_config: + self.volume_config[name] = copy.deepcopy(config) + if 'vid' in self.volume_config[name]: + del self.volume_config[name]['vid'] + + super(AppVM, self).__init__(app, xml, **kwargs) + if not hasattr(template, 'template') and template is not None: + self.template = template + if 'source' not in self.volume_config['root']: + msg = 'missing source for root volume' + raise qubes.exc.QubesException(msg) @qubes.events.handler('domain-load') def on_domain_loaded(self, event): diff --git a/qubes/vm/dispvm.py b/qubes/vm/dispvm.py index 6d28a705..44691695 100644 --- a/qubes/vm/dispvm.py +++ b/qubes/vm/dispvm.py @@ -46,24 +46,32 @@ class DispVM(qubes.vm.qubesvm.QubesVM): 'root': { 'name': 'root', 'pool': 'default', - 'volume_type': 'snapshot', + 'snap_on_start': True, + 'save_on_stop': False, + 'rw': False, + 'internal': True }, 'private': { 'name': 'private', 'pool': 'default', - 'volume_type': 'snapshot', + 'snap_on_start': True, + 'save_on_stop': False, + 'internal': True, + 'rw': True, }, 'volatile': { 'name': 'volatile', 'pool': 'default', - 'volume_type': 'volatile', + 'internal': True, 'size': qubes.config.defaults['root_img_size'] + qubes.config.defaults['private_img_size'], }, 'kernel': { 'name': 'kernel', 'pool': 'linux-kernel', - 'volume_type': 'read-only', + 'snap_on_start': True, + 'rw': False, + 'internal': True } } diff --git a/qubes/vm/standalonevm.py b/qubes/vm/standalonevm.py index 4ab3f78a..7e12c807 100644 --- a/qubes/vm/standalonevm.py +++ b/qubes/vm/standalonevm.py @@ -34,25 +34,34 @@ class StandaloneVM(qubes.vm.qubesvm.QubesVM): 'root': { 'name': 'root', 'pool': 'default', - 'volume_type': 'origin', + 'snap_on_start': False, + 'save_on_stop': True, + 'rw': True, + 'source': None, + 'internal': True, 'size': qubes.config.defaults['root_img_size'], }, 'private': { 'name': 'private', 'pool': 'default', - 'volume_type': 'origin', + 'snap_on_start': False, + 'save_on_stop': True, + 'rw': True, + 'source': None, + 'internal': True, 'size': qubes.config.defaults['private_img_size'], }, 'volatile': { 'name': 'volatile', 'pool': 'default', - 'volume_type': 'volatile', + 'internal': True, 'size': qubes.config.defaults['root_img_size'], }, 'kernel': { 'name': 'kernel', 'pool': 'linux-kernel', - 'volume_type': 'read-only', + 'rw': False, + 'internal': True } } super(StandaloneVM, self).__init__(*args, **kwargs) diff --git a/qubes/vm/templatevm.py b/qubes/vm/templatevm.py index e681f5a0..9ca789f2 100644 --- a/qubes/vm/templatevm.py +++ b/qubes/vm/templatevm.py @@ -60,39 +60,41 @@ class TemplateVM(QubesVM): 'root': { 'name': 'root', 'pool': 'default', - 'volume_type': 'origin', + 'snap_on_start': False, + 'save_on_stop': True, + 'rw': True, + 'source': None, 'size': defaults['root_img_size'], 'internal': True }, 'private': { 'name': 'private', 'pool': 'default', - 'volume_type': 'read-write', + 'snap_on_start': False, + 'save_on_stop': True, + 'rw': True, + 'source': None, 'size': defaults['private_img_size'], + 'revisions_to_keep': 0, 'internal': True }, 'volatile': { 'name': 'volatile', 'pool': 'default', 'size': defaults['root_img_size'], - 'volume_type': 'volatile', - 'internal': True + 'internal': True, + 'rw': True, }, 'kernel': { 'name': 'kernel', 'pool': 'linux-kernel', - 'volume_type': 'read-only', - 'internal': True + 'snap_on_start': True, + 'internal': True, + 'rw': False } } super(TemplateVM, self).__init__(*args, **kwargs) - def clone_disk_files(self, src): - super(TemplateVM, self).clone_disk_files(src) - - # Create root-cow.img - self.commit_changes() - def commit_changes(self): '''Commit changes to template''' self.log.debug('commit_changes()')