Skip to content

Commit ab8ae5f

Browse files
committed
q-dev: add device_identity to device assignment
1 parent 4102157 commit ab8ae5f

File tree

3 files changed

+26
-15
lines changed

3 files changed

+26
-15
lines changed

qubesadmin/device_protocol.py

+16-6
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ class DeviceAssignment(Port):
842842
def __init__(
843843
self,
844844
port: Port,
845-
device_id=None,
845+
device_identity=None,
846846
frontend_domain=None,
847847
options=None,
848848
mode: Union[str, AssignmentMode] = "manual",
@@ -854,25 +854,33 @@ def __init__(
854854
else:
855855
self.mode = AssignmentMode(mode)
856856
self.frontend_domain = frontend_domain
857+
self.device_identity = device_identity
857858

858859
def clone(self, **kwargs):
859860
"""
860861
Clone object and substitute attributes with explicitly given.
861862
"""
863+
port = kwargs.get(
864+
"port", Port(self.backend_domain, self.ident, self.devclass))
862865
attr = {
863866
"options": self.options,
864-
"required": self.required,
865-
"attach_automatically": self.attach_automatically,
867+
"mode": self.mode,
868+
"device_identity": self.device_identity,
866869
"frontend_domain": self.frontend_domain,
867870
}
868871
attr.update(kwargs)
869-
return self.__class__(
870-
Port(self.backend_domain, self.ident, self.devclass), **attr)
872+
return self.__class__(port, **attr)
871873

872874
@property
873875
def device(self) -> DeviceInfo:
874876
"""Get DeviceInfo object corresponding to this DeviceAssignment"""
875-
return self.backend_domain.devices[self.devclass][self.ident]
877+
dev = self.backend_domain.devices[self.devclass][self.ident]
878+
if (self.device_identity is not None
879+
and self.device_identity != dev.self_identity):
880+
raise ProtocolError(
881+
"Device identity does not match, expected "
882+
f"'{self.device_identity}' got '{dev.self_identity}'")
883+
return dev
876884

877885
@property
878886
def frontend_domain(self) -> Optional[QubesVM]:
@@ -917,6 +925,7 @@ def attach_automatically(self) -> bool:
917925
"""
918926
return self.mode in (
919927
AssignmentMode.AUTO,
928+
AssignmentMode.ASK,
920929
AssignmentMode.REQUIRED
921930
)
922931

@@ -942,6 +951,7 @@ def serialize(self) -> bytes:
942951
self.pack_property(key, value)
943952
for key, value in (
944953
('mode', self.mode.value),
954+
('device_identity', self.device_identity),
945955
('ident', self.ident),
946956
('devclass', self.devclass)))
947957

qubesadmin/tests/tools/qvm_device.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ def test_030_assign(self):
262262
'test-vm2', 'admin.vm.device.testclass.Assign', 'test-vm1+dev1',
263263
b"required='no' attach_automatically='yes' ident='dev1' "
264264
b"devclass='testclass' backend_domain='test-vm1' "
265-
b"frontend_domain='test-vm2' _identity='0000:0000::?******'"
265+
b"frontend_domain='test-vm2' device_identity='0000:0000::?******'"
266266
)] = b'0\0'
267267
qubesadmin.tools.qvm_device.main(
268268
['testclass', 'assign', 'test-vm2', 'test-vm1:dev1'], app=self.app)
@@ -275,7 +275,7 @@ def test_031_assign_required(self):
275275
'test-vm2', 'admin.vm.device.testclass.Assign', 'test-vm1+dev1',
276276
b"required='yes' attach_automatically='yes' ident='dev1' "
277277
b"devclass='testclass' backend_domain='test-vm1' "
278-
b"frontend_domain='test-vm2' _identity='0000:0000::?******'"
278+
b"frontend_domain='test-vm2' device_identity='0000:0000::?******'"
279279
)] = b'0\0'
280280
qubesadmin.tools.qvm_device.main(
281281
['testclass', 'assign', '--required', 'test-vm2', 'test-vm1:dev1'], app=self.app)
@@ -289,7 +289,7 @@ def test_032_assign_options(self):
289289
b"required='no' attach_automatically='yes' ident='dev1' "
290290
b"devclass='testclass' backend_domain='test-vm1' "
291291
b"frontend_domain='test-vm2' _read-only='yes' "
292-
b"_identity='0000:0000::?******'")] = b'0\0'
292+
b"device_identity='0000:0000::?******'")] = b'0\0'
293293
with qubesadmin.tests.tools.StdoutBuffer() as buf:
294294
qubesadmin.tools.qvm_device.main(
295295
['testclass', 'assign', '--ro', 'test-vm2', 'test-vm1:dev1'],

qubesadmin/tools/qvm_device.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -207,16 +207,17 @@ def assign_device(args):
207207
"""
208208
vm = args.domains[0]
209209
device = args.device
210-
assignment = DeviceAssignment(
211-
device, mode='required' if args.required else 'auto-attach')
210+
identity = device.self_identity if not args.port else None
212211
options = dict(opt.split('=', 1) for opt in args.option or [])
213212
if args.ro:
214213
options['read-only'] = 'yes'
215214
parse_ro_option_as_read_only(options)
216-
options['identity'] = device.self_identity
217-
if args.port:
218-
options['identity'] = 'any'
219-
assignment.options = options
215+
assignment = DeviceAssignment(
216+
device,
217+
device_identity=identity,
218+
mode='required' if args.required else 'auto-attach',
219+
options=options
220+
)
220221
vm.devices[args.devclass].assign(assignment)
221222
if vm.is_running() and not assignment.attached and not args.quiet:
222223
print("Assigned. To attach you can now restart domain or run: \n"

0 commit comments

Comments
 (0)