dom0/core: major rework of QubesVmCollection class
No longer individual QubesVm attributes hardcoded in QubesVmCollection (qubes.xml load). Now it is integrated to QubesVm attributes machinery. Also QubesVmCollection have no longer hardcoded supported VM types - this will greatly improve code extension possibilities. This commit doesn't cover QubesVmCollection.add_*vm methods (which are broken for now because of missing "collection" argument to QubesVm constructor). This will be done in next commit.
This commit is contained in:
parent
bc39e05a6a
commit
84e85c6a9a
@ -204,6 +204,11 @@ default_appvm_label = QubesVmLabels["red"]
|
|||||||
default_template_label = QubesVmLabels["gray"]
|
default_template_label = QubesVmLabels["gray"]
|
||||||
default_servicevm_label = QubesVmLabels["red"]
|
default_servicevm_label = QubesVmLabels["red"]
|
||||||
|
|
||||||
|
QubesVmClasses = {}
|
||||||
|
def register_qubes_vm_class(class_name, vm_class):
|
||||||
|
global QubesVmClasses
|
||||||
|
QubesVmClasses[class_name] = vm_class
|
||||||
|
|
||||||
class QubesVm(object):
|
class QubesVm(object):
|
||||||
"""
|
"""
|
||||||
A representation of one Qubes VM
|
A representation of one Qubes VM
|
||||||
@ -212,6 +217,9 @@ class QubesVm(object):
|
|||||||
Note that qid is not the same as Xen's domid!
|
Note that qid is not the same as Xen's domid!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# In which order load this VM type from qubes.xml
|
||||||
|
load_order = 100
|
||||||
|
|
||||||
def _get_attrs_config(self):
|
def _get_attrs_config(self):
|
||||||
""" Object attributes for serialization/deserialization
|
""" Object attributes for serialization/deserialization
|
||||||
inner dict keys:
|
inner dict keys:
|
||||||
@ -242,7 +250,8 @@ class QubesVm(object):
|
|||||||
### order >= 20: have template set
|
### order >= 20: have template set
|
||||||
"uses_default_netvm": { "default": True, 'order': 20 },
|
"uses_default_netvm": { "default": True, 'order': 20 },
|
||||||
"netvm": { "default": None, "attr": "_netvm", 'order': 20 },
|
"netvm": { "default": None, "attr": "_netvm", 'order': 20 },
|
||||||
"label": { "attr": "_label", "default": QubesVmLabels["red"], 'order': 20 },
|
"label": { "attr": "_label", "default": QubesVmLabels["red"], 'order': 20,
|
||||||
|
'xml_deserialize': lambda _x: QubesVmLabels[_x] },
|
||||||
"memory": { "default": default_memory, 'order': 20, "eval": "int(value)" },
|
"memory": { "default": default_memory, 'order': 20, "eval": "int(value)" },
|
||||||
"maxmem": { "default": None, 'order': 25, "eval": "int(value) if value else None" },
|
"maxmem": { "default": None, 'order': 25, "eval": "int(value) if value else None" },
|
||||||
"pcidevs": { "default": '[]', 'order': 25, "eval": \
|
"pcidevs": { "default": '[]', 'order': 25, "eval": \
|
||||||
@ -250,9 +259,10 @@ class QubesVm(object):
|
|||||||
# Internal VM (not shown in qubes-manager, doesn't create appmenus entries
|
# Internal VM (not shown in qubes-manager, doesn't create appmenus entries
|
||||||
"internal": { "default": False },
|
"internal": { "default": False },
|
||||||
"vcpus": { "default": None },
|
"vcpus": { "default": None },
|
||||||
"kernel": { "default": None, 'order': 30 },
|
|
||||||
"uses_default_kernel": { "default": True, 'order': 30 },
|
"uses_default_kernel": { "default": True, 'order': 30 },
|
||||||
"uses_default_kernelopts": { "default": True, 'order': 30 },
|
"uses_default_kernelopts": { "default": True, 'order': 30 },
|
||||||
|
"kernel": { "default": None, 'order': 31,
|
||||||
|
'eval': 'collection.get_default_kernel() if self.uses_default_kernel else value' },
|
||||||
"kernelopts": { "default": "", 'order': 31, "eval": \
|
"kernelopts": { "default": "", 'order': 31, "eval": \
|
||||||
'value if not self.uses_default_kernelopts else default_kernelopts_pcidevs if len(self.pcidevs) > 0 else default_kernelopts' },
|
'value if not self.uses_default_kernelopts else default_kernelopts_pcidevs if len(self.pcidevs) > 0 else default_kernelopts' },
|
||||||
"mac": { "attr": "_mac", "default": None },
|
"mac": { "attr": "_mac", "default": None },
|
||||||
@ -299,8 +309,35 @@ class QubesVm(object):
|
|||||||
|
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
def __basic_parse_xml_attr(self, value):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
if value.lower() == "none":
|
||||||
|
return None
|
||||||
|
if value.lower() == "true":
|
||||||
|
return True
|
||||||
|
if value.lower() == "false":
|
||||||
|
return False
|
||||||
|
if value.isdigit():
|
||||||
|
return int(value)
|
||||||
|
return value
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
|
||||||
|
collection = None
|
||||||
|
if 'collection' in kwargs:
|
||||||
|
collection = kwargs['collection']
|
||||||
|
else:
|
||||||
|
raise ValueError("No collection given to QubesVM constructor")
|
||||||
|
|
||||||
|
# Special case for template b/c it is given in "template_qid" property
|
||||||
|
if "xml_element" in kwargs and kwargs["xml_element"].get("template_qid"):
|
||||||
|
template_qid = kwargs["xml_element"].get("template_qid")
|
||||||
|
if template_qid.lower() != "none":
|
||||||
|
if int(template_qid) in collection:
|
||||||
|
kwargs["template"] = collection[int(template_qid)]
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknown template with QID %s" % template_qid)
|
||||||
attrs = self._get_attrs_config()
|
attrs = self._get_attrs_config()
|
||||||
for attr_name in sorted(attrs, key=lambda _x: attrs[_x]['order'] if 'order' in attrs[_x] else 1000):
|
for attr_name in sorted(attrs, key=lambda _x: attrs[_x]['order'] if 'order' in attrs[_x] else 1000):
|
||||||
attr_config = attrs[attr_name]
|
attr_config = attrs[attr_name]
|
||||||
@ -308,11 +345,16 @@ class QubesVm(object):
|
|||||||
if 'attr' in attr_config:
|
if 'attr' in attr_config:
|
||||||
attr = attr_config['attr']
|
attr = attr_config['attr']
|
||||||
value = None
|
value = None
|
||||||
if attr_name not in kwargs:
|
if attr_name in kwargs:
|
||||||
|
value = kwargs[attr_name]
|
||||||
|
elif 'xml_element' in kwargs and kwargs['xml_element'].get(attr_name) is not None:
|
||||||
|
if 'xml_deserialize' in attr_config and callable(attr_config['xml_deserialize']):
|
||||||
|
value = attr_config['xml_deserialize'](kwargs['xml_element'].get(attr_name))
|
||||||
|
else:
|
||||||
|
value = self.__basic_parse_xml_attr(kwargs['xml_element'].get(attr_name))
|
||||||
|
else:
|
||||||
if 'default' in attr_config:
|
if 'default' in attr_config:
|
||||||
value = attr_config['default']
|
value = attr_config['default']
|
||||||
else:
|
|
||||||
value = kwargs[attr_name]
|
|
||||||
if 'eval' in attr_config:
|
if 'eval' in attr_config:
|
||||||
setattr(self, attr, eval(attr_config['eval']))
|
setattr(self, attr, eval(attr_config['eval']))
|
||||||
else:
|
else:
|
||||||
@ -1627,6 +1669,9 @@ class QubesTemplateVm(QubesVm):
|
|||||||
A class that represents an TemplateVM. A child of QubesVm.
|
A class that represents an TemplateVM. A child of QubesVm.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# In which order load this VM type from qubes.xml
|
||||||
|
load_order = 50
|
||||||
|
|
||||||
def _get_attrs_config(self):
|
def _get_attrs_config(self):
|
||||||
attrs_config = super(QubesTemplateVm, self)._get_attrs_config()
|
attrs_config = super(QubesTemplateVm, self)._get_attrs_config()
|
||||||
attrs_config['dir_path']['eval'] = 'value if value is not None else qubes_templates_dir + "/" + self.name'
|
attrs_config['dir_path']['eval'] = 'value if value is not None else qubes_templates_dir + "/" + self.name'
|
||||||
@ -1800,6 +1845,10 @@ class QubesNetVm(QubesVm):
|
|||||||
"""
|
"""
|
||||||
A class that represents a NetVM. A child of QubesCowVM.
|
A class that represents a NetVM. A child of QubesCowVM.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# In which order load this VM type from qubes.xml
|
||||||
|
load_order = 70
|
||||||
|
|
||||||
def _get_attrs_config(self):
|
def _get_attrs_config(self):
|
||||||
attrs_config = super(QubesNetVm, self)._get_attrs_config()
|
attrs_config = super(QubesNetVm, self)._get_attrs_config()
|
||||||
attrs_config['dir_path']['eval'] = 'value if value is not None else qubes_servicevms_dir + "/" + self.name'
|
attrs_config['dir_path']['eval'] = 'value if value is not None else qubes_servicevms_dir + "/" + self.name'
|
||||||
@ -1807,7 +1856,8 @@ class QubesNetVm(QubesVm):
|
|||||||
attrs_config['memory']['default'] = 200
|
attrs_config['memory']['default'] = 200
|
||||||
|
|
||||||
# New attributes
|
# New attributes
|
||||||
attrs_config['netid'] = { 'save': 'str(self.netid)', 'order': 30 }
|
attrs_config['netid'] = { 'save': 'str(self.netid)', 'order': 30,
|
||||||
|
'eval': 'value if value is not None else collection.get_new_unused_netid()' }
|
||||||
attrs_config['netprefix'] = { 'eval': '"10.137.{0}.".format(self.netid)' }
|
attrs_config['netprefix'] = { 'eval': '"10.137.{0}.".format(self.netid)' }
|
||||||
attrs_config['dispnetprefix'] = { 'eval': '"10.138.{0}.".format(self.netid)' }
|
attrs_config['dispnetprefix'] = { 'eval': '"10.138.{0}.".format(self.netid)' }
|
||||||
|
|
||||||
@ -1960,7 +2010,6 @@ class QubesNetVm(QubesVm):
|
|||||||
self.remove_appmenus()
|
self.remove_appmenus()
|
||||||
super(QubesNetVm, self).remove_from_disk()
|
super(QubesNetVm, self).remove_from_disk()
|
||||||
|
|
||||||
|
|
||||||
class QubesProxyVm(QubesNetVm):
|
class QubesProxyVm(QubesNetVm):
|
||||||
"""
|
"""
|
||||||
A class that represents a ProxyVM, ex FirewallVM. A child of QubesNetVM.
|
A class that represents a ProxyVM, ex FirewallVM. A child of QubesNetVM.
|
||||||
@ -2191,6 +2240,9 @@ class QubesDisposableVm(QubesVm):
|
|||||||
A class that represents an DisposableVM. A child of QubesVm.
|
A class that represents an DisposableVM. A child of QubesVm.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# In which order load this VM type from qubes.xml
|
||||||
|
load_order = 120
|
||||||
|
|
||||||
def _get_attrs_config(self):
|
def _get_attrs_config(self):
|
||||||
attrs_config = super(QubesDisposableVm, self)._get_attrs_config()
|
attrs_config = super(QubesDisposableVm, self)._get_attrs_config()
|
||||||
|
|
||||||
@ -2237,7 +2289,6 @@ class QubesDisposableVm(QubesVm):
|
|||||||
def verify_files(self):
|
def verify_files(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class QubesAppVm(QubesVm):
|
class QubesAppVm(QubesVm):
|
||||||
"""
|
"""
|
||||||
A class that represents an AppVM. A child of QubesVm.
|
A class that represents an AppVM. A child of QubesVm.
|
||||||
@ -2307,7 +2358,8 @@ class QubesHVm(QubesVm):
|
|||||||
# Default for meminfo-writer have changed to (correct) False in the
|
# Default for meminfo-writer have changed to (correct) False in the
|
||||||
# same version as introduction of guiagent_installed, so for older VMs
|
# same version as introduction of guiagent_installed, so for older VMs
|
||||||
# with wrong setting, change it based on 'guiagent_installed' presence
|
# with wrong setting, change it based on 'guiagent_installed' presence
|
||||||
if "guiagent_installed" not in kwargs:
|
if "guiagent_installed" not in kwargs and \
|
||||||
|
(not 'xml_element' in kwargs or kwargs['xml_element'].get('guiagent_installed') is None):
|
||||||
self.services['meminfo-writer'] = False
|
self.services['meminfo-writer'] = False
|
||||||
|
|
||||||
# HVM normally doesn't support dynamic memory management
|
# HVM normally doesn't support dynamic memory management
|
||||||
@ -2531,6 +2583,13 @@ class QubesHVm(QubesVm):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
register_qubes_vm_class("QubesTemplateVm", QubesTemplateVm)
|
||||||
|
register_qubes_vm_class("QubesNetVm", QubesNetVm)
|
||||||
|
register_qubes_vm_class("QubesProxyVm", QubesProxyVm)
|
||||||
|
register_qubes_vm_class("QubesDisposableVm", QubesDisposableVm)
|
||||||
|
register_qubes_vm_class("QubesAppVm", QubesAppVm)
|
||||||
|
register_qubes_vm_class("QubesHVm", QubesHVm)
|
||||||
|
|
||||||
class QubesVmCollection(dict):
|
class QubesVmCollection(dict):
|
||||||
"""
|
"""
|
||||||
A collection of Qubes VMs indexed by Qubes id (qid)
|
A collection of Qubes VMs indexed by Qubes id (qid)
|
||||||
@ -2877,87 +2936,6 @@ class QubesVmCollection(dict):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def parse_xml_element(self, element):
|
|
||||||
kwargs = {}
|
|
||||||
common_attr_list = ("qid", "name", "dir_path", "conf_file",
|
|
||||||
"private_img", "root_img", "template_qid",
|
|
||||||
"installed_by_rpm", "internal",
|
|
||||||
"uses_default_netvm", "label", "memory", "vcpus", "pcidevs",
|
|
||||||
"maxmem", "kernel", "uses_default_kernel", "kernelopts", "uses_default_kernelopts",
|
|
||||||
"mac", "services", "include_in_backups", "debug",
|
|
||||||
"default_user", "qrexec_timeout", "qrexec_installed", "guiagent_installed", "drive" )
|
|
||||||
|
|
||||||
for attribute in common_attr_list:
|
|
||||||
kwargs[attribute] = element.get(attribute)
|
|
||||||
if kwargs[attribute] is None:
|
|
||||||
kwargs.pop(attribute)
|
|
||||||
|
|
||||||
kwargs["qid"] = int(kwargs["qid"])
|
|
||||||
|
|
||||||
if "include_in_backups" in kwargs:
|
|
||||||
kwargs["include_in_backups"] = True if kwargs["include_in_backups"] == "True" else False
|
|
||||||
|
|
||||||
if "installed_by_rpm" in kwargs:
|
|
||||||
kwargs["installed_by_rpm"] = True if kwargs["installed_by_rpm"] == "True" else False
|
|
||||||
|
|
||||||
if "internal" in kwargs:
|
|
||||||
kwargs["internal"] = True if kwargs["internal"] == "True" else False
|
|
||||||
|
|
||||||
if "template_qid" in kwargs:
|
|
||||||
if kwargs["template_qid"] == "none" or kwargs["template_qid"] is None:
|
|
||||||
kwargs.pop("template_qid")
|
|
||||||
else:
|
|
||||||
kwargs["template_qid"] = int(kwargs["template_qid"])
|
|
||||||
template = self[kwargs.pop("template_qid")]
|
|
||||||
if template is None:
|
|
||||||
print >> sys.stderr, "ERROR: VM '{0}' uses unkown template qid='{1}'!".\
|
|
||||||
format(kwargs["name"], kwargs["template_qid"])
|
|
||||||
else:
|
|
||||||
kwargs["template"] = template
|
|
||||||
|
|
||||||
if "label" in kwargs:
|
|
||||||
if kwargs["label"] not in QubesVmLabels:
|
|
||||||
print >> sys.stderr, "ERROR: incorrect label for VM '{0}'".format(kwargs["name"])
|
|
||||||
kwargs.pop ("label")
|
|
||||||
else:
|
|
||||||
kwargs["label"] = QubesVmLabels[kwargs["label"]]
|
|
||||||
|
|
||||||
if "kernel" in kwargs and kwargs["kernel"] == "None":
|
|
||||||
kwargs["kernel"] = None
|
|
||||||
if "uses_default_kernel" in kwargs:
|
|
||||||
kwargs["uses_default_kernel"] = True if kwargs["uses_default_kernel"] == "True" else False
|
|
||||||
else:
|
|
||||||
# For backward compatibility
|
|
||||||
kwargs["uses_default_kernel"] = False
|
|
||||||
if kwargs["uses_default_kernel"]:
|
|
||||||
kwargs["kernel"] = self.get_default_kernel()
|
|
||||||
else:
|
|
||||||
if "kernel" in kwargs and kwargs["kernel"]=="None":
|
|
||||||
kwargs["kernel"]=None
|
|
||||||
# for other cases - generic assigment is ok
|
|
||||||
|
|
||||||
if "uses_default_kernelopts" in kwargs:
|
|
||||||
kwargs["uses_default_kernelopts"] = False if kwargs["uses_default_kernelopts"] == "False" else True
|
|
||||||
|
|
||||||
if "kernelopts" in kwargs and kwargs["kernelopts"] == "None":
|
|
||||||
kwargs.pop("kernelopts")
|
|
||||||
if "kernelopts" not in kwargs:
|
|
||||||
kwargs["uses_default_kernelopts"] = True
|
|
||||||
|
|
||||||
if "debug" in kwargs:
|
|
||||||
kwargs["debug"] = True if kwargs["debug"] == "True" else False
|
|
||||||
|
|
||||||
if "qrexec_installed" in kwargs:
|
|
||||||
kwargs["qrexec_installed"] = True if kwargs["qrexec_installed"] == "True" else False
|
|
||||||
|
|
||||||
if "guiagent_installed" in kwargs:
|
|
||||||
kwargs["guiagent_installed"] = True if kwargs["guiagent_installed"] == "True" else False
|
|
||||||
|
|
||||||
if "drive" in kwargs and kwargs["drive"] == "None":
|
|
||||||
kwargs["drive"] = None
|
|
||||||
|
|
||||||
return kwargs
|
|
||||||
|
|
||||||
def set_netvm_dependency(self, element):
|
def set_netvm_dependency(self, element):
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
attr_list = ("qid", "uses_default_netvm", "netvm_qid")
|
attr_list = ("qid", "uses_default_netvm", "netvm_qid")
|
||||||
@ -2990,28 +2968,11 @@ class QubesVmCollection(dict):
|
|||||||
if netvm:
|
if netvm:
|
||||||
netvm.connected_vms[vm.qid] = vm
|
netvm.connected_vms[vm.qid] = vm
|
||||||
|
|
||||||
def load(self):
|
|
||||||
self.clear()
|
|
||||||
|
|
||||||
dom0vm = QubesDom0NetVm ()
|
def load_globals(self, element):
|
||||||
self[dom0vm.qid] = dom0vm
|
|
||||||
self.default_netvm_qid = 0
|
|
||||||
|
|
||||||
global dom0_vm
|
|
||||||
dom0_vm = dom0vm
|
|
||||||
|
|
||||||
try:
|
|
||||||
tree = lxml.etree.parse(self.qubes_store_file)
|
|
||||||
except (EnvironmentError,
|
|
||||||
xml.parsers.expat.ExpatError) as err:
|
|
||||||
print("{0}: import error: {1}".format(
|
|
||||||
os.path.basename(sys.argv[0]), err))
|
|
||||||
return False
|
|
||||||
|
|
||||||
element = tree.getroot()
|
|
||||||
default_template = element.get("default_template")
|
default_template = element.get("default_template")
|
||||||
self.default_template_qid = int(default_template) \
|
self.default_template_qid = int(default_template) \
|
||||||
if default_template != "None" else None
|
if default_template.lower() != "none" else None
|
||||||
|
|
||||||
default_netvm = element.get("default_netvm")
|
default_netvm = element.get("default_netvm")
|
||||||
if default_netvm is not None:
|
if default_netvm is not None:
|
||||||
@ -3038,152 +2999,53 @@ class QubesVmCollection(dict):
|
|||||||
|
|
||||||
self.default_kernel = element.get("default_kernel")
|
self.default_kernel = element.get("default_kernel")
|
||||||
|
|
||||||
# Then, read in the TemplateVMs, because a reference to template VM
|
|
||||||
# is needed to create each AppVM
|
|
||||||
for element in tree.findall("QubesTemplateVm"):
|
|
||||||
try:
|
|
||||||
|
|
||||||
kwargs = self.parse_xml_element(element)
|
def load(self):
|
||||||
|
self.clear()
|
||||||
|
|
||||||
vm = QubesTemplateVm(**kwargs)
|
dom0vm = QubesDom0NetVm (collection=self)
|
||||||
|
self[dom0vm.qid] = dom0vm
|
||||||
|
self.default_netvm_qid = 0
|
||||||
|
|
||||||
self[vm.qid] = vm
|
global dom0_vm
|
||||||
except (ValueError, LookupError) as err:
|
dom0_vm = dom0vm
|
||||||
print("{0}: import error (QubesTemplateVm): {1}".format(
|
|
||||||
os.path.basename(sys.argv[0]), err))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Read in the NetVMs first, because a reference to NetVM
|
try:
|
||||||
# is needed to create all other VMs
|
tree = lxml.etree.parse(self.qubes_store_file)
|
||||||
for element in tree.findall("QubesNetVm"):
|
except (EnvironmentError,
|
||||||
try:
|
xml.parsers.expat.ExpatError) as err:
|
||||||
kwargs = self.parse_xml_element(element)
|
print("{0}: import error: {1}".format(
|
||||||
# Add NetVM specific fields
|
os.path.basename(sys.argv[0]), err))
|
||||||
attr_list = ("netid",)
|
return False
|
||||||
|
|
||||||
for attribute in attr_list:
|
self.load_globals(tree.getroot())
|
||||||
kwargs[attribute] = element.get(attribute)
|
|
||||||
|
|
||||||
kwargs["netid"] = int(kwargs["netid"])
|
for (vm_class_name, vm_class) in sorted(QubesVmClasses.items(),
|
||||||
|
key=lambda _x: _x[1].load_order):
|
||||||
|
for element in tree.findall(vm_class_name):
|
||||||
|
try:
|
||||||
|
vm = vm_class(xml_element=element, collection=self)
|
||||||
|
self[vm.qid] = vm
|
||||||
|
except (ValueError, LookupError) as err:
|
||||||
|
print("{0}: import error ({1}): {2}".format(
|
||||||
|
os.path.basename(sys.argv[0]), vm_class_name, err))
|
||||||
|
raise
|
||||||
|
return False
|
||||||
|
|
||||||
vm = QubesNetVm(**kwargs)
|
# After importing all VMs, set netvm references, in the same order
|
||||||
self[vm.qid] = vm
|
for (vm_class_name, vm_class) in sorted(QubesVmClasses.items(),
|
||||||
|
key=lambda _x: _x[1].load_order):
|
||||||
except (ValueError, LookupError) as err:
|
for element in tree.findall(vm_class_name):
|
||||||
print("{0}: import error (QubesNetVM) {1}".format(
|
try:
|
||||||
os.path.basename(sys.argv[0]), err))
|
self.set_netvm_dependency(element)
|
||||||
return False
|
except (ValueError, LookupError) as err:
|
||||||
|
print("{0}: import error2 ({}): {}".format(
|
||||||
# Next read in the ProxyVMs, because they may be referenced
|
os.path.basename(sys.argv[0]), vm_class_name, err))
|
||||||
# by other VMs
|
return False
|
||||||
for element in tree.findall("QubesProxyVm"):
|
|
||||||
try:
|
|
||||||
kwargs = self.parse_xml_element(element)
|
|
||||||
# Add ProxyVM specific fields
|
|
||||||
attr_list = ("netid",)
|
|
||||||
|
|
||||||
for attribute in attr_list:
|
|
||||||
kwargs[attribute] = element.get(attribute)
|
|
||||||
|
|
||||||
kwargs["netid"] = int(kwargs["netid"])
|
|
||||||
|
|
||||||
vm = QubesProxyVm(**kwargs)
|
|
||||||
self[vm.qid] = vm
|
|
||||||
|
|
||||||
except (ValueError, LookupError) as err:
|
|
||||||
print("{0}: import error (QubesProxyVM) {1}".format(
|
|
||||||
os.path.basename(sys.argv[0]), err))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# After importing all NetVMs and ProxyVMs, set netvm references
|
|
||||||
# 1. For TemplateVMs
|
|
||||||
for element in tree.findall("QubesTemplateVm"):
|
|
||||||
try:
|
|
||||||
self.set_netvm_dependency(element)
|
|
||||||
except (ValueError, LookupError) as err:
|
|
||||||
print("{0}: import error (QubesTemplateVm): {1}".format(
|
|
||||||
os.path.basename(sys.argv[0]), err))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# 2. For PoxyVMs
|
|
||||||
for element in tree.findall("QubesProxyVm"):
|
|
||||||
try:
|
|
||||||
self.set_netvm_dependency(element)
|
|
||||||
except (ValueError, LookupError) as err:
|
|
||||||
print("{0}: import error (QubesProxyVM) {1}".format(
|
|
||||||
os.path.basename(sys.argv[0]), err))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Finally, read in the AppVMs
|
|
||||||
for element in tree.findall("QubesAppVm"):
|
|
||||||
try:
|
|
||||||
kwargs = self.parse_xml_element(element)
|
|
||||||
vm = QubesAppVm(**kwargs)
|
|
||||||
|
|
||||||
self[vm.qid] = vm
|
|
||||||
|
|
||||||
self.set_netvm_dependency(element)
|
|
||||||
except (ValueError, LookupError) as err:
|
|
||||||
print("{0}: import error (QubesAppVm): {1}".format(
|
|
||||||
os.path.basename(sys.argv[0]), err))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# And HVMs
|
|
||||||
for element in tree.findall("QubesHVm"):
|
|
||||||
try:
|
|
||||||
kwargs = self.parse_xml_element(element)
|
|
||||||
vm = QubesHVm(**kwargs)
|
|
||||||
|
|
||||||
self[vm.qid] = vm
|
|
||||||
|
|
||||||
self.set_netvm_dependency(element)
|
|
||||||
except (ValueError, LookupError) as err:
|
|
||||||
print("{0}: import error (QubesHVm): {1}".format(
|
|
||||||
os.path.basename(sys.argv[0]), err))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Really finally, read in the DisposableVMs
|
|
||||||
for element in tree.findall("QubesDisposableVm"):
|
|
||||||
try:
|
|
||||||
kwargs = {}
|
|
||||||
attr_list = ("qid", "name",
|
|
||||||
"template_qid",
|
|
||||||
"label", "dispid", "firewall_conf" )
|
|
||||||
|
|
||||||
for attribute in attr_list:
|
|
||||||
kwargs[attribute] = element.get(attribute)
|
|
||||||
|
|
||||||
kwargs["qid"] = int(kwargs["qid"])
|
|
||||||
kwargs["dispid"] = int(kwargs["dispid"])
|
|
||||||
kwargs["template_qid"] = int(kwargs["template_qid"])
|
|
||||||
|
|
||||||
template = self[kwargs.pop("template_qid")]
|
|
||||||
if template is None:
|
|
||||||
print >> sys.stderr, "ERROR: DisposableVM '{0}' uses unkown template qid='{1}'!".\
|
|
||||||
format(kwargs["name"], kwargs["template_qid"])
|
|
||||||
else:
|
|
||||||
kwargs["template"] = template
|
|
||||||
|
|
||||||
kwargs["netvm"] = self.get_default_netvm()
|
|
||||||
|
|
||||||
if kwargs["label"] is not None:
|
|
||||||
if kwargs["label"] not in QubesVmLabels:
|
|
||||||
print >> sys.stderr, "ERROR: incorrect label for VM '{0}'".format(kwargs["name"])
|
|
||||||
kwargs.pop ("label")
|
|
||||||
else:
|
|
||||||
kwargs["label"] = QubesVmLabels[kwargs["label"]]
|
|
||||||
|
|
||||||
vm = QubesDisposableVm(**kwargs)
|
|
||||||
|
|
||||||
self[vm.qid] = vm
|
|
||||||
except (ValueError, LookupError) as err:
|
|
||||||
print("{0}: import error (DisposableAppVm): {1}".format(
|
|
||||||
os.path.basename(sys.argv[0]), err))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# if there was no clockvm entry in qubes.xml, try to determine default:
|
# if there was no clockvm entry in qubes.xml, try to determine default:
|
||||||
# root of default NetVM chain
|
# root of default NetVM chain
|
||||||
if clockvm is None:
|
if element.get("clockvm") is None:
|
||||||
if self.default_netvm_qid is not None:
|
if self.default_netvm_qid is not None:
|
||||||
clockvm = self[self.default_netvm_qid]
|
clockvm = self[self.default_netvm_qid]
|
||||||
# Find root of netvm chain
|
# Find root of netvm chain
|
||||||
|
Loading…
Reference in New Issue
Block a user