def load(self, lock=False): '''Open qubes.xml :throws EnvironmentError: failure on parsing store :throws xml.parsers.expat.ExpatError: failure on parsing store :raises lxml.etree.XMLSyntaxError: on syntax error in qubes.xml ''' fh = self._acquire_lock() self.xml = lxml.etree.parse(fh) # stage 1: load labels and pools for node in self.xml.xpath('./labels/label'): label = qubes.Label.fromxml(node) self.labels[label.index] = label for node in self.xml.xpath('./pools/pool'): name = node.get('name') assert name, "Pool name '%s' is invalid " % name try: self.pools[name] = self._get_pool(**node.attrib) except qubes.exc.QubesException as e: self.log.error(str(e)) # stage 2: load VMs for node in self.xml.xpath('./domains/domain'): # pylint: disable=no-member cls = self.get_vm_class(node.get('class')) vm = cls(self, node) vm.load_properties(load_stage=2) vm.init_log() self.domains.add(vm, _enable_events=False) if 0 not in self.domains: self.domains.add( qubes.vm.adminvm.AdminVM(self, None), _enable_events=False) self._migrate_global_properties() # stage 3: load global properties self.load_properties(load_stage=3) # stage 4: fill all remaining VM properties for vm in self.domains: vm.load_properties(load_stage=4) vm.load_extras() # stage 5: misc fixups self.property_require('default_netvm', allow_none=True) self.property_require('default_template') self.property_require('clockvm', allow_none=True) self.property_require('updatevm', allow_none=True) for vm in self.domains: vm.events_enabled = True vm.fire_event('domain-load') # get a file timestamp (before closing it - still holding the lock!), # to detect whether anyone else have modified it in the meantime self.__load_timestamp = os.path.getmtime(self._store) if not lock: self._release_lock()