From cd4424235ba6f27b80aff1da8cf213e8ccf9a000 Mon Sep 17 00:00:00 2001 From: Patrik Hagara Date: Thu, 23 Aug 2018 22:42:22 +0200 Subject: [PATCH] qvm-ls: add filtering by tags --- doc/manpages/qvm-ls.rst | 6 +++- qubesadmin/tests/tools/qvm_ls.py | 54 ++++++++++++++++++++++++++++++++ qubesadmin/tools/qvm_ls.py | 9 ++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/doc/manpages/qvm-ls.rst b/doc/manpages/qvm-ls.rst index 8811825..5ca0650 100644 --- a/doc/manpages/qvm-ls.rst +++ b/doc/manpages/qvm-ls.rst @@ -6,7 +6,7 @@ Synopsis -------- -:command:`qvm-ls` [-h] [--verbose] [--quiet] [--help-columns] [--help-formats] [--format *FORMAT* | --fields *FIELD*,...] +:command:`qvm-ls` [-h] [--verbose] [--quiet] [--help-columns] [--help-formats] [--format *FORMAT* | --fields *FIELD*,...] [--tags *TAG* [*TAG* ...]] Options ------- @@ -43,6 +43,10 @@ Options :option:`--format`. All columns along with short descriptions can be listed with :option:`--help-columns`. +.. option:: --tags TAG ... + + Shows only VMs having specific tag(s). + .. option:: --raw-data Output data in easy to parse format. Table header is skipped and columns are diff --git a/qubesadmin/tests/tools/qvm_ls.py b/qubesadmin/tests/tools/qvm_ls.py index cb9f6fc..7bc3c53 100644 --- a/qubesadmin/tests/tools/qvm_ls.py +++ b/qubesadmin/tests/tools/qvm_ls.py @@ -121,6 +121,60 @@ class TC_50_List(qubesadmin.tests.QubesTestCase): 'test-vm\n') +class TC_70_Tags(qubesadmin.tests.QubesTestCase): + def setUp(self): + self.app = TestApp() + self.app.domains = TestVMCollection( + [ + ( + 'dom0', + TestVM( + 'dom0', + tags=['my'], + label='black' + ) + ), + ( + 'test-vm', + TestVM( + 'test-vm', + tags=['not-my', 'other'], + label='red', + netvm=TestVM('sys-firewall'), + template=TestVM('template') + ) + ), + ] + ) + + def test_100_tag(self): + with qubesadmin.tests.tools.StdoutBuffer() as stdout: + qubesadmin.tools.qvm_ls.main(['--tags', 'my'], app=self.app) + self.assertEqual(stdout.getvalue(), + 'NAME STATE CLASS LABEL TEMPLATE NETVM\n' + 'dom0 Running TestVM black - -\n') + + def test_100_tag_nomatch(self): + with qubesadmin.tests.tools.StdoutBuffer() as stdout: + qubesadmin.tools.qvm_ls.main(['--tags', 'nx'], app=self.app) + self.assertEqual(stdout.getvalue(), + 'NAME STATE CLASS LABEL TEMPLATE NETVM\n') + + def test_100_tags(self): + with qubesadmin.tests.tools.StdoutBuffer() as stdout: + qubesadmin.tools.qvm_ls.main(['--tags', 'my', 'other'], app=self.app) + self.assertEqual(stdout.getvalue(), + 'NAME STATE CLASS LABEL TEMPLATE NETVM\n' + 'dom0 Running TestVM black - -\n' + 'test-vm Running TestVM red template sys-firewall\n') + + def test_100_tags_nomatch(self): + with qubesadmin.tests.tools.StdoutBuffer() as stdout: + qubesadmin.tools.qvm_ls.main(['--tags', 'nx1', 'nx2'], app=self.app) + self.assertEqual(stdout.getvalue(), + 'NAME STATE CLASS LABEL TEMPLATE NETVM\n') + + class TC_90_List_with_qubesd_calls(qubesadmin.tests.QubesTestCase): def test_100_list_with_status(self): self.app.expected_calls[ diff --git a/qubesadmin/tools/qvm_ls.py b/qubesadmin/tools/qvm_ls.py index 14cefe8..5b52657 100644 --- a/qubesadmin/tools/qvm_ls.py +++ b/qubesadmin/tools/qvm_ls.py @@ -528,6 +528,9 @@ def get_parser(): help='user specified format (see available columns below)') + parser.add_argument('--tags', nargs='+', metavar='TAG', + help='show only VMs having specific tag(s)') + parser.add_argument('--raw-data', action='store_true', help='Display specify data of specified VMs. Intended for ' 'bash-parsing.') @@ -605,6 +608,12 @@ def main(args=None, app=None): domains = args.domains else: domains = args.app.domains + + if args.tags: + # filter only VMs having at least one of the specified tags + domains = [dom for dom in domains + if set(dom.tags).intersection(set(args.tags))] + table = Table(domains, columns, spinner, args.raw_data) table.write_table(sys.stdout)