pyinfra 3.1__tar.gz → 3.1.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.1 → pyinfra-3.1.1}/CHANGELOG.md +11 -0
- {pyinfra-3.1/pyinfra.egg-info → pyinfra-3.1.1}/PKG-INFO +1 -1
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/arguments.py +1 -1
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/deploy.py +8 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/host.py +2 -1
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/chroot.py +1 -1
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/local.py +1 -1
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/ssh.py +3 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/apt.py +2 -2
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/hardware.py +1 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/selinux.py +3 -1
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/apt.py +2 -1
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/files.py +2 -2
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/git.py +25 -2
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/server.py +1 -1
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/zfs.py +11 -11
- {pyinfra-3.1 → pyinfra-3.1.1/pyinfra.egg-info}/PKG-INFO +1 -1
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra_cli/util.py +2 -2
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_cli/test_cli_exceptions.py +2 -2
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_cli/test_cli_util.py +2 -4
- {pyinfra-3.1 → pyinfra-3.1.1}/LICENSE.md +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/MANIFEST.in +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/README.md +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/__init__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/__main__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/__init__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/arguments_typed.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/command.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/config.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/connect.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/connectors.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/exceptions.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/facts.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/inventory.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/operation.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/operations.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/state.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/api/util.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/__init__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/base.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/docker.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/dockerssh.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/ssh_util.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/sshuserclient/__init__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/sshuserclient/client.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/sshuserclient/config.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/terraform.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/util.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/connectors/vagrant.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/context.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/__init__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/apk.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/brew.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/bsdinit.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/cargo.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/choco.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/deb.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/dnf.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/docker.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/files.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/flatpak.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/gem.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/git.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/gpg.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/iptables.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/launchd.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/lxd.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/mysql.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/npm.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/openrc.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/pacman.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/pip.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/pkg.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/pkgin.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/postgres.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/postgresql.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/rpm.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/runit.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/server.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/snap.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/systemd.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/sysvinit.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/upstart.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/util/__init__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/util/databases.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/util/packaging.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/util/win_files.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/vzctl.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/xbps.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/yum.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/zfs.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/facts/zypper.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/local.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/__init__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/apk.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/brew.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/bsdinit.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/cargo.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/choco.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/dnf.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/docker.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/flatpak.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/gem.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/iptables.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/launchd.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/lxd.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/mysql.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/npm.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/openrc.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/pacman.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/pip.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/pkg.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/pkgin.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/postgres.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/postgresql.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/puppet.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/python.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/runit.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/selinux.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/snap.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/ssh.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/systemd.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/sysvinit.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/upstart.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/util/__init__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/util/docker.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/util/files.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/util/packaging.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/util/service.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/vzctl.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/xbps.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/yum.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/operations/zypper.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/progress.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/py.typed +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra/version.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra.egg-info/SOURCES.txt +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra.egg-info/dependency_links.txt +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra.egg-info/entry_points.txt +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra.egg-info/requires.txt +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra.egg-info/top_level.txt +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra_cli/__init__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra_cli/__main__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra_cli/commands.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra_cli/exceptions.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra_cli/inventory.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra_cli/log.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra_cli/main.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra_cli/prints.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyinfra_cli/virtualenv.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/pyproject.toml +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/setup.cfg +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/setup.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_api/__init__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_api/test_api.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_api/test_api_arguments.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_api/test_api_command.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_api/test_api_config.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_api/test_api_deploys.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_api/test_api_facts.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_api/test_api_host.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_api/test_api_inventory.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_api/test_api_operations.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_api/test_api_util.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_cli/__init__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_cli/test_cli.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_cli/test_cli_deploy.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_cli/test_cli_inventory.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_cli/test_context_objects.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_cli/util.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_connectors/__init__.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_connectors/test_chroot.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_connectors/test_docker.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_connectors/test_dockerssh.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_connectors/test_local.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_connectors/test_ssh.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_connectors/test_sshuserclient.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_connectors/test_terraform.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_connectors/test_util.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_connectors/test_vagrant.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_facts.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_global_arguments.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_operations.py +0 -0
- {pyinfra-3.1 → pyinfra-3.1.1}/tests/test_operations_utils.py +0 -0
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
# v3.1.1
|
|
2
|
+
|
|
3
|
+
- Improve errors with 2.x style `@decorator` (vs `@decorator()`) functions
|
|
4
|
+
- Document adding custom connectors (@simonhammes)
|
|
5
|
+
- Add basic API example to docs (@pirate)
|
|
6
|
+
- Fix sphinx warnings (@simonhammes)
|
|
7
|
+
- Fix force & pull arguments in `git.worktree` operation
|
|
8
|
+
- Fix `server.reboot` reconnection (@wackou)
|
|
9
|
+
- Fix chroot/local connector non-utf file gets (@evoldstad)
|
|
10
|
+
- Fix `AptSources` fact to parse components in order & with digits (@rsfzi)
|
|
11
|
+
|
|
1
12
|
# v3.1
|
|
2
13
|
|
|
3
14
|
Here's pyinfra 3.1 - a release primarily driven by contributors new and old - a HUGE THANK YOU to all of you who dedicate time to work on pushing pyinfra forward. New stuff:
|
|
@@ -137,7 +137,7 @@ shell_argument_meta: dict[str, ArgumentMeta] = {
|
|
|
137
137
|
),
|
|
138
138
|
"_chdir": ArgumentMeta(
|
|
139
139
|
"Directory to switch to before executing the command.",
|
|
140
|
-
default=lambda _:
|
|
140
|
+
default=lambda _: None,
|
|
141
141
|
),
|
|
142
142
|
"_env": ArgumentMeta(
|
|
143
143
|
"Dictionary of environment variables to set.",
|
|
@@ -60,6 +60,14 @@ def deploy(name: Optional[str] = None, data_defaults=None):
|
|
|
60
60
|
and wraps any operations called inside with any deploy-wide kwargs/data.
|
|
61
61
|
"""
|
|
62
62
|
|
|
63
|
+
if name and not isinstance(name, str):
|
|
64
|
+
raise PyinfraError(
|
|
65
|
+
(
|
|
66
|
+
"The `deploy` decorator must be called, ie `@deploy()`, "
|
|
67
|
+
"see: https://docs.pyinfra.com/en/3.x/compatibility.html#upgrading-pyinfra-from-2-x-3-x" # noqa
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
|
|
63
71
|
def decorator(func: Callable[P, Any]) -> PyinfraOperation[P]:
|
|
64
72
|
func.deploy_name = name or func.__name__ # type: ignore[attr-defined]
|
|
65
73
|
if data_defaults:
|
|
@@ -406,12 +406,13 @@ class Host:
|
|
|
406
406
|
# Disconnect is an optional function for connectors if needed
|
|
407
407
|
disconnect_func = getattr(self.connector, "disconnect", None)
|
|
408
408
|
if disconnect_func:
|
|
409
|
-
|
|
409
|
+
disconnect_func()
|
|
410
410
|
|
|
411
411
|
# TODO: consider whether this should be here!
|
|
412
412
|
remove_any_sudo_askpass_file(self)
|
|
413
413
|
|
|
414
414
|
self.state.trigger_callbacks("host_disconnect", self)
|
|
415
|
+
self.connected = False
|
|
415
416
|
|
|
416
417
|
def run_shell_command(self, *args, **kwargs) -> tuple[bool, CommandOutput]:
|
|
417
418
|
"""
|
|
@@ -174,7 +174,7 @@ class ChrootConnector(BaseConnector):
|
|
|
174
174
|
)
|
|
175
175
|
|
|
176
176
|
# Load the temporary file and write it to our file or IO object
|
|
177
|
-
with open(temp_filename,
|
|
177
|
+
with open(temp_filename, "rb") as temp_f:
|
|
178
178
|
with get_file_io(filename_or_io, "wb") as file_io:
|
|
179
179
|
data = temp_f.read()
|
|
180
180
|
data_bytes: bytes
|
|
@@ -184,7 +184,7 @@ class LocalConnector(BaseConnector):
|
|
|
184
184
|
raise IOError(output.stderr)
|
|
185
185
|
|
|
186
186
|
# Load our file or IO object and write it to the temporary file
|
|
187
|
-
with open(temp_filename,
|
|
187
|
+
with open(temp_filename, "rb") as temp_f:
|
|
188
188
|
with get_file_io(filename_or_io, "wb") as file_io:
|
|
189
189
|
data_bytes: bytes
|
|
190
190
|
|
|
@@ -9,7 +9,7 @@ from .util import make_cat_files_command
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def parse_apt_repo(name):
|
|
12
|
-
regex = r"^(deb(?:-src)?)(?:\s+\[([^\]]+)\])?\s+([^\s]+)\s+([^\s]+)\s+([a-z-\s]*)$"
|
|
12
|
+
regex = r"^(deb(?:-src)?)(?:\s+\[([^\]]+)\])?\s+([^\s]+)\s+([^\s]+)\s+([a-z-\s\d]*)$"
|
|
13
13
|
|
|
14
14
|
matches = re.match(regex, name)
|
|
15
15
|
|
|
@@ -32,7 +32,7 @@ def parse_apt_repo(name):
|
|
|
32
32
|
"type": matches.group(1),
|
|
33
33
|
"url": matches.group(3),
|
|
34
34
|
"distribution": matches.group(4),
|
|
35
|
-
"components":
|
|
35
|
+
"components": list(matches.group(5).split()),
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
|
|
@@ -58,7 +58,8 @@ class FileContext(FactBase):
|
|
|
58
58
|
class FileContextMapping(FactBase):
|
|
59
59
|
"""
|
|
60
60
|
Returns structured SELinux file context data for the specified target path prefix
|
|
61
|
-
using the same format as :ref:`selinux.FileContext`.
|
|
61
|
+
using the same format as :ref:`facts:selinux.FileContext`.
|
|
62
|
+
If there is no mapping, it returns ``{}``
|
|
62
63
|
Note: This fact requires root privileges.
|
|
63
64
|
"""
|
|
64
65
|
|
|
@@ -85,6 +86,7 @@ class SEPorts(FactBase):
|
|
|
85
86
|
Note: This fact requires root privileges.
|
|
86
87
|
|
|
87
88
|
.. code:: python
|
|
89
|
+
|
|
88
90
|
{
|
|
89
91
|
"tcp": { 22: "ssh_port_t", ...},
|
|
90
92
|
"udp": { ...}
|
|
@@ -53,7 +53,8 @@ def key(src: str | None = None, keyserver: str | None = None, keyid: str | list[
|
|
|
53
53
|
.. warning::
|
|
54
54
|
``apt-key`` is deprecated in Debian, it is recommended NOT to use this
|
|
55
55
|
operation and instead follow the instructions here:
|
|
56
|
-
|
|
56
|
+
|
|
57
|
+
https://wiki.debian.org/DebianRepository/UseThirdParty
|
|
57
58
|
|
|
58
59
|
**Examples:**
|
|
59
60
|
|
|
@@ -256,7 +256,7 @@ def line(
|
|
|
256
256
|
change bits of lines, see ``files.replace``.
|
|
257
257
|
|
|
258
258
|
Regex line escaping:
|
|
259
|
-
If matching special characters (eg a crontab line containing
|
|
259
|
+
If matching special characters (eg a crontab line containing ``*``), remember to escape
|
|
260
260
|
it first using Python's ``re.escape``.
|
|
261
261
|
|
|
262
262
|
Backup:
|
|
@@ -523,7 +523,7 @@ def sync(
|
|
|
523
523
|
+ mode: permissions of the files
|
|
524
524
|
+ dir_mode: permissions of the directories
|
|
525
525
|
+ delete: delete remote files not present locally
|
|
526
|
-
+ exclude: string or list/tuple of strings to match & exclude files (eg
|
|
526
|
+
+ exclude: string or list/tuple of strings to match & exclude files (eg ``*.pyc``)
|
|
527
527
|
+ exclude_dir: string or list/tuple of strings to match & exclude directories (eg node_modules)
|
|
528
528
|
+ add_deploy_dir: interpret src as relative to deploy directory instead of current directory
|
|
529
529
|
|
|
@@ -184,7 +184,7 @@ def worktree(
|
|
|
184
184
|
+ from_remote_branch: a 2-tuple ``(remote, branch)`` that identifies a remote branch
|
|
185
185
|
+ present: whether the working tree should exist
|
|
186
186
|
+ assume_repo_exists: whether to assume the main repo exists
|
|
187
|
-
+ force:
|
|
187
|
+
+ force: whether to use ``--force`` when adding/removing worktrees
|
|
188
188
|
+ user: chown files to this user after
|
|
189
189
|
+ group: chown files to this group after
|
|
190
190
|
|
|
@@ -205,6 +205,14 @@ def worktree(
|
|
|
205
205
|
commitish="4e091aa0"
|
|
206
206
|
)
|
|
207
207
|
|
|
208
|
+
git.worktree(
|
|
209
|
+
name="Create a worktree from the tag `4e091aa0`, even if already registered",
|
|
210
|
+
repo="/usr/local/src/pyinfra/master",
|
|
211
|
+
worktree="/usr/local/src/pyinfra/2.x",
|
|
212
|
+
commitish="2.x",
|
|
213
|
+
force=True
|
|
214
|
+
)
|
|
215
|
+
|
|
208
216
|
git.worktree(
|
|
209
217
|
name="Create a worktree with a new local branch `v1.0`",
|
|
210
218
|
repo="/usr/local/src/pyinfra/master",
|
|
@@ -250,6 +258,15 @@ def worktree(
|
|
|
250
258
|
commitish="v1.0"
|
|
251
259
|
)
|
|
252
260
|
|
|
261
|
+
git.worktree(
|
|
262
|
+
name="Idempotent worktree creation, never pulls",
|
|
263
|
+
repo="/usr/local/src/pyinfra/master",
|
|
264
|
+
worktree="/usr/local/src/pyinfra/hotfix",
|
|
265
|
+
new_branch="v1.0",
|
|
266
|
+
commitish="v1.0",
|
|
267
|
+
pull=False
|
|
268
|
+
)
|
|
269
|
+
|
|
253
270
|
git.worktree(
|
|
254
271
|
name="Pull an existing worktree already linked to a tracking branch",
|
|
255
272
|
repo="/usr/local/src/pyinfra/master",
|
|
@@ -295,6 +312,9 @@ def worktree(
|
|
|
295
312
|
elif detached:
|
|
296
313
|
command_parts.append("--detach")
|
|
297
314
|
|
|
315
|
+
if force:
|
|
316
|
+
command_parts.append("--force")
|
|
317
|
+
|
|
298
318
|
command_parts.append(worktree)
|
|
299
319
|
|
|
300
320
|
if commitish:
|
|
@@ -317,9 +337,12 @@ def worktree(
|
|
|
317
337
|
|
|
318
338
|
# It exists and we still want it => pull/rebase it
|
|
319
339
|
elif host.get_fact(Directory, path=worktree) and present:
|
|
340
|
+
if not pull:
|
|
341
|
+
host.noop("Pull is disabled")
|
|
342
|
+
|
|
320
343
|
# pull the worktree only if it's already linked to a tracking branch or
|
|
321
344
|
# if a remote branch is set
|
|
322
|
-
|
|
345
|
+
elif host.get_fact(GitTrackingBranch, repo=worktree) or from_remote_branch:
|
|
323
346
|
command = "cd {0} && git pull".format(worktree)
|
|
324
347
|
|
|
325
348
|
if rebase:
|
|
@@ -89,7 +89,7 @@ def reboot(delay=10, interval=1, reboot_timeout=300):
|
|
|
89
89
|
sleep(delay)
|
|
90
90
|
max_retries = round(reboot_timeout / interval)
|
|
91
91
|
|
|
92
|
-
host.
|
|
92
|
+
host.disconnect() # make sure we are properly disconnected
|
|
93
93
|
retries = 0
|
|
94
94
|
|
|
95
95
|
while True:
|
|
@@ -33,14 +33,14 @@ def dataset(
|
|
|
33
33
|
|
|
34
34
|
.. code:: python
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
zfs.dataset(
|
|
37
|
+
"tank/srv",
|
|
38
|
+
mountpoint="/srv",
|
|
39
|
+
compression="lz4",
|
|
40
|
+
properties={"com.sun:auto_snapshot": "true"}
|
|
41
|
+
)
|
|
42
|
+
zfs.dataset("tank/vm-disks/db_srv_04", volume_size="32G") # creates a volume
|
|
43
|
+
zfs.dataset("tank/home@old_version", present=False)
|
|
44
44
|
|
|
45
45
|
"""
|
|
46
46
|
|
|
@@ -99,7 +99,7 @@ def snapshot(snapshot_name, present=True, recursive=False, properties={}, **extr
|
|
|
99
99
|
|
|
100
100
|
.. code:: python
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
zfs.snapshot("tank/home@weekly_backup")
|
|
103
103
|
|
|
104
104
|
"""
|
|
105
105
|
properties.update(extra_props)
|
|
@@ -134,7 +134,7 @@ def volume(
|
|
|
134
134
|
|
|
135
135
|
.. code:: python
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
zfs.volume("tank/vm-disks/db_srv_04", "32G")
|
|
138
138
|
|
|
139
139
|
"""
|
|
140
140
|
properties.update(extra_props)
|
|
@@ -163,7 +163,7 @@ def filesystem(fs_name, present=True, recursive=False, properties={}, **extra_pr
|
|
|
163
163
|
|
|
164
164
|
.. code:: python
|
|
165
165
|
|
|
166
|
-
|
|
166
|
+
zfs.filesystem("tank/vm-disks/db_srv_04", "32G")
|
|
167
167
|
|
|
168
168
|
"""
|
|
169
169
|
properties.update(extra_props)
|
|
@@ -180,13 +180,13 @@ def try_import_module_attribute(path, prefix=None, raise_for_none=True):
|
|
|
180
180
|
|
|
181
181
|
if module is None:
|
|
182
182
|
if raise_for_none:
|
|
183
|
-
raise CliError(f"No such module: {possible_modules[
|
|
183
|
+
raise CliError(f"No such module: {possible_modules[0]}")
|
|
184
184
|
return
|
|
185
185
|
|
|
186
186
|
attr = getattr(module, attr_name, None)
|
|
187
187
|
if attr is None:
|
|
188
188
|
if raise_for_none:
|
|
189
|
-
raise CliError(f"No such attribute in module {possible_modules[
|
|
189
|
+
raise CliError(f"No such attribute in module {possible_modules[0]}: {attr_name}")
|
|
190
190
|
return
|
|
191
191
|
|
|
192
192
|
return attr
|
|
@@ -38,13 +38,13 @@ class TestCliExceptions(TestCase):
|
|
|
38
38
|
def test_no_fact_module(self):
|
|
39
39
|
self.assert_cli_exception(
|
|
40
40
|
["my-server.net", "fact", "not_a_module.SomeFact"],
|
|
41
|
-
"No such module:
|
|
41
|
+
"No such module: not_a_module",
|
|
42
42
|
)
|
|
43
43
|
|
|
44
44
|
def test_no_fact_cls(self):
|
|
45
45
|
self.assert_cli_exception(
|
|
46
46
|
["my-server.net", "fact", "server.NotAFact"],
|
|
47
|
-
"No such attribute in module
|
|
47
|
+
"No such attribute in module server: NotAFact",
|
|
48
48
|
)
|
|
49
49
|
|
|
50
50
|
|
|
@@ -30,15 +30,13 @@ class TestCliUtil(TestCase):
|
|
|
30
30
|
def test_setup_no_module(self):
|
|
31
31
|
with self.assertRaises(CliError) as context:
|
|
32
32
|
get_func_and_args(("no.op",))
|
|
33
|
-
assert context.exception.message == "No such module:
|
|
33
|
+
assert context.exception.message == "No such module: no"
|
|
34
34
|
|
|
35
35
|
def test_setup_no_op(self):
|
|
36
36
|
with self.assertRaises(CliError) as context:
|
|
37
37
|
get_func_and_args(("server.no",))
|
|
38
38
|
|
|
39
|
-
assert
|
|
40
|
-
context.exception.message == "No such attribute in module pyinfra.operations.server: no"
|
|
41
|
-
)
|
|
39
|
+
assert context.exception.message == "No such attribute in module server: no"
|
|
42
40
|
|
|
43
41
|
def test_setup_op_and_args(self):
|
|
44
42
|
commands = ("pyinfra.operations.server.user", "one", "two", "hello=world")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|