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.21k stars 5.48k forks source link

[BUG] salt-ssh /bin/sh shim failure #58946

Closed TimidRobot closed 4 years ago

TimidRobot commented 4 years ago

Description

I use salt-ssh for bootstrapping salt-minion. Recently it began failing (maybe after 3000.5 update? maybe after a Debian update?).

All of my salt-ssh invocations fail with an error like the following (including sudo salt-ssh HOST test.version):

    stdout:
        /bin/sh: 0: Can't open $HOME/.dd314d6e54f2.py

When I make the following change to /usr/lib/python2.7/dist-packages/salt/client/ssh/__init__.py, it works:

--- __init__.py.old 2020-11-13 18:48:26.941039563 +0000
+++ __init__.py.new 2020-11-13 18:49:17.760741526 +0000
@@ -1270,7 +1270,7 @@
             ret = self.shell.exec_cmd('"powershell {0}"'.format(target_shim_file))
         else:
             if not self.winrm:
-                ret = self.shell.exec_cmd('/bin/sh \'$HOME/{0}\''.format(target_shim_file))
+                ret = self.shell.exec_cmd('/bin/dash \'$HOME/{0}\''.format(target_shim_file))
             else:
                 ret = saltwinshell.call_python(self, target_shim_file)

However, if i copy /bin/dash to /bin/sh it does not work. There are no AppArmor errors on the target.

I'm fairly confident that it is not an issue with the shim file (ex. $HOME/.dd314d6e54f2.py). If, for example, I add self.shell.exec_cmd('ls -l \'$HOME/{0}\''.format(target_shim_file)), it works as expected.

Last, to further complicate matters, if I copy the /bin/sh '$HOME/.dd314d6e54f2.py' ssh command and execute it manually, it works fine. For example:

Setup With the exception of encrypted secrets, my entire configuration is public: creativecommons/sre-salt-prime: Site Reliability Engineering / DevOps SaltStack configuration files

Steps to Reproduce the behavior sudo salt-ssh HOST test.version

Expected behavior salt-ssh should be able to execute the shim without issue.

Versions Report

salt --versions-report (Provided by running salt --versions-report. Please also mention any differences in master/minion versions.) ``` Salt Version: Salt: 3000.5 Dependency Versions: cffi: Not Installed cherrypy: Not Installed dateutil: 2.5.3 docker-py: Not Installed gitdb: 2.0.0 gitpython: 2.1.1 Jinja2: 2.9.4 libgit2: Not Installed M2Crypto: Not Installed Mako: Not Installed msgpack-pure: Not Installed msgpack-python: 0.6.2 mysql-python: Not Installed pycparser: Not Installed pycrypto: 2.6.1 pycryptodome: Not Installed pygit2: Not Installed Python: 2.7.13 (default, Aug 22 2020, 10:03:02) python-gnupg: Not Installed PyYAML: 3.12 PyZMQ: 16.0.2 smmap: 2.0.1 timelib: Not Installed Tornado: 4.5.3 ZMQ: 4.2.1 System Versions: dist: debian 9.13 locale: UTF-8 machine: x86_64 release: 4.9.0-14-amd64 system: Linux version: debian 9.13 ```
Ch3LL commented 4 years ago

Duplicate of https://github.com/saltstack/salt/issues/58922

TimidRobot commented 4 years ago

Duplicate of #58922

The issue above is fixed by #58948. However the fix appears to be for a different code base than 3000.5 (assuming Python 2 vs Python 3). I believe the following change approximates the fix for 3000.5, in case anyone else needs to get 3000.5 working ASAP:

--- __init__.py.old 2020-11-13 18:48:26.941039563 +0000
+++ __init__.py.new 2020-11-16 15:25:38.277198560 +0000
@@ -1270,13 +1270,13 @@
             ret = self.shell.exec_cmd('"powershell {0}"'.format(target_shim_file))
         else:
             if not self.winrm:
-                ret = self.shell.exec_cmd('/bin/sh \'$HOME/{0}\''.format(target_shim_file))
+                ret = self.shell.exec_cmd('/bin/sh \'{0}\''.format(target_shim_file))
             else:
                 ret = saltwinshell.call_python(self, target_shim_file)

         # Remove shim from target system
         if not self.winrm:
-            self.shell.exec_cmd('rm \'$HOME/{0}\''.format(target_shim_file))
+            self.shell.exec_cmd('rm \'{0}\''.format(target_shim_file))
         else:
             self.shell.exec_cmd('del {0}'.format(target_shim_file))