Переглянути джерело

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 роки тому
батько
коміт
6ca54e18a3

+ 7 - 3
qubesadmin/tools/qvm_backup.py

@@ -157,9 +157,13 @@ def main(args=None, app=None):
     else:
     else:
         profile_name = args.profile
         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 not args.yes:
         if input("Do you want to proceed? [y/N] ").upper() != "Y":
         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 sys
 
 
+import qubesadmin.exc
 from qubesadmin.tools import QubesArgumentParser
 from qubesadmin.tools import QubesArgumentParser
 
 
 parser = QubesArgumentParser(description=__doc__, vmname_nargs=1)
 parser = QubesArgumentParser(description=__doc__, vmname_nargs=1)
@@ -70,7 +71,10 @@ def main(args=None, app=None):
                 parser.error(
                 parser.error(
                     'Pool argument must be of form: -P volume_name=pool_name')
                     '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__':
 if __name__ == '__main__':
     sys.exit(main())
     sys.exit(main())

+ 13 - 3
qubesadmin/tools/qvm_features.py

@@ -63,8 +63,11 @@ def main(args=None, app=None):
         if args.delete:
         if args.delete:
             parser.error('--unset requires a feature')
             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:
     elif args.delete:
         if args.value is not None:
         if args.value is not None:
@@ -73,6 +76,8 @@ def main(args=None, app=None):
             del vm.features[args.feature]
             del vm.features[args.feature]
         except KeyError:
         except KeyError:
             pass
             pass
+        except qubesadmin.exc.QubesException as e:
+            parser.error_runtime(e)
 
 
     elif args.value is None:
     elif args.value is None:
         try:
         try:
@@ -80,8 +85,13 @@ def main(args=None, app=None):
             return 0
             return 0
         except KeyError:
         except KeyError:
             return 1
             return 1
+        except qubesadmin.exc.QubesException as e:
+            parser.error_runtime(e)
     else:
     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
     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)
             args.app.remove_pool(args.name)
         except KeyError:
         except KeyError:
             parser.print_error('no such pool %s\n' % args.name)
             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':
     elif args.command == 'info':
         for pool in args.pools:
         for pool in args.pools:
             pool_info(pool)
             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)
             setattr(target, args.property, args.value)
         except AttributeError:
         except AttributeError:
             parser.error('no such property: {!r}'.format(args.property))
             parser.error('no such property: {!r}'.format(args.property))
+        except qubesadmin.exc.QubesException as e:
+            parser.error_runtime(e)
         return 0
         return 0
 
 
     if args.delete:
     if args.delete:
@@ -123,6 +125,8 @@ def process_actions(parser, args, target):
             delattr(target, args.property)
             delattr(target, args.property)
         except AttributeError:
         except AttributeError:
             parser.error('no such property: {!r}'.format(args.property))
             parser.error('no such property: {!r}'.format(args.property))
+        except qubesadmin.exc.QubesException as e:
+            parser.error_runtime(e)
         return 0
         return 0
 
 
     try:
     try:
@@ -131,6 +135,8 @@ def process_actions(parser, args, target):
             print(str(value))
             print(str(value))
     except AttributeError:
     except AttributeError:
         parser.error('no such property: {!r}'.format(args.property))
         parser.error('no such property: {!r}'.format(args.property))
+    except qubesadmin.exc.QubesException as e:
+        parser.error_runtime(e)
 
 
     return 0
     return 0
 
 

+ 5 - 1
qubesadmin/tools/qvm_remove.py

@@ -23,6 +23,7 @@
 
 
 import sys
 import sys
 
 
+import qubesadmin.exc
 from qubesadmin.tools import QubesArgumentParser
 from qubesadmin.tools import QubesArgumentParser
 
 
 parser = QubesArgumentParser(description=__doc__,
 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":
     if args.no_confirm or go_ahead == "Y":
         for vm in args.domains:
         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
         retcode = 0
     else:
     else:
         print("Remove cancelled.")
         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:
                     except qubesadmin.exc.QubesVMNotStartedError:
                         # already shut down
                         # already shut down
                         pass
                         pass
+                    except qubesadmin.exc.QubesException as e:
+                        parser.error_runtime(e)
         else:
         else:
             timeout = args.timeout
             timeout = args.timeout
             current_vms = list(sorted(this_round_domains))
             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:
                 except qubesadmin.exc.QubesVMNotStartedError:
                     # already shut down
                     # already shut down
                     pass
                     pass
+                except qubesadmin.exc.QubesException as e:
+                    parser.error_runtime(e)
 
 
     if args.wait:
     if args.wait:
         if have_events:
         if have_events:

+ 5 - 1
qubesadmin/tools/qvm_tags.py

@@ -26,6 +26,7 @@ from __future__ import print_function
 import sys
 import sys
 
 
 import qubesadmin
 import qubesadmin
+import qubesadmin.exc
 import qubesadmin.tools
 import qubesadmin.tools
 
 
 def mode_query(args):
 def mode_query(args):
@@ -101,7 +102,10 @@ def main(args=None, app=None):
 
 
     parser = get_parser()
     parser = get_parser()
     args = parser.parse_args(args, app=app)
     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__':
 if __name__ == '__main__':