saltstack / salt

Software to automate the management and configuration of any infrastructure or application at scale. Install Salt from the Salt package repositories here:
https://docs.saltproject.io/salt/install-guide/en/latest/
Apache License 2.0
14.22k stars 5.49k forks source link

[BUG] salt-ssh 3007.0 attempts to run commands in default shell, even if default shell is fish #66246

Open jpmckinney opened 8 months ago

jpmckinney commented 8 months ago

Description

salt-ssh attempts to run commands in the default shell, even if the default shell is fish. For example, { ... } from here is valid in bash, but this causes an error in fish:

fish: Unknown command: '{ brew --prefix }'
fish: '{ ... }' is not supported for grouping commands. Please use 'begin; ...; end'

Setup

Steps to Reproduce the behavior

brew install fish
chsh -s /opt/homebrew/bin/fish

Close and re-open Terminal.app

Run any salt-ssh command

Expected behavior

No hang or error.

Versions Report

Cannot run salt --versions-report as it hangs instead.

Additional context

My present workaround is:

chsh -s /bin/bash

And set Terminal > Settings... > Shells open with: to Command (complete path): with /opt/homebrew/bin/fish

This leaves $SHELL set to /bin/bash.

Note that the comment here is both out-of-date and incorrect (su doesn't run sh – it runs the user's login shell, which can be any valid shell)

https://github.com/saltstack/salt/blob/d036b1177efeec175164571e9cc07b52cddf7844/salt/modules/cmdmod.py#L472-L475

The previous line of code it refers to was:

https://github.com/saltstack/salt/commit/ab8b39ce1043c2421e5c750d90bd529be5e32250#diff-700b7d75700c9eafa3ee48d01236e59f37b2ed81d998267136fbcc0224766497R419-R421

l33 commented 6 months ago

@jpmckinney do you run salt-ssh as root? The workaround does not work for me, I am in zsh not bash and changing to bash does not make a difference. The problem I am having is that su only runs without silently asking for a password if run as root.

I pointed down the source of the problem to the change of salt/utils/rsax931.py _find_libcrypto() which in 3006.8 used a different way to determine the location of the libraries location while in 3007 it uses salt.modules.mac_brew.homebrew_prefix() which ultimately does the su which does not work unless you run salt-ssh as root.

The change that I believe introduced the problem is 21d80bfa3abe189e71ac2f24a43090161925f6be.

jpmckinney commented 6 months ago

I've been able to run it as either root or non-root with my workaround.

As non-root I get messages like below, but then it actually still runs the command successfully:

[ERROR   ] Command 'su' failed with return code: 1
[ERROR   ] stdout: su: Sorry
[ERROR   ] retcode: 1
[ERROR   ] Command 'brew' failed with return code: 1
l33 commented 6 months ago

I wonder why this looks better on your setup. On my machine, salt-ssh does output the same error but ends in an uncaught exception and not produce any proper output if run as non-root (note I had to press return once after executing the command for the waiting su to continue):

$ salt-ssh --version
Traceback (most recent call last):
  File "/private/tmp/.venv/bin/salt-ssh", line 8, in <module>
    sys.exit(salt_ssh())
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/scripts.py", line 463, in salt_ssh
    import salt.cli.ssh
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/cli/ssh.py", line 3, in <module>
    import salt.client.ssh
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/client/__init__.py", line 30, in <module>
    import salt.cache
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/cache/__init__.py", line 12, in <module>
    import salt.loader
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/loader/__init__.py", line 33, in <module>
    from .lazy import SALT_BASE_PATH, FilterDictWrapper, LazyLoader
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/loader/lazy.py", line 29, in <module>
    import salt.utils.event
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/utils/event.py", line 67, in <module>
    import salt.channel.client
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/channel/client.py", line 14, in <module>
    import salt.crypt
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/crypt.py", line 34, in <module>
    import salt.utils.rsax931
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/utils/rsax931.py", line 174, in <module>
    libcrypto = _init_libcrypto()
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/utils/rsax931.py", line 127, in _init_libcrypto
    libcrypto = _load_libcrypto()
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/utils/rsax931.py", line 120, in _load_libcrypto
    return cdll.LoadLibrary(_find_libcrypto())
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/utils/rsax931.py", line 112, in _find_libcrypto
    raise OSError("Cannot locate OpenSSL libcrypto")
OSError: Cannot locate OpenSSL libcrypto
[ERROR   ] Command 'su' failed with return code: 1
[ERROR   ] stdout: Password:su: Sorry
[ERROR   ] retcode: 1
[ERROR   ] Command 'brew' failed with return code: 1
[ERROR   ] An un-handled exception was caught by Salt's global exception handler:
OSError: Cannot locate OpenSSL libcrypto
Traceback (most recent call last):
  File "/private/tmp/.venv/bin/salt-ssh", line 8, in <module>
    sys.exit(salt_ssh())
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/scripts.py", line 463, in salt_ssh
    import salt.cli.ssh
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/cli/ssh.py", line 3, in <module>
    import salt.client.ssh
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/client/__init__.py", line 30, in <module>
    import salt.cache
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/cache/__init__.py", line 12, in <module>
    import salt.loader
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/loader/__init__.py", line 33, in <module>
    from .lazy import SALT_BASE_PATH, FilterDictWrapper, LazyLoader
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/loader/lazy.py", line 29, in <module>
    import salt.utils.event
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/utils/event.py", line 67, in <module>
    import salt.channel.client
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/channel/client.py", line 14, in <module>
    import salt.crypt
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/crypt.py", line 34, in <module>
    import salt.utils.rsax931
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/utils/rsax931.py", line 174, in <module>
    libcrypto = _init_libcrypto()
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/utils/rsax931.py", line 127, in _init_libcrypto
    libcrypto = _load_libcrypto()
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/utils/rsax931.py", line 120, in _load_libcrypto
    return cdll.LoadLibrary(_find_libcrypto())
  File "/private/tmp/.venv/lib/python3.9/site-packages/salt/utils/rsax931.py", line 112, in _find_libcrypto
    raise OSError("Cannot locate OpenSSL libcrypto")
OSError: Cannot locate OpenSSL libcrypto

Now as root:

$ sudo salt-ssh --version
salt-ssh 3007.0 (Chlorine)
jpmckinney commented 6 months ago

One difference is that I installed as onedir described here https://docs.saltproject.io/salt/install-guide/en/latest/topics/install-by-operating-system/macos.html#install-salt-on-macos

You seem to have it installed in a virtualenv, so the actual Salt code/setup might differ.