Skip to content

Commit ea39376

Browse files
committed
Add top-like monitoring tool
Inspiration and code from qui-domains and visuals from xentop. - Colors entries according to state - Footer with clock to show last time the screen was refreshed - Allows scrolling domain list when it is longer than the screen height, with a less-type hint indicating how many lines to scroll - To scroll, readline style (Emacs) navigation is supported, with some Vi keys also supported - Inexpensive calls using "admin.vm.Stats"
1 parent 4e4fa79 commit ea39376

5 files changed

Lines changed: 558 additions & 7 deletions

File tree

doc/conf.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,8 @@
366366
u'Manage tags on a qube', _man_pages_author, 1),
367367
('manpages/qvm-template', 'qvm-template',
368368
u'Manage templates', _man_pages_author, 1),
369+
('manpages/qvm-top', 'qvm-top',
370+
u'Top-like monitoring tool', _man_pages_author, 1),
369371
('manpages/qvm-unpause', 'qvm-unpause',
370372
u'Pause a qube', _man_pages_author, 1),
371373
('manpages/qvm-volume', 'qvm-volume',

doc/manpages/qvm-top.rst

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
.. program:: qvm-top
2+
3+
:program:`qvm-top` -- top-like monitoring tool
4+
==============================================
5+
6+
Synopsis
7+
--------
8+
9+
:command:`qvm-top` [--verbose] [--quiet] [--help] [--version] [--all] [--exclude EXCLUDE] [*VMNAME* ...]
10+
11+
Options
12+
-------
13+
14+
.. option:: --help, -h
15+
16+
Show the help message and exit.
17+
18+
.. option:: --verbose, -v
19+
20+
Increase verbosity.
21+
22+
.. option:: --quiet, -q
23+
24+
Decrease verbosity.
25+
26+
.. option:: --all
27+
28+
Show all qubes. It's the default. Pass qubes as positional parameters to
29+
show only those.
30+
31+
.. option:: --exclude=EXCLUDE
32+
33+
Exclude the qube from :option:`--all`.
34+
35+
.. option:: --version
36+
37+
Show program's version number and exit
38+
39+
40+
Notes
41+
-----
42+
43+
Quit by pressing `q`, `Q`, or `ESC`. When scrolling up or down, there is
44+
readline-style (Emacs) navigation, with a pinch of Vi navigation.
45+
46+
Authors
47+
-------
48+
49+
| Benjamin Grande <ben.grande.b at gmail dot com>
50+
| For complete author list see: https://github.com/QubesOS/qubes-core-admin-client.git
51+
52+
.. vim: ts=3 sw=3 et tw=80

doc/qubesadmin.tools.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,14 @@ qubesadmin\.tools\.qvm\_template\_postprocess module
196196
:undoc-members:
197197
:show-inheritance:
198198

199+
qubesadmin\.tools\.qvm\_top module
200+
----------------------------------------------------
201+
202+
.. automodule:: qubesadmin.tools.qvm_top
203+
:members:
204+
:undoc-members:
205+
:show-inheritance:
206+
199207
qubesadmin\.tools\.qvm\_unpause module
200208
--------------------------------------
201209

qubesadmin/tools/__init__.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,18 @@ def parse_qubes_app(self, parser, namespace):
157157
assert hasattr(namespace, 'app')
158158
setattr(namespace, 'domains', [])
159159
app = namespace.app
160-
if hasattr(namespace, 'all_domains') and namespace.all_domains:
160+
if (
161+
hasattr(namespace, 'all_domains')
162+
and namespace.all_domains
163+
and not getattr(namespace, 'VMNAME')
164+
):
161165
namespace.domains = [
162166
vm
163167
for vm in app.domains
164-
if not vm.klass == 'AdminVM' and
165-
vm.name not in namespace.exclude
168+
if (
169+
namespace.all_domains == "global"
170+
or not vm.klass == 'AdminVM'
171+
) and vm.name not in namespace.exclude
166172
]
167173
else:
168174
if hasattr(namespace, 'exclude') and namespace.exclude:
@@ -361,7 +367,7 @@ class QubesArgumentParser(argparse.ArgumentParser):
361367
'''
362368

363369
def __init__(self, vmname_nargs=None, show_forceroot=False, version=None, \
364-
**kwargs):
370+
all_default=False, all_include_adminvm=False, **kwargs):
365371

366372
super().__init__(add_help=False, **kwargs)
367373

@@ -398,7 +404,8 @@ def __init__(self, vmname_nargs=None, show_forceroot=False, version=None, \
398404
self.add_argument('--version', action='version')
399405

400406
if self._vmname_nargs in [argparse.ZERO_OR_MORE, argparse.ONE_OR_MORE]:
401-
vm_name_group = VmNameGroup(self,
407+
vm_name_group = VmNameGroup(self, all_default=all_default,
408+
all_include_adminvm=all_include_adminvm,
402409
required=(self._vmname_nargs
403410
not in [argparse.ZERO_OR_MORE, argparse.OPTIONAL]))
404411
self._mutually_exclusive_groups.append(vm_name_group)
@@ -574,13 +581,16 @@ class VmNameGroup(argparse._MutuallyExclusiveGroup):
574581
:py:class:``argparse.ArgumentParser```.
575582
'''
576583

577-
def __init__(self, container, required, vm_action=VmNameAction, help=None):
584+
def __init__(self, container, required, vm_action=VmNameAction,\
585+
all_default=False, all_include_adminvm=False, help=None):
578586
# pylint: disable=redefined-builtin
579587
super().__init__(container, required=required)
580588
if not help:
581589
help = 'perform the action on all qubes'
590+
if all_default and all_include_adminvm:
591+
all_default = "global"
582592
self.add_argument('--all', action='store_true', dest='all_domains',
583-
help=help)
593+
default=all_default, help=help)
584594
container.add_argument('--exclude', action='append', default=[],
585595
help='exclude the qube from --all')
586596

0 commit comments

Comments
 (0)