Browse Source

tools: suppress full traceback in console tools

QubesException class is used with meaningful messages and should be ok
to use it directly as error message. For other exceptions, still use
full traceback (most likely a bug somewhere, not user error).

Fixes QubesOS/qubes-issues#3610
Marek Marczykowski-Górecki 6 years ago
parent
commit
6ca54e18a3

+ 7 - 3
qubesadmin/tools/qvm_backup.py

@@ -157,9 +157,13 @@ def main(args=None, app=None):
     else:
         profile_name = args.profile
 
-    backup_summary = args.app.qubesd_call(
-        'dom0', 'admin.backup.Info', profile_name)
-    print(backup_summary.decode())
+    try:
+        backup_summary = args.app.qubesd_call(
+            'dom0', 'admin.backup.Info', profile_name)
+        print(backup_summary.decode())
+    except QubesException as err:
+        print('\nBackup preparation error: {}'.format(err), file=sys.stderr)
+        return 1
 
     if not args.yes:
         if input("Do you want to proceed? [y/N] ").upper() != "Y":

+ 5 - 1
qubesadmin/tools/qvm_clone.py

@@ -24,6 +24,7 @@
 
 import sys
 
+import qubesadmin.exc
 from qubesadmin.tools import QubesArgumentParser
 
 parser = QubesArgumentParser(description=__doc__, vmname_nargs=1)
@@ -70,7 +71,10 @@ def main(args=None, app=None):
                 parser.error(
                     'Pool argument must be of form: -P volume_name=pool_name')
 
-    app.clone_vm(src_vm, new_name, new_cls=args.cls, pool=pool, pools=pools)
+    try:
+        app.clone_vm(src_vm, new_name, new_cls=args.cls, pool=pool, pools=pools)
+    except qubesadmin.exc.QubesException as e:
+        parser.error_runtime(e)
 
 if __name__ == '__main__':
     sys.exit(main())

+ 13 - 3
qubesadmin/tools/qvm_features.py

@@ -63,8 +63,11 @@ def main(args=None, app=None):
         if args.delete:
             parser.error('--unset requires a feature')
 
-        features = [(feat, vm.features[feat]) for feat in vm.features]
-        qubesadmin.tools.print_table(features)
+        try:
+            features = [(feat, vm.features[feat]) for feat in vm.features]
+            qubesadmin.tools.print_table(features)
+        except qubesadmin.exc.QubesException as e:
+            parser.error_runtime(e)
 
     elif args.delete:
         if args.value is not None:
@@ -73,6 +76,8 @@ def main(args=None, app=None):
             del vm.features[args.feature]
         except KeyError:
             pass
+        except qubesadmin.exc.QubesException as e:
+            parser.error_runtime(e)
 
     elif args.value is None:
         try:
@@ -80,8 +85,13 @@ def main(args=None, app=None):
             return 0
         except KeyError:
             return 1
+        except qubesadmin.exc.QubesException as e:
+            parser.error_runtime(e)
     else:
-        vm.features[args.feature] = args.value
+        try:
+            vm.features[args.feature] = args.value
+        except qubesadmin.exc.QubesException as e:
+            parser.error_runtime(e)
 
     return 0
 

+ 2 - 0
qubesadmin/tools/qvm_pool.py

@@ -168,6 +168,8 @@ def main(args=None, app=None):
             args.app.remove_pool(args.name)
         except KeyError:
             parser.print_error('no such pool %s\n' % args.name)
+        except qubesadmin.exc.QubesException as e:
+            parser.error('failed to remove pool %s: %s\n' % (args.name, str(e)))
     elif args.command == 'info':
         for pool in args.pools:
             pool_info(pool)

+ 6 - 0
qubesadmin/tools/qvm_prefs.py

@@ -116,6 +116,8 @@ def process_actions(parser, args, target):
             setattr(target, args.property, args.value)
         except AttributeError:
             parser.error('no such property: {!r}'.format(args.property))
+        except qubesadmin.exc.QubesException as e:
+            parser.error_runtime(e)
         return 0
 
     if args.delete:
@@ -123,6 +125,8 @@ def process_actions(parser, args, target):
             delattr(target, args.property)
         except AttributeError:
             parser.error('no such property: {!r}'.format(args.property))
+        except qubesadmin.exc.QubesException as e:
+            parser.error_runtime(e)
         return 0
 
     try:
@@ -131,6 +135,8 @@ def process_actions(parser, args, target):
             print(str(value))
     except AttributeError:
         parser.error('no such property: {!r}'.format(args.property))
+    except qubesadmin.exc.QubesException as e:
+        parser.error_runtime(e)
 
     return 0
 

+ 5 - 1
qubesadmin/tools/qvm_remove.py

@@ -23,6 +23,7 @@
 
 import sys
 
+import qubesadmin.exc
 from qubesadmin.tools import QubesArgumentParser
 
 parser = QubesArgumentParser(description=__doc__,
@@ -44,7 +45,10 @@ def main(args=None, app=None):  # pylint: disable=missing-docstring
 
     if args.no_confirm or go_ahead == "Y":
         for vm in args.domains:
-            del args.app.domains[vm.name]
+            try:
+                del args.app.domains[vm.name]
+            except qubesadmin.exc.QubesException as e:
+                parser.error_runtime(e)
         retcode = 0
     else:
         print("Remove cancelled.")

+ 4 - 0
qubesadmin/tools/qvm_shutdown.py

@@ -92,6 +92,8 @@ def main(args=None, app=None):  # pylint: disable=missing-docstring
                     except qubesadmin.exc.QubesVMNotStartedError:
                         # already shut down
                         pass
+                    except qubesadmin.exc.QubesException as e:
+                        parser.error_runtime(e)
         else:
             timeout = args.timeout
             current_vms = list(sorted(this_round_domains))
@@ -114,6 +116,8 @@ def main(args=None, app=None):  # pylint: disable=missing-docstring
                 except qubesadmin.exc.QubesVMNotStartedError:
                     # already shut down
                     pass
+                except qubesadmin.exc.QubesException as e:
+                    parser.error_runtime(e)
 
     if args.wait:
         if have_events:

+ 5 - 1
qubesadmin/tools/qvm_tags.py

@@ -26,6 +26,7 @@ from __future__ import print_function
 import sys
 
 import qubesadmin
+import qubesadmin.exc
 import qubesadmin.tools
 
 def mode_query(args):
@@ -101,7 +102,10 @@ def main(args=None, app=None):
 
     parser = get_parser()
     args = parser.parse_args(args, app=app)
-    return args.func(args)
+    try:
+        return args.func(args)
+    except qubesadmin.exc.QubesException as e:
+        parser.error_runtime(e)
 
 
 if __name__ == '__main__':