-
-
Notifications
You must be signed in to change notification settings - Fork 446
Open
Description
Describe the bug
When using server.service to manage mysql-server service on FreeBSD 14 machine, pyinfra is trying to handle the service script as an old sysvinit system
I believe this is because of the conditional exit before determining the exactly case:
elif (
host.get_fact(Which, command="service")
or host.get_fact(Link, path="/etc/init.d")
or host.get_fact(Directory, path="/etc/init.d")
):
service_operation = sysvinit.service
# NOTE: important that we are not Linux here because /etc/rc.d will exist but checking it's
# contents may trigger things (like a reboot: https://github.com/Fizzadar/pyinfra/issues/819)
elif host.get_fact(Os) != "Linux" and bool(host.get_fact(Directory, path="/etc/rc.d")):
service_operation = bsdinit.service
To Reproduce
from pyinfra.operations import server, pkg
pkg.packages(
packages="mysql84-server",
present=True,
_sudo = True,
)
server.service(
name = f"Enable service mysql",
service="mysql-server",
running=True,
enabled=True,
_sudo=True,
)
- Operation code & usage
using following operations: server, pkg - Target system information
freebsd 14 as vagrant box - Example using the
@dockerconnector (helps isolate the problem)
pyinfra @vagrant main.py
Expected behavior
Expected to handle service enablement and startup
Meta
- Include output of
pyinfra --support.
❯ pyinfra --support
If you are having issues with pyinfra or wish to make feature requests, please
check out the GitHub issues at https://github.com/Fizzadar/pyinfra/issues .
When adding an issue, be sure to include the following:
System: Darwin
Platform: macOS-15.5-arm64-arm-64bit-Mach-O
Release: 24.5.0
Machine: arm64
pyinfra: v3.5.1
click: v8.3.0
distro: v1.9.0
gevent: v25.9.1
jinja2: v3.1.6
packaging: v25.0
paramiko: v3.5.1
python-dateutil: v2.9.0.post0
typeguard: v4.4.4
typing-extensions: v4.15.0
Executable: /Users/alebedev/.pyenv/versions/infra/bin/pyinfra
Python: 3.14.0 (CPython, Clang 17.0.0 (clang-1700.0.13.5))
- How was pyinfra installed (source/pip)?
pip - Include pyinfra-debug.log (if one was created)
no pyinfra-debug.log created - Consider including output with
-vvand--debug.
❯ pyinfra @vagrant main.py -vv
--> Loading config...
--> Loading inventory...
Getting Vagrant config...
localhost: >>> vagrant status --machine-readable
localhost: >>> vagrant ssh-config default
--> Connecting to hosts...
[@vagrant/default] Connected
--> Preparing operation files...
Loading: main.py
[@vagrant/default] >>> sudo -H -n sh -c '! (test -e /etc/installurl || test -L /etc/installurl ) || ( stat -c '"'"'user=%U group=%G mode=%A atime=%X mtime=%Y ctime=%Z size=%s %N'"'"' /etc/installurl 2> /dev/null || stat -f '"'"'user=%Su group=%Sg mode=%Sp atime=%a mtime=%m ctime=%c size=%z %N%SY'"'"' /etc/installurl || ls -ld /etc/installurl )'
[@vagrant/default] Loaded fact files.File (path=/etc/installurl)
[@vagrant/default] >>> sudo -H -n sh -c 'uname -s'
[@vagrant/default] Loaded fact server.Os
[@vagrant/default] >>> sudo -H -n sh -c 'uname -r'
[@vagrant/default] Loaded fact server.OsVersion
[@vagrant/default] >>> sudo -H -n sh -c 'uname -m'
[@vagrant/default] Loaded fact server.Arch
[@vagrant/default] >>> sudo -H -n sh -c 'command -v pkg || true'
[@vagrant/default] Loaded fact server.Which (command=pkg)
[@vagrant/default] >>> sudo -H -n sh -c 'pkg info || pkg_info || true'
[@vagrant/default] Loaded fact pkg.PkgPackages
[@vagrant/default] noop: package mysql84-server is installed (8.4.5)
[@vagrant/default] >>> sudo -H -n sh -c 'command -v systemctl || true'
[@vagrant/default] Loaded fact server.Which (command=systemctl)
[@vagrant/default] >>> sudo -H -n sh -c 'command -v rc-service || true'
[@vagrant/default] Loaded fact server.Which (command=rc-service)
[@vagrant/default] >>> sudo -H -n sh -c 'command -v initctl || true'
[@vagrant/default] Loaded fact server.Which (command=initctl)
[@vagrant/default] >>> sudo -H -n sh -c 'command -v sv || true'
[@vagrant/default] Loaded fact server.Which (command=sv)
[@vagrant/default] >>> sudo -H -n sh -c 'command -v service || true'
[@vagrant/default] Loaded fact server.Which (command=service)
[@vagrant/default] >>> sudo -H -n sh -c '
for SERVICE in `ls /etc/init.d/`; do
_=`cat /etc/init.d/$SERVICE | grep "### BEGIN INIT INFO"`
if [ "$?" = "0" ]; then
STATUS=`/etc/init.d/$SERVICE status`
echo "$SERVICE=$?"
fi
done
'
[@vagrant/default] Loaded fact sysvinit.InitdStatus
[@vagrant/default] Ready: main.py
--> Detected changes:
Operation Change Conditional Change
pkg.packages (packages=mysql84-server, present=True) - -
Enable service mysql 1 (@vagrant/default) -
Detected changes may not include every change pyinfra will execute.
Hidden side effects of operations may alter behaviour of future operations,
this will be shown in the results. The remote state will always be updated
to reflect the state defined by the input operations.
Detected changes displayed above, skip this step with -y
--> Beginning operation run...
--> Starting operation: pkg.packages (packages=mysql84-server, present=True)
[@vagrant/default] >>> sudo -H -n sh -c '! (test -e /etc/installurl || test -L /etc/installurl ) || ( stat -c '"'"'user=%U group=%G mode=%A atime=%X mtime=%Y ctime=%Z size=%s %N'"'"' /etc/installurl 2> /dev/null || stat -f '"'"'user=%Su group=%Sg mode=%Sp atime=%a mtime=%m ctime=%c size=%z %N%SY'"'"' /etc/installurl || ls -ld /etc/installurl )'
[@vagrant/default] Loaded fact files.File (path=/etc/installurl)
[@vagrant/default] >>> sudo -H -n sh -c 'uname -s'
[@vagrant/default] Loaded fact server.Os
[@vagrant/default] >>> sudo -H -n sh -c 'uname -r'
[@vagrant/default] Loaded fact server.OsVersion
[@vagrant/default] >>> sudo -H -n sh -c 'uname -m'
[@vagrant/default] Loaded fact server.Arch
[@vagrant/default] >>> sudo -H -n sh -c 'command -v pkg || true'
[@vagrant/default] Loaded fact server.Which (command=pkg)
[@vagrant/default] >>> sudo -H -n sh -c 'pkg info || pkg_info || true'
[@vagrant/default] Loaded fact pkg.PkgPackages
[@vagrant/default] noop: package mysql84-server is installed (8.4.5)
[@vagrant/default] No changes
--> Starting operation: Enable service mysql
[@vagrant/default] >>> sudo -H -n sh -c 'command -v systemctl || true'
[@vagrant/default] Loaded fact server.Which (command=systemctl)
[@vagrant/default] >>> sudo -H -n sh -c 'command -v rc-service || true'
[@vagrant/default] Loaded fact server.Which (command=rc-service)
[@vagrant/default] >>> sudo -H -n sh -c 'command -v initctl || true'
[@vagrant/default] Loaded fact server.Which (command=initctl)
[@vagrant/default] >>> sudo -H -n sh -c 'command -v sv || true'
[@vagrant/default] Loaded fact server.Which (command=sv)
[@vagrant/default] >>> sudo -H -n sh -c 'command -v service || true'
[@vagrant/default] Loaded fact server.Which (command=service)
[@vagrant/default] >>> sudo -H -n sh -c '
for SERVICE in `ls /etc/init.d/`; do
_=`cat /etc/init.d/$SERVICE | grep "### BEGIN INIT INFO"`
if [ "$?" = "0" ]; then
STATUS=`/etc/init.d/$SERVICE status`
echo "$SERVICE=$?"
fi
done
'
[@vagrant/default] Loaded fact sysvinit.InitdStatus
[@vagrant/default] >>> sudo -H -n sh -c '/etc/init.d/mysql-server start'
[@vagrant/default] sh: /etc/init.d/mysql-server: not found
[@vagrant/default] Error: executed 0 commands
--> Disconnecting from hosts...
--> pyinfra error: No hosts remaining!
❯ pyinfra @vagrant main.py --debug
--> Loading config...
--> Loading inventory...
[pyinfra_cli.inventory] Creating fake inventory...
Getting Vagrant config...
[pyinfra.connectors.util] --> Waiting for exit status...
[pyinfra.connectors.util] --> Command exit status: 0
[pyinfra.connectors.vagrant] Loading SSH config for default
[pyinfra.connectors.util] --> Waiting for exit status...
[pyinfra.connectors.util] --> Command exit status: 0
[pyinfra.connectors.vagrant] Got Vagrant SSH info:
['Host default', 'HostName 127.0.0.1', 'User vagrant', 'Port 2222', 'UserKnownHostsFile /dev/null', 'StrictHostKeyChecking no', 'PasswordAuthentication no', 'IdentityFile /Users/alebedev/projects/infra/.vagrant/machines/default/virtualbox/private_key', 'IdentitiesOnly yes', 'LogLevel FATAL', 'PubkeyAcceptedKeyTypes +ssh-rsa', 'HostKeyAlgorithms +ssh-rsa', '']
[pyinfra_cli.inventory] Checking possible group_data at: /Users/alebedev/projects/infra/group_data
[pyinfra.connectors.vagrant] Got Vagrant SSH info:
['Host default', 'HostName 127.0.0.1', 'User vagrant', 'Port 2222', 'UserKnownHostsFile /dev/null', 'StrictHostKeyChecking no', 'PasswordAuthentication no', 'IdentityFile /Users/alebedev/projects/infra/.vagrant/machines/default/virtualbox/private_key', 'IdentitiesOnly yes', 'LogLevel FATAL', 'PubkeyAcceptedKeyTypes +ssh-rsa', 'HostKeyAlgorithms +ssh-rsa', '']
--> Connecting to hosts...
[pyinfra.connectors.ssh] Connecting to: 127.0.0.1 ({'allow_agent': False, 'look_for_keys': False, '_pyinfra_ssh_forward_agent': False, '_pyinfra_ssh_config_file': None, '_pyinfra_ssh_known_hosts_file': None, '_pyinfra_ssh_strict_host_key_checking': 'accept-new', '_pyinfra_ssh_paramiko_connect_kwargs': None, 'username': 'vagrant', 'port': 2222, 'timeout': 10, 'pkey': PKey(alg=ED25519, bits=256, fp=SHA256:efIsuzMq8Qo4F3IGWZ4nNe1MsxGdzBsI5vcdj6amYew)})
[pyinfra.connectors.sshuserclient.client] Loading SSH config: None
[@vagrant/default] Connected
[pyinfra.api.state] Activating host: @vagrant/default
--> Preparing operation files...
Loading: main.py
[pyinfra.api.operation] Adding operation, {'pkg.packages'}, opOrder=(0, 27), opHash=659ab31686b0d58dc7a9e32eb9de81d0f07a8459
[pyinfra.api.facts] Getting fact: files.File (path=/etc/installurl) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c '! (test -e /etc/installurl || test -L /etc/installurl ) || ( stat -c '"'"'user=%U group=%G mode=%A atime=%X mtime=%Y ctime=%Z size=%s %N'"'"' /etc/installurl 2> /dev/null || stat -f '"'"'user=%Su group=%Sg mode=%Sp atime=%a mtime=%m ctime=%c size=%z %N%SY'"'"' /etc/installurl || ls -ld /etc/installurl )'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact files.File (path=/etc/installurl)
[pyinfra.api.facts] Getting fact: server.Os () (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'uname -s'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Os
[pyinfra.api.facts] Getting fact: server.OsVersion () (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'uname -r'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.OsVersion
[pyinfra.api.facts] Getting fact: server.Arch () (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'uname -m'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Arch
[pyinfra.api.facts] Getting fact: server.Which (command=pkg) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'command -v pkg || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Which (command=pkg)
[pyinfra.api.facts] Getting fact: pkg.PkgPackages () (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'pkg info || pkg_info || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact pkg.PkgPackages
[pyinfra.api.host] [@vagrant/default] noop: package mysql84-server is installed (8.4.5)
[pyinfra.api.operation] Adding operation, {'Enable service mysql'}, opOrder=(0, 42), opHash=dcacca10d0098e2654c41fa3e5ea6f51f7b07533
[pyinfra.api.facts] Getting fact: server.Which (command=systemctl) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'command -v systemctl || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Which (command=systemctl)
[pyinfra.api.facts] Getting fact: server.Which (command=rc-service) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'command -v rc-service || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Which (command=rc-service)
[pyinfra.api.facts] Getting fact: server.Which (command=initctl) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'command -v initctl || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Which (command=initctl)
[pyinfra.api.facts] Getting fact: server.Which (command=sv) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'command -v sv || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Which (command=sv)
[pyinfra.api.facts] Getting fact: server.Which (command=service) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'command -v service || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Which (command=service)
[pyinfra.api.facts] Getting fact: sysvinit.InitdStatus () (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c '
for SERVICE in `ls /etc/init.d/`; do
_=`cat /etc/init.d/$SERVICE | grep "### BEGIN INIT INFO"`
if [ "$?" = "0" ]; then
STATUS=`/etc/init.d/$SERVICE status`
echo "$SERVICE=$?"
fi
done
'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact sysvinit.InitdStatus
[@vagrant/default] Ready: main.py
--> Detected changes:
Operation Change Conditional Change
pkg.packages (packages=mysql84-server, present=True) - -
Enable service mysql 1 (@vagrant/default) -
Detected changes may not include every change pyinfra will execute.
Hidden side effects of operations may alter behaviour of future operations,
this will be shown in the results. The remote state will always be updated
to reflect the state defined by the input operations.
Detected changes displayed above, skip this step with -y
--> Beginning operation run...
--> Starting operation: pkg.packages (packages=mysql84-server, present=True)
[pyinfra.api.operations] Starting operation {'pkg.packages'} on @vagrant/default
[pyinfra.api.facts] Getting fact: files.File (path=/etc/installurl) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c '! (test -e /etc/installurl || test -L /etc/installurl ) || ( stat -c '"'"'user=%U group=%G mode=%A atime=%X mtime=%Y ctime=%Z size=%s %N'"'"' /etc/installurl 2> /dev/null || stat -f '"'"'user=%Su group=%Sg mode=%Sp atime=%a mtime=%m ctime=%c size=%z %N%SY'"'"' /etc/installurl || ls -ld /etc/installurl )'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact files.File (path=/etc/installurl)
[pyinfra.api.facts] Getting fact: server.Os () (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'uname -s'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Os
[pyinfra.api.facts] Getting fact: server.OsVersion () (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'uname -r'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.OsVersion
[pyinfra.api.facts] Getting fact: server.Arch () (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'uname -m'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Arch
[pyinfra.api.facts] Getting fact: server.Which (command=pkg) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'command -v pkg || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Which (command=pkg)
[pyinfra.api.facts] Getting fact: pkg.PkgPackages () (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'pkg info || pkg_info || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact pkg.PkgPackages
[pyinfra.api.host] [@vagrant/default] noop: package mysql84-server is installed (8.4.5)
[@vagrant/default] No changes
--> Starting operation: Enable service mysql
[pyinfra.api.operations] Starting operation {'Enable service mysql'} on @vagrant/default
[pyinfra.api.facts] Getting fact: server.Which (command=systemctl) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'command -v systemctl || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Which (command=systemctl)
[pyinfra.api.facts] Getting fact: server.Which (command=rc-service) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'command -v rc-service || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Which (command=rc-service)
[pyinfra.api.facts] Getting fact: server.Which (command=initctl) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'command -v initctl || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Which (command=initctl)
[pyinfra.api.facts] Getting fact: server.Which (command=sv) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'command -v sv || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Which (command=sv)
[pyinfra.api.facts] Getting fact: server.Which (command=service) (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c 'command -v service || true'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact server.Which (command=service)
[pyinfra.api.facts] Getting fact: sysvinit.InitdStatus () (ensure_hosts: None)
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c '
for SERVICE in `ls /etc/init.d/`; do
_=`cat /etc/init.d/$SERVICE | grep "### BEGIN INIT INFO"`
if [ "$?" = "0" ]; then
STATUS=`/etc/init.d/$SERVICE status`
echo "$SERVICE=$?"
fi
done
'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] [@vagrant/default] Loaded fact sysvinit.InitdStatus
[pyinfra.connectors.ssh] Running command on @vagrant/default: (pty=False) sudo -H -n sh -c '/etc/init.d/mysql-server start'
[pyinfra.connectors.ssh] Waiting for exit status...
[pyinfra.connectors.ssh] Command exit status: 127
[@vagrant/default] sh: /etc/init.d/mysql-server: not found
[@vagrant/default] Error: executed 0 commands
[pyinfra.api.state] Failing hosts: @vagrant/default
--> Disconnecting from hosts...
--> pyinfra error: No hosts remaining!
Metadata
Metadata
Assignees
Labels
No labels