installing Python

Description

I am trying to install a Python web app on a site and I’m running into difficulty trying to understand the instructions for Python in the docs.

As the user, it looks like Python is not available at all.

$ python3 —version
-bash: python3: command not found

As root, I can see that there is a very old version of Python on the machine. I don’t know whether/how I am supposed to upgrade it or install another version, nor do I know how to make it available to the user.

[root]# which python3
/usr/bin/python3
[root]# python3 --version
Python 3.6.8

Is there some setup I need to do to make (a current version of) Python available to the user account?

Use pyenv

pyenv install 3.4.1
# Switch to 3.4.1 locally
pyenv local 3.4.1
# Set 3.4.1 as the default system interpreter for future logins
pyenv global 3.4.1

Thanks for the encouragement to try harder. I had tried this command already, but I got nervous when I saw an error. After a couple tries I made some progress.

# pyenv install 3.12.8
python-build: TMPDIR=/tmp cannot hold executables (partition possibly mounted with `noexec`)
# TMPDIR=/var/tmp pyenv install 3.12.8
Downloading Python-3.12.8.tar.xz...
-> https://www.python.org/ftp/python/3.12.8/Python-3.12.8.tar.xz
Installing Python-3.12.8...
Installed Python-3.12.8 to /usr/local/share/python/pyenv/versions/3.12.8
# pyenv global 3.12.8
# python3 --version
Python 3.12.8

Unfortunately, I still don’t see a working python from my user shell. I tried systemctl reload fsmount just in case, but that didn’t help. As the user, I do see /bin/python3 but it is a broken symlink pointing to /etc/alternatives/python3. Likewise, /bin/pyenv is a broken symlink pointing to /usr/local/share/python/pyenv/bin/pyenv.

You’re installing globally, which would make it available to all users.

In this context, flip into the user’s shell - ensure ssh service is enabled for the user - then you can set per-directory:

# Install:
TMPDIR=/var/tmp pyenv install 3.12.8

# Downloading Python-3.12.8.tar.xz...
# -> https://www.python.org/ftp/python/3.12.8/Python-3.12.8.tar.xz
# Installing Python-3.12.8...
# Installed Python-3.12.8 to /usr/local/share/python/pyenv/versions/3.12.8

# Flip into site1
su site1

pyenv versions

# Reports:
#  3.12.8
#  pypy3.10-7.3.17

# Use 3.12.8
pyenv global 3.12.8

python --version
# Reports: Python 3.12.8

which python
# Reports: /usr/local/share/python/pyenv/shims/python

From there, you can configure the default version using a file named .python-version that contains a single line which represents any component of the version (major, major + minor, full).

Use the shim path (/usr/local/share/python/pyenv/shims/python) to ensure pyenv is loaded, which in turn handles any-version population.

This is also part of the API as the “python” module.

cpcmd -d DOMAIN python:install 3.12.8
# Autosource latest 3.12...
cpcmd -d DOMAIN python:make-default 3.12 /var/www/app

OK, so it looks like there’s a problem with a particular user account (just happens it’s the one I was trying to test on). I checked a different user and it looks like python is there as you describe.

[root ~]# su site6
[site6 /]$ pyenv versions
* 3.12.8 (set by /usr/local/share/python/pyenv/version)
[site6 /]$ exit
exit
[root ~]# su site3
bash: /usr/local/share/go/goenv/libexec/../completions/goenv.bash: No such file or directory
[site3 /]$ pyenv versions
bash: pyenv: command not found

[edit] some additional poking around … about half of my sites don’t have a working pyenv. I can’t identify any pattern, they include older sites and newer sites. I created a test site just now and that one worked. Missing pyenv corellates with the goenv.bash error, fwiw.

Enable ssh service for the site. If that is enabled, then a whiteout exists on /usr/local/share for that site. This occurs if the user rm -rf’d /usr/local/share or any component within.

Removing the opaque property using setfattr under shadow/, then running systemctl reload fsmount will clear the cache.

Thank you! I have no idea how it got that way, but setfattr -n trusted.overlay.opaque -v n /home/virtual/site3/shadow/usr/local seems to have fixed it.

1 Like

@msaladna
Does a python version need to be installed global as root for a user to be able to use it?
Or, can a user install a version that is not currently installed in any context?

On this topic, I’m seeing this as a user which makes me believe I need to install it globally first.

