Skip to content

Commit

Permalink
q-dev: update and fix tests for backup
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrbartman committed May 26, 2024
1 parent a8650a7 commit 1ec3549
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 26 deletions.
9 changes: 4 additions & 5 deletions qubesadmin/backup/core2.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,11 +336,10 @@ def import_core2_vm(self, element):
if pcidevs:
pcidevs = ast.literal_eval(pcidevs)
for pcidev in pcidevs:
if not pci_strictreset:
vm.devices['pci'][('dom0', pcidev.replace(':', '_'))] = {
'no-strict-reset': True}
else:
vm.devices['pci'][('dom0', pcidev.replace(':', '_'))] = {}
ident = pcidev.replace(':', '_')
options = {'no-strict-reset': True} if not pci_strictreset else {}
options['required'] = True
vm.devices['pci'][('dom0', ident)] = options

def load(self):
with open(self.store, encoding='utf-8') as fh:
Expand Down
4 changes: 4 additions & 0 deletions qubesadmin/backup/core3.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

import qubesadmin.backup
import qubesadmin.firewall
from qubesadmin import device_protocol


class Core3VM(qubesadmin.backup.BackupVM):
'''VM object'''
Expand Down Expand Up @@ -125,6 +127,8 @@ def import_core3_vm(self, element):
for opt_node in node.findall('./option'):
opt_name = opt_node.get('name')
options[opt_name] = opt_node.text
options['required'] = device_protocol.qbool(
node.get('required', 'yes'))
vm.devices[bus_name][(backend_domain, ident)] = options

# extract base properties
Expand Down
16 changes: 12 additions & 4 deletions qubesadmin/backup/restore.py
Original file line number Diff line number Diff line change
Expand Up @@ -2087,16 +2087,24 @@ def _restore_vms_metadata(self, restore_info):
for bus in vm.devices:
for backend_domain, ident in vm.devices[bus]:
options = vm.devices[bus][(backend_domain, ident)]
if 'required' in options:
required = options['required']
del options['required']
else:
required = False
assignment = DeviceAssignment(
backend_domain=backend_domain,
backend_domain=self.app.domains[backend_domain],
ident=ident,
devclass=bus,
options=options,
attach_automatically=True)
attach_automatically=True,
required=required,
)
try:
if not self.options.verify_only:
new_vm.devices[bus].attach(assignment)
new_vm.devices[bus].assign(assignment)
except Exception as err: # pylint: disable=broad-except
self.log.error('Error attaching device %s:%s to %s: %s',
self.log.error('Error assigning device %s:%s to %s: %s',
bus, ident, vm.name, err)

# Set VM dependencies - only non-default setting
Expand Down
14 changes: 9 additions & 5 deletions qubesadmin/device_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,20 @@ def __hash__(self):
return hash((str(self.backend_domain), self.ident))

def __eq__(self, other):
return (
self.backend_domain == other.backend_domain and
self.ident == other.ident
)
if isinstance(other, Device):
return (
self.backend_domain == other.backend_domain and
self.ident == other.ident
)
raise TypeError(f"Comparing instances of 'Device' and '{type(other)}' "
"is not supported")

def __lt__(self, other):
if isinstance(other, Device):
return (self.backend_domain.name, self.ident) < \
(other.backend_domain.name, other.ident)
raise NotImplementedError()
raise TypeError(f"Comparing instances of 'Device' and '{type(other)}' "
"is not supported")

def __repr__(self):
return "[%s]:%s" % (self.backend_domain, self.ident)
Expand Down
23 changes: 11 additions & 12 deletions qubesadmin/tests/backup/backupcompatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@
'provides_network': True},
'devices': {
'pci': {
('dom0', '02_00.0'): {},
('dom0', '03_00.0'): {},
('dom0', '02_00.0'): {'required': True},
('dom0', '03_00.0'): {'required': True},
}
},
'tags': set(),
Expand Down Expand Up @@ -371,8 +371,8 @@
'provides_network': True},
'devices': {
'pci': {
('dom0', '02_00.0'): {},
('dom0', '03_00.0'): {},
('dom0', '02_00.0'): {'required': True},
('dom0', '03_00.0'): {'required': True},
}
},
'tags': set(),
Expand Down Expand Up @@ -490,7 +490,7 @@
'provides_network': 'True'},
'devices': {
'pci': {
('dom0', '02_00.0'): {},
('dom0', '02_00.0'): {'required': True},
}
},
'tags': set(),
Expand Down Expand Up @@ -704,7 +704,7 @@
},
'devices': {
'pci': {
('dom0', '03_00.0'): {},
('dom0', '03_00.0'): {'required': True},
}
},
'tags': set(),
Expand Down Expand Up @@ -1434,13 +1434,12 @@ def setup_expected_calls(self, parsed_qubes_xml, templates_map=None):

for bus, devices in vm['devices'].items():
for (backend_domain, ident), options in devices.items():
all_options = options.copy()
all_options['required'] = True
# all_options['attach_automatically'] = True # TODO
encoded_options = ' '.join('{}={}'.format(key, value) for
key, value in all_options.items()).encode()
encoded_options = \
(f"required='yes' attach_automatically='yes' "
f"ident='{ident}' devclass='{bus}' backend_domain='{backend_domain}'"
f" frontend_domain='{name}'".encode())
self.app.expected_calls[
(name, 'admin.vm.device.{}.Attach'.format(bus),
(name, 'admin.vm.device.{}.Assign'.format(bus),
'{}+{}'.format(backend_domain, ident),
encoded_options)] = b'0\0'

Expand Down

0 comments on commit 1ec3549

Please sign in to comment.