Selaa lähdekoodia

qubes/tools: add qubes-prefs

fixes QubesOS/qubes-issues#1209
Wojtek Porczyk 8 vuotta sitten
vanhempi
commit
7b30361fa6

+ 54 - 7
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 <joanna at invisiblethingslab dot com>
 | Rafal Wojtczuk <rafal at invisiblethingslab dot com>
 | Marek Marczykowski <marmarek at invisiblethingslab dot com>
+| Wojtek Porczyk <woju at invisiblethingslab dot com>
+
+.. vim: ts=3 sw=3 et tw=80

+ 41 - 0
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.
 

+ 103 - 0
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 <joanna@invisiblethingslab.com>
+# Copyright (C) 2015       Wojtek Porczyk <woju@invisiblethingslab.com>
+#
+# 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())

+ 3 - 34
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='?',

+ 1 - 0
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*