@@ -11,10 +11,24 @@ FROM registry.access.redhat.com/ubi9/go-toolset:latest AS mongocli-builder
1111ARG MONGOCLI_VERSION=2.0.4
1212
1313WORKDIR /tmp/
14- RUN curl -Lo mongodb-cli-mongocli-v${MONGOCLI_VERSION}.zip https://github.com/mongodb/mongodb-cli/archive/refs/tags/mongocli/v${MONGOCLI_VERSION}.zip
15- RUN unzip ./mongodb-cli-mongocli-v${MONGOCLI_VERSION}.zip
16- RUN cd ./mongodb-cli-mongocli-v${MONGOCLI_VERSION}/ && \
17- CGO_ENABLED=1 GOOS=linux go build -a -tags strictfipsruntime -o /tmp/mongocli ./cmd/mongocli/
14+
15+ ARG TARGETARCH
16+
17+ # Keep s390x special-case from original (create dummy binary) but
18+ # include explicit curl/unzip steps from the delta for non-s390x.
19+ RUN arch="${TARGETARCH:-$(uname -m)}" && \
20+ arch=$(echo "$arch" | cut -d- -f1) && \
21+ if [ "$arch" = "s390x" ]; then \
22+ echo "Skipping mongocli build for ${arch}, creating dummy binary"; \
23+ mkdir -p /tmp && echo -e '#!/bin/sh\necho "mongocli not supported on s390x"' > /tmp/mongocli && \
24+ chmod +x /tmp/mongocli; \
25+ else \
26+ echo "Building mongocli for ${arch}"; \
27+ curl -Lo mongodb-cli-mongocli-v${MONGOCLI_VERSION}.zip https://github.com/mongodb/mongodb-cli/archive/refs/tags/mongocli/v${MONGOCLI_VERSION}.zip && \
28+ unzip ./mongodb-cli-mongocli-v${MONGOCLI_VERSION}.zip && \
29+ cd ./mongodb-cli-mongocli-v${MONGOCLI_VERSION}/ && \
30+ CGO_ENABLED=1 GOOS=linux GOARCH=${arch} GO111MODULE=on go build -a -tags strictfipsruntime -o /tmp/mongocli ./cmd/mongocli/; \
31+ fi
1832
1933####################
2034# cpu-base #
@@ -25,6 +39,7 @@ WORKDIR /opt/app-root/bin
2539
2640# OS Packages needs to be installed as root
2741USER root
42+ ARG TARGETARCH
2843
2944# Inject the official UBI 9 repository configuration into the AIPCC base image.
3045# 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.
@@ -37,7 +52,38 @@ RUN dnf -y upgrade --refresh --best --nodocs --noplugins --setopt=install_weak_d
3752# upgrade first to avoid fixable vulnerabilities end
3853
3954# Install useful OS packages
40- RUN dnf install -y perl mesa-libGL skopeo && dnf clean all && rm -rf /var/cache/yum
55+ RUN --mount=type=cache,target=/var/cache/dnf \
56+ echo "Building for architecture: ${TARGETARCH}" && \
57+ if [ "$TARGETARCH" = "s390x" ]; then \
58+ PACKAGES="perl mesa-libGL skopeo gcc gcc-c++ make openssl-devel autoconf automake libtool cmake python3-devel pybind11-devel openblas-devel unixODBC-devel"; \
59+ else \
60+ PACKAGES="perl mesa-libGL skopeo"; \
61+ fi && \
62+ echo "Installing: $PACKAGES" && \
63+ dnf install -y $PACKAGES && \
64+ dnf clean all && rm -rf /var/cache/yum
65+
66+ RUN if [ "$TARGETARCH" = "s390x" ]; then \
67+ # Install Rust and set up environment
68+ mkdir -p /opt/.cargo && \
69+ export HOME=/root && \
70+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o rustup-init.sh && \
71+ chmod +x rustup-init.sh && \
72+ CARGO_HOME=/opt/.cargo HOME=/root ./rustup-init.sh -y --no-modify-path && \
73+ rm -f rustup-init.sh && \
74+ chown -R 1001:0 /opt/.cargo && \
75+ # Set environment variables
76+ echo 'export PATH=/opt/.cargo/bin:$PATH' >> /etc/profile.d/cargo.sh && \
77+ echo 'export CARGO_HOME=/opt/.cargo' >> /etc/profile.d/cargo.sh && \
78+ echo 'export GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1' >> /etc/profile.d/cargo.sh; \
79+ fi
80+
81+ # Set python alternatives only for s390x (not needed for other arches)
82+ RUN if [ "$TARGETARCH" = "s390x" ]; then \
83+ alternatives --install /usr/bin/python python /usr/bin/python3.12 1 && \
84+ alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1 && \
85+ python --version && python3 --version; \
86+ fi
4187
4288# Other apps and tools installed as default user
4389USER 1001
@@ -53,6 +99,64 @@ RUN curl -L https://mirror.openshift.com/pub/openshift-v4/$(uname -m)/clients/oc
5399 rm -f /tmp/openshift-client-linux.tar.gz
54100# Install the oc client end
55101
102+ ##############################
103+ # wheel-builder stage #
104+ # NOTE: Only used in s390x
105+ ##############################
106+ FROM cpu-base AS s390x-builder
107+
108+ ARG TARGETARCH
109+ USER 0
110+ WORKDIR /tmp/build-wheels
111+
112+ # Build pyarrow optimized for s390x
113+ RUN --mount=type=cache,target=/root/.cache/pip \
114+ --mount=type=cache,target=/root/.cache/dnf \
115+ if [ "$TARGETARCH" = "s390x" ]; then \
116+ # Install build dependencies (shared for pyarrow and onnx)
117+ dnf install -y cmake make gcc-c++ pybind11-devel wget && \
118+ dnf clean all && \
119+ # Build and collect pyarrow wheel
120+ git clone --depth 1 https://github.com/apache/arrow.git && \
121+ cd arrow/cpp && \
122+ mkdir release && cd release && \
123+ cmake -DCMAKE_BUILD_TYPE=Release \
124+ -DCMAKE_INSTALL_PREFIX=/usr/local \
125+ -DARROW_PYTHON=ON \
126+ -DARROW_PARQUET=ON \
127+ -DARROW_ORC=ON \
128+ -DARROW_FILESYSTEM=ON \
129+ -DARROW_JSON=ON \
130+ -DARROW_CSV=ON \
131+ -DARROW_DATASET=ON \
132+ -DARROW_DEPENDENCY_SOURCE=BUNDLED \
133+ -DARROW_WITH_LZ4=OFF \
134+ -DARROW_WITH_ZSTD=OFF \
135+ -DARROW_WITH_SNAPPY=OFF \
136+ -DARROW_BUILD_TESTS=OFF \
137+ -DARROW_BUILD_BENCHMARKS=OFF \
138+ .. && \
139+ make -j$(nproc) VERBOSE=1 && \
140+ make install -j$(nproc) && \
141+ cd ../../python && \
142+ pip install --no-cache-dir -r requirements-build.txt && \
143+ PYARROW_WITH_PARQUET=1 \
144+ PYARROW_WITH_DATASET=1 \
145+ PYARROW_WITH_FILESYSTEM=1 \
146+ PYARROW_WITH_JSON=1 \
147+ PYARROW_WITH_CSV=1 \
148+ PYARROW_PARALLEL=$(nproc) \
149+ python setup.py build_ext --build-type=release --bundle-arrow-cpp bdist_wheel && \
150+ mkdir -p /tmp/wheels && \
151+ cp dist/pyarrow-*.whl /tmp/wheels/ && \
152+ chmod -R 777 /tmp/wheels && \
153+ # Ensure wheels directory exists and has content
154+ ls -la /tmp/wheels/; \
155+ else \
156+ # Create empty wheels directory for non-s390x
157+ mkdir -p /tmp/wheels; \
158+ fi
159+
56160####################
57161# jupyter-minimal #
58162####################
@@ -79,12 +183,14 @@ WORKDIR /opt/app-root/src
79183
80184ENTRYPOINT ["start-notebook.sh"]
81185
186+
82187########################
83188# jupytyer-datascience #
84189########################
85190FROM jupyter-minimal AS jupyter-datascience
86191
87192ARG DATASCIENCE_SOURCE_CODE=jupyter/datascience/ubi9-python-3.12
193+ ARG TARGETARCH
88194
89195LABEL name="odh-notebook-jupyter-datascience-ubi9-python-3.12" \
90196 summary="Jupyter data science notebook image for ODH notebooks" \
@@ -110,22 +216,45 @@ COPY --from=mongocli-builder /tmp/mongocli /opt/app-root/bin/
110216# Other apps and tools installed as default user
111217USER 1001
112218
219+ # Copy wheels from build stage (s390x only)
220+ COPY --from=s390x-builder /tmp/wheels /tmp/wheels
221+ RUN if [ "$TARGETARCH" = "s390x" ]; then \
222+ pip install --no-cache-dir /tmp/wheels/*.whl; \
223+ else \
224+ echo "Skipping wheel install for $TARGETARCH"; \
225+ fi
226+
113227# Install Python packages and Jupyterlab extensions from requirements.txt
114228COPY ${DATASCIENCE_SOURCE_CODE}/pylock.toml ./
115229# Copy Elyra setup to utils so that it's sourced at startup
116230COPY ${DATASCIENCE_SOURCE_CODE}/setup-elyra.sh ${DATASCIENCE_SOURCE_CODE}/utils ./utils/
117231
118- RUN echo "Installing softwares and packages" && \
232+ RUN --mount=type=cache,target=/root/.cache/pip \
233+ echo "Installing softwares and packages" && \
119234 # This may have to download and compile some dependencies, and as we don't lock requirements from `build-system.requires`,
120235 # we often don't know the correct hashes and `--require-hashes` would therefore fail on non amd64, where building is common.
121- uv pip install --strict --no-deps --no-cache --no-config --no-progress --verify-hashes --compile-bytecode --index-strategy=unsafe-best-match --requirements=./pylock.toml && \
236+ if [ "$TARGETARCH" = "s390x" ]; then \
237+ # For s390x, we need special flags and environment variables for building packages
238+ GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1 \
239+ CFLAGS="-O3" CXXFLAGS="-O3" \
240+ uv pip install --strict --no-deps --no-cache --no-config --no-progress \
241+ --verify-hashes --compile-bytecode --index-strategy=unsafe-best-match \
242+ --requirements=./pylock.toml; \
243+ else \
244+ # This may have to download and compile some dependencies, and as we don't lock requirements from `build-system.requires`,
245+ # we often don't know the correct hashes and `--require-hashes` would therefore fail on non amd64, where building is common.
246+ uv pip install --strict --no-deps --no-cache --no-config --no-progress \
247+ --verify-hashes --compile-bytecode --index-strategy=unsafe-best-match \
248+ --requirements=./pylock.toml; \
249+ fi && \
122250 # setup path for runtime configuration
123251 mkdir /opt/app-root/runtimes && \
124252 mkdir /opt/app-root/pipeline-runtimes && \
125253 # Remove default Elyra runtime-images \
126254 rm /opt/app-root/share/jupyter/metadata/runtime-images/*.json && \
127255 # Replace Notebook's launcher, "(ipykernel)" with Python's version 3.x.y \
128- sed -i -e "s/Python.*/$(python --version | cut -d '.' -f-2)\",/" /opt/app-root/share/jupyter/kernels/python3/kernel.json && \
256+ sed -i -e "s/Python.*/$(python --version | cut -d '.' -f-2)\",/" \
257+ /opt/app-root/share/jupyter/kernels/python3/kernel.json && \
129258 # copy jupyter configuration
130259 install -D -m 0644 /opt/app-root/bin/utils/jupyter_server_config.py \
131260 /opt/app-root/etc/jupyter/jupyter_server_config.py && \
0 commit comments