diff --git a/jupyter/minimal/ubi9-python-3.12/Dockerfile.cpu b/jupyter/minimal/ubi9-python-3.12/Dockerfile.cpu index b9ed08b9fc..c82572d6df 100644 --- a/jupyter/minimal/ubi9-python-3.12/Dockerfile.cpu +++ b/jupyter/minimal/ubi9-python-3.12/Dockerfile.cpu @@ -6,6 +6,26 @@ ARG BASE_IMAGE # External image alias for UBI repository configuration FROM registry.access.redhat.com/ubi9/ubi AS ubi-repos +############################ +# Stage 1: PDF Tool Build # +############################ +FROM registry.access.redhat.com/ubi9/python-312:latest AS pdf-builder + +WORKDIR /opt/app-root/bin + +# OS Packages needs to be installed as root +USER 0 + +# Copy scripts +COPY jupyter/utils/install_texlive.sh ./install_texlive.sh +COPY jupyter/utils/install_pandoc.sh ./install_pandoc.sh +RUN chmod +x install_texlive.sh install_pandoc.sh + +RUN ./install_texlive.sh +RUN ./install_pandoc.sh + +USER 1001 + #################### # cpu-base # #################### @@ -16,48 +36,35 @@ WORKDIR /opt/app-root/bin # OS Packages needs to be installed as root USER 0 -### BEGIN upgrade first to avoid fixable vulnerabilities -# If we have a Red Hat subscription prepared, refresh it -RUN /bin/bash <<'EOF' -set -Eeuxo pipefail -if command -v subscription-manager &> /dev/null; then - subscription-manager identity &>/dev/null && subscription-manager refresh || echo "No identity, skipping refresh." -fi -EOF +# Inject the official UBI 9 repository configuration into the AIPCC base image. +# The Quay-based AIPCC image is "repo-less" by default (https://gitlab.com/redhat/rhel-ai/core/base-images/app#repositories), so dnf cannot upgrade or install packages. +# By copying ubi.repo from the public UBI 9 image, we enable package management for upgrades and installations. +COPY --from=ubi-repos /etc/yum.repos.d/ubi.repo /etc/yum.repos.d/ubi.repo +# upgrade first to avoid fixable vulnerabilities begin # Problem: The operation would result in removing the following protected packages: systemd # (try to add '--allowerasing' to command line to replace conflicting packages or '--skip-broken' to skip uninstallable packages) # Solution: --best --skip-broken does not work either, so use --nobest -RUN --mount=type=cache,target=/var/cache/dnf,sharing=locked,id=notebooks-dnf /bin/bash <<'EOF' -set -Eeuxo pipefail -dnf -y upgrade --refresh --nobest --skip-broken --nodocs --noplugins --setopt=install_weak_deps=0 --setopt=keepcache=1 -EOF - -### END upgrade first to avoid fixable vulnerabilities +RUN dnf -y upgrade --refresh --nobest --skip-broken --nodocs --noplugins --setopt=install_weak_deps=0 --setopt=keepcache=0 \ + && dnf clean all -y +# upgrade first to avoid fixable vulnerabilities end # Install useful OS packages -RUN --mount=type=cache,target=/var/cache/dnf,sharing=locked,id=notebooks-dnf /bin/bash <<'EOF' -set -Eeuxo pipefail -dnf install -y --setopt=keepcache=1 perl mesa-libGL skopeo -EOF +RUN dnf install -y perl mesa-libGL skopeo && dnf clean all && rm -rf /var/cache/yum # Other apps and tools installed as default user USER 1001 -### BEGIN Install micropipenv and uv to deploy packages from requirements.txt -RUN pip install --no-cache-dir --extra-index-url https://pypi.org/simple -U "micropipenv[toml]==1.9.0" "uv==0.8.12" -### END Install micropipenv and uv to deploy packages from requirements.txt - -### BEGIN Install the oc client -RUN /bin/bash <<'EOF' -set -Eeuxo pipefail -curl -L https://mirror.openshift.com/pub/openshift-v4/$(uname -m)/clients/ocp/stable/openshift-client-linux.tar.gz \ - -o /tmp/openshift-client-linux.tar.gz -tar -xzvf /tmp/openshift-client-linux.tar.gz oc -rm -f /tmp/openshift-client-linux.tar.gz -EOF +# Install micropipenv and uv to deploy packages from requirements.txt begin +RUN pip install --no-cache-dir -U "micropipenv[toml]==1.9.0" "uv==0.8.12" +# Install micropipenv and uv to deploy packages from requirements.txt end -### END Install the oc client +# Install the oc client begin +RUN curl -L https://mirror.openshift.com/pub/openshift-v4/$(uname -m)/clients/ocp/stable/openshift-client-linux.tar.gz \ + -o /tmp/openshift-client-linux.tar.gz && \ + tar -xzvf /tmp/openshift-client-linux.tar.gz oc && \ + rm -f /tmp/openshift-client-linux.tar.gz +# Install the oc client end #################### # jupyter-minimal # @@ -83,35 +90,36 @@ COPY ${JUPYTER_REUSABLE_UTILS} utils/ USER 0 -### BEGIN Dependencies for PDF export -RUN ./utils/install_pdf_deps.sh -ENV PATH="/usr/local/texlive/bin/linux:/usr/local/pandoc/bin:$PATH" - -### END Dependencies for PDF export +# Dependencies for PDF export begin +RUN --mount=type=cache,from=pdf-builder,source=/usr/local/,target=/pdf_builder/,rw \ + bash -c ' \ + if [[ "$(uname -m)" == "ppc64le" ]]; then \ + cp -r /pdf_builder/texlive /usr/local/; \ + cp -r /pdf_builder/pandoc /usr/local/; \ + else \ + ./utils/install_pdf_deps.sh; \ + fi' USER 1001 COPY ${MINIMAL_SOURCE_CODE}/pylock.toml ${MINIMAL_SOURCE_CODE}/start-notebook.sh ./ # Install Python dependencies from requirements.txt file -RUN /bin/bash <<'EOF' -set -Eeuxo pipefail -echo "Installing softwares and packages" -# This may have to download and compile some dependencies, and as we don't lock requirements from `build-system.requires`, -# we often don't know the correct hashes and `--require-hashes` would therefore fail on non amd64, where building is common. -uv pip install --strict --no-deps --no-cache --no-config --no-progress --verify-hashes --compile-bytecode --index-strategy=unsafe-best-match --requirements=./pylock.toml -# Disable announcement plugin of jupyterlab -jupyter labextension disable "@jupyterlab/apputils-extension:announcements" -# Replace Notebook's launcher, "(ipykernel)" with Python's version 3.x.y -sed -i -e "s/Python.*/$(python --version | cut -d '.' -f-2)\",/" /opt/app-root/share/jupyter/kernels/python3/kernel.json -# copy jupyter configuration -cp /opt/app-root/bin/utils/jupyter_server_config.py /opt/app-root/etc/jupyter -# Fix permissions to support pip in Openshift environments -chmod -R g+w /opt/app-root/lib/python3.12/site-packages -fix-permissions /opt/app-root -P -# Apply JupyterLab addons -/opt/app-root/bin/utils/addons/apply.sh -EOF +RUN echo "Installing softwares and packages" && \ + # This may have to download and compile some dependencies, and as we don't lock requirements from `build-system.requires`, + # we often don't know the correct hashes and `--require-hashes` would therefore fail on non amd64, where building is common. + uv pip install --strict --no-deps --no-cache --no-config --no-progress --verify-hashes --compile-bytecode --index-strategy=unsafe-best-match --requirements=./pylock.toml && \ + # Disable announcement plugin of jupyterlab \ + jupyter labextension disable "@jupyterlab/apputils-extension:announcements" && \ + # Replace Notebook's launcher, "(ipykernel)" with Python's version 3.x.y \ + sed -i -e "s/Python.*/$(python --version | cut -d '.' -f-2)\",/" /opt/app-root/share/jupyter/kernels/python3/kernel.json && \ + # copy jupyter configuration + cp /opt/app-root/bin/utils/jupyter_server_config.py /opt/app-root/etc/jupyter && \ + # Fix permissions to support pip in Openshift environments \ + chmod -R g+w /opt/app-root/lib/python3.12/site-packages && \ + fix-permissions /opt/app-root -P && \ + # Apply JupyterLab addons \ + /opt/app-root/bin/utils/addons/apply.sh WORKDIR /opt/app-root/src diff --git a/jupyter/utils/install_pandoc.sh b/jupyter/utils/install_pandoc.sh new file mode 100644 index 0000000000..89b6e435ef --- /dev/null +++ b/jupyter/utils/install_pandoc.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -euxo pipefail + +# Mapping of `uname -m` values to equivalent GOARCH values +declare -A UNAME_TO_GOARCH +UNAME_TO_GOARCH["x86_64"]="amd64" +UNAME_TO_GOARCH["aarch64"]="arm64" +UNAME_TO_GOARCH["ppc64le"]="ppc64le" +UNAME_TO_GOARCH["s390x"]="s390x" + +ARCH="${UNAME_TO_GOARCH[$(uname -m)]}" + +if [[ "$ARCH" == "ppc64le" ]]; then + + # Install Pandoc from EPEL repository + dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm + dnf install -y pandoc + pandoc --version + +fi diff --git a/jupyter/utils/install_texlive.sh b/jupyter/utils/install_texlive.sh new file mode 100644 index 0000000000..0c488fe57d --- /dev/null +++ b/jupyter/utils/install_texlive.sh @@ -0,0 +1,83 @@ +#!/bin/bash +set -euxo pipefail + +# Mapping of `uname -m` values to equivalent GOARCH values +declare -A UNAME_TO_GOARCH +UNAME_TO_GOARCH["x86_64"]="amd64" +UNAME_TO_GOARCH["aarch64"]="arm64" +UNAME_TO_GOARCH["ppc64le"]="ppc64le" +UNAME_TO_GOARCH["s390x"]="s390x" + +ARCH="${UNAME_TO_GOARCH[$(uname -m)]}" + +if [[ "$ARCH" == "ppc64le" ]]; then + + echo "Installing TeX Live from source for $ARCH..." + + # Install build dependencies + dnf install -y gcc-toolset-13 perl make libX11-devel \ + zlib-devel freetype-devel libpng-devel ncurses-devel \ + gd-devel libtool wget tar xz \ + https://mirror.stream.centos.org/9-stream/AppStream/ppc64le/os/Packages/libXmu-devel-1.1.3-8.el9.ppc64le.rpm \ + https://mirror.stream.centos.org/9-stream/AppStream/ppc64le/os/Packages/libXext-devel-1.3.4-8.el9.ppc64le.rpm \ + https://mirror.stream.centos.org/9-stream/AppStream/ppc64le/os/Packages/libICE-devel-1.0.10-8.el9.ppc64le.rpm \ + https://mirror.stream.centos.org/9-stream/AppStream/ppc64le/os/Packages/libSM-devel-1.2.3-10.el9.ppc64le.rpm \ + https://mirror.stream.centos.org/9-stream/AppStream/ppc64le/os/Packages/libXmu-1.1.3-8.el9.ppc64le.rpm \ + https://mirror.stream.centos.org/9-stream/AppStream/ppc64le/os/Packages/libXaw-devel-1.0.13-19.el9.ppc64le.rpm \ + https://mirror.stream.centos.org/9-stream/AppStream/ppc64le/os/Packages/libXaw-1.0.13-19.el9.ppc64le.rpm \ + https://mirror.stream.centos.org/9-stream/AppStream/ppc64le/os/Packages/libXt-devel-1.2.0-6.el9.ppc64le.rpm \ + https://mirror.stream.centos.org/9-stream/AppStream/ppc64le/os/Packages/flex-2.6.4-9.el9.ppc64le.rpm \ + https://mirror.stream.centos.org/9-stream/AppStream/ppc64le/os/Packages/bison-3.7.4-5.el9.ppc64le.rpm + + # Step 1: Download and extract the TeX Live source + wget https://ftp.math.utah.edu/pub/tex/historic/systems/texlive/2025/texlive-20250308-source.tar.xz + tar -xf texlive-20250308-source.tar.xz + cd texlive-20250308-source + + # Enable newer GCC toolchain + source /opt/rh/gcc-toolset-13/enable + + # Create build directory and build + mkdir -p ../texlive-build + cd ../texlive-build + ../texlive-20250308-source/configure --prefix=/usr/local/texlive + make -j"$(nproc)" + make install + + # Symlink for pdflatex + ln -sf pdftex /usr/local/texlive/bin/powerpc64le-unknown-linux-gnu/pdflatex + + # Cleanup sources to reduce image size + rm -rf /texlive-20250308-source /texlive-build + + # Step 2: Run TeX Live installer for runtime tree setup + cd / + wget https://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz + tar -xzf install-tl-unx.tar.gz + cd install-tl-2*/ + + # Create a custom install profile + TEXLIVE_INSTALL_PREFIX="/usr/local/texlive" + cat < texlive.profile +selected_scheme scheme-small +TEXDIR $TEXLIVE_INSTALL_PREFIX +TEXMFCONFIG ~/.texlive2025/texmf-config +TEXMFVAR ~/.texlive2025/texmf-var +option_doc 0 +option_src 0 +EOF + + ./install-tl --profile=texlive.profile --custom-bin=$TEXLIVE_INSTALL_PREFIX/bin/powerpc64le-unknown-linux-gnu + +# TeX Live binary directory +TEX_BIN_DIR="/usr/local/texlive/bin/powerpc64le-unknown-linux-gnu" + +# Create standard symlink 'linux' → arch-specific folder +ln -sf "$TEX_BIN_DIR" /usr/local/texlive/bin/linux + + # Set up environment + export PATH="$TEXLIVE_INSTALL_PREFIX/bin/linux:$PATH" + pdflatex --version + tlmgr --version + +fi