Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/test_images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ jobs:
needs: prepare
container:
image: "nvidia/cuopt:${{ inputs.IMAGE_TAG_PREFIX }}-cuda${{ needs.prepare.outputs.CUDA_SHORT }}-py${{ needs.prepare.outputs.PYTHON_SHORT }}"
options: --user root
steps:
- name: Checkout code repo
uses: actions/checkout@v4
Expand Down
71 changes: 43 additions & 28 deletions ci/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -46,58 +46,73 @@ RUN apt-get update && apt-get install -y --no-install-recommends build-essential

ENV DEBIAN_FRONTEND=""

RUN ln -sf /usr/bin/python${PYTHON_SHORT_VER} /usr/bin/python && \
groupadd -r cuopt && \
useradd -r -g cuopt cuopt && \
chown -R cuopt:cuopt /usr/local/lib/python${PYTHON_SHORT_VER}/dist-packages

USER cuopt
RUN ln -sf /usr/bin/python${PYTHON_SHORT_VER} /usr/bin/python

FROM python-env AS install-env

WORKDIR /home/cuopt

ARG CUOPT_VER
ARG PYTHON_SHORT_VER

# Install cuOpt as root to make it available to all users
RUN cuda_suffix=cu$(echo ${CUDA_VER} | cut -d'.' -f1) && \
cuda_major_minor=$(echo ${CUDA_VER} | cut -d'.' -f1-2) && \
python -m pip install \
--extra-index-url https://pypi.nvidia.com \
--extra-index-url https://pypi.anaconda.org/rapidsai-wheels-nightly/simple \
--user \
--no-cache-dir \
"cuopt-server-${cuda_suffix}==${CUOPT_VER}" \
"cuopt-sh-client==${CUOPT_VER}" \
"nvidia-cuda-runtime-${cuda_suffix}==${cuda_major_minor}.*" && \
python -m pip list

USER root