~]$ pyenv install 3.11.11
Downloading Python-3.11.11.tar.xz...
-> https://www.python.org/ftp/python/3.11.11/Python-3.11.11.tar.xz
Installing Python-3.11.11...

BUILD FAILED (Linux 4.18.0-553.79.1.el8_10.x86_64 using python-build 2.4.22-22-g0b8baddd)

Inspect or clean up the working tree at /tmp/python-build.20260109083921.1571154
Results logged to /tmp/python-build.20260109083921.1571154.log

Last 10 log lines:
/bin/sh: fork: retry: Resource temporarily unavailable
gcc: error: vfork: Resource temporarily unavailable
gcc: error: vfork: Resource temporarily unavailable
gcc: error: vfork: Resource temporarily unavailable
gcc: error: vfork: Resource temporarily unavailable
make: *** [Makefile:2517: Objects/boolobject.o] Error 1
make: *** Waiting for unfinished jobs....
make: *** [Makefile:2517: Objects/bytes_methods.o] Error 1
make: *** [Makefile:2517: Objects/bytearrayobject.o] Error 1
make: *** [Makefile:2517: Objects/bytesobject.o] Error 1

Ran again after cleaning the /tmp build directory and got:

]$ pyenv install 3.11.11
Downloading Python-3.11.11.tar.xz...
-> https://www.python.org/ftp/python/3.11.11/Python-3.11.11.tar.xz
Installing Python-3.11.11...

BUILD FAILED (Linux 4.18.0-553.79.1.el8_10.x86_64 using python-build 2.4.22-22-g0b8baddd)

Inspect or clean up the working tree at /tmp/python-build.20260109101812.1625955
Results logged to /tmp/python-build.20260109101812.1625955.log

Last 10 log lines:
running build_scripts
copying and adjusting /tmp/python-build.20260109101812.1625955/Python-3.11.11/Tools/scripts/pydoc3 -> build/scripts-3.11
copying and adjusting /tmp/python-build.20260109101812.1625955/Python-3.11.11/Tools/scripts/idle3 -> build/scripts-3.11
copying and adjusting /tmp/python-build.20260109101812.1625955/Python-3.11.11/Tools/scripts/2to3 -> build/scripts-3.11
changing mode of build/scripts-3.11/pydoc3 from 664 to 775
changing mode of build/scripts-3.11/idle3 from 664 to 775
changing mode of build/scripts-3.11/2to3 from 664 to 775
renaming build/scripts-3.11/pydoc3 to build/scripts-3.11/pydoc3.11
renaming build/scripts-3.11/idle3 to build/scripts-3.11/idle3.11
renaming build/scripts-3.11/2to3 to build/scripts-3.11/2to3-3.11

Log file shows:

cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
Creating directory /usr/local/share/python/pyenv/versions/3.11.11/include/python3.11
make: *** [Makefile:2019: altmaninstall] Error 1
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
Creating directory /usr/local/share/python/pyenv/versions/3.11.11/lib/python3.11/lib-dynload
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
Creating directory /usr/local/share/python/pyenv/versions/3.11.11/include/python3.11
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied

They’re hitting resource limits. Check dmesg and raise the offending cgroup parameter that it’s hitting (proclimit or memory).

-c 'cgroup,memory'='2048' -c 'cgroup,proclimit'='100'

]$ pyenv install 3.11.11
Downloading Python-3.11.11.tar.xz...
-> https://www.python.org/ftp/python/3.11.11/Python-3.11.11.tar.xz
Installing Python-3.11.11...

BUILD FAILED (Linux 4.18.0-553.79.1.el8_10.x86_64 using python-build 2.4.22-22-g0b8baddd)

Inspect or clean up the working tree at /tmp/python-build.20260109103921.1695447
Results logged to /tmp/python-build.20260109103921.1695447.log

Last 10 log lines:
running build_scripts
copying and adjusting /tmp/python-build.20260109103921.1695447/Python-3.11.11/Tools/scripts/pydoc3 -> build/scripts-3.11
copying and adjusting /tmp/python-build.20260109103921.1695447/Python-3.11.11/Tools/scripts/idle3 -> build/scripts-3.11
copying and adjusting /tmp/python-build.20260109103921.1695447/Python-3.11.11/Tools/scripts/2to3 -> build/scripts-3.11
changing mode of build/scripts-3.11/pydoc3 from 664 to 775
changing mode of build/scripts-3.11/idle3 from 664 to 775
changing mode of build/scripts-3.11/2to3 from 664 to 775
renaming build/scripts-3.11/pydoc3 to build/scripts-3.11/pydoc3.11
renaming build/scripts-3.11/idle3 to build/scripts-3.11/idle3.11
renaming build/scripts-3.11/2to3 to build/scripts-3.11/2to3-3.11

