Clean LD_LIBRARY_PATH when shelling out under a tiamat package

Signed-off-by: Pedro Algarvio <palgarvio@vmware.com>
This commit is contained in:
Pedro Algarvio 2022-03-28 18:51:18 +01:00 committed by Megan Wilhite
parent 924e17f6d9
commit 8266505c99
3 changed files with 158 additions and 0 deletions

View file

@ -134,3 +134,7 @@ del __define_global_system_encoding_variable__
# Import Salt's logging machinery
import salt._logging.impl # isort:skip pylint: disable=unused-import
# Do any nessessary patching when salt is running from a tiamat package
# This code is temporary and will exist until we can handle this on salt-pkg
import salt.utils.tiamatpkg # isort:skip pylint: disable=unused-import

51
salt/utils/tiamatpkg.py Normal file
View file

@ -0,0 +1,51 @@
import os
import subprocess
import sys
import salt.utils.vt
from salt.utils.decorators import memoize
# This code is temporary and will exist until we can handle this on salt-pkg
@memoize
def is_tiamat_packaged():
"""
Returns True if salt is running from a tiamat pacakge, False otherwise
"""
return hasattr(sys, "_MEIPASS")
def _cleanup_environ(environ):
if environ is None:
environ = os.environ.copy()
# When Salt is bundled with tiamat, it MUST NOT contain LD_LIBRARY_PATH
# when shelling out, or, at least the value of LD_LIBRARY_PATH set by
# pyinstaller.
# See:
# https://pyinstaller.readthedocs.io/en/stable/runtime-information.html#ld-library-path-libpath-considerations
for varname in ("LD_LIBRARY_PATH", "LIBPATH"):
original_varname = "{}_ORIG".format(varname)
if original_varname in environ:
environ[varname] = environ.pop(original_varname)
elif varname in environ:
environ.pop(varname)
return environ
class TiamatPopen(subprocess.Popen):
def __init__(self, *args, **kwargs):
kwargs["env"] = _cleanup_environ(kwargs.pop("env", None))
super().__init__(*args, **kwargs)
class TiamatTerminal(salt.utils.vt.Terminal): # pylint: disable=abstract-method
def __init__(self, *args, **kwargs):
kwargs["env"] = _cleanup_environ(kwargs.pop("env", None))
super().__init__(*args, **kwargs)
if is_tiamat_packaged():
subprocess.Popen = TiamatPopen
salt.utils.vt.Terminal = TiamatTerminal

View file

@ -0,0 +1,103 @@
import json
import subprocess
import sys
import pytest
import salt.utils.tiamatpkg
@pytest.fixture(params=("LD_LIBRARY_PATH", "LIBPATH"))
def envvar(request):
return request.param
def test_subprocess_popen_environ_cleanup_existing(envvar):
envvar_value = "foo"
orig_envvar = "{}_ORIG".format(envvar)
env = {
orig_envvar: envvar_value,
}
instance = salt.utils.tiamatpkg.TiamatPopen(
[sys.executable, "-c", "import os, json; print(json.dumps(dict(os.environ)))"],
env=env.copy(),
stdout=subprocess.PIPE,
)
stdout, _ = instance.communicate()
assert instance.returncode == 0
returned_env = json.loads(stdout)
assert returned_env != env
assert envvar in returned_env
assert orig_envvar not in returned_env
assert returned_env[envvar] == envvar_value
def test_subprocess_popen_environ_cleanup(envvar):
envvar_value = "foo"
env = {
envvar: envvar_value,
}
instance = salt.utils.tiamatpkg.TiamatPopen(
[sys.executable, "-c", "import os, json; print(json.dumps(dict(os.environ)))"],
env=env.copy(),
stdout=subprocess.PIPE,
)
stdout, _ = instance.communicate()
assert instance.returncode == 0
returned_env = json.loads(stdout)
assert returned_env != env
assert envvar not in returned_env
def test_vt_terminal_environ_cleanup_existing(envvar):
envvar_value = "foo"
orig_envvar = "{}_ORIG".format(envvar)
env = {
orig_envvar: envvar_value,
}
instance = salt.utils.tiamatpkg.TiamatTerminal(
[sys.executable, "-c", "import os, json; print(json.dumps(dict(os.environ)))"],
env=env.copy(),
stream_stdout=False,
stream_stderr=False,
)
buffer_o = buffer_e = ""
while instance.has_unread_data:
stdout, stderr = instance.recv()
if stdout:
buffer_o += stdout
if stderr:
buffer_e += stderr
instance.terminate()
assert instance.exitstatus == 0
returned_env = json.loads(buffer_o)
assert returned_env != env
assert envvar in returned_env
assert orig_envvar not in returned_env
assert returned_env[envvar] == envvar_value
def test_vt_terminal_environ_cleanup(envvar):
envvar_value = "foo"
env = {
envvar: envvar_value,
}
instance = salt.utils.tiamatpkg.TiamatTerminal(
[sys.executable, "-c", "import os, json; print(json.dumps(dict(os.environ)))"],
env=env.copy(),
stream_stdout=False,
stream_stderr=False,
)
buffer_o = buffer_e = ""
while instance.has_unread_data:
stdout, stderr = instance.recv()
if stdout:
buffer_o += stdout
if stderr:
buffer_e += stderr
instance.terminate()
assert instance.exitstatus == 0
returned_env = json.loads(buffer_o)
assert returned_env != env
assert envvar not in returned_env