tools/qvm-device: allow detaching all devices

QubesOS/qubes-issues#4530
This commit is contained in:
Marek Marczykowski-Górecki 2018-12-07 21:50:55 +01:00
parent 954ffc4bf2
commit bee55a3bce
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
3 changed files with 24 additions and 5 deletions

View File

@ -8,7 +8,7 @@ Synopsis
========
| :command:`qvm-device` [*options*] *DEVICE_CLASS* {list,ls,l} <*vm-name*>
| :command:`qvm-device` [*options*] *DEVICE_CLASS* {attach,at,a} <*vm-name*> <*device*>
| :command:`qvm-device` [*options*] *DEVICE_CLASS* {detach,dt,d} <*vm-name*> <*device*>
| :command:`qvm-device` [*options*] *DEVICE_CLASS* {detach,dt,d} <*vm-name*> [<*device*>]
| :command:`qvm-*DEVICE_CLASS*` [*options*] {list,ls,l,attach,at,a,detach,dt,d} <*vmname*> ...
Tool can be called either as `qvm-device *DEVICE_CLASS* ...`, or
@ -79,7 +79,8 @@ detach
| :command:`qvm-device` *DEVICE_CLASS* detach [-h] [--verbose] [--quiet] *VMNAME* *BACKEND_DOMAIN:DEVICE_ID*
Detach the device with *BACKEND_DOMAIN:DEVICE_ID* from domain *VMNAME*
Detach the device with *BACKEND_DOMAIN:DEVICE_ID* from domain *VMNAME*.
If no device is given, detach all *DEVICE_CLASS* devices.
aliases: d, dt

View File

@ -199,3 +199,16 @@ class TC_00_qvm_device(qubesadmin.tests.QubesTestCase):
['test', 'detach', 'test-vm2', 'test-vm1:dev7'], app=self.app)
self.assertAllCalled()
def test_022_detach_all(self):
''' Test detach action '''
self.app.expected_calls[('test-vm2', 'admin.vm.device.test.List',
None, None)] = \
b'0\0test-vm1+dev1\ntest-vm1+dev2\n'
self.app.expected_calls[('test-vm2', 'admin.vm.device.test.Detach',
'test-vm1+dev1', None)] = b'0\0'
self.app.expected_calls[('test-vm2', 'admin.vm.device.test.Detach',
'test-vm1+dev2', None)] = b'0\0'
qubesadmin.tools.qvm_device.main(
['test', 'detach', 'test-vm2'], app=self.app)
self.assertAllCalled()

View File

@ -130,9 +130,12 @@ def detach_device(args):
''' Called by the parser to execute the :program:`qvm-devices detach`
subcommand.
'''
device_assignment = args.device_assignment
vm = args.domains[0]
vm.devices[args.devclass].detach(device_assignment)
if args.device_assignment:
vm.devices[args.devclass].detach(args.device_assignment)
else:
for device_assignment in vm.devices[args.devclass].assignments():
vm.devices[args.devclass].detach(device_assignment)
def init_list_parser(sub_parsers):
@ -169,6 +172,8 @@ class DeviceAction(qubesadmin.tools.QubesAction):
app = namespace.app
backend_device_id = getattr(namespace, self.dest)
devclass = namespace.devclass
if backend_device_id is None:
return
try:
vmname, device_id = backend_device_id.split(':', 1)
@ -232,7 +237,7 @@ def get_parser(device_class=None):
dest='device_assignment',
action=DeviceAction)
detach_parser.add_argument(metavar='BACKEND:DEVICE_ID',
dest='device_assignment',
dest='device_assignment', nargs=argparse.OPTIONAL,
action=DeviceAction, allow_unknown=True)
attach_parser.add_argument('--option', '-o', action='append',