Browse Source

qvm-ls & qvm-device: Handle removal of VM during on_shutdown.

Fixes QubesOS/qubes-issues#5105
3hhh 3 years ago
parent
commit
7c977f98a5
2 changed files with 32 additions and 17 deletions
  1. 21 14
      qubesadmin/tools/qvm_device.py
  2. 11 3
      qubesadmin/tools/qvm_ls.py

+ 21 - 14
qubesadmin/tools/qvm_device.py

@@ -91,8 +91,11 @@ def list_devices(args):
 
         else:
             for domain in app.domains:
-                for dev in domain.devices[args.devclass].available():
-                    devices.add(dev)
+                try:
+                    for dev in domain.devices[args.devclass].available():
+                        devices.add(dev)
+                except qubesadmin.exc.QubesVMNotFoundError:
+                    continue
     except qubesadmin.exc.QubesDaemonAccessError:
         raise qubesadmin.exc.QubesException(
             "Failed to list '%s' devices, this device type either "
@@ -105,16 +108,19 @@ def list_devices(args):
             if domain == dev.backend_domain:
                 continue
 
-            for assignment in domain.devices[args.devclass].assignments():
-                if dev != assignment:
-                    continue
-                if assignment.options:
-                    result[dev].frontends.append('{!s} ({})'.format(
-                        domain, ', '.join('{}={}'.format(key, value)
-                                          for key, value in
-                                          assignment.options.items())))
-                else:
-                    result[dev].frontends.append(str(domain))
+            try:
+                for assignment in domain.devices[args.devclass].assignments():
+                    if dev != assignment:
+                        continue
+                    if assignment.options:
+                        result[dev].frontends.append('{!s} ({})'.format(
+                            domain, ', '.join('{}={}'.format(key, value)
+                                              for key, value in
+                                              assignment.options.items())))
+                    else:
+                        result[dev].frontends.append(str(domain))
+            except qubesadmin.exc.QubesVMNotFoundError:
+                continue
 
     qubesadmin.tools.print_table(prepare_table(result.values()))
 
@@ -281,7 +287,8 @@ def main(args=None, app=None):
     if basename.startswith('qvm-') and basename != 'qvm-device':
         devclass = basename[4:]
 
-    args = get_parser(devclass).parse_args(args, app=app)
+    parser = get_parser(devclass)
+    args = parser.parse_args(args, app=app)
 
     if args.list_device_classes:
         print('\n'.join(qubesadmin.Qubes().list_deviceclass()))
@@ -290,7 +297,7 @@ def main(args=None, app=None):
     try:
         args.func(args)
     except qubesadmin.exc.QubesException as e:
-        print(str(e), file=sys.stderr)
+        parser.print_error(str(e))
         return 1
     return 0
 

+ 11 - 3
qubesadmin/tools/qvm_ls.py

@@ -467,17 +467,25 @@ class Table(object):
             table_data.append(self.get_head())
             self.spinner.update()
             if self.tree_sorted:
+                #FIXME: handle qubesadmin.exc.QubesVMNotFoundError
+                #       (see QubesOS/qubes-issues#5105)
                 insertion_vm_list = self.sort_to_tree(self.domains)
                 for insertion, vm in insertion_vm_list:
                     table_data.append(self.get_row(vm, insertion))
             else:
                 for vm in sorted(self.domains):
-                    table_data.append(self.get_row(vm))
+                    try:
+                        table_data.append(self.get_row(vm))
+                    except qubesadmin.exc.QubesVMNotFoundError:
+                        continue
             self.spinner.hide()
             qubesadmin.tools.print_table(table_data, stream=stream)
         else:
             for vm in sorted(self.domains):
-                stream.write('|'.join(self.get_row(vm)) + '\n')
+                try:
+                    stream.write('|'.join(self.get_row(vm)) + '\n')
+                except qubesadmin.exc.QubesVMNotFoundError:
+                    continue
 
 
 #: Available formats. Feel free to plug your own one.
@@ -576,7 +584,7 @@ def get_parser():
     parser = qubesadmin.tools.QubesArgumentParser(
         vmname_nargs=argparse.ZERO_OR_MORE,
         formatter_class=argparse.RawTextHelpFormatter,
-        description='List Qubes domains and their parametres.',
+        description='List Qubes domains and their parameters.',
         epilog='available formats (see --help-formats):\n{}\n\n'
                'available columns (see --help-columns):\n{}'.format(
                 wrapper.fill(', '.join(sorted(formats.keys()))),