Open dmacvicar opened 2 years ago
Duplicate of #59942? @dwoz there are other reports there that it wasn't fixed.
same issue
Also same issue, would love to see a workaround for this even if a real fix won't come for a good while
The issue seems to come from these lines: https://github.com/saltstack/salt/blob/38341cb2fe208498393780921a17cdf7963663c0/salt/utils/thin.py#L429-L435
contextvars
is part of the standard library, so I'm not really understanding why this is packaging it if any python version from 3.7 up would already have it.
Given that a 3.7+ master is not going to have the backport (Or prefer it if its installed), this means that an incompatible version of contextvars gets packaged before being sent to the 3.6 target.
I was able to solve this in our system by commenting these lines, then using the pre-flight script to install the contextvars backport. Not sure right now how to best handle this without using pre-flight
Same here, commenting these lines on my salt-ssh client side (running with python 3.10), and installing contextvars using pip on my python3.6 server was successfull.
Python 3.10 contextvars.py is packaged in the salt-ssh thin but this contextvars.py version is not compatible if servers are running python 3.6/3.7 anyway.
This is already fixed, but is a bit counter-intuitive: you need to install contextvars
backport package even when the salt-master
is using Python 3.7+
An execution returning the already known error:
# salt-ssh 'ijurn.oci' -w -t test.ping
ijurn.oci:
----------
retcode:
1
stderr:
Traceback (most recent call last):
File "/var/tmp/.opc_706a4b_salt/pyall/salt/loader/context.py", line 10, in <module>
import _contextvars as contextvars
ModuleNotFoundError: No module named '_contextvars'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/var/tmp/.opc_706a4b_salt/salt-call", line 27, in <module>
salt_call()
File "/var/tmp/.opc_706a4b_salt/pyall/salt/scripts.py", line 435, in salt_call
import salt.cli.call
File "/var/tmp/.opc_706a4b_salt/pyall/salt/cli/call.py", line 3, in <module>
import salt.cli.caller
File "/var/tmp/.opc_706a4b_salt/pyall/salt/cli/caller.py", line 12, in <module>
import salt.channel.client
File "/var/tmp/.opc_706a4b_salt/pyall/salt/channel/client.py", line 13, in <module>
import salt.crypt
File "/var/tmp/.opc_706a4b_salt/pyall/salt/crypt.py", line 26, in <module>
import salt.payload
File "/var/tmp/.opc_706a4b_salt/pyall/salt/payload.py", line 12, in <module>
import salt.loader.context
File "/var/tmp/.opc_706a4b_salt/pyall/salt/loader/__init__.py", line 15, in <module>
import salt.config
File "/var/tmp/.opc_706a4b_salt/pyall/salt/config/__init__.py", line 100, in <module>
_DFLT_IPC_WBUFFER = _gather_buffer_space() * 0.5
File "/var/tmp/.opc_706a4b_salt/pyall/salt/config/__init__.py", line 88, in _gather_buffer_space
import salt.grains.core
File "/var/tmp/.opc_706a4b_salt/pyall/salt/grains/core.py", line 31, in <module>
import salt.modules.cmdmod
File "/var/tmp/.opc_706a4b_salt/pyall/salt/modules/cmdmod.py", line 31, in <module>
import salt.utils.templates
File "/var/tmp/.opc_706a4b_salt/pyall/salt/utils/templates.py", line 27, in <module>
from salt.loader.context import NamedLoaderContext
File "/var/tmp/.opc_706a4b_salt/pyall/salt/loader/context.py", line 13, in <module>
import contextvars
File "/var/tmp/.opc_706a4b_salt/py3/contextvars.py", line 1, in <module>
from _contextvars import Context, ContextVar, Token, copy_context
ModuleNotFoundError: No module named '_contextvars'
[ERROR ] An un-handled exception was caught by Salt's global exception handler:
ModuleNotFoundError: No module named '_contextvars'
Traceback (most recent call last):
File "/var/tmp/.opc_706a4b_salt/pyall/salt/loader/context.py", line 10, in <module>
import _contextvars as contextvars
ModuleNotFoundError: No module named '_contextvars'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/var/tmp/.opc_706a4b_salt/salt-call", line 27, in <module>
salt_call()
File "/var/tmp/.opc_706a4b_salt/pyall/salt/scripts.py", line 435, in salt_call
import salt.cli.call
File "/var/tmp/.opc_706a4b_salt/pyall/salt/cli/call.py", line 3, in <module>
import salt.cli.caller
File "/var/tmp/.opc_706a4b_salt/pyall/salt/cli/caller.py", line 12, in <module>
import salt.channel.client
File "/var/tmp/.opc_706a4b_salt/pyall/salt/channel/client.py", line 13, in <module>
import salt.crypt
File "/var/tmp/.opc_706a4b_salt/pyall/salt/crypt.py", line 26, in <module>
import salt.payload
File "/var/tmp/.opc_706a4b_salt/pyall/salt/payload.py", line 12, in <module>
import salt.loader.context
File "/var/tmp/.opc_706a4b_salt/pyall/salt/loader/__init__.py", line 15, in <module>
import salt.config
File "/var/tmp/.opc_706a4b_salt/pyall/salt/config/__init__.py", line 100, in <module>
_DFLT_IPC_WBUFFER = _gather_buffer_space() * 0.5
File "/var/tmp/.opc_706a4b_salt/pyall/salt/config/__init__.py", line 88, in _gather_buffer_space
import salt.grains.core
File "/var/tmp/.opc_706a4b_salt/pyall/salt/grains/core.py", line 31, in <module>
import salt.modules.cmdmod
File "/var/tmp/.opc_706a4b_salt/pyall/salt/modules/cmdmod.py", line 31, in <module>
import salt.utils.templates
File "/var/tmp/.opc_706a4b_salt/pyall/salt/utils/templates.py", line 27, in <module>
from salt.loader.context import NamedLoaderContext
File "/var/tmp/.opc_706a4b_salt/pyall/salt/loader/context.py", line 13, in <module>
import contextvars
File "/var/tmp/.opc_706a4b_salt/py3/contextvars.py", line 1, in <module>
from _contextvars import Context, ContextVar, Token, copy_context
ModuleNotFoundError: No module named '_contextvars'
stdout:
Then, install contextvars
and run the same command:
# pip install contextvars
Collecting contextvars
Using cached contextvars-2.4-py3-none-any.whl
Requirement already satisfied: immutables>=0.9 in /usr/lib/python3.9/site-packages (from contextvars) (0.18)
Installing collected packages: contextvars
Successfully installed contextvars-2.4
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
# salt-ssh 'ijurn.oci' -w -t test.ping
ijurn.oci:
True
In the requires.txt
, even when using Python 3.7+, the contextvars
module is listed as a requirement:
Jinja2
msgpack>=0.5,!=0.5.5
PyYAML
MarkupSafe
requests>=1.0.0
distro>=1.0.1
contextvars
psutil>=5.0.0
pyzmq>19.0.2 ; python_version >= "3.9"
pycryptodomex>=3.9.8
And it's there exactly to make salt-ssh
works OK with targets using versions of Python lower than 3.7, as @bryceml stated in #60483:
if downstream packages want to remove contextvars from the requirements on py3.7+, that's up to them, it just won't work with salt-ssh targets less than py3.7.
Take care that the thin
package should be regenerated after contextvars
installation.
Thanks for the detailed walkthrough @piterpunk.
I've followed your instructions and can confirms that on my setup (Archlinux source salt-ssh on a Python 3.9 virtualenv, Rockylinux 8 target using the system Python 3.6), installing contextvars
in the source virtualenv then re-generating the thin
package does not seem to be sufficient to work the issue around.
This is particularly confusing considering contextvars==2.4 is already installed on the target host, as part of a regular salt-3004 on python3.6 install.
EDIT: Turns out I've stumbled upon this issue already back in January and I found another workaround on a duplicate issue, https://github.com/saltstack/salt/issues/59942#issuecomment-1020494839 that's related to an issue with typing_extensions
. My memory is poor !
To whom it may concern, if Piter's instructions aren't sufficient because your issue is caused by typing_extensions
, install typing_extensions (version 4.1.1 maximum, 4.2.0 introduces a breaking change...), then follow those instructions https://github.com/saltstack/salt/issues/59942#issuecomment-961153192
I just installed salt-ssh on a centos 7 via rpm repo. When connecting to another centos 7 machine, after installing python3.x86_64 and python36-distro.noarch (because got another error as well), got this error:
retcode:
1
stderr:
Traceback (most recent call last):
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/loader/context.py", line 10, in <module>
import _contextvars as contextvars
ModuleNotFoundError: No module named '_contextvars'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/var/tmp/.saltuser_44a047_salt/salt-call", line 27, in <module>
salt_call()
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/scripts.py", line 435, in salt_call
import salt.cli.call
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/cli/call.py", line 3, in <module>
import salt.cli.caller
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/cli/caller.py", line 12, in <module>
import salt.channel.client
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/channel/client.py", line 13, in <module>
import salt.crypt
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/crypt.py", line 26, in <module>
import salt.payload
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/payload.py", line 12, in <module>
import salt.loader.context
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/loader/__init__.py", line 15, in <module>
import salt.config
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/config/__init__.py", line 100, in <module>
_DFLT_IPC_WBUFFER = int(_gather_buffer_space() * 0.5)
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/config/__init__.py", line 88, in _gather_buffer_space
import salt.grains.core
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/grains/core.py", line 31, in <module>
import salt.modules.cmdmod
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/modules/cmdmod.py", line 32, in <module>
import salt.utils.templates
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/utils/templates.py", line 27, in <module>
from salt.loader.context import NamedLoaderContext
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/loader/context.py", line 13, in <module>
import contextvars
ModuleNotFoundError: No module named 'contextvars'
[ERROR ] An un-handled exception was caught by Salt's global exception handler:
ModuleNotFoundError: No module named 'contextvars'
Traceback (most recent call last):
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/loader/context.py", line 10, in <module>
import _contextvars as contextvars
ModuleNotFoundError: No module named '_contextvars'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/var/tmp/.saltuser_44a047_salt/salt-call", line 27, in <module>
salt_call()
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/scripts.py", line 435, in salt_call
import salt.cli.call
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/cli/call.py", line 3, in <module>
import salt.cli.caller
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/cli/caller.py", line 12, in <module>
import salt.channel.client
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/channel/client.py", line 13, in <module>
import salt.crypt
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/crypt.py", line 26, in <module>
import salt.payload
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/payload.py", line 12, in <module>
import salt.loader.context
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/loader/__init__.py", line 15, in <module>
import salt.config
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/config/__init__.py", line 100, in <module>
_DFLT_IPC_WBUFFER = int(_gather_buffer_space() * 0.5)
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/config/__init__.py", line 88, in _gather_buffer_space
import salt.grains.core
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/grains/core.py", line 31, in <module>
import salt.modules.cmdmod
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/modules/cmdmod.py", line 32, in <module>
import salt.utils.templates
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/utils/templates.py", line 27, in <module>
from salt.loader.context import NamedLoaderContext
File "/var/tmp/.saltuser_44a047_salt/pyall/salt/loader/context.py", line 13, in <module>
import contextvars
ModuleNotFoundError: No module named 'contextvars'
stdout:
EDIT: OK, doing pip3 install contextvars fixed it
Description
salt-ssh on a Python 3.9 host and a Python 3.6.15 target fails with
ModuleNotFoundError: No module named '_contextvars'
error:Setup
My setup on the host is a Nix environment with Salt 3004 and a target machine with openSUSE and Python 3.9.15 on ARM, but from what I see in the code, it should happen on a Python > 3.7 host / Python 3.6 target.
Steps to Reproduce the behavior
After running
salt-ssh rpi01 grains.items
, it will fail:I believe the reason could be (I could be wrong):
/var/tmp/.root_05dd7c_salt/pyall/salt/loader/context.py
does:The fallback import should end importing contextvars backport. but because
sys.path
includes/var/tmp/.root_05dd7c_salt/py3/contextvars.py
first, which is a copy of the 3.9 stdlib, which also depends on_contextvars
!! native module:which brings Python 3.6 back into importing something that is not in Python 3.6, even if the backport package is installed on the machine.
So there are a few things I can't make sense of:
The contextvars backport states:
So I assume just importing just
context
insalt/loader/context.py
should attempt to load the 3.7 module, or fallback to the backport.contextvars
without depending on_contextvars
, so if we are on a newer Python, this module is already included, and if we are on < 3.6, the 3.7 module can't be used. What is the point of copying it?Fixes and workarounds
Just deleting
rm /var/tmp/.root_05dd7c_salt/py3/contextvars.py
makes things work, as Python 3.6 would then use the installed contextvars backport.I tried to use python 3.9 on the target machine. It would still use the "wrong"
py3
dir module, but it would work as_contextvars
is available. salt-ssh does not allow me to select /usr/bin/python3.9 as the interpreter to use in the target machine, so it uses /usr/bin/python3.My intuition tells me there is no point in packing contextvars in the thin, unless we are packing the backport package.
Expected behavior
salt-ssh rpi01 grains.items
to worksalt --versions-report
Host: ``` Salt Version: Salt: 3004 Dependency Versions: cffi: 1.14.6 cherrypy: Not Installed dateutil: Not Installed docker-py: Not Installed gitdb: Not Installed gitpython: Not Installed Jinja2: 3.0.2 libgit2: Not Installed M2Crypto: Not Installed Mako: Not Installed msgpack: 1.0.2 msgpack-pure: Not Installed mysql-python: Not Installed pycparser: 2.20 pycrypto: Not Installed pycryptodome: 3.11.0 pygit2: Not Installed Python: 3.9.6 (default, Jun 28 2021, 08:57:49) python-gnupg: Not Installed PyYAML: 5.4.1 PyZMQ: 21.0.2 smmap: Not Installed timelib: Not Installed Tornado: 4.5.3 ZMQ: 4.3.4 System Versions: dist: opensuse-tumbleweed 20211215 n/a locale: utf-8 machine: x86_64 release: 5.15.8-1-default system: Linux version: openSUSE Tumbleweed 20211215 n/a ``` Target: ``` python3-3.6.13-3.81.2.aarch64 python3-contextvars-2.4-bp153.1.14.noarch ```