From e4d68ab1113bca0b351b4422f49c97526c9d354c Mon Sep 17 00:00:00 2001 From: Austin Dimmer Date: Mon, 26 Oct 2026 13:03:03 +0000 Subject: [PATCH 1/2] fix(INFIAAS-11916): jenkins-agent-terraform-2306 Node 24 LTS, eMudhra/emSign CA refresh The eMudhra/emSign incident (eight compromised intermediates) needs every CA store in the agent refreshed: pip always loads its vendored certifi in addition to the system store, so OS ca-certificates alone is not enough. - NODEJS_VERSION 18 -> 24 (Node 18 is EOL; 24.22.1 ships the fixed root store) - uv 0.10.9 -> 0.13.5 (embedded CA store fix) - pip >= 26.2.2 and certifi >= 2026.10.23 for the uv-managed Python - dnf update ca-certificates in the package layer - drop Python 3.8 and 3.9: EOL, and no pip release with the fix supports them (pip >= 26.1 requires Python >= 3.10); the 3.8 pip's vendored certifi 2024.02.02 still trusted the AAA cross-signed intermediates. uv is installed, so users can still `uv python install 3.8` / `3.9` - the default Python (PYTHON_DEFAULT_VERSION=3.11, defined once) becomes python3, python and python3-config (an exec wrapper, because the script derives its prefix from its own path), and its console scripts (pipenv, virtualenv, az, pre-commit, ...) are linked into /usr/local/bin, which already precedes /usr/bin on PATH. Before, python3 and these scripts had the agent's libraries only because `--system --python 3.9` resolved to the RHEL platform python3.9. The build asserts python3, its libraries, python3-config, the CLIs, and that dnf still works on the platform python3 - the Python loop now fails the build on the first interpreter that fails; before, `fi;` let a later successful iteration mask an earlier failure - CHANGELOG: the python3/pipenv default under Changed, the Python 3.8/3.9 removal under Removed - docs: Node/Python versions, python3 and uv-managed Pythons for 2306 --- CHANGELOG.md | 5 ++ .../terraform-2306/docker/Dockerfile.ubi9 | 51 ++++++++++++++++--- .../terraform-2306/docker/python_requirements | 1 + .../jenkins-agents/pages/inf-terraform.adoc | 3 +- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 441fd655..8976408e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,13 @@ ### Added ### Changed +- jenkins-agent-terraform-2306: `python3`, `python` and `python3-config` are now the uv-managed default Python 3.11 with the agent's libraries (before: the RHEL platform Python 3.9), and pipenv creates Python 3.11 environments by default (before: 3.8) ([#NNNN](https://github.com/opendevstack/ods-quickstarters/pull/NNNN)) ### Fixed +- jenkins-agent-terraform-2306: Node 24 LTS, CA store refresh for eMudhra/emSign (pip>=26.2.2, certifi>=2026.10.23, ca-certificates, uv 0.13.5) ([#NNNN](https://github.com/opendevstack/ods-quickstarters/pull/NNNN)) + +### Removed +- jenkins-agent-terraform-2306: Python 3.8 and 3.9 (EOL, and no pip release with the CA fix supports them); install them on demand with `uv python install 3.8` / `3.9` ([#NNNN](https://github.com/opendevstack/ods-quickstarters/pull/NNNN)) ## [4.13.1] - 2026-07-30 ### Fixed diff --git a/common/jenkins-agents/terraform-2306/docker/Dockerfile.ubi9 b/common/jenkins-agents/terraform-2306/docker/Dockerfile.ubi9 index 4ff4f8de..3a2e9372 100644 --- a/common/jenkins-agents/terraform-2306/docker/Dockerfile.ubi9 +++ b/common/jenkins-agents/terraform-2306/docker/Dockerfile.ubi9 @@ -25,10 +25,11 @@ ENV TERRAFORM_VERSION=1.4.6 \ CONSUL_VERSION=1.15.2 \ TFENV_VERSION=3.0.0 \ TFLINT_VERSION=0.46.1 \ - NODEJS_VERSION=18 \ + NODEJS_VERSION=24 \ BUNDLER_VERSION=2.4.13 \ AGE_VERSION=1.1.1 \ - UV_VERSION=0.10.9 \ + UV_VERSION=0.13.5 \ + PYTHON_DEFAULT_VERSION=3.11 \ GEM_HOME=/opt/bundle \ RBENV_ROOT=/opt/rbenv \ RBENV_SHELL=bash \ @@ -61,6 +62,7 @@ RUN set -x \ && dnf -y repolist \ && dnf -y install --allowerasing $INSTALL_PKGS \ && dnf -y install --allowerasing --enablerepo almalinux-baseos --enablerepo almalinux-appstream $INSTALL_DNF_PKGS \ + && dnf -y update ca-certificates \ && dnf clean all RUN curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh && \ @@ -75,23 +77,60 @@ RUN curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh && \ fi && \ yum -y clean all -RUN for pyVersion in 3.8 3.9 3.11; do \ +# Python 3.8 and 3.9 are not installed any more: they are EOL and pip >= 26.2.2 (the release with +# the refreshed vendored CA store, see eMudhra/emSign incident) requires Python >= 3.10. +# Users who still need them can run `uv python install 3.8` / `uv python install 3.9` themselves. +# pip is upgraded explicitly because pip always loads its vendored certifi CA store in +# addition to the system store; the floor makes the build fail if it cannot be met. +# The default Python (PYTHON_DEFAULT_VERSION) becomes `python3`, `python` and `python3-config`, and +# its console scripts (pipenv, virtualenv, az, pre-commit, ...) are linked into /usr/local/bin. +# Before, `python3` and these scripts had the agent's libraries only as a side effect of +# `--system --python 3.9` resolving to the RHEL platform /usr/bin/python3.9; a uv-managed +# interpreter keeps its scripts in its own bin dir, which is not on PATH. /usr/bin/python3 stays +# the platform Python, which dnf uses through its shebang; the build checks that dnf still works. +# python3-config is an exec wrapper, not a symlink: the script derives its prefix from its own path. +# The loop keeps the shape of the other agents, so a second version is a one-word change. +# hadolint ignore=SC2043 +RUN for pyVersion in ${PYTHON_DEFAULT_VERSION}; do \ uv python install $pyVersion && \ if [ -n "${nexusHost}" ] && [ -n "${nexusAuth}" ]; then \ uv pip install --system --break-system-packages --python $pyVersion --index-url https://${nexusAuth}@${nexusHost}/repository/pypi-all/simple --trusted-host ${nexusHost} --prerelease=allow \ + "pip>=26.2.2" \ virtualenv==20.26.3 \ pycodestyle==2.12.1 \ -r /tmp/requirements.txt; \ else \ uv pip install --system --break-system-packages --python $pyVersion --prerelease=allow \ + "pip>=26.2.2" \ virtualenv==20.26.3 \ pycodestyle==2.12.1 \ -r /tmp/requirements.txt; \ - fi; \ + fi && \ + "$(uv python find $pyVersion)" -m pip --version && \ + "$(uv python find $pyVersion)" -c "import certifi; print('certifi', certifi.__version__)" || exit 1; \ done && \ rm -f /tmp/requirements.txt && \ - uv python pin 3.11 && \ - uv tool update-shell + uv python pin ${PYTHON_DEFAULT_VERSION} && \ + uv tool update-shell && \ + PY_DEFAULT="$(uv python find ${PYTHON_DEFAULT_VERSION})" && \ + PY_SCRIPTS="$("$PY_DEFAULT" -c 'import sysconfig; print(sysconfig.get_path("scripts"))')" && \ + ln -sf "$PY_DEFAULT" /usr/local/bin/python3 && \ + ln -sf "$PY_DEFAULT" /usr/local/bin/python && \ + printf '#!/bin/sh\nexec "%s" "$@"\n' "$PY_SCRIPTS/python${PYTHON_DEFAULT_VERSION}-config" >/usr/local/bin/python3-config && \ + chmod 755 /usr/local/bin/python3-config && \ + for script in "$PY_SCRIPTS"/*; do \ + name="$(basename "$script")"; \ + case "$name" in python*|pip|pip3|pip3.*|idle*|pydoc*|2to3*) continue ;; esac; \ + [ -e "/usr/local/bin/$name" ] || ln -s "$script" "/usr/local/bin/$name" || exit 1; \ + done && \ + [ "$(command -v python3)" = /usr/local/bin/python3 ] && \ + python3 --version | grep -q "^Python ${PYTHON_DEFAULT_VERSION}\." && \ + python3 -c 'import boto3, botocore, requests, hcl2, certifi' && \ + PY_INCLUDE="$(python3 -c 'import sysconfig; print(sysconfig.get_paths()["include"])')" && \ + [ -f "$PY_INCLUDE/Python.h" ] && \ + [ "$(python3-config --includes | awk '{print $1}')" = "-I$PY_INCLUDE" ] && \ + pipenv --version && virtualenv --version && pre-commit --version && pycodestyle --version && command -v az && \ + /usr/bin/python3 -c 'import dnf' && dnf --version # Install awscli2 RUN curl -sSL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" \ diff --git a/common/jenkins-agents/terraform-2306/docker/python_requirements b/common/jenkins-agents/terraform-2306/docker/python_requirements index 40e1ca74..4fc69493 100644 --- a/common/jenkins-agents/terraform-2306/docker/python_requirements +++ b/common/jenkins-agents/terraform-2306/docker/python_requirements @@ -8,3 +8,4 @@ pipenv~=2023.4 python-hcl2~=2.0 pre-commit~=3.3.1 azure-cli~=2.48 +certifi>=2026.10.23 diff --git a/docs/modules/jenkins-agents/pages/inf-terraform.adoc b/docs/modules/jenkins-agents/pages/inf-terraform.adoc index baae869d..d7030bed 100644 --- a/docs/modules/jenkins-agents/pages/inf-terraform.adoc +++ b/docs/modules/jenkins-agents/pages/inf-terraform.adoc @@ -4,7 +4,7 @@ This agents are used to deploy (Cloud) resources using terraform code. There are two terraform jenkins agents available: -1. jenkins-agent-terraform-2306 (ruby 3.2.2, terraform 1.4.6, and matching tools). +1. jenkins-agent-terraform-2306 (ruby 3.2.2, terraform 1.4.6, Node.js 24 LTS, Python 3.11 (default, also `python3`), and matching tools). 1. jenkins-agent-terraform-2408 (ruby 3.3.4, terraform 1.9.4, and matching tools) - this is the current active jenkins agent. The images are built in the global `ods` project and are named `jenkins-agent-terraform-2306` and `jenkins-agent-terraform-2408`. @@ -13,6 +13,7 @@ It can be referenced in a `Jenkinsfile` with e.g. `ods/jenkins-agent-terraform-2 == Features 1. support of multiple terraform versions using tfenv 2. integrated test-framework using kitchen-terraform and cinc-auditor +3. Python versions managed by uv in jenkins-agent-terraform-2306 (default 3.11, which is also `python3` and `python` and has the agent's Python libraries; pipenv creates 3.11 environments by default); other versions, e.g. the EOL 3.8 or 3.9, can be installed with `uv python install `. `/usr/bin/python3` is the RHEL platform Python, kept for the OS tools only. == Known limitations n/a From 47caf517db724255c35b812aa5f4b492c3360f40 Mon Sep 17 00:00:00 2001 From: Austin Dimmer Date: Mon, 26 Oct 2026 15:05:10 +0000 Subject: [PATCH 2/2] docs(INFIAAS-11916): link CHANGELOG entry to #1178 --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8976408e..5fea13bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,13 @@ ### Added ### Changed -- jenkins-agent-terraform-2306: `python3`, `python` and `python3-config` are now the uv-managed default Python 3.11 with the agent's libraries (before: the RHEL platform Python 3.9), and pipenv creates Python 3.11 environments by default (before: 3.8) ([#NNNN](https://github.com/opendevstack/ods-quickstarters/pull/NNNN)) +- jenkins-agent-terraform-2306: `python3`, `python` and `python3-config` are now the uv-managed default Python 3.11 with the agent's libraries (before: the RHEL platform Python 3.9), and pipenv creates Python 3.11 environments by default (before: 3.8) ([#1178](https://github.com/opendevstack/ods-quickstarters/pull/1178)) ### Fixed -- jenkins-agent-terraform-2306: Node 24 LTS, CA store refresh for eMudhra/emSign (pip>=26.2.2, certifi>=2026.10.23, ca-certificates, uv 0.13.5) ([#NNNN](https://github.com/opendevstack/ods-quickstarters/pull/NNNN)) +- jenkins-agent-terraform-2306: Node 24 LTS, CA store refresh for eMudhra/emSign (pip>=26.2.2, certifi>=2026.10.23, ca-certificates, uv 0.13.5) ([#1178](https://github.com/opendevstack/ods-quickstarters/pull/1178)) ### Removed -- jenkins-agent-terraform-2306: Python 3.8 and 3.9 (EOL, and no pip release with the CA fix supports them); install them on demand with `uv python install 3.8` / `3.9` ([#NNNN](https://github.com/opendevstack/ods-quickstarters/pull/NNNN)) +- jenkins-agent-terraform-2306: Python 3.8 and 3.9 (EOL, and no pip release with the CA fix supports them); install them on demand with `uv python install 3.8` / `3.9` ([#1178](https://github.com/opendevstack/ods-quickstarters/pull/1178)) ## [4.13.1] - 2026-07-30 ### Fixed