The log confirms it’s not a resource issue but a permissions issue, so my question remains, do I need to globally install it for a user to use it?

Creating directory /usr/local/share/python/pyenv/versions/3.11.11/bin
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
Creating directory /usr/local/share/python/pyenv/versions/3.11.11/lib
Creating directory /usr/local/share/python/pyenv/versions/3.11.11/include
Creating directory /usr/local/share/python/pyenv/versions/3.11.11/share/man
Creating directory /usr/local/share/python/pyenv/versions/3.11.11
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
LD_LIBRARY_PATH=/tmp/python-build.20260109103921.1695447/Python-3.11.11 CC='gcc -pthread' LDSHARED='gcc -pthread -shared -L/usr/local/share/python/pyenv/versions/3.11.11/lib -Wl,-rpath,/usr/local/share/python/pyenv/versions/3.11.$
make: *** [Makefile:1926: altbininstall] Error 1
make: *** Waiting for unfinished jobs....
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
/usr/bin/install: Creating directory /usr/local/share/python/pyenv/versions/3.11.11/include
cannot change permissions of ‘/usr/local/share/python/pyenv/versions/3.11.11’/usr/bin/install: : No such file or directory
cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
Creating directory /usr/local/share/python/pyenv/versions/3.11.11/lib
Creating directory /usr/local/share/python/pyenv/versions/3.11.11/share/man/man1
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
Creating directory /usr/local/share/python/pyenv/versions/3.11.11/include/python3.11
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
Creating directory /usr/local/share/python/pyenv/versions/3.11.11/lib/python3.11
make: *** [Makefile:2019: altmaninstall] Error 1
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
Creating directory /usr/local/share/python/pyenv/versions/3.11.11/include/python3.11
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
Creating directory /usr/local/share/python/pyenv/versions/3.11.11/lib/python3.11/lib-dynload
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
/usr/bin/install: cannot create directory ‘/usr/local/share/python/pyenv/versions/3.11.11’: Permission denied
make: *** [Makefile:2326: inclinstall] Error 1
make: *** [Makefile:1914: /usr/local/share/python/pyenv/versions/3.11.11/lib/python3.11/lib-dynload] Error 1
running build
running build_ext

It looks like this is the proper way to do it, but none of the docs line up.
TMPDIR=/var/tmp pyenv install 3.11.11
pyenv global 3.11.11
systemctl reload fsmount
Without defining the TMPDIR, it fails because /tmp has noexec like outlined in the OP above.

After installing Python 3.11.11, pyenv versions does show the new version and the user can use it via pyenv local 3.11.11

These are 2 distinct errors. Previously, you encountered a vfork/fork error. That was resource.

/bin/sh: fork: retry: Resource temporarily unavailable
gcc: error: vfork: Resource temporarily unavailable

Now that has been addressed, it’s permission. That’s linked back to changes in NSS with v2 of nss-apnscp. Jailing occurs separate of NSS lookups, which when supplemental groups are determined, fail.

# su site2
[sdfdfsa@rocky-test /]$ groups
sdfdfsa
[sdfdfsa@rocky-test /]$ su sdfdfsa
[sdfdfsa@rocky-test /]$ groups
sdfdfsa wheel
[sdfdfsa@rocky-test /]$ pyenv install 3.10.1
Downloading Python-3.10.1.tar.xz...
-> https://www.python.org/ftp/python/3.10.1/Python-3.10.1.tar.xz
Installing Python-3.10.1...
Installed Python-3.10.1 to /usr/local/share/python/pyenv/versions/3.10.1
[sdfdfsa@rocky-test /]$ echo $TMPDIR
# Unset

If you ssh in as that user, jailing then lookup happens as expected. It’s only when su’ing directly as root that this problem presents itself. I’ll need to implement group support in the NSS package.

This is fixed in pam-apnscp-2.0-3. A separate initgroups() call is done after translating into account vfs.

yum clean all ; yum update -y pam-apnscp

Expected output for both su and runuser packages. wheel is included in account admin, which in turn permits write to any-version directories in /usr/local/share.

[root@localhost ~]# su myadmin@site1 -c groups
myadmin wheel
[root@localhost ~]# runuser -u myadmin@site1 groups
myadmin wheel