diff --git a/doc/manpages/qubes-prefs.rst b/doc/manpages/qubes-prefs.rst index d8b89754..03f7acc2 100644 --- a/doc/manpages/qubes-prefs.rst +++ b/doc/manpages/qubes-prefs.rst @@ -1,8 +1,55 @@ .. program:: qubes-prefs +:program:`qubes-prefs` -- List/set various global properties ============================================================ -:program:`qubes-prefs` -- Display system-wide Qubes settings -============================================================ + +Synopsis +-------- + +:command:`qubes-prefs` [-h] [--xml *XMLFILE*] [--verbose] [--quiet] [--force-root] [--help-properties] [*PROPERTY* [*VALUE*\|--delete]] + +Options +------- + +.. option:: --help, -h + + Show help message and exit. + +.. option:: --help-properties + + List available properties with short descriptions and exit. + +.. option:: --qubesxml=XMLFILE + + Qubes OS store file. + +.. option:: --verbose, -v + + Increase verbosity. + +.. option:: --quiet, -q + + Decrease verbosity. + +.. option:: --force-root + + Force to run as root. + +.. option:: --unset, --default, --delete, -D + + Unset the property. If is has default value, it will be used instead. + + +Common properties +================= + +This list is non-exhaustive. For authoritative listing, see +:option:`--help-properties` and documentation of the source code. + +.. warning:: + + This list is from the core2. It is wrong in many cases, some of them obvious, + some of them not. - clock VM - update VM @@ -11,12 +58,12 @@ - default kernel - default netVM -Synopsis -======== -:command:`qubes-prefs` - Authors -======= +------- + | Joanna Rutkowska | Rafal Wojtczuk | Marek Marczykowski +| Wojtek Porczyk + +.. vim: ts=3 sw=3 et tw=80 diff --git a/qubes/tools/__init__.py b/qubes/tools/__init__.py index 29d63c09..66257840 100644 --- a/qubes/tools/__init__.py +++ b/qubes/tools/__init__.py @@ -86,6 +86,47 @@ class SinglePropertyAction(argparse.Action): if self.const is None else self.const +class HelpPropertiesAction(argparse.Action): + '''Action for argument parser that displays all properties and exits.''' + # pylint: disable=redefined-builtin,too-few-public-methods + def __init__(self, + option_strings, + klass=None, + dest=argparse.SUPPRESS, + default=argparse.SUPPRESS, + help='list all available properties with short descriptions' + ' and exit'): + super(HelpPropertiesAction, self).__init__( + option_strings=option_strings, + dest=dest, + default=default, + nargs=0, + help=help) + + # late import because of circular dependency + import qubes + self._klass = klass if klass is not None else qubes.Qubes + + + def __call__(self, parser, namespace, values, option_string=None): + # pylint: disable=redefined-outer-name + properties = self._klass.property_list() + width = max(len(prop.__name__) for prop in properties) + wrapper = textwrap.TextWrapper(width=80, + initial_indent=' ', subsequent_indent=' ' * (width + 6)) + + text = 'Common properties:\n' + '\n'.join( + wrapper.fill('{name:{width}s} {doc}'.format( + name=prop.__name__, + doc=qubes.utils.format_doc(prop.__doc__) if prop.__doc__ else'', + width=width)) + for prop in sorted(properties)) + if self._klass is not qubes.Qubes: + text += '\n\n' \ + 'There may be more properties in specific domain classes.\n' + parser.exit(message=text) + + class QubesArgumentParser(argparse.ArgumentParser): '''Parser preconfigured for use in most of the Qubes command-line tools. diff --git a/qubes/tools/qubes_prefs.py b/qubes/tools/qubes_prefs.py new file mode 100644 index 00000000..1fc3d363 --- /dev/null +++ b/qubes/tools/qubes_prefs.py @@ -0,0 +1,103 @@ +#!/usr/bin/python2 +# -*- encoding: utf8 -*- +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2010-2015 Joanna Rutkowska +# Copyright (C) 2015 Wojtek Porczyk +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +# TODO merge printing with qvm-prefs +# TODO list only non-default properties + +from __future__ import print_function + +import argparse +import sys +import textwrap + +import qubes +import qubes.tools +import qubes.utils + + +parser = qubes.tools.QubesArgumentParser( + want_force_root=True) + +parser.add_argument('--help-properties', + action=qubes.tools.HelpPropertiesAction) + +parser.add_argument('property', metavar='PROPERTY', + nargs='?', + help='name of the property to show or change') + +parser_value = parser.add_mutually_exclusive_group() + +parser_value.add_argument('value', metavar='VALUE', + nargs='?', + help='new value of the property') + +parser.add_argument('--unset', '--default', '--delete', '-D', + dest='delete', + action='store_true', + help='unset the property; if property has default value, it will be used' + ' instead') + + +def main(): + args = parser.parse_args() + + if args.property is None: + properties = args.app.property_list() + width = max(len(prop.__name__) for prop in properties) + + for prop in sorted(properties): + try: + value = getattr(args.app, prop.__name__) + except AttributeError: + print('{name:{width}s} U'.format( + name=prop.__name__, width=width)) + continue + + if args.app.property_is_default(prop): + print('{name:{width}s} D {value!r}'.format( + name=prop.__name__, width=width, value=value)) + else: + print('{name:{width}s} - {value!r}'.format( + name=prop.__name__, width=width, value=value)) + + return True + + + if args.value is not None: + setattr(args.app, args.property, args.value) + args.app.save() + return True + + if args.delete: + delattr(args.app, args.property) + args.app.save() + return True + + + print(str(getattr(args.app, args.property))) + + return True + + +if __name__ == '__main__': + sys.exit(not main()) diff --git a/qubes/tools/qvm_prefs.py b/qubes/tools/qvm_prefs.py index 7ec74047..be9d297e 100644 --- a/qubes/tools/qvm_prefs.py +++ b/qubes/tools/qvm_prefs.py @@ -36,44 +36,13 @@ import qubes.utils import qubes.vm -class _HelpPropertiesAction(argparse.Action): - '''Action for argument parser that displays all properties and exits.''' - # pylint: disable=redefined-builtin,too-few-public-methods - def __init__(self, - option_strings, - dest=argparse.SUPPRESS, - default=argparse.SUPPRESS, - help='list all available properties with short descriptions' - ' and exit'): - super(_HelpPropertiesAction, self).__init__( - option_strings=option_strings, - dest=dest, - default=default, - nargs=0, - help=help) - - def __call__(self, parser, namespace, values, option_string=None): - # pylint: disable=redefined-outer-name - properties = qubes.vm.qubesvm.QubesVM.property_list() - width = max(len(prop.__name__) for prop in properties) - wrapper = textwrap.TextWrapper(width=80, - initial_indent=' ', subsequent_indent=' ' * (width + 6)) - - text = 'Common properties:\n' + '\n'.join( - wrapper.fill('{name:{width}s} {doc}'.format( - name=prop.__name__, - doc=qubes.utils.format_doc(prop.__doc__) if prop.__doc__ else'', - width=width)) - for prop in sorted(properties)) - parser.exit(message=text - + '\n\nThere may be more properties in specific domain classes.\n') - - parser = qubes.tools.QubesArgumentParser( want_force_root=True, want_vm=True) -parser.add_argument('--help-properties', action=_HelpPropertiesAction) +parser.add_argument('--help-properties', + action=qubes.tools.HelpPropertiesAction, + klass=qubes.vm.qubesvm.QubesVM) parser.add_argument('property', metavar='PROPERTY', nargs='?', diff --git a/rpm_spec/core-dom0.spec b/rpm_spec/core-dom0.spec index 366c109e..a37530d0 100644 --- a/rpm_spec/core-dom0.spec +++ b/rpm_spec/core-dom0.spec @@ -232,6 +232,7 @@ fi %{python_sitelib}/qubes/tools/__init__.py* %{python_sitelib}/qubes/tools/qmemmand.py* %{python_sitelib}/qubes/tools/qubes_create.py* +%{python_sitelib}/qubes/tools/qubes_prefs.py* %{python_sitelib}/qubes/tools/qvm_create.py* %{python_sitelib}/qubes/tools/qvm_kill.py* %{python_sitelib}/qubes/tools/qvm_ls.py*