Do not insert local paths before standard library paths#68756
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... |
|
Any sign of this getting fixed up and merged? This problem has bitten us many times in the past too and I'd love to see it merged. Hopefully this ridiculous problem serves as a warning to anyone else thinking they could fuck with |
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