core3: fixes from Marek
This is adapted from commit 90a50dca406e3d40c88ea338566e0460589df7a3.
This commit is contained in:
parent
e9b998400d
commit
80d664441d
@ -640,7 +640,7 @@ class property(object): # pylint: disable=redefined-builtin,invalid-name
|
||||
|
||||
if self._setter is not None:
|
||||
value = self._setter(instance, self, value)
|
||||
if self._type is not None:
|
||||
if self._type is not None: # XXX what about QubesVM and other types?
|
||||
value = self._type(value)
|
||||
|
||||
if has_oldvalue:
|
||||
@ -705,7 +705,7 @@ class property(object): # pylint: disable=redefined-builtin,invalid-name
|
||||
#
|
||||
|
||||
class DontSave(Exception):
|
||||
'''This exception may be raised from saver to sing that property should
|
||||
'''This exception may be raised from saver to sign that property should
|
||||
not be saved.
|
||||
'''
|
||||
pass
|
||||
@ -1023,23 +1023,28 @@ class VMProperty(property):
|
||||
raise TypeError(
|
||||
"'vmclass' should specify a subclass of qubes.vm.BaseVM")
|
||||
|
||||
super(VMProperty, self).__init__(name, **kwargs)
|
||||
super(VMProperty, self).__init__(name,
|
||||
saver=(lambda self, prop, value: value.name if value else 'None'),
|
||||
**kwargs)
|
||||
self.vmclass = vmclass
|
||||
self.allow_none = allow_none
|
||||
|
||||
|
||||
def __set__(self, instance, value):
|
||||
if value is None:
|
||||
if self.allow_none:
|
||||
super(VMProperty, self).__set__(self, instance, value)
|
||||
super(VMProperty, self).__set__(instance, value)
|
||||
return
|
||||
else:
|
||||
raise ValueError(
|
||||
'Property {!r} does not allow setting to {!r}'.format(
|
||||
self.__name__, value))
|
||||
|
||||
app = instance if isinstance(instance, Qubes) else instance.app
|
||||
|
||||
# XXX this may throw LookupError; that's good until introduction
|
||||
# of QubesNoSuchVMException or whatever
|
||||
vm = instance.app.domains[value]
|
||||
vm = app.domains[value]
|
||||
|
||||
if not isinstance(vm, self.vmclass):
|
||||
raise TypeError('wrong VM class: domains[{!r}] if of type {!s} '
|
||||
@ -1047,7 +1052,7 @@ class VMProperty(property):
|
||||
vm.__class__.__name__,
|
||||
self.vmclass.__name__))
|
||||
|
||||
super(VMProperty, self).__set__(self, instance, vm)
|
||||
super(VMProperty, self).__set__(instance, vm)
|
||||
|
||||
|
||||
import qubes.vm.qubesvm
|
||||
@ -1100,11 +1105,11 @@ class Qubes(PropertyHolder):
|
||||
'''
|
||||
|
||||
default_netvm = VMProperty('default_netvm', load_stage=3,
|
||||
default=None,
|
||||
default=None, allow_none=True,
|
||||
doc='''Default NetVM for AppVMs. Initial state is `None`, which means
|
||||
that AppVMs are not connected to the Internet.''')
|
||||
default_fw_netvm = VMProperty('default_fw_netvm', load_stage=3,
|
||||
default=None,
|
||||
default=None, allow_none=True,
|
||||
doc='''Default NetVM for ProxyVMs. Initial state is `None`, which means
|
||||
that ProxyVMs (including FirewallVM) are not connected to the
|
||||
Internet.''')
|
||||
@ -1112,9 +1117,11 @@ class Qubes(PropertyHolder):
|
||||
vmclass=qubes.vm.templatevm.TemplateVM,
|
||||
doc='Default template for new AppVMs')
|
||||
updatevm = VMProperty('updatevm', load_stage=3,
|
||||
allow_none=True,
|
||||
doc='''Which VM to use as `yum` proxy for updating AdminVM and
|
||||
TemplateVMs''')
|
||||
clockvm = VMProperty('clockvm', load_stage=3,
|
||||
allow_none=True,
|
||||
doc='Which VM to use as NTP proxy for updating AdminVM')
|
||||
default_kernel = property('default_kernel', load_stage=3,
|
||||
doc='Which kernel to use when not overriden in VM')
|
||||
@ -1209,7 +1216,7 @@ class Qubes(PropertyHolder):
|
||||
|
||||
# Disable ntpd in ClockVM - to not conflict with ntpdate (both are
|
||||
# using 123/udp port)
|
||||
if hasattr(self, 'clockvm'):
|
||||
if hasattr(self, 'clockvm') and self.clockvm is not None:
|
||||
if 'ntpd' in self.clockvm.services:
|
||||
if self.clockvm.services['ntpd']:
|
||||
self.log.warning("VM set as clockvm ({!r}) has enabled "
|
||||
@ -1367,6 +1374,8 @@ class Qubes(PropertyHolder):
|
||||
@qubes.events.handler('property-pre-set:clockvm')
|
||||
def on_property_pre_set_clockvm(self, event, name, newvalue, oldvalue=None):
|
||||
# pylint: disable=unused-argument,no-self-use
|
||||
if newvalue is None:
|
||||
return
|
||||
if 'ntpd' in newvalue.services:
|
||||
if newvalue.services['ntpd']:
|
||||
raise QubesException('Cannot set {!r} as {!r} property since '
|
||||
|
@ -102,7 +102,8 @@ class Emitter(object):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Emitter, self).__init__(*args, **kwargs)
|
||||
self.events_enabled = False
|
||||
if not hasattr(self, 'events_enabled'):
|
||||
self.events_enabled = False
|
||||
|
||||
|
||||
@classmethod
|
||||
|
5
qubes/qdb.py
Normal file
5
qubes/qdb.py
Normal file
@ -0,0 +1,5 @@
|
||||
# This is mock file, not installed. It is needed. because pylint needs to
|
||||
# import all the modules, and qubes.qbd is one of them.
|
||||
|
||||
def QubesDB(dummy):
|
||||
return None
|
@ -353,7 +353,7 @@ class BaseVM(qubes.PropertyHolder):
|
||||
args['name'] = self.name
|
||||
if hasattr(self, 'kernels_dir'):
|
||||
args['kerneldir'] = self.kernels_dir
|
||||
args['uuidnode'] = '<uuid>{!r}</uuid>'.format(self.uuid) \
|
||||
args['uuidnode'] = '<uuid>{!s}</uuid>'.format(self.uuid) \
|
||||
if hasattr(self, 'uuid') else ''
|
||||
args['vmdir'] = self.dir_path
|
||||
args['pcidevs'] = ''.join(lxml.etree.tostring(self.lvxml_pci_dev(dev))
|
||||
@ -398,6 +398,8 @@ class BaseVM(qubes.PropertyHolder):
|
||||
"Debug mode: adding 'earlyprintk=xen' to kernel opts")
|
||||
args['kernelopts'] += ' earlyprintk=xen'
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def create_config_file(self, file_path=None, prepare_dvm=False):
|
||||
'''Create libvirt's XML domain config file
|
||||
|
@ -1,6 +1,7 @@
|
||||
#!/usr/bin/python2 -O
|
||||
# vim: fileencoding=utf-8
|
||||
|
||||
import qubes.events
|
||||
import qubes.vm.qubesvm
|
||||
|
||||
class AppVM(qubes.vm.qubesvm.QubesVM):
|
||||
@ -11,9 +12,11 @@ class AppVM(qubes.vm.qubesvm.QubesVM):
|
||||
ls_width=31,
|
||||
doc='Template, on which this AppVM is based.')
|
||||
|
||||
def __init__(self, D):
|
||||
super(AppVM, self).__init__(D)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(AppVM, self).__init__(*args, **kwargs)
|
||||
|
||||
@qubes.events.handler('domain-loaded')
|
||||
def on_domain_loaded(self, event):
|
||||
# Some additional checks for template based VM
|
||||
assert self.template
|
||||
self.template.appvms.add(self)
|
||||
#self.template.appvms.add(self) # XXX
|
||||
|
@ -3,7 +3,32 @@
|
||||
|
||||
import qubes.vm.qubesvm
|
||||
|
||||
class NetVM(qubes.vm.qubesvm.QubesVM):
|
||||
class NetVM(qubes.vm.appvm.AppVM):
|
||||
'''Network interface VM'''
|
||||
def __init__(self, D):
|
||||
super(NetVM, self).__init__(D)
|
||||
|
||||
netvm = qubes.property('netvm', setter=qubes.property.forbidden)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(NetVM, self).__init__(*args, **kwargs)
|
||||
|
||||
def get_ip_for_vm(self, vm):
|
||||
return '10.137.{}.{}'.format(self.qid, vm.qid + 2)
|
||||
|
||||
@property
|
||||
def gateway(self):
|
||||
return '10.137.{}.1'.format(self.qid)
|
||||
|
||||
@property
|
||||
def secondary_dns(self):
|
||||
return '10.137.{}.254'.format(self.qid)
|
||||
|
||||
# @property
|
||||
# def netmask(self):
|
||||
# return '255.255.255.0'
|
||||
#
|
||||
# @property
|
||||
# def provides_network(self):
|
||||
# return True
|
||||
|
||||
netmask = '255.255.255.0'
|
||||
provides_network = True
|
||||
|
@ -24,6 +24,8 @@
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import datetime
|
||||
import lxml.etree
|
||||
import os
|
||||
@ -34,11 +36,13 @@ import subprocess
|
||||
import sys
|
||||
import time
|
||||
import uuid
|
||||
import warnings
|
||||
|
||||
import libvirt
|
||||
|
||||
import qubes
|
||||
import qubes.config
|
||||
#import qubes.qdb
|
||||
import qubes.qdb
|
||||
#import qubes.qmemman
|
||||
#import qubes.qmemman_algo
|
||||
import qubes.storage
|
||||
@ -90,19 +94,29 @@ def _setter_name(self, prop, value):
|
||||
|
||||
def _setter_kernel(self, prop, value):
|
||||
# pylint: disable=unused-argument
|
||||
if not os.path.exists(os.path.join(
|
||||
qubes.config.system_path['qubes_kernels_base_dir'], value)):
|
||||
dirname = os.path.join(
|
||||
qubes.config.system_path['qubes_base_dir'],
|
||||
qubes.config.system_path['qubes_kernels_base_dir'],
|
||||
value)
|
||||
if not os.path.exists(dirname):
|
||||
raise qubes.QubesException('Kernel {!r} not installed'.format(value))
|
||||
for filename in ('vmlinuz', 'modules.img'):
|
||||
if not os.path.exists(os.path.join(
|
||||
qubes.config.system_path['qubes_kernels_base_dir'],
|
||||
value, filename)):
|
||||
if not os.path.exists(os.path.join(dirname, filename)):
|
||||
raise qubes.QubesException(
|
||||
'Kernel {!r} not properly installed: missing {!r} file'.format(
|
||||
value, filename))
|
||||
return value
|
||||
|
||||
|
||||
def _setter_label(self, prop, value):
|
||||
if isinstance(value, qubes.Label):
|
||||
return value
|
||||
if value.startswith('label-'):
|
||||
return self.app.labels[int(value.split('-', 1)[1])]
|
||||
|
||||
return self.app.get_label(value)
|
||||
|
||||
|
||||
def _default_conf_file(self, name=None):
|
||||
return (name or self.name) + '.conf'
|
||||
|
||||
@ -115,7 +129,8 @@ class QubesVM(qubes.vm.BaseVM):
|
||||
#
|
||||
|
||||
label = qubes.property('label',
|
||||
setter=(lambda self, prop, value: self.app.get_label(value)),
|
||||
setter=_setter_label,
|
||||
saver=(lambda self, prop, value: 'label-{}'.format(value.index)),
|
||||
ls_width=14,
|
||||
doc='''Colourful label assigned to VM. This is where the colour of the
|
||||
padlock is set.''')
|
||||
@ -129,9 +144,9 @@ class QubesVM(qubes.vm.BaseVM):
|
||||
`None`, machine is disconnected. When absent, domain uses default
|
||||
NetVM.''')
|
||||
|
||||
provides_network = qubes.property('provides_network',
|
||||
type=bool, setter=qubes.property.bool,
|
||||
doc='`True` if it is NetVM or ProxyVM, false otherwise.')
|
||||
# provides_network = qubes.property('provides_network',
|
||||
# type=bool, setter=qubes.property.bool,
|
||||
# doc='`True` if it is NetVM or ProxyVM, false otherwise.')
|
||||
|
||||
qid = qubes.property('qid', type=int,
|
||||
setter=_setter_qid,
|
||||
@ -180,8 +195,9 @@ class QubesVM(qubes.vm.BaseVM):
|
||||
doc='''Internal VM (not shown in qubes-manager, don't create appmenus
|
||||
entries.''')
|
||||
|
||||
# XXX what is that
|
||||
vcpus = qubes.property('vcpus', default=None,
|
||||
# FIXME self.app.host could not exist - only self.app.vm required by API
|
||||
vcpus = qubes.property('vcpus',
|
||||
default=(lambda self: self.app.host.no_cpus),
|
||||
ls_width=2,
|
||||
doc='FIXME')
|
||||
|
||||
@ -215,7 +231,8 @@ class QubesVM(qubes.vm.BaseVM):
|
||||
# XXX shouldn't this go to standalone VM and TemplateVM, and leave here
|
||||
# only plain property?
|
||||
default_user = qubes.property('default_user', type=str,
|
||||
default=(lambda self: self.template.default_user),
|
||||
default=(lambda self: self.template.default_user
|
||||
if hasattr(self, 'template') else 'user'),
|
||||
ls_width=12,
|
||||
doc='FIXME')
|
||||
|
||||
@ -353,7 +370,7 @@ class QubesVM(qubes.vm.BaseVM):
|
||||
If :py:attr:`self.kernel` is :py:obj:`None`, the this points inside
|
||||
:py:attr:`self.dir_path`
|
||||
'''
|
||||
return os.path.join(
|
||||
return os.path.join(qubes.config.system_path['qubes_base_dir'],
|
||||
qubes.config.system_path['qubes_kernels_base_dir'], self.kernel) \
|
||||
if self.kernel is not None \
|
||||
else os.path.join(self.dir_path,
|
||||
@ -379,17 +396,25 @@ class QubesVM(qubes.vm.BaseVM):
|
||||
|
||||
|
||||
# XXX I don't know what to do with these; probably should be isinstance(...)
|
||||
# def is_template(self):
|
||||
# return False
|
||||
#
|
||||
# def is_appvm(self):
|
||||
# return False
|
||||
#
|
||||
# def is_proxyvm(self):
|
||||
# return False
|
||||
#
|
||||
# def is_disposablevm(self):
|
||||
# return False
|
||||
def is_template(self):
|
||||
warnings.warn('vm.is_template() is deprecated, use isinstance()',
|
||||
DeprecationWarning)
|
||||
return isinstance(self, qubes.vm.templatevm.TemplateVM)
|
||||
|
||||
def is_appvm(self):
|
||||
warnings.warn('vm.is_appvm() is deprecated, use isinstance()',
|
||||
DeprecationWarning)
|
||||
return isinstance(self, qubes.vm.appvm.AppVM)
|
||||
|
||||
def is_proxyvm(self):
|
||||
warnings.warn('vm.is_proxyvm() is deprecated, use isinstance()',
|
||||
DeprecationWarning)
|
||||
return isinstance(self, qubes.vm.proxyvm.ProxyVM)
|
||||
|
||||
def is_disposablevm(self):
|
||||
warnings.warn('vm.is_disposable() is deprecated, use isinstance()',
|
||||
DeprecationWarning)
|
||||
return isinstance(self, qubes.vm.dispvm.DispVM)
|
||||
|
||||
|
||||
# network-related
|
||||
@ -399,7 +424,7 @@ class QubesVM(qubes.vm.BaseVM):
|
||||
def ip(self):
|
||||
'''IP address of this domain.'''
|
||||
if self.netvm is not None:
|
||||
return self.netvm.get_ip_for_vm(self.qid)
|
||||
return self.netvm.get_ip_for_vm(self)
|
||||
else:
|
||||
return None
|
||||
|
||||
@ -441,6 +466,13 @@ class QubesVM(qubes.vm.BaseVM):
|
||||
return None
|
||||
return "vif{0}.+".format(self.xid)
|
||||
|
||||
@property
|
||||
def provides_network(self):
|
||||
''':py:obj:`True` if it is :py:class:`qubes.vm.netvm.NetVM` or
|
||||
:py:class:`qubes.vm.proxyvm.ProxyVM`, :py:obj:`False` otherwise'''
|
||||
return isinstance(self,
|
||||
(qubes.vm.netvm.NetVM, qubes.vm.proxyvm.ProxyVM))
|
||||
|
||||
#
|
||||
# constructor
|
||||
#
|
||||
@ -472,8 +504,8 @@ class QubesVM(qubes.vm.BaseVM):
|
||||
self.maxmem = self.memory * 10
|
||||
|
||||
# By default allow use all VCPUs
|
||||
if not hasattr(self, 'vcpus') and not self.app.vmm.offline_mode:
|
||||
self.vcpus = self.app.host.no_cpus
|
||||
# if not hasattr(self, 'vcpus') and not self.app.vmm.offline_mode:
|
||||
# self.vcpus = self.app.host.no_cpus
|
||||
|
||||
if len(self.devices['pci']) > 0:
|
||||
# Force meminfo-writer disabled when VM have PCI devices
|
||||
@ -486,10 +518,11 @@ class QubesVM(qubes.vm.BaseVM):
|
||||
# Initialize VM image storage class
|
||||
self.storage = qubes.storage.get_storage(self)
|
||||
|
||||
if self.kernels_dir is not None: # it is None for AdminVM
|
||||
self.storage.modules_img = os.path.join(self.kernels_dir,
|
||||
'modules.img')
|
||||
self.storage.modules_img_rw = self.kernel is None
|
||||
# XXX should be moved to defaults in storage class
|
||||
# if self.kernels_dir is not None: # it is None for AdminVM
|
||||
# self.storage.modules_img = os.path.join(self.kernels_dir,
|
||||
# 'modules.img')
|
||||
# self.storage.modules_img_rw = self.kernel is None
|
||||
|
||||
# fire hooks
|
||||
self.fire_event('domain-init')
|
||||
|
@ -1,6 +1,8 @@
|
||||
#!/usr/bin/python2 -O
|
||||
# vim: fileencoding=utf-8
|
||||
|
||||
import os.path
|
||||
|
||||
import qubes
|
||||
import qubes.vm.qubesvm
|
||||
|
||||
@ -38,3 +40,8 @@ class TemplateVM(qubes.vm.qubesvm.QubesVM):
|
||||
self.log.info(
|
||||
'Commiting template update; COW: {}'.format(self.rootcow_img))
|
||||
self.storage.commit_template_changes()
|
||||
|
||||
|
||||
@property
|
||||
def rootcow_img(self):
|
||||
return os.path.join(self.dir_path, qubes.config.vm_files['rootcow_img'])
|
||||
|
Loading…
Reference in New Issue
Block a user