qubes/tools/qvm-features: add tool for managing qvm-features
QubesOS/qubes-issues#1637
This commit is contained in:
parent
a65b0edcd4
commit
e757444c35
14
Makefile
14
Makefile
@ -67,16 +67,18 @@ endif
|
||||
$(MAKE) install -C dispvm
|
||||
mkdir -p $(DESTDIR)/etc/qubes-rpc/policy
|
||||
mkdir -p $(DESTDIR)/usr/libexec/qubes
|
||||
cp qubes-rpc-policy/qubes.FeaturesRequest.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.FeaturesRequest
|
||||
cp qubes-rpc-policy/qubes.Filecopy.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.Filecopy
|
||||
cp qubes-rpc-policy/qubes.OpenInVM.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.OpenInVM
|
||||
cp qubes-rpc-policy/qubes.VMShell.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMShell
|
||||
cp qubes-rpc-policy/qubes.NotifyUpdates.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyUpdates
|
||||
cp qubes-rpc-policy/qubes.NotifyTools.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyTools
|
||||
cp qubes-rpc-policy/qubes.GetImageRGBA.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.GetImageRGBA
|
||||
cp qubes-rpc-policy/qubes.GetRandomizedTime.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.GetRandomizedTime
|
||||
cp qubes-rpc/qubes.NotifyUpdates $(DESTDIR)/etc/qubes-rpc/
|
||||
cp qubes-rpc/qubes.NotifyTools $(DESTDIR)/etc/qubes-rpc/
|
||||
cp qubes-rpc-policy/qubes.NotifyTools.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyTools
|
||||
cp qubes-rpc-policy/qubes.NotifyUpdates.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyUpdates
|
||||
cp qubes-rpc-policy/qubes.OpenInVM.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.OpenInVM
|
||||
cp qubes-rpc-policy/qubes.VMShell.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMShell
|
||||
cp qubes-rpc/qubes.FeaturesRequest $(DESTDIR)/etc/qubes-rpc/
|
||||
cp qubes-rpc/qubes.GetRandomizedTime $(DESTDIR)/etc/qubes-rpc/
|
||||
cp qubes-rpc/qubes.NotifyTools $(DESTDIR)/etc/qubes-rpc/
|
||||
cp qubes-rpc/qubes.NotifyUpdates $(DESTDIR)/etc/qubes-rpc/
|
||||
cp qubes-rpc/qubes-notify-updates $(DESTDIR)/usr/libexec/qubes/
|
||||
cp qubes-rpc/qubes-notify-tools $(DESTDIR)/usr/libexec/qubes/
|
||||
|
||||
|
53
doc/manpages/qvm-features.rst
Normal file
53
doc/manpages/qvm-features.rst
Normal file
@ -0,0 +1,53 @@
|
||||
.. program:: qvm-features
|
||||
|
||||
:program:`qvm-features` -- manage domain's features
|
||||
===================================================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
:command:`qvm-features` [-h] [--verbose] [--quiet] *VMNAME* [*FEATURE* [*VALUE*]]
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
.. option:: --help, -h
|
||||
|
||||
show this help message and exit
|
||||
|
||||
.. option:: --verbose, -v
|
||||
|
||||
increase verbosity
|
||||
|
||||
.. option:: --quiet, -q
|
||||
|
||||
decrease verbosity
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
This command is used to manually manage the *features* of the domain. The
|
||||
features are key-value pairs with both key and value being strings. They are
|
||||
used by extensions to store information about the domain and make policy
|
||||
decisions based on them. For example, they may indicate that some specific
|
||||
software package was installed inside the template and the domains based on it
|
||||
have some specific capability.
|
||||
|
||||
.. warning::
|
||||
|
||||
The features are normally managed by the extensions themselves and you should
|
||||
not change them directly. Strange things might happen otherwise.
|
||||
|
||||
Some extensions interpret the values as boolean. In this case, the empty string
|
||||
means :py:obj:`False` and non-empty string (commonly ``'1'``) means
|
||||
:py:obj:`True`. An absence of the feature means "default", which is
|
||||
extension-dependent.
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
| Joanna Rutkowska <joanna 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
|
6
qubes-rpc-policy/qubes.FeaturesRequest.policy
Normal file
6
qubes-rpc-policy/qubes.FeaturesRequest.policy
Normal file
@ -0,0 +1,6 @@
|
||||
## Note that policy parsing stops at the first match,
|
||||
## so adding anything below "$anyvm $anyvm action" line will have no effect
|
||||
|
||||
## Please use a single # to start your custom comments
|
||||
|
||||
$anyvm dom0 allow
|
13
qubes-rpc/qubes.FeaturesRequest
Executable file
13
qubes-rpc/qubes.FeaturesRequest
Executable file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
import os
|
||||
import qubes
|
||||
|
||||
PREFIX = '/features-request/'
|
||||
|
||||
app = qubes.Qubes()
|
||||
vm = app.domains[os.environ['QREXEC_REMOTE_DOMAIN']]
|
||||
vm.fire_event('features-request',
|
||||
untrusted_features={key[len(PREFIX):]: vm.qdb.read(key)
|
||||
for key in vm.qdb.list(PREFIX)})
|
||||
app.save()
|
101
qubes/tools/qvm_features.py
Normal file
101
qubes/tools/qvm_features.py
Normal file
@ -0,0 +1,101 @@
|
||||
#!/usr/bin/python2 -O
|
||||
# vim: fileencoding=utf-8
|
||||
|
||||
#
|
||||
# The Qubes OS Project, https://www.qubes-os.org/
|
||||
#
|
||||
# Copyright (C) 2010-2016 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
||||
# Copyright (C) 2016 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.
|
||||
#
|
||||
|
||||
'''qvm-features - Manage domain's features'''
|
||||
|
||||
import argparse
|
||||
import qubes
|
||||
|
||||
parser = qubes.tools.QubesArgumentParser(
|
||||
want_vm=True,
|
||||
description='manage domain\'s features')
|
||||
|
||||
parser.add_argument('--request',
|
||||
action='store_true', default=False,
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('feature', metavar='FEATURE',
|
||||
action='store', nargs='?',
|
||||
help='name of the feature')
|
||||
|
||||
parser.add_argument('value', metavar='VALUE',
|
||||
action='store', nargs='?',
|
||||
help='new value of the feature')
|
||||
|
||||
parser.add_argument('--unset', '--default', '--delete', '-D',
|
||||
dest='delete',
|
||||
action='store_true',
|
||||
help='unset the feature')
|
||||
|
||||
|
||||
def main(args=None):
|
||||
'''Main routine of :program:`qvm-features`.
|
||||
|
||||
:param list args: Optional arguments to override those delivered from \
|
||||
command line.
|
||||
'''
|
||||
|
||||
args = parser.parse_args(args)
|
||||
|
||||
if args.request:
|
||||
# Request mode: instead of setting the features directly,
|
||||
# let the extensions handle them first.
|
||||
args.vm.fire_event('feature-request', untrusted_features=args.features)
|
||||
return 0
|
||||
|
||||
if args.feature is None:
|
||||
if args.delete:
|
||||
parser.error('--unset requires a feature')
|
||||
|
||||
width = max(len(feature) for feature in args.vm.features)
|
||||
for feature in sorted(args.vm.features):
|
||||
print('{name:{width}s} {value}'.format(
|
||||
name=feature, value=args.vm.features[feature], width=width))
|
||||
|
||||
return 0
|
||||
|
||||
if args.delete:
|
||||
if args.value is not None:
|
||||
parser.error('cannot both set and unset a value')
|
||||
try:
|
||||
del args.vm.features[args.feature]
|
||||
args.app.save()
|
||||
except KeyError:
|
||||
pass
|
||||
return 0
|
||||
|
||||
if args.value is None:
|
||||
try:
|
||||
print(args.vm.features[args.feature])
|
||||
return 0
|
||||
except KeyError:
|
||||
return 1
|
||||
|
||||
args.vm.features[args.feature] = args.value
|
||||
args.app.save()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
@ -243,6 +243,7 @@ fi
|
||||
%{python_sitelib}/qubes/tools/qubes_monitor_layout_notify.py*
|
||||
%{python_sitelib}/qubes/tools/qubes_prefs.py*
|
||||
%{python_sitelib}/qubes/tools/qvm_create.py*
|
||||
%{python_sitelib}/qubes/tools/qvm_features.py*
|
||||
%{python_sitelib}/qubes/tools/qvm_kill.py*
|
||||
%{python_sitelib}/qubes/tools/qvm_ls.py*
|
||||
%{python_sitelib}/qubes/tools/qvm_pause.py*
|
||||
@ -340,16 +341,18 @@ fi
|
||||
/etc/xen/scripts/block-snapshot
|
||||
/etc/xen/scripts/block-origin
|
||||
/etc/xen/scripts/vif-route-qubes
|
||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.FeaturesRequest
|
||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.Filecopy
|
||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.GetImageRGBA
|
||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.OpenInVM
|
||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.GetRandomizedTime
|
||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.NotifyTools
|
||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.NotifyUpdates
|
||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.OpenInVM
|
||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMShell
|
||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.GetRandomizedTime
|
||||
/etc/qubes-rpc/qubes.FeaturesRequest
|
||||
/etc/qubes-rpc/qubes.GetRandomizedTime
|
||||
/etc/qubes-rpc/qubes.NotifyTools
|
||||
/etc/qubes-rpc/qubes.NotifyUpdates
|
||||
/etc/qubes-rpc/qubes.GetRandomizedTime
|
||||
%attr(2770,root,qubes) %dir /var/log/qubes
|
||||
%attr(0770,root,qubes) %dir /var/run/qubes
|
||||
/etc/xdg/autostart/qubes-guid.desktop
|
||||
|
Loading…
Reference in New Issue
Block a user