pyinfra 0.11.dev3__py3-none-any.whl → 3.5.1__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 +18 -3
- pyinfra/api/arguments.py +406 -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 +67 -18
- pyinfra/api/facts.py +253 -202
- pyinfra/api/host.py +413 -50
- pyinfra/api/inventory.py +121 -160
- pyinfra/api/operation.py +432 -262
- pyinfra/api/operations.py +273 -260
- pyinfra/api/state.py +302 -248
- pyinfra/api/util.py +291 -368
- pyinfra/connectors/base.py +173 -0
- pyinfra/connectors/chroot.py +212 -0
- pyinfra/connectors/docker.py +381 -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 +670 -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 +410 -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 +630 -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 +746 -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 +98 -0
- pyinfra/operations/apt.py +488 -0
- pyinfra/operations/brew.py +231 -0
- pyinfra/operations/bsdinit.py +59 -0
- pyinfra/operations/cargo.py +45 -0
- pyinfra/operations/choco.py +61 -0
- pyinfra/operations/crontab.py +191 -0
- pyinfra/operations/dnf.py +210 -0
- pyinfra/operations/docker.py +446 -0
- pyinfra/operations/files.py +1939 -0
- pyinfra/operations/flatpak.py +94 -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 +47 -0
- pyinfra/operations/git.py +419 -0
- pyinfra/operations/iptables.py +311 -0
- pyinfra/operations/launchd.py +45 -0
- pyinfra/operations/lxd.py +68 -0
- pyinfra/operations/mysql.py +609 -0
- pyinfra/operations/npm.py +57 -0
- pyinfra/operations/openrc.py +63 -0
- pyinfra/operations/opkg.py +88 -0
- pyinfra/operations/pacman.py +81 -0
- pyinfra/operations/pip.py +205 -0
- pyinfra/operations/pipx.py +102 -0
- pyinfra/operations/pkg.py +70 -0
- pyinfra/operations/pkgin.py +91 -0
- pyinfra/operations/postgres.py +436 -0
- pyinfra/operations/postgresql.py +30 -0
- pyinfra/operations/puppet.py +40 -0
- pyinfra/operations/python.py +72 -0
- pyinfra/operations/runit.py +184 -0
- pyinfra/operations/selinux.py +189 -0
- pyinfra/operations/server.py +1099 -0
- pyinfra/operations/snap.py +117 -0
- pyinfra/operations/ssh.py +216 -0
- pyinfra/operations/systemd.py +149 -0
- pyinfra/operations/sysvinit.py +141 -0
- pyinfra/operations/upstart.py +68 -0
- pyinfra/operations/util/__init__.py +12 -0
- pyinfra/operations/util/docker.py +251 -0
- pyinfra/operations/util/files.py +247 -0
- pyinfra/operations/util/packaging.py +336 -0
- pyinfra/operations/util/service.py +46 -0
- pyinfra/operations/vzctl.py +137 -0
- pyinfra/operations/xbps.py +77 -0
- pyinfra/operations/yum.py +210 -0
- pyinfra/operations/zfs.py +175 -0
- pyinfra/operations/zypper.py +192 -0
- pyinfra/progress.py +44 -32
- pyinfra/py.typed +0 -0
- pyinfra/version.py +9 -1
- pyinfra-3.5.1.dist-info/METADATA +141 -0
- pyinfra-3.5.1.dist-info/RECORD +159 -0
- {pyinfra-0.11.dev3.dist-info → pyinfra-3.5.1.dist-info}/WHEEL +1 -2
- pyinfra-3.5.1.dist-info/entry_points.txt +12 -0
- {pyinfra-0.11.dev3.dist-info → pyinfra-3.5.1.dist-info/licenses}/LICENSE.md +1 -1
- pyinfra_cli/__init__.py +1 -0
- pyinfra_cli/cli.py +780 -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/facts/yum.py
CHANGED
|
@@ -1,53 +1,47 @@
|
|
|
1
|
-
import
|
|
1
|
+
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from typing_extensions import override
|
|
4
4
|
|
|
5
|
-
from .
|
|
5
|
+
from pyinfra.api import FactBase
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
from .util import make_cat_files_command
|
|
8
|
+
from .util.packaging import parse_yum_repositories
|
|
8
9
|
|
|
9
10
|
|
|
10
|
-
class
|
|
11
|
-
|
|
12
|
-
Returns a
|
|
11
|
+
class YumRepositories(FactBase):
|
|
12
|
+
"""
|
|
13
|
+
Returns a list of installed yum repositories:
|
|
13
14
|
|
|
14
15
|
.. code:: python
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
[
|
|
18
|
+
{
|
|
19
|
+
"repoid": "baseos",
|
|
20
|
+
"name": "AlmaLinux $releasever - BaseOS",
|
|
21
|
+
"mirrorlist": "https://mirrors.almalinux.org/mirrorlist/$releasever/baseos",
|
|
22
|
+
"enabled": "1",
|
|
23
|
+
"gpgcheck": "1",
|
|
24
|
+
"countme": "1",
|
|
25
|
+
"gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux-9",
|
|
26
|
+
"metadata_expire": "86400",
|
|
27
|
+
"enabled_metadata": "1"
|
|
28
|
+
},
|
|
29
|
+
]
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
@override
|
|
33
|
+
def command(self) -> str:
|
|
34
|
+
return make_cat_files_command(
|
|
35
|
+
"/etc/yum.conf",
|
|
36
|
+
"/etc/yum.repos.d/*.repo",
|
|
28
37
|
)
|
|
29
38
|
|
|
39
|
+
@override
|
|
40
|
+
def requires_command(self) -> str:
|
|
41
|
+
return "yum"
|
|
30
42
|
|
|
31
|
-
|
|
32
|
-
'''
|
|
33
|
-
Returns information on a .rpm file:
|
|
34
|
-
|
|
35
|
-
.. code:: python
|
|
36
|
-
|
|
37
|
-
{
|
|
38
|
-
'name': 'my_package',
|
|
39
|
-
'version': '1.0.0'
|
|
40
|
-
}
|
|
41
|
-
'''
|
|
42
|
-
|
|
43
|
-
def command(self, name):
|
|
44
|
-
return 'rpm -qp {0}'.format(name)
|
|
43
|
+
default = list
|
|
45
44
|
|
|
45
|
+
@override
|
|
46
46
|
def process(self, output):
|
|
47
|
-
|
|
48
|
-
matches = re.match(rpm_regex, line)
|
|
49
|
-
if matches:
|
|
50
|
-
return {
|
|
51
|
-
'name': matches.group(1),
|
|
52
|
-
'version': matches.group(2),
|
|
53
|
-
}
|
|
47
|
+
return parse_yum_repositories(output)
|
pyinfra/facts/zfs.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Gather information about ZFS filesystems.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing_extensions import override
|
|
6
|
+
|
|
7
|
+
from pyinfra.api import FactBase, ShortFactBase
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _process_zfs_props_table(output):
|
|
11
|
+
datasets: dict = {}
|
|
12
|
+
for line in output:
|
|
13
|
+
dataset, property, value, source = tuple(line.split("\t"))
|
|
14
|
+
if dataset not in datasets:
|
|
15
|
+
datasets[dataset] = {}
|
|
16
|
+
datasets[dataset][property] = value
|
|
17
|
+
return datasets
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ZfsPools(FactBase):
|
|
21
|
+
@override
|
|
22
|
+
def command(self) -> str:
|
|
23
|
+
return "zpool get -H all"
|
|
24
|
+
|
|
25
|
+
@override
|
|
26
|
+
def requires_command(self) -> str:
|
|
27
|
+
return "zpool"
|
|
28
|
+
|
|
29
|
+
@override
|
|
30
|
+
def process(self, output):
|
|
31
|
+
return _process_zfs_props_table(output)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ZfsDatasets(FactBase):
|
|
35
|
+
@override
|
|
36
|
+
def command(self) -> str:
|
|
37
|
+
return "zfs get -H all"
|
|
38
|
+
|
|
39
|
+
@override
|
|
40
|
+
def requires_command(self) -> str:
|
|
41
|
+
return "zfs"
|
|
42
|
+
|
|
43
|
+
@override
|
|
44
|
+
def process(self, output):
|
|
45
|
+
return _process_zfs_props_table(output)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class ZfsFilesystems(ShortFactBase):
|
|
49
|
+
fact = ZfsDatasets
|
|
50
|
+
|
|
51
|
+
@override
|
|
52
|
+
def process_data(self, data):
|
|
53
|
+
return {name: props for name, props in data.items() if props.get("type") == "filesystem"}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ZfsSnapshots(ShortFactBase):
|
|
57
|
+
fact = ZfsDatasets
|
|
58
|
+
|
|
59
|
+
@override
|
|
60
|
+
def process_data(self, data):
|
|
61
|
+
return {name: props for name, props in data.items() if props.get("type") == "snapshot"}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class ZfsVolumes(ShortFactBase):
|
|
65
|
+
fact = ZfsDatasets
|
|
66
|
+
|
|
67
|
+
@override
|
|
68
|
+
def process_data(self, data):
|
|
69
|
+
return {name: props for name, props in data.items() if props.get("type") == "volume"}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# TODO: remove these in v4! Or flip the convention and remove all the other fact prefixes!
|
|
73
|
+
Pools = ZfsPools
|
|
74
|
+
Datasets = ZfsDatasets
|
|
75
|
+
Filesystems = ZfsFilesystems
|
|
76
|
+
Snapshots = ZfsSnapshots
|
|
77
|
+
Volumes = ZfsVolumes
|
pyinfra/facts/zypper.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing_extensions import override
|
|
4
|
+
|
|
5
|
+
from pyinfra.api import FactBase
|
|
6
|
+
|
|
7
|
+
from .util import make_cat_files_command
|
|
8
|
+
from .util.packaging import parse_zypper_repositories
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ZypperRepositories(FactBase):
|
|
12
|
+
"""
|
|
13
|
+
Returns a list of installed zypper repositories:
|
|
14
|
+
|
|
15
|
+
.. code:: python
|
|
16
|
+
|
|
17
|
+
[
|
|
18
|
+
{
|
|
19
|
+
"repoid": "repo-oss",
|
|
20
|
+
"name": "Main Repository",
|
|
21
|
+
"enabled": "1",
|
|
22
|
+
"autorefresh": "1",
|
|
23
|
+
"baseurl": "http://download.opensuse.org/distribution/leap/$releasever/repo/oss/"
|
|
24
|
+
},
|
|
25
|
+
]
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
@override
|
|
29
|
+
def command(self) -> str:
|
|
30
|
+
return make_cat_files_command(
|
|
31
|
+
"/etc/zypp/repos.d/*.repo",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
@override
|
|
35
|
+
def requires_command(self) -> str:
|
|
36
|
+
return "zypper"
|
|
37
|
+
|
|
38
|
+
default = list
|
|
39
|
+
|
|
40
|
+
@override
|
|
41
|
+
def process(self, output):
|
|
42
|
+
return parse_zypper_repositories(output)
|
pyinfra/local.py
CHANGED
|
@@ -1,134 +1,96 @@
|
|
|
1
1
|
from os import path
|
|
2
|
-
from
|
|
2
|
+
from typing import Optional
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
import click
|
|
5
5
|
|
|
6
6
|
import pyinfra
|
|
7
|
+
from pyinfra import config, host, logger, state
|
|
8
|
+
from pyinfra.api.exceptions import PyinfraError
|
|
9
|
+
from pyinfra.api.util import get_file_path
|
|
10
|
+
from pyinfra.connectors.util import run_local_process
|
|
11
|
+
from pyinfra.context import ctx_state
|
|
7
12
|
|
|
8
|
-
from . import logger, pseudo_host, pseudo_state
|
|
9
|
-
from .api.exceptions import PyinfraError
|
|
10
|
-
from .api.util import ensure_host_list, get_caller_frameinfo, read_buffer
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Executes a local python file within the ``pyinfra.pseudo_state.deploy_dir``
|
|
14
|
+
def include(filename: str, data: Optional[dict] = None):
|
|
15
|
+
"""
|
|
16
|
+
Executes a local python file within the ``pyinfra.state.cwd``
|
|
16
17
|
directory.
|
|
17
|
-
|
|
18
|
-
Args:
|
|
19
|
-
hosts (string, list): group name or list of hosts to limit this include to
|
|
20
|
-
when (bool): indicate whether to trigger operations in this include
|
|
21
|
-
'''
|
|
18
|
+
"""
|
|
22
19
|
|
|
23
20
|
if not pyinfra.is_cli:
|
|
24
|
-
raise PyinfraError(
|
|
21
|
+
raise PyinfraError("local.include is only available in CLI mode.")
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
return
|
|
23
|
+
filename = get_file_path(state, filename)
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
hosts = ensure_host_list(hosts, inventory=pseudo_state.inventory)
|
|
31
|
-
if pseudo_host not in hosts:
|
|
32
|
-
return
|
|
25
|
+
logger.debug("Including local file: %s", filename)
|
|
33
26
|
|
|
34
|
-
|
|
35
|
-
filename = path.join(pseudo_state.deploy_dir, filename)
|
|
36
|
-
|
|
37
|
-
frameinfo = get_caller_frameinfo()
|
|
38
|
-
|
|
39
|
-
logger.debug('Including local file: {0}'.format(filename))
|
|
27
|
+
config_state = config.get_current_state()
|
|
40
28
|
|
|
41
29
|
try:
|
|
42
30
|
# Fixes a circular import because `pyinfra.local` is really a CLI
|
|
43
31
|
# only thing (so should be `pyinfra_cli.local`). It is kept here
|
|
44
|
-
# to maintain backwards
|
|
32
|
+
# to maintain backwards compatibility and the nicer public import
|
|
45
33
|
# (ideally users never need to import from `pyinfra_cli`).
|
|
46
34
|
|
|
47
|
-
from pyinfra_cli.config import extract_file_config
|
|
48
35
|
from pyinfra_cli.util import exec_file
|
|
49
36
|
|
|
50
|
-
|
|
51
|
-
config_data = extract_file_config(filename)
|
|
52
|
-
kwargs = {
|
|
53
|
-
key.lower(): value
|
|
54
|
-
for key, value in config_data.items()
|
|
55
|
-
if key in [
|
|
56
|
-
'SUDO', 'SUDO_USER', 'SU_USER',
|
|
57
|
-
'PRESERVE_SUDO_ENV', 'IGNORE_ERRORS',
|
|
58
|
-
]
|
|
59
|
-
}
|
|
60
|
-
with pseudo_state.deploy(
|
|
61
|
-
filename, kwargs, None, frameinfo.lineno,
|
|
62
|
-
in_deploy=False,
|
|
63
|
-
):
|
|
37
|
+
with host.deploy(path.relpath(filename, state.cwd), None, data, in_deploy=False):
|
|
64
38
|
exec_file(filename)
|
|
65
39
|
|
|
66
40
|
# One potential solution to the above is to add local as an actual
|
|
67
|
-
# module, ie `pyinfra.
|
|
41
|
+
# module, ie `pyinfra.operations.local`.
|
|
68
42
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
'Could not include local file: {0}\n{1}'.format(filename, e),
|
|
72
|
-
)
|
|
43
|
+
finally:
|
|
44
|
+
config.set_current_state(config_state)
|
|
73
45
|
|
|
74
46
|
|
|
75
|
-
def shell(
|
|
76
|
-
|
|
47
|
+
def shell(
|
|
48
|
+
commands,
|
|
49
|
+
splitlines: bool = False,
|
|
50
|
+
ignore_errors: bool = False,
|
|
51
|
+
print_output: bool = False,
|
|
52
|
+
print_input: bool = False,
|
|
53
|
+
):
|
|
54
|
+
"""
|
|
77
55
|
Subprocess based implementation of pyinfra/api/ssh.py's ``run_shell_command``.
|
|
78
56
|
|
|
79
57
|
Args:
|
|
80
58
|
commands (string, list): command or list of commands to execute
|
|
81
|
-
|
|
59
|
+
splitlines (bool): optionally have the output split by lines
|
|
82
60
|
ignore_errors (bool): ignore errors when executing these commands
|
|
83
|
-
|
|
61
|
+
"""
|
|
84
62
|
|
|
85
63
|
if isinstance(commands, str):
|
|
86
64
|
commands = [commands]
|
|
87
65
|
|
|
88
66
|
all_stdout = []
|
|
89
67
|
|
|
90
|
-
# Checking for
|
|
91
|
-
#
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
else False
|
|
96
|
-
)
|
|
68
|
+
# Checking for state context being set means this function works outside a deploy
|
|
69
|
+
# e.g.: the vagrant connector.
|
|
70
|
+
if ctx_state.isset():
|
|
71
|
+
print_output = state.print_output
|
|
72
|
+
print_input = state.print_input
|
|
97
73
|
|
|
98
74
|
for command in commands:
|
|
99
|
-
print_prefix =
|
|
75
|
+
print_prefix = "localhost: "
|
|
100
76
|
|
|
101
|
-
if
|
|
102
|
-
|
|
77
|
+
if print_input:
|
|
78
|
+
click.echo("{0}>>> {1}".format(print_prefix, command), err=True)
|
|
103
79
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
stdout_queue = Queue()
|
|
107
|
-
|
|
108
|
-
read_buffer(
|
|
109
|
-
'stdout',
|
|
110
|
-
process.stdout,
|
|
111
|
-
stdout_queue,
|
|
80
|
+
return_code, output = run_local_process(
|
|
81
|
+
command,
|
|
112
82
|
print_output=print_output,
|
|
113
|
-
|
|
83
|
+
print_prefix=print_prefix,
|
|
114
84
|
)
|
|
115
85
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
# Get & check result
|
|
119
|
-
result = process.wait()
|
|
120
|
-
|
|
121
|
-
# Close any open file descriptor
|
|
122
|
-
process.stdout.close()
|
|
123
|
-
|
|
124
|
-
if result > 0 and not ignore_errors:
|
|
86
|
+
if return_code > 0 and not ignore_errors:
|
|
125
87
|
raise PyinfraError(
|
|
126
|
-
|
|
88
|
+
"Local command failed: {0}\n{1}".format(command, output.stderr),
|
|
127
89
|
)
|
|
128
90
|
|
|
129
|
-
all_stdout.extend(
|
|
91
|
+
all_stdout.extend(output.stdout_lines)
|
|
130
92
|
|
|
131
93
|
if not splitlines:
|
|
132
|
-
return
|
|
94
|
+
return "\n".join(all_stdout)
|
|
133
95
|
|
|
134
96
|
return all_stdout
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# This file only exists to support:
|
|
2
|
+
# from pyinfra import operations
|
|
3
|
+
# operations.X.Y
|
|
4
|
+
|
|
5
|
+
from glob import glob
|
|
6
|
+
from os import path
|
|
7
|
+
|
|
8
|
+
module_filenames = glob(path.join(path.dirname(__file__), "*.py"))
|
|
9
|
+
module_names = [path.basename(name)[:-3] for name in module_filenames]
|
|
10
|
+
__all__ = [name for name in module_names if name != "__init__"]
|
|
11
|
+
|
|
12
|
+
from . import * # noqa
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manage apk packages.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from pyinfra import host
|
|
8
|
+
from pyinfra.api import operation
|
|
9
|
+
from pyinfra.facts.apk import ApkPackages
|
|
10
|
+
|
|
11
|
+
from .util.packaging import ensure_packages
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@operation(is_idempotent=False)
|
|
15
|
+
def upgrade(available: bool = False):
|
|
16
|
+
"""
|
|
17
|
+
Upgrades all apk packages.
|
|
18
|
+
|
|
19
|
+
+ available: force all packages to be upgraded (recommended on whole Alpine version upgrades)
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
if available:
|
|
23
|
+
yield "apk upgrade --available"
|
|
24
|
+
else:
|
|
25
|
+
yield "apk upgrade"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
_upgrade = upgrade._inner # noqa: E305
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@operation(is_idempotent=False)
|
|
32
|
+
def update():
|
|
33
|
+
"""
|
|
34
|
+
Updates apk repositories.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
yield "apk update"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
_update = update._inner # noqa: E305
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@operation()
|
|
44
|
+
def packages(
|
|
45
|
+
packages: str | list[str] | None = None,
|
|
46
|
+
present=True,
|
|
47
|
+
latest=False,
|
|
48
|
+
update=False,
|
|
49
|
+
upgrade=False,
|
|
50
|
+
):
|
|
51
|
+
"""
|
|
52
|
+
Add/remove/update apk packages.
|
|
53
|
+
|
|
54
|
+
+ packages: list of packages to ensure
|
|
55
|
+
+ present: whether the packages should be installed
|
|
56
|
+
+ latest: whether to upgrade packages without a specified version
|
|
57
|
+
+ update: run ``apk update`` before installing packages
|
|
58
|
+
+ upgrade: run ``apk upgrade`` before installing packages
|
|
59
|
+
|
|
60
|
+
Versions:
|
|
61
|
+
Package versions can be pinned like apk: ``<pkg>=<version>``.
|
|
62
|
+
|
|
63
|
+
**Examples:**
|
|
64
|
+
|
|
65
|
+
.. code:: python
|
|
66
|
+
|
|
67
|
+
# Update package list and install packages
|
|
68
|
+
apk.packages(
|
|
69
|
+
name="Install Asterisk and Vim",
|
|
70
|
+
packages=["asterisk", "vim"],
|
|
71
|
+
update=True,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Install the latest versions of packages (always check)
|
|
75
|
+
apk.packages(
|
|
76
|
+
name="Install latest Vim",
|
|
77
|
+
packages=["vim"],
|
|
78
|
+
latest=True,
|
|
79
|
+
)
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
if update:
|
|
83
|
+
yield from _update()
|
|
84
|
+
|
|
85
|
+
if upgrade:
|
|
86
|
+
yield from _upgrade()
|
|
87
|
+
|
|
88
|
+
yield from ensure_packages(
|
|
89
|
+
host,
|
|
90
|
+
packages,
|
|
91
|
+
host.get_fact(ApkPackages),
|
|
92
|
+
present,
|
|
93
|
+
install_command="apk add",
|
|
94
|
+
uninstall_command="apk del",
|
|
95
|
+
upgrade_command="apk upgrade",
|
|
96
|
+
version_join="=",
|
|
97
|
+
latest=latest,
|
|
98
|
+
)
|