pyinfra 3.0b4__tar.gz → 3.0.1__tar.gz
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-3.0.1/CHANGELOG.md +73 -0
- {pyinfra-3.0b4/pyinfra.egg-info → pyinfra-3.0.1}/PKG-INFO +1 -5
- {pyinfra-3.0b4 → pyinfra-3.0.1}/README.md +0 -4
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/facts.py +7 -50
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/util.py +1 -1
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/ssh.py +3 -3
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/sshuserclient/client.py +1 -1
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/apk.py +5 -2
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/apt.py +13 -7
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/brew.py +26 -13
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/bsdinit.py +7 -6
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/cargo.py +4 -3
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/choco.py +6 -4
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/deb.py +12 -5
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/dnf.py +9 -6
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/docker.py +13 -6
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/files.py +3 -3
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/gem.py +5 -2
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/git.py +14 -21
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/gpg.py +2 -1
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/hardware.py +17 -11
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/launchd.py +5 -2
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/lxd.py +6 -2
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/mysql.py +7 -6
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/npm.py +2 -1
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/openrc.py +6 -2
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/pacman.py +7 -3
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/pkg.py +3 -1
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/pkgin.py +5 -2
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/postgres.py +3 -1
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/rpm.py +12 -9
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/runit.py +4 -2
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/selinux.py +12 -4
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/server.py +80 -51
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/snap.py +6 -2
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/systemd.py +10 -5
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/sysvinit.py +2 -1
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/upstart.py +5 -2
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/vzctl.py +6 -4
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/xbps.py +5 -2
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/yum.py +8 -5
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/zypper.py +7 -4
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/apt.py +5 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/selinux.py +1 -1
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/server.py +1 -1
- {pyinfra-3.0b4 → pyinfra-3.0.1/pyinfra.egg-info}/PKG-INFO +1 -5
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra.egg-info/SOURCES.txt +1 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra_cli/__main__.py +2 -3
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra_cli/inventory.py +13 -11
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra_cli/main.py +10 -9
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_api/test_api_facts.py +2 -2
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_cli/test_cli.py +0 -1
- pyinfra-3.0.1/tests/test_cli/test_cli_inventory.py +66 -0
- pyinfra-3.0b4/CHANGELOG.md +0 -29
- {pyinfra-3.0b4 → pyinfra-3.0.1}/LICENSE.md +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/MANIFEST.in +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/__init__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/__main__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/__init__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/arguments.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/arguments_typed.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/command.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/config.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/connect.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/connectors.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/deploy.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/exceptions.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/host.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/inventory.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/operation.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/operations.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/api/state.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/__init__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/base.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/chroot.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/docker.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/dockerssh.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/local.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/ssh_util.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/sshuserclient/__init__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/sshuserclient/config.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/terraform.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/util.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/connectors/vagrant.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/context.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/__init__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/iptables.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/pip.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/postgresql.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/util/__init__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/util/databases.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/util/packaging.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/facts/util/win_files.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/local.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/__init__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/apk.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/brew.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/bsdinit.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/cargo.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/choco.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/dnf.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/docker.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/files.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/gem.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/git.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/iptables.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/launchd.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/lxd.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/mysql.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/npm.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/openrc.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/pacman.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/pip.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/pkg.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/pkgin.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/postgres.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/postgresql.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/puppet.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/python.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/runit.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/snap.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/ssh.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/systemd.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/sysvinit.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/upstart.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/util/__init__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/util/docker.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/util/files.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/util/packaging.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/util/service.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/vzctl.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/xbps.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/yum.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/operations/zypper.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/progress.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/py.typed +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra/version.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra.egg-info/dependency_links.txt +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra.egg-info/entry_points.txt +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra.egg-info/requires.txt +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra.egg-info/top_level.txt +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra_cli/__init__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra_cli/commands.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra_cli/exceptions.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra_cli/log.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra_cli/prints.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra_cli/util.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyinfra_cli/virtualenv.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/pyproject.toml +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/setup.cfg +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/setup.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_api/__init__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_api/test_api.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_api/test_api_arguments.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_api/test_api_command.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_api/test_api_config.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_api/test_api_deploys.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_api/test_api_host.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_api/test_api_inventory.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_api/test_api_operations.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_api/test_api_util.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_cli/__init__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_cli/test_cli_deploy.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_cli/test_cli_exceptions.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_cli/test_cli_util.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_cli/test_context_objects.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_cli/util.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_connectors/__init__.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_connectors/test_chroot.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_connectors/test_docker.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_connectors/test_dockerssh.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_connectors/test_local.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_connectors/test_ssh.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_connectors/test_sshuserclient.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_connectors/test_terraform.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_connectors/test_util.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_connectors/test_vagrant.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_facts.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_global_arguments.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_operations.py +0 -0
- {pyinfra-3.0b4 → pyinfra-3.0.1}/tests/test_operations_utils.py +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# v3.0.1
|
|
2
|
+
|
|
3
|
+
- Switch to `command -v` not `which` in `server.Which` fact (@lemmi)
|
|
4
|
+
- Fix detection of xbps in `server.packages` operation (@romain-dartigues)
|
|
5
|
+
- Fix argument typo in operations doc (@scoufman)
|
|
6
|
+
- Add expanded note about detected changes + hidden side effects during execution
|
|
7
|
+
- Fix missing global arguments in group data files
|
|
8
|
+
- Fix `--group-data` CLI argument behaviour
|
|
9
|
+
- Remove unused/dead `--quiet` flag
|
|
10
|
+
|
|
11
|
+
# v3.0
|
|
12
|
+
|
|
13
|
+
Welcome to pyinfra v3! This version is the biggest overhaul of pyinfra since it was created back in 2015. Most v2 deployment code should be automatically compatible, but as always be aware. Major changes:
|
|
14
|
+
|
|
15
|
+
### Runtime operation execution
|
|
16
|
+
|
|
17
|
+
pyinfra now executes operations at runtime, rather than pre-generating commands. Although the change isn't noticeable this fixes an entire class of bugs and confusion. See the [limitations](https://docs.pyinfra.com/en/2.x/deploy-process.html#limitations) section in the v2 docs. All of those issues are now a thing of the past.
|
|
18
|
+
|
|
19
|
+
This represents a huge overhaul of pyinfra's internals and should be a huge improvement for users.
|
|
20
|
+
|
|
21
|
+
Care has been taken to reduce the overhead of this change which still supports the same diffs and change proposal mechanism.
|
|
22
|
+
|
|
23
|
+
### CLI flow & prompts
|
|
24
|
+
|
|
25
|
+
The pyinfra CLI will now prompt (instead of ignore, or immediately exit) when problems are encountered, allowing the user to choose to continue. Additionally an approval step is added before executing changes (this can be skipped with `-y` or setting the `PYINFRA_YES` environment variable).
|
|
26
|
+
|
|
27
|
+
### Extendable connectors API, typing overhaul
|
|
28
|
+
|
|
29
|
+
v3 of pyinfra includes for the first time a (mostly) typed internal API with proper support for IDE linting. There's a whole new connectors API that provides a framework for building new connectors.
|
|
30
|
+
|
|
31
|
+
### Breaking changes
|
|
32
|
+
|
|
33
|
+
- Rename `_use_sudo_password` argument to `_sudo_password`
|
|
34
|
+
- Remove `winrm` connector and `windows*` operations/facts, moving to [`pyinfra-windows`](https://github.com/pyinfra-dev/pyinfra-windows)
|
|
35
|
+
- The deploy decorator must now be called, ie used as `@deploy()`, and is now typed
|
|
36
|
+
- Remove broken Ansible inventory connector
|
|
37
|
+
|
|
38
|
+
### Operations & Facts
|
|
39
|
+
|
|
40
|
+
- Add `docker.container`, `docker.image`, `docker.volume`, `docker.network` & `docker.prune` operations (@apecnascimento)
|
|
41
|
+
- Add `runit.service` operation and `RunitStatus` fact (@lemmi)
|
|
42
|
+
- Add `TmpDir` fact
|
|
43
|
+
- Add `services` argument to systemd facts for filtering
|
|
44
|
+
- Add type hints for all the operations (@stone-w4tch3r)
|
|
45
|
+
- Lowercase pip packages properly (PEP-0426)
|
|
46
|
+
- Rename `postgresql` -> `postgres` operations & facts (old ones still work)
|
|
47
|
+
- Improve IP/MAC parsing in `NetworkDevices` fact (@sudoBash418)
|
|
48
|
+
- Enable getting `Home` fact for other users (@matthijskooijman)
|
|
49
|
+
- Use users correct home directory in `server.user_authorized_keys` operation (@matthijskooijman)
|
|
50
|
+
- Fix `destination`/`not_destination` arguments in `iptables.rule` operation
|
|
51
|
+
- Fix remote dirs when executing from Windows in `files.sync` operation (@Renerick)
|
|
52
|
+
- Fix quoting of systemd unit names (@martenlienen)
|
|
53
|
+
|
|
54
|
+
### Other Changes
|
|
55
|
+
|
|
56
|
+
- Add new `_if` global argument to control operation execution at runtime
|
|
57
|
+
- Add `--debug-all` flag to set debug logging for all packages
|
|
58
|
+
- Retry SSH connections on failure (configurable, see [SSH connector](https://docs.pyinfra.com/en/3.x/connectors/ssh.html#available-data)) (@fwiesel)
|
|
59
|
+
- Documentation typo fixes (@szepeviktor, @sudoBash418)
|
|
60
|
+
- Fix handling of binary files in Docker connector (@matthijskooijman)
|
|
61
|
+
- Add `will_change` attribute and `did_change` context manager to `OperationMeta`
|
|
62
|
+
- Replace use of `pkg_resources` with `importlib.metadata` (@diazona)
|
|
63
|
+
- Fix identifying Python inventory files as modules (@martenlienen)
|
|
64
|
+
- Fix typed arguments order (@cdleonard)
|
|
65
|
+
- Check that fact commands don't take global arguments (@martenlienen)
|
|
66
|
+
|
|
67
|
+
# v2.x
|
|
68
|
+
|
|
69
|
+
[See this file in the `2.x` branch](https://github.com/Fizzadar/pyinfra/blob/2.x/CHANGELOG.md).
|
|
70
|
+
|
|
71
|
+
# v1.x
|
|
72
|
+
|
|
73
|
+
[See this file in the `1.x` branch](https://github.com/Fizzadar/pyinfra/blob/1.x/CHANGELOG.md).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyinfra
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.0.1
|
|
4
4
|
Summary: pyinfra automates/provisions/manages/deploys infrastructure.
|
|
5
5
|
Home-page: https://pyinfra.com
|
|
6
6
|
Author: Nick / Fizzadar
|
|
@@ -92,10 +92,6 @@ Requires-Dist: redbaron; extra == "dev"
|
|
|
92
92
|
</a>
|
|
93
93
|
</p>
|
|
94
94
|
|
|
95
|
-
<p>
|
|
96
|
-
<strong>Note: this is the v3 branch, which is currently in beta. <a href="https://docs.pyinfra.com/en/next">See the docs for v3</a>. If needed the <a href="https://github.com/pyinfra-dev/pyinfra/tree/2.x/">2.x branch is here</a>, but is in bugfix only mode.</strong>
|
|
97
|
-
</p>
|
|
98
|
-
|
|
99
95
|
<p>
|
|
100
96
|
pyinfra turns Python code into shell commands and runs them on your servers. Execute ad-hoc commands and write declarative operations. Target SSH servers, local machine and Docker containers. Fast and scales from one server to thousands. Think <code>ansible</code> but Python instead of YAML, and a lot faster.
|
|
101
97
|
</p>
|
|
@@ -4,10 +4,6 @@
|
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
-
<p>
|
|
8
|
-
<strong>Note: this is the v3 branch, which is currently in beta. <a href="https://docs.pyinfra.com/en/next">See the docs for v3</a>. If needed the <a href="https://github.com/pyinfra-dev/pyinfra/tree/2.x/">2.x branch is here</a>, but is in bugfix only mode.</strong>
|
|
9
|
-
</p>
|
|
10
|
-
|
|
11
7
|
<p>
|
|
12
8
|
pyinfra turns Python code into shell commands and runs them on your servers. Execute ad-hoc commands and write declarative operations. Target SSH servers, local machine and Docker containers. Fast and scales from one server to thousands. Think <code>ansible</code> but Python instead of YAML, and a lot faster.
|
|
13
9
|
</p>
|
|
@@ -14,18 +14,7 @@ import inspect
|
|
|
14
14
|
import re
|
|
15
15
|
from inspect import getcallargs
|
|
16
16
|
from socket import error as socket_error, timeout as timeout_error
|
|
17
|
-
from typing import
|
|
18
|
-
TYPE_CHECKING,
|
|
19
|
-
Any,
|
|
20
|
-
Callable,
|
|
21
|
-
Generic,
|
|
22
|
-
Iterable,
|
|
23
|
-
Optional,
|
|
24
|
-
Type,
|
|
25
|
-
TypeVar,
|
|
26
|
-
Union,
|
|
27
|
-
cast,
|
|
28
|
-
)
|
|
17
|
+
from typing import TYPE_CHECKING, Any, Callable, Generic, Iterable, Optional, Type, TypeVar, cast
|
|
29
18
|
|
|
30
19
|
import click
|
|
31
20
|
import gevent
|
|
@@ -38,7 +27,6 @@ from pyinfra.api.util import (
|
|
|
38
27
|
get_kwargs_str,
|
|
39
28
|
log_error_or_warning,
|
|
40
29
|
log_host_command_error,
|
|
41
|
-
make_hash,
|
|
42
30
|
print_host_combined_output,
|
|
43
31
|
)
|
|
44
32
|
from pyinfra.connectors.util import CommandOutput
|
|
@@ -66,11 +54,12 @@ class FactBase(Generic[T]):
|
|
|
66
54
|
|
|
67
55
|
abstract: bool = True
|
|
68
56
|
|
|
69
|
-
shell_executable:
|
|
57
|
+
shell_executable: str | None = None
|
|
70
58
|
|
|
71
|
-
|
|
59
|
+
command: Callable[..., str | StringCommand]
|
|
72
60
|
|
|
73
|
-
|
|
61
|
+
def requires_command(self, *args, **kwargs) -> str | None:
|
|
62
|
+
return None
|
|
74
63
|
|
|
75
64
|
def __init_subclass__(cls) -> None:
|
|
76
65
|
super().__init_subclass__()
|
|
@@ -113,8 +102,7 @@ class ShortFactBase(Generic[T]):
|
|
|
113
102
|
module_name = cls.__module__.replace("pyinfra.facts.", "")
|
|
114
103
|
cls.name = f"{module_name}.{cls.__name__}"
|
|
115
104
|
|
|
116
|
-
|
|
117
|
-
def process_data(data):
|
|
105
|
+
def process_data(self, data):
|
|
118
106
|
return data
|
|
119
107
|
|
|
120
108
|
|
|
@@ -130,30 +118,6 @@ def _make_command(command_attribute, host_args):
|
|
|
130
118
|
return command_attribute
|
|
131
119
|
|
|
132
120
|
|
|
133
|
-
def _get_executor_kwargs(
|
|
134
|
-
state: "State",
|
|
135
|
-
host: "Host",
|
|
136
|
-
override_kwargs: Optional[dict[str, Any]] = None,
|
|
137
|
-
override_kwarg_keys: Optional[list[str]] = None,
|
|
138
|
-
):
|
|
139
|
-
if override_kwargs is None:
|
|
140
|
-
override_kwargs = {}
|
|
141
|
-
if override_kwarg_keys is None:
|
|
142
|
-
override_kwarg_keys = []
|
|
143
|
-
|
|
144
|
-
# Use the current operation global kwargs, or generate defaults
|
|
145
|
-
global_kwargs = host.current_op_global_arguments
|
|
146
|
-
if not global_kwargs:
|
|
147
|
-
global_kwargs, _ = pop_global_arguments({}, state, host)
|
|
148
|
-
|
|
149
|
-
# Apply any current op kwargs that *weren't* found in the overrides
|
|
150
|
-
override_kwargs.update(
|
|
151
|
-
{key: value for key, value in global_kwargs.items() if key not in override_kwarg_keys},
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
return {key: value for key, value in override_kwargs.items() if key in CONNECTOR_ARGUMENT_KEYS}
|
|
155
|
-
|
|
156
|
-
|
|
157
121
|
def _handle_fact_kwargs(state, host, cls, args, kwargs):
|
|
158
122
|
args = args or []
|
|
159
123
|
kwargs = kwargs or {}
|
|
@@ -296,7 +260,7 @@ def _get_fact(
|
|
|
296
260
|
log_host_command_error(
|
|
297
261
|
host,
|
|
298
262
|
e,
|
|
299
|
-
timeout=global_kwargs
|
|
263
|
+
timeout=global_kwargs.get("_timeout"),
|
|
300
264
|
)
|
|
301
265
|
|
|
302
266
|
stdout_lines, stderr_lines = output.stdout_lines, output.stderr_lines
|
|
@@ -346,13 +310,6 @@ def _get_fact(
|
|
|
346
310
|
return data
|
|
347
311
|
|
|
348
312
|
|
|
349
|
-
def _get_fact_hash(state: "State", host: "Host", cls, args, kwargs):
|
|
350
|
-
if issubclass(cls, ShortFactBase):
|
|
351
|
-
cls = cls.fact
|
|
352
|
-
fact_kwargs, executor_kwargs = _handle_fact_kwargs(state, host, cls, args, kwargs)
|
|
353
|
-
return make_hash((cls, fact_kwargs, executor_kwargs))
|
|
354
|
-
|
|
355
|
-
|
|
356
313
|
def get_host_fact(
|
|
357
314
|
state: "State",
|
|
358
315
|
host: "Host",
|
|
@@ -241,7 +241,7 @@ def log_error_or_warning(
|
|
|
241
241
|
)
|
|
242
242
|
|
|
243
243
|
|
|
244
|
-
def log_host_command_error(host: "Host", e: Exception, timeout: int = 0) -> None:
|
|
244
|
+
def log_host_command_error(host: "Host", e: Exception, timeout: int | None = 0) -> None:
|
|
245
245
|
if isinstance(e, timeout_error):
|
|
246
246
|
logger.error(
|
|
247
247
|
"{0}{1}".format(
|
|
@@ -123,7 +123,7 @@ class SSHConnector(BaseConnector):
|
|
|
123
123
|
|
|
124
124
|
hosts = (
|
|
125
125
|
["my-host-1.net", "my-host-2.net"],
|
|
126
|
-
{"
|
|
126
|
+
{"ssh_user": "ssh-user"},
|
|
127
127
|
)
|
|
128
128
|
|
|
129
129
|
Multiple hosts with different SSH usernames:
|
|
@@ -131,8 +131,8 @@ class SSHConnector(BaseConnector):
|
|
|
131
131
|
.. code:: python
|
|
132
132
|
|
|
133
133
|
hosts = [
|
|
134
|
-
("my-host-1.net", {"
|
|
135
|
-
("my-host-2.net", {"
|
|
134
|
+
("my-host-1.net", {"ssh_user": "ssh-user"}),
|
|
135
|
+
("my-host-2.net", {"ssh_user": "other-user"}),
|
|
136
136
|
]
|
|
137
137
|
"""
|
|
138
138
|
|
|
@@ -18,8 +18,11 @@ class ApkPackages(FactBase):
|
|
|
18
18
|
}
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
command
|
|
22
|
-
|
|
21
|
+
def command(self) -> str:
|
|
22
|
+
return "apk list --installed"
|
|
23
|
+
|
|
24
|
+
def requires_command(self) -> str:
|
|
25
|
+
return "apk"
|
|
23
26
|
|
|
24
27
|
default = dict
|
|
25
28
|
|
|
@@ -52,11 +52,14 @@ class AptSources(FactBase):
|
|
|
52
52
|
]
|
|
53
53
|
"""
|
|
54
54
|
|
|
55
|
-
command
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
def command(self) -> str:
|
|
56
|
+
return make_cat_files_command(
|
|
57
|
+
"/etc/apt/sources.list",
|
|
58
|
+
"/etc/apt/sources.list.d/*.list",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def requires_command(self) -> str:
|
|
62
|
+
return "apt" # if apt installed, above should exist
|
|
60
63
|
|
|
61
64
|
default = list
|
|
62
65
|
|
|
@@ -86,5 +89,8 @@ class AptKeys(GpgFactBase):
|
|
|
86
89
|
"""
|
|
87
90
|
|
|
88
91
|
# This requires both apt-key *and* apt-key itself requires gpg
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
def command(self) -> str:
|
|
93
|
+
return "! command -v gpg || apt-key list --with-colons"
|
|
94
|
+
|
|
95
|
+
def requires_command(self) -> str:
|
|
96
|
+
return "apt-key"
|
|
@@ -37,18 +37,22 @@ class BrewVersion(FactBase):
|
|
|
37
37
|
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
|
-
command
|
|
41
|
-
|
|
40
|
+
def command(self) -> str:
|
|
41
|
+
return "brew --version"
|
|
42
|
+
|
|
43
|
+
def requires_command(self) -> str:
|
|
44
|
+
return "brew"
|
|
42
45
|
|
|
43
46
|
@staticmethod
|
|
44
47
|
def default():
|
|
45
48
|
return [0, 0, 0]
|
|
46
49
|
|
|
47
50
|
def process(self, output):
|
|
48
|
-
|
|
51
|
+
out = list(output)[0]
|
|
52
|
+
m = VERSION_MATCHER.match(out)
|
|
49
53
|
if m is not None:
|
|
50
54
|
return [int(m.group(key)) for key in ["major", "minor", "patch"]]
|
|
51
|
-
logger.warning("could not parse version string from brew: %s",
|
|
55
|
+
logger.warning("could not parse version string from brew: %s", out)
|
|
52
56
|
return self.default()
|
|
53
57
|
|
|
54
58
|
|
|
@@ -63,8 +67,11 @@ class BrewPackages(FactBase):
|
|
|
63
67
|
}
|
|
64
68
|
"""
|
|
65
69
|
|
|
66
|
-
command
|
|
67
|
-
|
|
70
|
+
def command(self) -> str:
|
|
71
|
+
return "brew list --versions"
|
|
72
|
+
|
|
73
|
+
def requires_command(self) -> str:
|
|
74
|
+
return "brew"
|
|
68
75
|
|
|
69
76
|
default = dict
|
|
70
77
|
|
|
@@ -83,11 +90,14 @@ class BrewCasks(BrewPackages):
|
|
|
83
90
|
}
|
|
84
91
|
"""
|
|
85
92
|
|
|
86
|
-
command
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
def command(self) -> str:
|
|
94
|
+
return (
|
|
95
|
+
r'if brew --version | grep -q -e "Homebrew\ +(1\.|2\.[0-5]).*" 1>/dev/null;'
|
|
96
|
+
r"then brew cask list --versions; else brew list --cask --versions; fi"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def requires_command(self) -> str:
|
|
100
|
+
return "brew"
|
|
91
101
|
|
|
92
102
|
|
|
93
103
|
class BrewTaps(FactBase):
|
|
@@ -95,8 +105,11 @@ class BrewTaps(FactBase):
|
|
|
95
105
|
Returns a list of brew taps.
|
|
96
106
|
"""
|
|
97
107
|
|
|
98
|
-
command
|
|
99
|
-
|
|
108
|
+
def command(self) -> str:
|
|
109
|
+
return "brew tap"
|
|
110
|
+
|
|
111
|
+
def requires_command(self) -> str:
|
|
112
|
+
return "brew"
|
|
100
113
|
|
|
101
114
|
default = list
|
|
102
115
|
|
|
@@ -9,11 +9,12 @@ class RcdStatus(InitdStatus):
|
|
|
9
9
|
BSD init scripts are well behaved and as such their output can be trusted.
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
|
-
command
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
def command(self) -> str:
|
|
13
|
+
return """
|
|
14
|
+
for SERVICE in `find /etc/rc.d /usr/local/etc/rc.d -type f`; do
|
|
15
|
+
$SERVICE status 2> /dev/null || $SERVICE check 2> /dev/null
|
|
16
|
+
echo "`basename $SERVICE`=$?"
|
|
17
|
+
done
|
|
18
|
+
"""
|
|
18
19
|
|
|
19
20
|
default = dict
|
|
@@ -22,10 +22,11 @@ class CargoPackages(FactBase):
|
|
|
22
22
|
|
|
23
23
|
default = dict
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def command(self):
|
|
25
|
+
def command(self) -> str:
|
|
28
26
|
return "cargo install --list"
|
|
29
27
|
|
|
28
|
+
def requires_command(self) -> str:
|
|
29
|
+
return "cargo"
|
|
30
|
+
|
|
30
31
|
def process(self, output):
|
|
31
32
|
return parse_packages(CARGO_REGEX, output)
|
|
@@ -18,7 +18,9 @@ class ChocoPackages(FactBase):
|
|
|
18
18
|
}
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
command
|
|
21
|
+
def command(self) -> str:
|
|
22
|
+
return "choco list"
|
|
23
|
+
|
|
22
24
|
shell_executable = "ps"
|
|
23
25
|
|
|
24
26
|
default = dict
|
|
@@ -32,8 +34,8 @@ class ChocoVersion(FactBase):
|
|
|
32
34
|
Returns the choco (Chocolatey) version.
|
|
33
35
|
"""
|
|
34
36
|
|
|
35
|
-
command
|
|
37
|
+
def command(self) -> str:
|
|
38
|
+
return "choco --version"
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
def process(output):
|
|
40
|
+
def process(self, output):
|
|
39
41
|
return "".join(output).replace("\n", "")
|
|
@@ -16,8 +16,11 @@ class DebArch(FactBase):
|
|
|
16
16
|
Returns the architecture string used in apt repository sources, eg ``amd64``.
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
-
command
|
|
20
|
-
|
|
19
|
+
def command(self) -> str:
|
|
20
|
+
return "dpkg --print-architecture"
|
|
21
|
+
|
|
22
|
+
def requires_command(self) -> str:
|
|
23
|
+
return "dpkg"
|
|
21
24
|
|
|
22
25
|
|
|
23
26
|
class DebPackages(FactBase):
|
|
@@ -31,8 +34,11 @@ class DebPackages(FactBase):
|
|
|
31
34
|
}
|
|
32
35
|
"""
|
|
33
36
|
|
|
34
|
-
command
|
|
35
|
-
|
|
37
|
+
def command(self) -> str:
|
|
38
|
+
return "dpkg -l"
|
|
39
|
+
|
|
40
|
+
def requires_command(self) -> str:
|
|
41
|
+
return "dpkg"
|
|
36
42
|
|
|
37
43
|
default = dict
|
|
38
44
|
|
|
@@ -55,7 +61,8 @@ class DebPackage(FactBase):
|
|
|
55
61
|
"version": r"^Version:\s+({0})$".format(DEB_PACKAGE_VERSION_REGEX),
|
|
56
62
|
}
|
|
57
63
|
|
|
58
|
-
requires_command
|
|
64
|
+
def requires_command(self, package) -> str:
|
|
65
|
+
return "dpkg"
|
|
59
66
|
|
|
60
67
|
def command(self, package):
|
|
61
68
|
return "! test -e {0} && (dpkg -s {0} 2>/dev/null || true) || dpkg -I {0}".format(
|
|
@@ -23,12 +23,15 @@ class DnfRepositories(FactBase):
|
|
|
23
23
|
]
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
|
-
command
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
def command(self) -> str:
|
|
27
|
+
return make_cat_files_command(
|
|
28
|
+
"/etc/dnf.conf",
|
|
29
|
+
"/etc/dnf.repos.d/*.repo",
|
|
30
|
+
"/etc/yum.repos.d/*.repo",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
def requires_command(self) -> str:
|
|
34
|
+
return "dnf"
|
|
32
35
|
|
|
33
36
|
default = list
|
|
34
37
|
|
|
@@ -9,7 +9,9 @@ class DockerFactBase(FactBase):
|
|
|
9
9
|
abstract = True
|
|
10
10
|
|
|
11
11
|
docker_type: str
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
def requires_command(self, *args, **kwargs) -> str:
|
|
14
|
+
return "docker"
|
|
13
15
|
|
|
14
16
|
def process(self, output):
|
|
15
17
|
output = "".join(output)
|
|
@@ -21,7 +23,8 @@ class DockerSystemInfo(DockerFactBase):
|
|
|
21
23
|
Returns ``docker system info`` output in JSON format.
|
|
22
24
|
"""
|
|
23
25
|
|
|
24
|
-
command
|
|
26
|
+
def command(self) -> str:
|
|
27
|
+
return 'docker system info --format="{{json .}}"'
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
# All Docker objects
|
|
@@ -33,7 +36,8 @@ class DockerContainers(DockerFactBase):
|
|
|
33
36
|
Returns ``docker inspect`` output for all Docker containers.
|
|
34
37
|
"""
|
|
35
38
|
|
|
36
|
-
command
|
|
39
|
+
def command(self) -> str:
|
|
40
|
+
return "docker container inspect `docker ps -qa`"
|
|
37
41
|
|
|
38
42
|
|
|
39
43
|
class DockerImages(DockerFactBase):
|
|
@@ -41,7 +45,8 @@ class DockerImages(DockerFactBase):
|
|
|
41
45
|
Returns ``docker inspect`` output for all Docker images.
|
|
42
46
|
"""
|
|
43
47
|
|
|
44
|
-
command
|
|
48
|
+
def command(self) -> str:
|
|
49
|
+
return "docker image inspect `docker images -q`"
|
|
45
50
|
|
|
46
51
|
|
|
47
52
|
class DockerNetworks(DockerFactBase):
|
|
@@ -49,7 +54,8 @@ class DockerNetworks(DockerFactBase):
|
|
|
49
54
|
Returns ``docker inspect`` output for all Docker networks.
|
|
50
55
|
"""
|
|
51
56
|
|
|
52
|
-
command
|
|
57
|
+
def command(self) -> str:
|
|
58
|
+
return "docker network inspect `docker network ls -q`"
|
|
53
59
|
|
|
54
60
|
|
|
55
61
|
# Single Docker objects
|
|
@@ -93,7 +99,8 @@ class DockerVolumes(DockerFactBase):
|
|
|
93
99
|
Returns ``docker inspect`` output for all Docker volumes.
|
|
94
100
|
"""
|
|
95
101
|
|
|
96
|
-
command
|
|
102
|
+
def command(self) -> str:
|
|
103
|
+
return "docker volume inspect `docker volume ls -q`"
|
|
97
104
|
|
|
98
105
|
|
|
99
106
|
class DockerVolume(DockerSingleMixin):
|
|
@@ -312,8 +312,7 @@ class FindFilesBase(FactBase):
|
|
|
312
312
|
default = list
|
|
313
313
|
type_flag: str
|
|
314
314
|
|
|
315
|
-
|
|
316
|
-
def process(output):
|
|
315
|
+
def process(self, output):
|
|
317
316
|
return output
|
|
318
317
|
|
|
319
318
|
def command(self, path, quote_path=True):
|
|
@@ -353,7 +352,8 @@ class Flags(FactBase):
|
|
|
353
352
|
Returns a list of the file flags set for the specified file or directory.
|
|
354
353
|
"""
|
|
355
354
|
|
|
356
|
-
requires_command
|
|
355
|
+
def requires_command(self, path) -> str:
|
|
356
|
+
return "chflags" # don't try to retrieve them if we can't set them
|
|
357
357
|
|
|
358
358
|
def command(self, path):
|
|
359
359
|
return make_formatted_string_command(
|
|
@@ -5,32 +5,29 @@ import re
|
|
|
5
5
|
from pyinfra.api.facts import FactBase
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class
|
|
9
|
-
requires_command
|
|
8
|
+
class GitFactBase(FactBase):
|
|
9
|
+
def requires_command(self, *args, **kwargs) -> str:
|
|
10
|
+
return "git"
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
class GitBranch(GitFactBase):
|
|
14
|
+
def command(self, repo) -> str:
|
|
13
15
|
return "! test -d {0} || (cd {0} && git describe --all)".format(repo)
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
def process(output):
|
|
17
|
+
def process(self, output):
|
|
17
18
|
return re.sub(r"(heads|tags)/", r"", "\n".join(output))
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
class GitConfig(
|
|
21
|
+
class GitConfig(GitFactBase):
|
|
21
22
|
default = dict
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@staticmethod
|
|
26
|
-
def command(repo=None):
|
|
24
|
+
def command(self, repo=None) -> str:
|
|
27
25
|
if repo is None:
|
|
28
26
|
return "git config --global -l || true"
|
|
29
27
|
|
|
30
28
|
return "! test -d {0} || (cd {0} && git config --local -l)".format(repo)
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
def process(output):
|
|
30
|
+
def process(self, output):
|
|
34
31
|
items: dict[str, list[str]] = {}
|
|
35
32
|
|
|
36
33
|
for line in output:
|
|
@@ -40,19 +37,15 @@ class GitConfig(FactBase):
|
|
|
40
37
|
return items
|
|
41
38
|
|
|
42
39
|
|
|
43
|
-
class GitTrackingBranch(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@staticmethod
|
|
47
|
-
def command(repo):
|
|
40
|
+
class GitTrackingBranch(GitFactBase):
|
|
41
|
+
def command(self, repo) -> str:
|
|
48
42
|
return r"! test -d {0} || (cd {0} && git status --branch --porcelain)".format(repo)
|
|
49
43
|
|
|
50
|
-
|
|
51
|
-
def process(output):
|
|
44
|
+
def process(self, output):
|
|
52
45
|
if not output:
|
|
53
46
|
return None
|
|
54
47
|
|
|
55
|
-
m = re.search(r"\.{3}(\S+)\b", output[0])
|
|
48
|
+
m = re.search(r"\.{3}(\S+)\b", list(output)[0])
|
|
56
49
|
if m:
|
|
57
50
|
return m.group(1)
|
|
58
51
|
return None
|