Skip to content

Commit 559e03b

Browse files
committed
Return UnknownDevice for assignments where device is unknown
references QubesOS/qubes-issues#10409
1 parent a5ea121 commit 559e03b

4 files changed

Lines changed: 29 additions & 18 deletions

File tree

qubesadmin/device_protocol.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,8 +1356,9 @@ def devices(self) -> List[DeviceInfo]:
13561356
@property
13571357
def device(self) -> DeviceInfo:
13581358
"""
1359-
Get single DeviceInfo object or raise an error.
1360-
1359+
Get single DeviceInfo object or UnknownDevice, if the device has
1360+
not been found.
1361+
If there are more devices than one matching, raise ProtocolError.
13611362
If port id is set we have exactly one device
13621363
since we can attach ony one device to one port.
13631364
If assignment is more general we can get 0 or many devices.
@@ -1367,7 +1368,8 @@ def device(self) -> DeviceInfo:
13671368
return devices[0]
13681369
if len(devices) > 1:
13691370
raise ProtocolError("Too many devices matches to assignment")
1370-
raise ProtocolError("No devices matches to assignment")
1371+
return UnknownDevice(port=self.port,
1372+
device_id=self.device_id)
13711373

13721374
@property
13731375
def port(self) -> Port:

qubesadmin/tests/mock_app.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ def __init__(
691691
vendor: str,
692692
attached: Optional[str] = None,
693693
assigned: Optional[List[Tuple[str, str, list[Any] | None]]] = None,
694+
device_unknown: bool = False,
694695
):
695696
"""
696697
:param qapp: QubesTest object
@@ -712,6 +713,7 @@ def __init__(
712713
self.assigned = assigned
713714
self.product = product
714715
self.vendor = vendor
716+
self.device_unknown = device_unknown
715717

716718
self.interface = self.device_id.split(":")[-1]
717719

@@ -761,16 +763,17 @@ def update_calls(self):
761763
)
762764
]
763765

764-
self.qapp.expected_calls[
765-
(
766-
self.backend_vm,
767-
f"admin.vm.device.{self.dev_class}.Available",
768-
None,
769-
None,
766+
if not self.device_unknown:
767+
self.qapp.expected_calls[
768+
(
769+
self.backend_vm,
770+
f"admin.vm.device.{self.dev_class}.Available",
771+
None,
772+
None,
773+
)
774+
] = (
775+
current_response + self.device_string().encode()
770776
)
771-
] = (
772-
current_response + self.device_string().encode()
773-
)
774777

775778
if self.attached:
776779
current_response = self.qapp.expected_calls[

qubesadmin/tests/tools/qvm_device.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,12 +284,12 @@ def test_020_detach(self):
284284

285285
def test_021_detach_unknown(self):
286286
""" Test detach action """
287-
self.app.expected_calls[
288-
('test-vm2', 'admin.vm.device.testclass.Detach',
289-
'test-vm1+dev7:0000:0000::?******', None)] = b'0\0'
290-
qubesadmin.tools.qvm_device.main(
291-
['testclass', 'detach', 'test-vm2', 'test-vm1:dev7'], app=self.app)
292-
self.assertAllCalled()
287+
with qubesadmin.tests.tools.StderrBuffer() as stderr:
288+
retcode = qubesadmin.tools.qvm_device.main(
289+
['testclass', 'detach', 'test-vm2', 'test-vm1:dev7'],
290+
app=self.app)
291+
self.assertEqual(retcode, 1)
292+
self.assertIn("not found", stderr.getvalue())
293293

294294
def test_022_detach_all(self):
295295
""" Test detach action """

qubesadmin/tools/qvm_device.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ def attach_device(args):
236236
try:
237237
try:
238238
dev = assignment.device
239+
if isinstance(dev, UnknownDevice):
240+
raise qubesadmin.exc.QubesException(
241+
"Unknown device, skipping attachment of device from the "
242+
f"port {assignment}")
239243
except ProtocolError as exc:
240244
raise qubesadmin.exc.QubesException(str(exc))
241245

@@ -299,6 +303,8 @@ def detach_device(args):
299303

300304
if not assignment.matches(actual_dev):
301305
raise qubesadmin.exc.QubesException(f"{device} is not attached.")
306+
if isinstance(actual_dev, UnknownDevice):
307+
raise qubesadmin.exc.QubesException(f"{device} not found.")
302308

303309
vm.devices[args.devclass].detach(assignment)
304310
elif args.device:

0 commit comments

Comments
 (0)