pyinfra 0.11.dev3__py3-none-any.whl → 3.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyinfra/__init__.py +9 -12
- pyinfra/__main__.py +4 -0
- pyinfra/api/__init__.py +19 -3
- pyinfra/api/arguments.py +413 -0
- pyinfra/api/arguments_typed.py +79 -0
- pyinfra/api/command.py +274 -0
- pyinfra/api/config.py +222 -28
- pyinfra/api/connect.py +33 -13
- pyinfra/api/connectors.py +27 -0
- pyinfra/api/deploy.py +65 -66
- pyinfra/api/exceptions.py +73 -18
- pyinfra/api/facts.py +267 -200
- pyinfra/api/host.py +416 -50
- pyinfra/api/inventory.py +121 -160
- pyinfra/api/metadata.py +69 -0
- pyinfra/api/operation.py +432 -262
- pyinfra/api/operations.py +273 -260
- pyinfra/api/state.py +302 -248
- pyinfra/api/util.py +309 -369
- pyinfra/connectors/base.py +173 -0
- pyinfra/connectors/chroot.py +212 -0
- pyinfra/connectors/docker.py +405 -0
- pyinfra/connectors/dockerssh.py +297 -0
- pyinfra/connectors/local.py +238 -0
- pyinfra/connectors/scp/__init__.py +1 -0
- pyinfra/connectors/scp/client.py +204 -0
- pyinfra/connectors/ssh.py +727 -0
- pyinfra/connectors/ssh_util.py +114 -0
- pyinfra/connectors/sshuserclient/client.py +309 -0
- pyinfra/connectors/sshuserclient/config.py +102 -0
- pyinfra/connectors/terraform.py +135 -0
- pyinfra/connectors/util.py +417 -0
- pyinfra/connectors/vagrant.py +183 -0
- pyinfra/context.py +145 -0
- pyinfra/facts/__init__.py +7 -6
- pyinfra/facts/apk.py +22 -7
- pyinfra/facts/apt.py +117 -60
- pyinfra/facts/brew.py +100 -15
- pyinfra/facts/bsdinit.py +23 -0
- pyinfra/facts/cargo.py +37 -0
- pyinfra/facts/choco.py +47 -0
- pyinfra/facts/crontab.py +195 -0
- pyinfra/facts/deb.py +94 -0
- pyinfra/facts/dnf.py +48 -0
- pyinfra/facts/docker.py +96 -23
- pyinfra/facts/efibootmgr.py +113 -0
- pyinfra/facts/files.py +629 -58
- pyinfra/facts/flatpak.py +77 -0
- pyinfra/facts/freebsd.py +70 -0
- pyinfra/facts/gem.py +19 -6
- pyinfra/facts/git.py +59 -14
- pyinfra/facts/gpg.py +150 -0
- pyinfra/facts/hardware.py +313 -167
- pyinfra/facts/iptables.py +72 -62
- pyinfra/facts/launchd.py +44 -0
- pyinfra/facts/lxd.py +17 -4
- pyinfra/facts/mysql.py +122 -86
- pyinfra/facts/npm.py +17 -9
- pyinfra/facts/openrc.py +71 -0
- pyinfra/facts/opkg.py +246 -0
- pyinfra/facts/pacman.py +50 -7
- pyinfra/facts/pip.py +24 -7
- pyinfra/facts/pipx.py +82 -0
- pyinfra/facts/pkg.py +15 -6
- pyinfra/facts/pkgin.py +35 -0
- pyinfra/facts/podman.py +54 -0
- pyinfra/facts/postgres.py +178 -0
- pyinfra/facts/postgresql.py +6 -147
- pyinfra/facts/rpm.py +105 -0
- pyinfra/facts/runit.py +77 -0
- pyinfra/facts/selinux.py +161 -0
- pyinfra/facts/server.py +762 -285
- pyinfra/facts/snap.py +88 -0
- pyinfra/facts/systemd.py +139 -0
- pyinfra/facts/sysvinit.py +59 -0
- pyinfra/facts/upstart.py +35 -0
- pyinfra/facts/util/__init__.py +17 -0
- pyinfra/facts/util/databases.py +4 -6
- pyinfra/facts/util/packaging.py +37 -6
- pyinfra/facts/util/units.py +30 -0
- pyinfra/facts/util/win_files.py +99 -0
- pyinfra/facts/vzctl.py +20 -13
- pyinfra/facts/xbps.py +35 -0
- pyinfra/facts/yum.py +34 -40
- pyinfra/facts/zfs.py +77 -0
- pyinfra/facts/zypper.py +42 -0
- pyinfra/local.py +45 -83
- pyinfra/operations/__init__.py +12 -0
- pyinfra/operations/apk.py +99 -0
- pyinfra/operations/apt.py +496 -0
- pyinfra/operations/brew.py +232 -0
- pyinfra/operations/bsdinit.py +59 -0
- pyinfra/operations/cargo.py +45 -0
- pyinfra/operations/choco.py +61 -0
- pyinfra/operations/crontab.py +194 -0
- pyinfra/operations/dnf.py +213 -0
- pyinfra/operations/docker.py +492 -0
- pyinfra/operations/files.py +2014 -0
- pyinfra/operations/flatpak.py +95 -0
- pyinfra/operations/freebsd/__init__.py +12 -0
- pyinfra/operations/freebsd/freebsd_update.py +70 -0
- pyinfra/operations/freebsd/pkg.py +219 -0
- pyinfra/operations/freebsd/service.py +116 -0
- pyinfra/operations/freebsd/sysrc.py +92 -0
- pyinfra/operations/gem.py +48 -0
- pyinfra/operations/git.py +420 -0
- pyinfra/operations/iptables.py +312 -0
- pyinfra/operations/launchd.py +45 -0
- pyinfra/operations/lxd.py +69 -0
- pyinfra/operations/mysql.py +610 -0
- pyinfra/operations/npm.py +57 -0
- pyinfra/operations/openrc.py +63 -0
- pyinfra/operations/opkg.py +89 -0
- pyinfra/operations/pacman.py +82 -0
- pyinfra/operations/pip.py +206 -0
- pyinfra/operations/pipx.py +103 -0
- pyinfra/operations/pkg.py +71 -0
- pyinfra/operations/pkgin.py +92 -0
- pyinfra/operations/postgres.py +437 -0
- pyinfra/operations/postgresql.py +30 -0
- pyinfra/operations/puppet.py +41 -0
- pyinfra/operations/python.py +73 -0
- pyinfra/operations/runit.py +184 -0
- pyinfra/operations/selinux.py +190 -0
- pyinfra/operations/server.py +1100 -0
- pyinfra/operations/snap.py +118 -0
- pyinfra/operations/ssh.py +217 -0
- pyinfra/operations/systemd.py +150 -0
- pyinfra/operations/sysvinit.py +142 -0
- pyinfra/operations/upstart.py +68 -0
- pyinfra/operations/util/__init__.py +12 -0
- pyinfra/operations/util/docker.py +407 -0
- pyinfra/operations/util/files.py +247 -0
- pyinfra/operations/util/packaging.py +338 -0
- pyinfra/operations/util/service.py +46 -0
- pyinfra/operations/vzctl.py +137 -0
- pyinfra/operations/xbps.py +78 -0
- pyinfra/operations/yum.py +213 -0
- pyinfra/operations/zfs.py +176 -0
- pyinfra/operations/zypper.py +193 -0
- pyinfra/progress.py +44 -32
- pyinfra/py.typed +0 -0
- pyinfra/version.py +9 -1
- pyinfra-3.6.dist-info/METADATA +142 -0
- pyinfra-3.6.dist-info/RECORD +160 -0
- {pyinfra-0.11.dev3.dist-info → pyinfra-3.6.dist-info}/WHEEL +1 -2
- pyinfra-3.6.dist-info/entry_points.txt +12 -0
- {pyinfra-0.11.dev3.dist-info → pyinfra-3.6.dist-info/licenses}/LICENSE.md +1 -1
- pyinfra_cli/__init__.py +1 -0
- pyinfra_cli/cli.py +793 -0
- pyinfra_cli/commands.py +66 -0
- pyinfra_cli/exceptions.py +155 -65
- pyinfra_cli/inventory.py +233 -89
- pyinfra_cli/log.py +39 -43
- pyinfra_cli/main.py +26 -495
- pyinfra_cli/prints.py +215 -156
- pyinfra_cli/util.py +172 -105
- pyinfra_cli/virtualenv.py +25 -20
- pyinfra/api/connectors/__init__.py +0 -21
- pyinfra/api/connectors/ansible.py +0 -99
- pyinfra/api/connectors/docker.py +0 -178
- pyinfra/api/connectors/local.py +0 -169
- pyinfra/api/connectors/ssh.py +0 -402
- pyinfra/api/connectors/sshuserclient/client.py +0 -105
- pyinfra/api/connectors/sshuserclient/config.py +0 -90
- pyinfra/api/connectors/util.py +0 -63
- pyinfra/api/connectors/vagrant.py +0 -155
- pyinfra/facts/init.py +0 -176
- pyinfra/facts/util/files.py +0 -102
- pyinfra/hook.py +0 -41
- pyinfra/modules/__init__.py +0 -11
- pyinfra/modules/apk.py +0 -64
- pyinfra/modules/apt.py +0 -272
- pyinfra/modules/brew.py +0 -122
- pyinfra/modules/files.py +0 -711
- pyinfra/modules/gem.py +0 -30
- pyinfra/modules/git.py +0 -115
- pyinfra/modules/init.py +0 -344
- pyinfra/modules/iptables.py +0 -271
- pyinfra/modules/lxd.py +0 -45
- pyinfra/modules/mysql.py +0 -347
- pyinfra/modules/npm.py +0 -47
- pyinfra/modules/pacman.py +0 -60
- pyinfra/modules/pip.py +0 -99
- pyinfra/modules/pkg.py +0 -43
- pyinfra/modules/postgresql.py +0 -245
- pyinfra/modules/puppet.py +0 -20
- pyinfra/modules/python.py +0 -37
- pyinfra/modules/server.py +0 -524
- pyinfra/modules/ssh.py +0 -150
- pyinfra/modules/util/files.py +0 -52
- pyinfra/modules/util/packaging.py +0 -118
- pyinfra/modules/vzctl.py +0 -133
- pyinfra/modules/yum.py +0 -171
- pyinfra/pseudo_modules.py +0 -64
- pyinfra-0.11.dev3.dist-info/.DS_Store +0 -0
- pyinfra-0.11.dev3.dist-info/METADATA +0 -135
- pyinfra-0.11.dev3.dist-info/RECORD +0 -95
- pyinfra-0.11.dev3.dist-info/entry_points.txt +0 -3
- pyinfra-0.11.dev3.dist-info/top_level.txt +0 -2
- pyinfra_cli/__main__.py +0 -40
- pyinfra_cli/config.py +0 -92
- /pyinfra/{modules/util → connectors}/__init__.py +0 -0
- /pyinfra/{api/connectors → connectors}/sshuserclient/__init__.py +0 -0
pyinfra_cli/prints.py
CHANGED
|
@@ -1,26 +1,33 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import json
|
|
4
|
+
import platform
|
|
2
5
|
import re
|
|
6
|
+
import sys
|
|
7
|
+
from typing import TYPE_CHECKING, Callable, Dict, Iterator, List, Tuple, Union
|
|
3
8
|
|
|
4
9
|
import click
|
|
5
10
|
|
|
6
|
-
from pyinfra import logger
|
|
7
|
-
from pyinfra.api.facts import get_fact_names
|
|
11
|
+
from pyinfra import __version__, logger
|
|
8
12
|
from pyinfra.api.host import Host
|
|
9
|
-
from pyinfra.api.operation import get_operation_names
|
|
10
13
|
|
|
11
14
|
from .util import json_encode
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from pyinfra.api.state import State
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
ANSI_RE = re.compile(r"\033\[((?:\d|;)*)([a-zA-Z])")
|
|
14
21
|
|
|
15
22
|
|
|
16
23
|
def _strip_ansi(value):
|
|
17
|
-
return ANSI_RE.sub(
|
|
24
|
+
return ANSI_RE.sub("", value)
|
|
18
25
|
|
|
19
26
|
|
|
20
|
-
def _get_group_combinations(inventory):
|
|
21
|
-
group_combinations = {}
|
|
27
|
+
def _get_group_combinations(inventory: Iterator[Host]):
|
|
28
|
+
group_combinations: Dict[Tuple, List[Host]] = {}
|
|
22
29
|
|
|
23
|
-
for host in inventory
|
|
30
|
+
for host in inventory:
|
|
24
31
|
# Tuple for hashability, set to normalise order
|
|
25
32
|
host_groups = tuple(set(host.groups))
|
|
26
33
|
|
|
@@ -45,34 +52,32 @@ def jsonify(data, *args, **kwargs):
|
|
|
45
52
|
return json.dumps(data, *args, **kwargs)
|
|
46
53
|
|
|
47
54
|
|
|
48
|
-
def
|
|
49
|
-
|
|
50
|
-
print('--> Facts:')
|
|
51
|
-
print(jsonify(state.facts, indent=4, default=json_encode))
|
|
55
|
+
def print_state_operations(state: "State"):
|
|
56
|
+
state_ops = {host: ops for host, ops in state.ops.items() if state.is_host_in_limit(host)}
|
|
52
57
|
|
|
58
|
+
click.echo(err=True)
|
|
59
|
+
click.echo("--> Operations:", err=True)
|
|
60
|
+
click.echo(jsonify(state_ops, indent=4, default=json_encode), err=True)
|
|
61
|
+
click.echo(err=True)
|
|
62
|
+
click.echo("--> Operation meta:", err=True)
|
|
63
|
+
click.echo(jsonify(state.op_meta, indent=4, default=json_encode), err=True)
|
|
53
64
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
print(jsonify(state.ops, indent=4, default=json_encode))
|
|
58
|
-
print()
|
|
59
|
-
print('--> Operation meta:')
|
|
60
|
-
print(jsonify(state.op_meta, indent=4, default=json_encode))
|
|
61
|
-
|
|
62
|
-
print()
|
|
63
|
-
print('--> Operation order:')
|
|
64
|
-
print()
|
|
65
|
+
click.echo(err=True)
|
|
66
|
+
click.echo("--> Operation order:", err=True)
|
|
67
|
+
click.echo(err=True)
|
|
65
68
|
for op_hash in state.get_op_order():
|
|
66
69
|
meta = state.op_meta[op_hash]
|
|
67
|
-
hosts = set(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
hosts = set(host for host, operations in state.ops.items() if op_hash in operations)
|
|
71
|
+
|
|
72
|
+
click.echo(
|
|
73
|
+
" {0} (names={1}, hosts={2})".format(
|
|
74
|
+
op_hash,
|
|
75
|
+
meta.names,
|
|
76
|
+
hosts,
|
|
77
|
+
),
|
|
78
|
+
err=True,
|
|
70
79
|
)
|
|
71
80
|
|
|
72
|
-
print(' {0} (names={1}, hosts={2})'.format(
|
|
73
|
-
op_hash, meta['names'], hosts,
|
|
74
|
-
))
|
|
75
|
-
|
|
76
81
|
|
|
77
82
|
def print_groups_by_comparison(print_items, comparator=lambda item: item[0]):
|
|
78
83
|
items = []
|
|
@@ -84,79 +89,110 @@ def print_groups_by_comparison(print_items, comparator=lambda item: item[0]):
|
|
|
84
89
|
items.append(name)
|
|
85
90
|
|
|
86
91
|
else:
|
|
87
|
-
|
|
88
|
-
click.style(name, bold=True)
|
|
89
|
-
|
|
90
|
-
)
|
|
92
|
+
click.echo(
|
|
93
|
+
" {0}".format(", ".join((click.style(name, bold=True) for name in items))),
|
|
94
|
+
err=True,
|
|
95
|
+
)
|
|
91
96
|
|
|
92
97
|
items = [name]
|
|
93
98
|
|
|
94
99
|
last_name = name
|
|
95
100
|
|
|
96
101
|
if items:
|
|
97
|
-
|
|
98
|
-
click.style(name, bold=True)
|
|
99
|
-
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
def print_facts_list():
|
|
104
|
-
fact_names = sorted(get_fact_names())
|
|
105
|
-
print_groups_by_comparison(fact_names)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def print_operations_list():
|
|
109
|
-
operation_names = sorted(get_operation_names())
|
|
110
|
-
print_groups_by_comparison(
|
|
111
|
-
operation_names,
|
|
112
|
-
comparator=lambda item: item.split('.')[0],
|
|
113
|
-
)
|
|
102
|
+
click.echo(
|
|
103
|
+
" {0}".format(", ".join((click.style(name, bold=True) for name in items))),
|
|
104
|
+
err=True,
|
|
105
|
+
)
|
|
114
106
|
|
|
115
107
|
|
|
116
108
|
def print_fact(fact_data):
|
|
117
|
-
|
|
109
|
+
click.echo(jsonify(fact_data, indent=4, default=json_encode), err=True)
|
|
118
110
|
|
|
119
111
|
|
|
120
|
-
def print_inventory(state):
|
|
112
|
+
def print_inventory(state: "State"):
|
|
121
113
|
for host in state.inventory:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
print(jsonify(host.data, indent=4, default=json_encode))
|
|
114
|
+
click.echo(err=True)
|
|
115
|
+
click.echo(host.print_prefix, err=True)
|
|
116
|
+
click.echo("--> Groups: {0}".format(", ".join(host.groups)), err=True)
|
|
117
|
+
click.echo("--> Data:", err=True)
|
|
118
|
+
click.echo(jsonify(host.data, indent=4, default=json_encode), err=True)
|
|
128
119
|
|
|
129
120
|
|
|
130
121
|
def print_facts(facts):
|
|
131
122
|
for name, data in facts.items():
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
123
|
+
click.echo(err=True)
|
|
124
|
+
click.echo(
|
|
125
|
+
"--> Fact data for: {0}".format(
|
|
126
|
+
click.style(name, bold=True),
|
|
127
|
+
),
|
|
128
|
+
err=True,
|
|
129
|
+
)
|
|
136
130
|
print_fact(data)
|
|
137
131
|
|
|
138
132
|
|
|
133
|
+
def print_support_info() -> None:
|
|
134
|
+
from importlib.metadata import PackageNotFoundError, requires, version
|
|
135
|
+
|
|
136
|
+
from packaging.requirements import Requirement
|
|
137
|
+
|
|
138
|
+
click.echo(
|
|
139
|
+
"""
|
|
140
|
+
If you are having issues with pyinfra or wish to make feature requests, please
|
|
141
|
+
check out the GitHub issues at https://github.com/Fizzadar/pyinfra/issues .
|
|
142
|
+
When adding an issue, be sure to include the following:
|
|
143
|
+
""",
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
click.echo(" System: {0}".format(platform.system()), err=True)
|
|
147
|
+
click.echo(" Platform: {0}".format(platform.platform()), err=True)
|
|
148
|
+
click.echo(" Release: {0}".format(platform.uname()[2]), err=True)
|
|
149
|
+
click.echo(" Machine: {0}".format(platform.uname()[4]), err=True)
|
|
150
|
+
click.echo(" pyinfra: v{0}".format(__version__), err=True)
|
|
151
|
+
|
|
152
|
+
seen_reqs: set[str] = set()
|
|
153
|
+
for requirement_string in sorted(requires("pyinfra") or []):
|
|
154
|
+
requirement = Requirement(requirement_string)
|
|
155
|
+
if requirement.name in seen_reqs:
|
|
156
|
+
continue
|
|
157
|
+
seen_reqs.add(requirement.name)
|
|
158
|
+
try:
|
|
159
|
+
click.echo(
|
|
160
|
+
" {0}: v{1}".format(requirement.name, version(requirement.name)),
|
|
161
|
+
err=True,
|
|
162
|
+
)
|
|
163
|
+
except PackageNotFoundError:
|
|
164
|
+
# package not installed in this environment
|
|
165
|
+
continue
|
|
166
|
+
|
|
167
|
+
click.echo(" Executable: {0}".format(sys.argv[0]), err=True)
|
|
168
|
+
click.echo(
|
|
169
|
+
" Python: {0} ({1}, {2})".format(
|
|
170
|
+
platform.python_version(),
|
|
171
|
+
platform.python_implementation(),
|
|
172
|
+
platform.python_compiler(),
|
|
173
|
+
),
|
|
174
|
+
err=True,
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
|
|
139
178
|
def print_rows(rows):
|
|
140
179
|
# Go through the rows and work out all the widths in each column
|
|
141
|
-
|
|
180
|
+
row_column_widths: list[list[int]] = []
|
|
142
181
|
|
|
143
182
|
for _, columns in rows:
|
|
144
183
|
if isinstance(columns, str):
|
|
145
184
|
continue
|
|
146
185
|
|
|
147
186
|
for i, column in enumerate(columns):
|
|
148
|
-
if i >= len(
|
|
149
|
-
|
|
187
|
+
if i >= len(row_column_widths):
|
|
188
|
+
row_column_widths.append([])
|
|
150
189
|
|
|
151
190
|
# Length of the column (with ansi codes removed)
|
|
152
191
|
width = len(_strip_ansi(column.strip()))
|
|
153
|
-
|
|
192
|
+
row_column_widths[i].append(width)
|
|
154
193
|
|
|
155
194
|
# Get the max width of each column and add 4 padding spaces
|
|
156
|
-
column_widths = [
|
|
157
|
-
max(widths) + 4
|
|
158
|
-
for widths in column_widths
|
|
159
|
-
]
|
|
195
|
+
column_widths = [max(widths) + 4 for widths in row_column_widths]
|
|
160
196
|
|
|
161
197
|
# Now print each column, keeping text justified to the widths above
|
|
162
198
|
for func, columns in rows:
|
|
@@ -170,115 +206,138 @@ def print_rows(rows):
|
|
|
170
206
|
desired_width = column_widths[i]
|
|
171
207
|
padding = desired_width - len(stripped)
|
|
172
208
|
|
|
173
|
-
justified.append(
|
|
174
|
-
|
|
175
|
-
|
|
209
|
+
justified.append(
|
|
210
|
+
"{0}{1}".format(
|
|
211
|
+
column,
|
|
212
|
+
" ".join("" for _ in range(padding)),
|
|
213
|
+
),
|
|
214
|
+
)
|
|
176
215
|
|
|
177
|
-
line =
|
|
216
|
+
line = "".join(justified)
|
|
178
217
|
|
|
179
218
|
func(line)
|
|
180
219
|
|
|
181
220
|
|
|
182
|
-
def
|
|
183
|
-
|
|
184
|
-
|
|
221
|
+
def truncate(text, max_length):
|
|
222
|
+
if len(text) <= max_length:
|
|
223
|
+
return text
|
|
185
224
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
host for host in hosts
|
|
189
|
-
if state.is_host_in_limit(host)
|
|
190
|
-
]
|
|
225
|
+
text = text[: max_length - 3]
|
|
226
|
+
return f"{text}..."
|
|
191
227
|
|
|
192
|
-
if not hosts:
|
|
193
|
-
continue # pragma: no cover
|
|
194
228
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
click.style(' / '.join(groups), bold=True),
|
|
198
|
-
)))
|
|
199
|
-
else:
|
|
200
|
-
rows.append((logger.info, 'Ungrouped:'))
|
|
229
|
+
def pretty_op_name(op_meta):
|
|
230
|
+
name = list(op_meta.names)[0]
|
|
201
231
|
|
|
202
|
-
|
|
203
|
-
|
|
232
|
+
if op_meta.args:
|
|
233
|
+
name = "{0} ({1})".format(name, ", ".join(str(arg) for arg in op_meta.args))
|
|
234
|
+
|
|
235
|
+
return name
|
|
204
236
|
|
|
205
|
-
# Didn't connect to this host?
|
|
206
|
-
if host not in state.activated_hosts:
|
|
207
|
-
rows.append((logger.info, [
|
|
208
|
-
host.style_print_prefix('red', bold=True),
|
|
209
|
-
click.style('No connection', 'red'),
|
|
210
|
-
]))
|
|
211
|
-
continue
|
|
212
237
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
]))
|
|
238
|
+
def print_meta(state: "State"):
|
|
239
|
+
rows: List[Tuple[Callable, Union[List[str], str]]] = [
|
|
240
|
+
(logger.info, ["Operation", "Change", "Conditional Change"]),
|
|
241
|
+
]
|
|
218
242
|
|
|
219
|
-
|
|
220
|
-
|
|
243
|
+
for op_hash in state.get_op_order():
|
|
244
|
+
hosts_in_op = []
|
|
245
|
+
hosts_maybe_in_op = []
|
|
246
|
+
for host in state.inventory.iter_activated_hosts():
|
|
247
|
+
if op_hash in state.ops[host]:
|
|
248
|
+
op_data = state.get_op_data_for_host(host, op_hash)
|
|
249
|
+
if op_data.operation_meta._maybe_is_change:
|
|
250
|
+
if op_data.global_arguments["_if"]:
|
|
251
|
+
hosts_maybe_in_op.append(host.name)
|
|
252
|
+
else:
|
|
253
|
+
hosts_in_op.append(host.name)
|
|
254
|
+
|
|
255
|
+
rows.append(
|
|
256
|
+
(
|
|
257
|
+
logger.info,
|
|
258
|
+
[
|
|
259
|
+
pretty_op_name(state.op_meta[op_hash]),
|
|
260
|
+
(
|
|
261
|
+
"-"
|
|
262
|
+
if len(hosts_in_op) == 0
|
|
263
|
+
else "{0} ({1})".format(
|
|
264
|
+
len(hosts_in_op),
|
|
265
|
+
truncate(", ".join(sorted(hosts_in_op)), 48),
|
|
266
|
+
)
|
|
267
|
+
),
|
|
268
|
+
(
|
|
269
|
+
"-"
|
|
270
|
+
if len(hosts_maybe_in_op) == 0
|
|
271
|
+
else "{0} ({1})".format(
|
|
272
|
+
len(hosts_maybe_in_op),
|
|
273
|
+
truncate(", ".join(sorted(hosts_maybe_in_op)), 48),
|
|
274
|
+
)
|
|
275
|
+
),
|
|
276
|
+
],
|
|
277
|
+
)
|
|
278
|
+
)
|
|
221
279
|
|
|
222
280
|
print_rows(rows)
|
|
223
281
|
|
|
224
282
|
|
|
225
|
-
def print_results(state):
|
|
226
|
-
|
|
227
|
-
|
|
283
|
+
def print_results(state: "State"):
|
|
284
|
+
rows: List[Tuple[Callable, Union[List[str], str]]] = [
|
|
285
|
+
(logger.info, ["Operation", "Hosts", "Success", "Error", "No Change"]),
|
|
286
|
+
]
|
|
287
|
+
|
|
288
|
+
totals = {"hosts": 0, "success": 0, "error": 0, "no_change": 0}
|
|
228
289
|
|
|
229
|
-
for
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
290
|
+
for op_hash in state.get_op_order():
|
|
291
|
+
hosts_in_op = 0
|
|
292
|
+
hosts_in_op_success: list[str] = []
|
|
293
|
+
hosts_in_op_error: list[str] = []
|
|
294
|
+
hosts_in_op_no_change: list[str] = []
|
|
295
|
+
for host in state.inventory.iter_activated_hosts():
|
|
296
|
+
if op_hash not in state.ops[host]:
|
|
297
|
+
continue
|
|
298
|
+
|
|
299
|
+
hosts_in_op += 1
|
|
300
|
+
|
|
301
|
+
op_meta = state.ops[host][op_hash].operation_meta
|
|
302
|
+
if op_meta.did_succeed(_raise_if_not_complete=False):
|
|
303
|
+
if op_meta.did_change():
|
|
304
|
+
hosts_in_op_success.append(host.name)
|
|
305
|
+
else:
|
|
306
|
+
hosts_in_op_no_change.append(host.name)
|
|
307
|
+
else:
|
|
308
|
+
hosts_in_op_error.append(host.name)
|
|
309
|
+
|
|
310
|
+
row = [
|
|
311
|
+
pretty_op_name(state.op_meta[op_hash]),
|
|
312
|
+
str(hosts_in_op),
|
|
233
313
|
]
|
|
234
314
|
|
|
235
|
-
|
|
236
|
-
continue
|
|
315
|
+
totals["hosts"] += hosts_in_op
|
|
237
316
|
|
|
238
|
-
if
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
317
|
+
if hosts_in_op_success:
|
|
318
|
+
num_hosts_in_op_success = len(hosts_in_op_success)
|
|
319
|
+
row.append(str(num_hosts_in_op_success))
|
|
320
|
+
totals["success"] += num_hosts_in_op_success
|
|
242
321
|
else:
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
for host in hosts:
|
|
246
|
-
# Didn't conenct to this host?
|
|
247
|
-
if host not in state.activated_hosts:
|
|
248
|
-
rows.append((logger.info, [
|
|
249
|
-
host.style_print_prefix('red', bold=True),
|
|
250
|
-
click.style('No connection', 'red'),
|
|
251
|
-
]))
|
|
252
|
-
continue
|
|
253
|
-
|
|
254
|
-
results = state.results[host]
|
|
322
|
+
row.append("-")
|
|
255
323
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
324
|
+
if hosts_in_op_error:
|
|
325
|
+
num_hosts_in_op_error = len(hosts_in_op_error)
|
|
326
|
+
row.append(str(num_hosts_in_op_error))
|
|
327
|
+
totals["error"] += num_hosts_in_op_error
|
|
328
|
+
else:
|
|
329
|
+
row.append("-")
|
|
259
330
|
|
|
260
|
-
|
|
261
|
-
|
|
331
|
+
if hosts_in_op_no_change:
|
|
332
|
+
num_hosts_in_op_no_change = len(hosts_in_op_no_change)
|
|
333
|
+
row.append(str(num_hosts_in_op_no_change))
|
|
334
|
+
totals["no_change"] += num_hosts_in_op_no_change
|
|
335
|
+
else:
|
|
336
|
+
row.append("-")
|
|
262
337
|
|
|
263
|
-
|
|
264
|
-
if results['ops'] == meta['ops']:
|
|
265
|
-
# We had some errors - but we ignored them - so "warning" color
|
|
266
|
-
if error_ops != 0:
|
|
267
|
-
host_args = ('yellow',)
|
|
338
|
+
rows.append((logger.info, row))
|
|
268
339
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
host_args = ('red',)
|
|
272
|
-
host_kwargs['bold'] = True
|
|
273
|
-
|
|
274
|
-
rows.append((logger.info, [
|
|
275
|
-
host.style_print_prefix(*host_args, **host_kwargs),
|
|
276
|
-
'Successful: {0}'.format(click.style(str(success_ops), bold=True)),
|
|
277
|
-
'Errors: {0}'.format(click.style(str(error_ops), bold=True)),
|
|
278
|
-
'Commands: {0}/{1}'.format(results['commands'], meta['commands']),
|
|
279
|
-
]))
|
|
280
|
-
|
|
281
|
-
if i != len(group_combinations):
|
|
282
|
-
rows.append((print, []))
|
|
340
|
+
totals_row = ["Grand total"] + [str(i) if i else "-" for i in totals.values()]
|
|
341
|
+
rows.append((logger.info, totals_row))
|
|
283
342
|
|
|
284
343
|
print_rows(rows)
|