qvm-ls: add filtering by domain power state
This commit is contained in:
		
							parent
							
								
									427f4587e5
								
							
						
					
					
						commit
						4cd513757b
					
				| @ -6,7 +6,7 @@ | |||||||
| Synopsis | Synopsis | ||||||
| -------- | -------- | ||||||
| 
 | 
 | ||||||
| :command:`qvm-ls` [-h] [--verbose] [--quiet] [--help-columns] [--help-formats] [--format *FORMAT* | --fields *FIELD*,...] [--tags *TAG* [*TAG* ...]] | :command:`qvm-ls` [-h] [--verbose] [--quiet] [--help-columns] [--help-formats] [--format *FORMAT* | --fields *FIELD*,...] [--tags *TAG* [*TAG* ...]] [--running] [--paused] [--halted] | ||||||
| 
 | 
 | ||||||
| Options | Options | ||||||
| ------- | ------- | ||||||
| @ -47,6 +47,11 @@ Options | |||||||
| 
 | 
 | ||||||
|    Shows only VMs having specific tag(s). |    Shows only VMs having specific tag(s). | ||||||
| 
 | 
 | ||||||
|  | .. option:: --running, --paused, --halted | ||||||
|  | 
 | ||||||
|  |    Shows only VMs matching the specified power state(s). When none of these | ||||||
|  |    options is used (default), all VMs are shown. | ||||||
|  | 
 | ||||||
| .. option:: --raw-data | .. option:: --raw-data | ||||||
| 
 | 
 | ||||||
|    Output data in easy to parse format. Table header is skipped and columns are |    Output data in easy to parse format. Table header is skipped and columns are | ||||||
|  | |||||||
| @ -175,6 +175,42 @@ class TC_70_Tags(qubesadmin.tests.QubesTestCase): | |||||||
|             'NAME  STATE  CLASS  LABEL  TEMPLATE  NETVM\n') |             'NAME  STATE  CLASS  LABEL  TEMPLATE  NETVM\n') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class TC_80_Power_state_filters(qubesadmin.tests.QubesTestCase): | ||||||
|  |     def setUp(self): | ||||||
|  |         self.app = TestApp() | ||||||
|  |         self.app.domains = TestVMCollection( | ||||||
|  |             [ | ||||||
|  |                 ('a', TestVM('a', power_state='Halted')), | ||||||
|  |                 ('b', TestVM('b', power_state='Transient')), | ||||||
|  |                 ('c', TestVM('c', power_state='Running')) | ||||||
|  |             ] | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     def test_100_nofilter(self): | ||||||
|  |         with qubesadmin.tests.tools.StdoutBuffer() as stdout: | ||||||
|  |             qubesadmin.tools.qvm_ls.main([], app=self.app) | ||||||
|  |         self.assertEqual(stdout.getvalue(), | ||||||
|  |             'NAME  STATE      CLASS   LABEL  TEMPLATE  NETVM\n' | ||||||
|  |             'a     Halted     TestVM  -      -         -\n' | ||||||
|  |             'b     Transient  TestVM  -      -         -\n' | ||||||
|  |             'c     Running    TestVM  -      -         -\n') | ||||||
|  | 
 | ||||||
|  |     def test_100_running(self): | ||||||
|  |         with qubesadmin.tests.tools.StdoutBuffer() as stdout: | ||||||
|  |             qubesadmin.tools.qvm_ls.main(['--running'], app=self.app) | ||||||
|  |         self.assertEqual(stdout.getvalue(), | ||||||
|  |             'NAME  STATE    CLASS   LABEL  TEMPLATE  NETVM\n' | ||||||
|  |             'c     Running  TestVM  -      -         -\n') | ||||||
|  | 
 | ||||||
|  |     def test_100_running_or_halted(self): | ||||||
|  |         with qubesadmin.tests.tools.StdoutBuffer() as stdout: | ||||||
|  |             qubesadmin.tools.qvm_ls.main(['--running', '--halted'], app=self.app) | ||||||
|  |         self.assertEqual(stdout.getvalue(), | ||||||
|  |             'NAME  STATE    CLASS   LABEL  TEMPLATE  NETVM\n' | ||||||
|  |             'a     Halted   TestVM  -      -         -\n' | ||||||
|  |             'c     Running  TestVM  -      -         -\n') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class TC_90_List_with_qubesd_calls(qubesadmin.tests.QubesTestCase): | class TC_90_List_with_qubesd_calls(qubesadmin.tests.QubesTestCase): | ||||||
|     def test_100_list_with_status(self): |     def test_100_list_with_status(self): | ||||||
|         self.app.expected_calls[ |         self.app.expected_calls[ | ||||||
|  | |||||||
| @ -494,6 +494,21 @@ class _HelpFormatsAction(argparse.Action): | |||||||
|         parser.exit(message=text) |         parser.exit(message=text) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | # common VM power states for easy command-line filtering | ||||||
|  | DOMAIN_POWER_STATES = ['running', 'paused', 'halted'] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def matches_power_states(domain, **states): | ||||||
|  |     '''Filter domains by their power state''' | ||||||
|  |     # if all values are False (default) => return match on every VM | ||||||
|  |     if not states or set(states.values()) == {False}: | ||||||
|  |         return True | ||||||
|  | 
 | ||||||
|  |     # otherwise => only VMs matching True states | ||||||
|  |     requested_states = [state for state, active in states.items() if active] | ||||||
|  |     return domain.get_power_state().lower() in requested_states | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def get_parser(): | def get_parser(): | ||||||
|     '''Create :py:class:`argparse.ArgumentParser` suitable for |     '''Create :py:class:`argparse.ArgumentParser` suitable for | ||||||
|     :program:`qvm-ls`. |     :program:`qvm-ls`. | ||||||
| @ -531,6 +546,10 @@ def get_parser(): | |||||||
|     parser.add_argument('--tags', nargs='+', metavar='TAG', |     parser.add_argument('--tags', nargs='+', metavar='TAG', | ||||||
|         help='show only VMs having specific tag(s)') |         help='show only VMs having specific tag(s)') | ||||||
| 
 | 
 | ||||||
|  |     for pwrstate in DOMAIN_POWER_STATES: | ||||||
|  |         parser.add_argument('--{}'.format(pwrstate), action='store_true', | ||||||
|  |             help='show {} VMs'.format(pwrstate)) | ||||||
|  | 
 | ||||||
|     parser.add_argument('--raw-data', action='store_true', |     parser.add_argument('--raw-data', action='store_true', | ||||||
|         help='Display specify data of specified VMs. Intended for ' |         help='Display specify data of specified VMs. Intended for ' | ||||||
|              'bash-parsing.') |              'bash-parsing.') | ||||||
| @ -614,6 +633,9 @@ def main(args=None, app=None): | |||||||
|         domains = [dom for dom in domains |         domains = [dom for dom in domains | ||||||
|                    if set(dom.tags).intersection(set(args.tags))] |                    if set(dom.tags).intersection(set(args.tags))] | ||||||
| 
 | 
 | ||||||
|  |     pwrstates = {state: getattr(args, state) for state in DOMAIN_POWER_STATES} | ||||||
|  |     domains = filter(lambda x: matches_power_states(x, **pwrstates), domains) | ||||||
|  | 
 | ||||||
|     table = Table(domains, columns, spinner, args.raw_data) |     table = Table(domains, columns, spinner, args.raw_data) | ||||||
|     table.write_table(sys.stdout) |     table.write_table(sys.stdout) | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Patrik Hagara
						Patrik Hagara