Add `path` fact (brew operations fail due to missing path on macOS by default)
See original GitHub issueDescribe the bug
Currently, all brew
operations (or at least, I would assume all) fail on macOS because the PATH
does not contain /usr/local/bin
by default ( I could have sworn this used to work in the past?). The default path that I get with pyinfra <host> exec -- env
is PATH=/usr/bin:/bin:/usr/sbin:/sbin
.
I don’t think this is due to a change with my setup/environment.
To Reproduce Steps to reproduce the behavior (include code & usage example): Basic deploy that fails:
from pyinfra.operations import brew
brew.packages(
name="Test install",
packages=["tree"],
latest=True,
update=True,
)
Failed run:
❯ pyinfra inventories/----.py --limit ---- deploys/tasks/base/simple.py --debug
[pyinfra_cli.main] Checking potential directory: deploys/tasks/base
[pyinfra_cli.main] Setting directory to: deploys/tasks/base
--> Loading config...
--> Loading inventory...
[pyinfra_cli.inventory] Creating fake inventory...
[pyinfra_cli.inventory] Looking for group data in: deploys/tasks/base/group_data/all.py
[pyinfra_cli.inventory] Looking for group data in: deploys/tasks/base/group_data/<inventory file>
--> Connecting to hosts...
[pyinfra.api.connectors.ssh] Connecting to: ---- ({'allow_agent': True, 'look_for_keys': True, 'hostname': ----, 'timeout': 10})
[----] Connected
[pyinfra.api.state] Activating host: ----
--> Preparing operations...
Loading: deploys/tasks/base/simple.py
[pyinfra.api.operation] Adding operation, {'Test install'}, opOrder=(8,), opHash=bd05d67789318d253923550b574ee43b70bbb955
[pyinfra.api.facts] Getting fact: brew_packages (ensure_hosts: (Host(----),))
[pyinfra.api.connectors.ssh] Running command on ----: (pty=False) sh -c '! command -v brew > /dev/null || (brew list --versions)'
[pyinfra.api.connectors.ssh] Waiting for exit status...
[pyinfra.api.connectors.ssh] Command exit status: 0
[pyinfra.api.facts] Loaded fact brew_packages
[----] Ready: deploys/tasks/base/simple.py
--> Proposed changes:
Groups: ----
[----] Operations: 1 Commands: 2
--> Beginning operation run...
--> Starting operation: Test install
[pyinfra.api.operations] Starting operation Test install on ----
[pyinfra.api.connectors.ssh] Running command on ----: (pty=None) sh -c 'brew update'
[pyinfra.api.connectors.ssh] Waiting for exit status...
[pyinfra.api.connectors.ssh] Command exit status: 127
[----] sh: brew: command not found
[----] Error
[pyinfra.api.state] Failing hosts: ----
--> pyinfra error: No hosts remaining!
Adding shell_executable="bash -l"
allows the deploy to work properly.
Also wondering: Is it possible to run the brew
operations directly from the CLI in an adhoc manner? I tried pyinfra <host> brew update
but that did not work.
Expected behavior
Not sure what the best way to deal with this would be, especially since macOS and Linux have slightly different configurations for brew
by default. Maybe handle the expected case for each platform and then also add param to set the “brew install location” or something like that? Could also potentially get around this by modifying the environment. The env
global params works for this, but is there a way to append to the PATH
without fully overwriting the value?
Meta
- Include output of
pyinfra --support
.
❯ pyinfra --support
--> Support information:
System: Darwin
Platform: Darwin-18.7.0-x86_64-i386-64bit
Release: 18.7.0
Machine: x86_64
pyinfra: v1.3
Executable: /Users/----/.local/bin/pyinfra
Python: 3.7.8 (CPython, Clang 10.0.1 (clang-1001.0.46.4))
- How was pyinfra installed (source/pip)?
Installed via
pipx
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (4 by maintainers)
Top GitHub Comments
Hmm, I see. Yeah, I am connecting via ssh. Seems like it would be helpful to have a dedicated
path
fact, as well as the ability to append to ENV var, as opposed to completely overriding it.For now, I think I will just add a custom fact to get the
PATH
and then useenv={"PATH": f"/usr/local/bin:{path_fact}"}
or something to that effect.Thanks for the info on CLI use. I think I was getting confused with the way facts vs other operations are called (e.g.
pyinfra <host> fact <fact name>
vspyinfra <host> operation_cat.name
).@taranlu-houzz are you connecting to the Mac instance via SSH? I’ve been testing brew locally (using
@local
) which does work but has the full path from my login shell.I’ve encountered very similar issues with CentOS before which in some versions doesn’t have
/usr/local/bin
or/usr/local/sbin
in the default path - ultimately this isn’t somethingpyinfra
can fix itself. It should be possible to “fix” by overriding thePATH
variable by settingenv={'path': '/usr/local/bin'}
or similar.Running them via the CLI is possible:
pyinfra host brew.update
, for example (the docs have some more in depth examples of this too).