Do not insert local paths before standard library paths#68756
Do not insert local paths before standard library paths#68756marmarek wants to merge 4 commits intosaltstack:3006.xfrom
Conversation
|
The failure I get is: Is it related to my change? I think it isn't given I got it also in https://github.com/saltstack/salt/actions/runs/22261566839, which doesn't include this change. |
twangboy
left a comment
There was a problem hiding this comment.
Please create this against the 3006.x branch as the bug also exists there.
bdddbea to
247e43f
Compare
Done. |
I can try, but I believe it might be related to python version (not sure why else I didn't hit it before). With Fedora 42 target, reproducer is as simple as I can try harder to come up with some state that would trigger the issue regardless of distribution version. |
|
We were able to reproduce the issue for openSUSE Leap 15.6 with Python 3.11. And we are using this patch now to fix our deployment. |
c1ce0ce to
c6265f2
Compare
Inserting local paths like `salt/utils` before standard library makes
many modules in utils conflict with standard library. This is especially
relevant for salt-ssh. For example salt.utils.configparser - it tries to
import configparser from stdlib, but due to salt/utils path being
prepended to sys.path, it imports itself:
[ERROR ] Failed to import fileserver gitfs, this is due most likely to a syntax error:
Traceback (most recent call last):
File "/var/tmp/.root_dd8a91_salt/pyall/salt/loader/lazy.py", line 902, in _load_module
self.run(spec.loader.exec_module, mod)
~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/tmp/.root_dd8a91_salt/pyall/salt/loader/lazy.py", line 1365, in run
return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/tmp/.root_dd8a91_salt/pyall/salt/loader/lazy.py", line 1380, in _run_as
ret = _func_or_method(*args, **kwargs)
File "<frozen importlib._bootstrap_external>", line 1023, in exec_module
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
File "/var/tmp/.root_dd8a91_salt/pyall/salt/fileserver/gitfs.py", line 52, in <module>
import salt.utils.gitfs
File "/var/tmp/.root_dd8a91_salt/pyall/salt/utils/gitfs.py", line 31, in <module>
import salt.utils.configparser
File "/var/tmp/.root_dd8a91_salt/pyall/salt/utils/configparser.py", line 7, in <module>
from configparser import * # pylint: disable=no-name-in-module,wildcard-import,unused-wildcard-import
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/tmp/.root_dd8a91_salt/running_data/var/cache/salt/minion/extmods/utils/configparser.py", line 12, in <module>
class GitConfigParser(RawConfigParser):
^^^^^^^^^^^^^^^
NameError: name 'RawConfigParser' is not defined
On the other hand, places that try to use such duplicated modules from
utils, import them via full name (as seen above: `import salt.utils.configparser`).
Change the insert_system_path() function to not insert paths before
standard library.
Fixes saltstack#68755
Temporarily for checkig if test works. This reverts commit b13c203.
Check if it works correctly, especially if it can be imported.
LazyLoader._load_module() appends a dir of imported module (fpath_dirname) to sys.path and then undoes that change by sys.path.remove(). But if that directory was in sys.path already, the remove call will remove an earlier item than the appended one - effectively changing the items order in sys.path. Fix this by avoiding adding and removing fpath_dirname if it was in sys.path already. Ironically, this side effect sometimes (depending on module discovery order) cancels out with bug saltstack#68755 (the wrongly removed path is the one that was wrongly inserted in the first place). While contributed to it being unnoticed for quite some time, and made writting a test of the fix harder.
|
@twangboy do you have some idea what is different in CI that the bug doesn't happen here? In the process of testing the test, I found another |
|
I don't, maybe @dwoz could take a look. You're saying that the passing tests below should not be passing, correct? |
Yes... |
What does this PR do?
Inserting local paths like
salt/utilsbefore standard library makes many modules in utils conflict with standard library. This is especially relevant for salt-ssh. For example salt.utils.configparser - it tries to import configparser from stdlib, but due to salt/utils path being prepended to sys.path, it imports itself:On the other hand, places that try to use such duplicated modules from utils, import them via full name (as seen above:
import salt.utils.configparser).Change the insert_system_path() function to not insert paths before standard library.
What issues does this PR fix or reference?
Fixes #68755
Previous Behavior
Several state modules (including
pkg.installedon RedHat-based distro) are unavailable via salt-sshNew Behavior
No import conflict,
pkg.installedworks.Merge requirements satisfied?
[NOTICE] Bug fixes or features added to Salt require tests.
Commits signed with GPG?
Yes