Merge branch 'improved-tools-messages'
* improved-tools-messages: tools: suppress full traceback in console tools tools: add SubParsersHelpAction, which include subcommands details in --help
This commit is contained in:
commit
a99acc68da
@ -339,7 +339,7 @@ class QubesArgumentParser(argparse.ArgumentParser):
|
||||
def __init__(self, want_app=True, want_app_no_instance=False,
|
||||
vmname_nargs=None, **kwargs):
|
||||
|
||||
super(QubesArgumentParser, self).__init__(**kwargs)
|
||||
super(QubesArgumentParser, self).__init__(add_help=False, **kwargs)
|
||||
|
||||
self._want_app = want_app
|
||||
self._want_app_no_instance = want_app_no_instance
|
||||
@ -360,6 +360,9 @@ class QubesArgumentParser(argparse.ArgumentParser):
|
||||
self.add_argument('--force-root', action='store_true',
|
||||
default=False, help=argparse.SUPPRESS)
|
||||
|
||||
self.add_argument('--help', '-h', action=SubParsersHelpAction,
|
||||
help='show this help message and exit')
|
||||
|
||||
if self._vmname_nargs in [argparse.ZERO_OR_MORE, argparse.ONE_OR_MORE]:
|
||||
vm_name_group = VmNameGroup(self,
|
||||
required=(self._vmname_nargs
|
||||
@ -436,6 +439,37 @@ class QubesArgumentParser(argparse.ArgumentParser):
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
|
||||
class SubParsersHelpAction(argparse._HelpAction):
|
||||
''' Print help for all options _and all subparsers_ '''
|
||||
# source https://stackoverflow.com/a/24122778
|
||||
# pylint: disable=protected-access,too-few-public-methods
|
||||
|
||||
@staticmethod
|
||||
def _indent(indent, text):
|
||||
'''Indent *text* by *indent* spaces'''
|
||||
return '\n'.join((' ' * indent) + l for l in text.splitlines())
|
||||
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
parser.print_help()
|
||||
|
||||
# retrieve subparsers from parser
|
||||
subparsers_actions = [
|
||||
action for action in parser._actions
|
||||
if isinstance(action, argparse._SubParsersAction)]
|
||||
# there will probably only be one subparser_action,
|
||||
# but better save than sorry
|
||||
for subparsers_action in subparsers_actions:
|
||||
# get all subparsers and print help
|
||||
for pseudo_action in subparsers_action._choices_actions:
|
||||
choice = pseudo_action.dest.split(' ', 1)[0]
|
||||
subparser = subparsers_action.choices[choice]
|
||||
print("\nCommand '{}':".format(choice))
|
||||
choice_help = subparser.format_usage()
|
||||
choice_help = self._indent(2, choice_help)
|
||||
print(choice_help)
|
||||
parser.exit()
|
||||
|
||||
|
||||
class AliasedSubParsersAction(argparse._SubParsersAction):
|
||||
'''SubParser with support for action aliases'''
|
||||
# source https://gist.github.com/sampsyo/471779
|
||||
|
@ -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":
|
||||
|
@ -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())
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.")
|
||||
|
@ -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:
|
||||
|
@ -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__':
|
||||
|
Loading…
Reference in New Issue
Block a user