forked from QubesOS/qubes-mgmt-salt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
qubesctl
executable file
·112 lines (100 loc) · 4.38 KB
/
qubesctl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/python3
"""
Directly call a salt command in the modules, does not require a running salt
minion to run.
"""
from __future__ import print_function
import argparse
import sys
import subprocess
import qubessalt
import qubesadmin
import qubesadmin.vm
def main(args=None): # pylint: disable=missing-docstring
parser = argparse.ArgumentParser()
parser.add_argument('--show-output', action='store_true',
help='Show output of management commands')
parser.add_argument('--force-color', action='store_true',
help='Force color output, allow control characters '
'from VM, UNSAFE')
parser.add_argument('--skip-dom0', action='store_true',
help='Skip dom0 configuration (VM creation etc)')
parser.add_argument('--max-concurrency', action='store',
help='Maximum number of VMs configured simultaneously '
'(default: %(default)d)',
type=int, default=4)
group = parser.add_mutually_exclusive_group()
group.add_argument('--targets', action='store',
help='Comma separated list of VMs to target')
group.add_argument('--templates', action='store_true',
help='Target all TemplatesVMs')
group.add_argument('--standalones', action='store_true',
help='Target all StandaloneVMs')
group.add_argument('--app', action='store_true',
help='Target all AppVMs')
group.add_argument('--all', action='store_true',
help='Target all non-disposable VMs (TemplateVMs and '
'AppVMs)')
parser.add_argument('command',
help='Salt command to execute (for example: '
'state.highstate)',
nargs=argparse.REMAINDER)
args = parser.parse_args(args)
if not args.skip_dom0:
try:
# TODO handle args.show_output - if false, log to some file
subprocess.check_call(['qubesctl', '--dom0-only'] + args.command)
except subprocess.CalledProcessError:
print("DOM0 configuration failed, not continuing", file=sys.stderr)
return 1
app = qubesadmin.Qubes()
# Load VM list only after dom0 salt call - some new VMs might be created
targets = []
if args.templates:
targets += [vm for vm in app.domains.values()
if vm.klass == 'TemplateVM']
if args.standalones:
targets += [vm for vm in app.domains.values()
if vm.klass == 'StandaloneVM']
if args.app:
targets += [vm for vm in app.domains.values()
if vm.klass == 'AppVM']
if args.all:
# all but DispVMs
targets = [vm for vm in app.domains.values()
if not vm.klass == 'DispVM']
elif args.targets:
names = args.targets.split(',')
targets = [vm for vm in app.domains.values() if vm.name in names]
# remove dom0 - already handled
targets = [vm for vm in targets if vm.name != 'dom0']
if args.show_output and args.force_color:
args.command.insert(0, '--force-color')
# templates first
vms_to_go = [vm for vm in targets
if vm.klass == 'TemplateVM']
runner = qubessalt.ManageVMRunner(app, vms_to_go, args.command,
show_output=args.show_output,
force_color=args.force_color,
max_concurrency=args.max_concurrency)
exit_code = runner.run()
# then non-templates (AppVMs)
vms_to_go = [vm for vm in targets
if not vm.klass == 'TemplateVM']
runner = qubessalt.ManageVMRunner(app, vms_to_go, args.command,
show_output=args.show_output,
force_color=args.force_color,
max_concurrency=args.max_concurrency)
return max(exit_code, runner.run())
if __name__ == '__main__':
# --dom0-only is a passthrough to salt-call
if len(sys.argv) > 1 and sys.argv[1] == '--dom0-only':
try:
import qubes.mgmt.patches
except ImportError:
pass
from salt.scripts import salt_call
sys.argv[1] = '--local'
salt_call()
else:
sys.exit(main())