# Remove gcc to save space, gcc was required for building psutils
RUN apt-get purge -y gcc && rm -rf /var/lib/apt/lists/*

USER cuopt

COPY ./LICENSE /home/cuopt/LICENSE
COPY ./VERSION /home/cuopt/VERSION
COPY ./THIRD_PARTY_LICENSES /home/cuopt/THIRD_PARTY_LICENSES

FROM install-env AS cuopt-final

ARG PYTHON_SHORT_VER

# Set environment variables in .bashrc for all future shells
RUN echo 'export PATH="/usr/local/cuda/bin:/usr/bin:/usr/local/bin:/usr/local/nvidia/bin/:/home/cuopt/.local/lib/python${PYTHON_SHORT_VER}/dist-packages/libcuopt/bin/:/home/cuopt/.local/bin:$PATH"' >> /home/cuopt/.bashrc && \
echo 'export LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu:/usr/lib/aarch64-linux-gnu:/usr/local/cuda/lib64:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/lib/wsl/lib:/usr/lib/wsl/lib/libnvidia-container:/usr/lib/nvidia:/usr/lib/nvidia-current:/home/cuopt/.local/lib/python${PYTHON_SHORT_VER}/dist-packages/libcuopt/lib/:/home/cuopt/.local/lib/python${PYTHON_SHORT_VER}/dist-packages/rapids_logger/lib64:${LD_LIBRARY_PATH}"' >> /home/cuopt/.bashrc


# Create a .bash_profile that sources .bashrc if it exists
RUN echo 'if [ -f ~/.bashrc ]; then . ~/.bashrc; fi' > /home/cuopt/.bash_profile

# Consolidate all directory creation, permissions, and file operations into a single layer
RUN mkdir -p /opt/cuopt && \
chmod 777 /opt/cuopt && \
# Create profile.d script for universal access
echo '#!/bin/bash' > /etc/profile.d/cuopt.sh && \
echo 'export PATH="/usr/local/cuda/bin:/usr/bin:/usr/local/bin:/usr/local/nvidia/bin/:/usr/local/lib/python${PYTHON_SHORT_VER}/dist-packages/libcuopt/bin:$PATH"' >> /etc/profile.d/cuopt.sh && \
echo 'export LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu:/usr/lib/aarch64-linux-gnu:/usr/local/cuda/lib64:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/lib/wsl/lib:/usr/lib/wsl/lib/libnvidia-container:/usr/lib/nvidia:/usr/lib/nvidia-current:/usr/local/lib/python${PYTHON_SHORT_VER}/dist-packages/libcuopt/lib/:/usr/local/lib/python${PYTHON_SHORT_VER}/dist-packages/rapids_logger/lib64:${LD_LIBRARY_PATH}"' >> /etc/profile.d/cuopt.sh && \
chmod +x /etc/profile.d/cuopt.sh && \
# Set in /etc/environment for system-wide access
echo 'PATH="/usr/local/cuda/bin:/usr/bin:/usr/local/bin:/usr/local/nvidia/bin/:/usr/local/lib/python${PYTHON_SHORT_VER}/dist-packages/libcuopt/bin:$PATH"' >> /etc/environment && \
echo 'LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu:/usr/lib/aarch64-linux-gnu:/usr/local/cuda/lib64:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/lib/wsl/lib:/usr/lib/wsl/lib/libnvidia-container:/usr/lib/nvidia:/usr/lib/nvidia-current:/usr/local/lib/python${PYTHON_SHORT_VER}/dist-packages/libcuopt/lib/:/usr/local/lib/python${PYTHON_SHORT_VER}/dist-packages/rapids_logger/lib64:${LD_LIBRARY_PATH}"' >> /etc/environment && \
# Set proper permissions for cuOpt installation
chmod -R 755 /usr/local/lib/python${PYTHON_SHORT_VER}/dist-packages/cuopt* && \
chmod -R 755 /usr/local/lib/python${PYTHON_SHORT_VER}/dist-packages/libcuopt* && \
chmod -R 755 /usr/local/lib/python${PYTHON_SHORT_VER}/dist-packages/cuopt_* && \
chmod -R 755 /usr/local/bin/* && \
# Create entrypoint script in a single operation
echo '#!/bin/bash' > /opt/cuopt/entrypoint.sh && \
echo 'set -e' >> /opt/cuopt/entrypoint.sh && \
echo '' >> /opt/cuopt/entrypoint.sh && \
echo '# Get current user info from Docker environment variables' >> /opt/cuopt/entrypoint.sh && \
echo 'CURRENT_UID=${UID:-1000}' >> /opt/cuopt/entrypoint.sh && \
echo 'CURRENT_GID=${GID:-1000}' >> /opt/cuopt/entrypoint.sh && \
echo '' >> /opt/cuopt/entrypoint.sh && \
echo '# Set environment variables for the current user' >> /opt/cuopt/entrypoint.sh && \
echo 'export HOME="/opt/cuopt"' >> /opt/cuopt/entrypoint.sh && \
echo '' >> /opt/cuopt/entrypoint.sh && \
echo '# Execute the command' >> /opt/cuopt/entrypoint.sh && \
echo 'exec "$@"' >> /opt/cuopt/entrypoint.sh && \
chmod +x /opt/cuopt/entrypoint.sh

# Set the default working directory to the cuopt folder
WORKDIR /opt/cuopt

# Copy all static files in a single layer
COPY ./LICENSE ./VERSION ./THIRD_PARTY_LICENSES /opt/cuopt/

# Copy CUDA libraries from the cuda-libs stage
COPY --from=cuda-libs /usr/local/cuda/lib64/libnvrtc* /usr/local/cuda/lib64/
COPY --from=cuda-libs /usr/local/cuda/lib64/libnvJitLink* /usr/local/cuda/lib64/

# Use a shell as entrypoint to handle both service and interactive modes
ENTRYPOINT ["/bin/bash", "-c"]
CMD ["python -m cuopt_server.cuopt_service"]
# Use the flexible entrypoint
ENTRYPOINT ["/opt/cuopt/entrypoint.sh"]
CMD ["python", "-m", "cuopt_server.cuopt_service"]
21 changes: 10 additions & 11 deletions ci/docker/test_image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@

set -euo pipefail

chsh -s /bin/bash cuopt

# Install dependencies
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends file bzip2
Expand All @@ -32,18 +30,14 @@ pushd ./datasets
popd

# Create symlink to cuopt
ln -sf "$(pwd)" /home/cuopt/cuopt
ln -sf "$(pwd)" /opt/cuopt/cuopt

# Set permissions since the repo is mounted on root
chmod -R a+w "$(pwd)"

# If this script is being run as root, use 'su - cuopt -c "<command>"' to run each command as cuopt.

# Change to cuopt home directory and then to cuopt repo
cat > /home/cuopt/test.sh <<EOF
cd ~/cuopt
pip install --user pytest pexpect
export PATH=\$PATH:/home/cuopt/.local/bin
cat > /opt/cuopt/test.sh <<EOF
cd /opt/cuopt/cuopt
pip install pytest pexpect
export RAPIDS_DATASET_ROOT_DIR=\$(realpath datasets)
echo '----------------- CLI TEST START ---------------'
bash python/libcuopt/libcuopt/tests/test_cli.sh
Expand All @@ -56,4 +50,9 @@ echo '----------------- CUOPT SERVER TEST START ---------------'
python -m pytest python/cuopt_server/cuopt_server/tests/
echo '----------------- CUOPT SERVER TEST END ---------------'
EOF
su - cuopt -c "bash ~/test.sh"

# Create a temporary user with UID 888
useradd -m -u 888 -s /bin/bash tempuser888

# Switch to it
su - tempuser888 -c "bash /opt/cuopt/test.sh"