Skip to content
Merged
Changes from 2 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
77 changes: 76 additions & 1 deletion container/templates/trtllm_runtime.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,52 @@ RUN --mount=type=bind,source=./container/compliance/enumerate_bundled_decoders.p
RUN /usr/bin/python3 -m pip install --break-system-packages --upgrade "aiohttp>=3.14.3,<4.0" && \
/usr/bin/python3 -c 'import glob, os, sys; d = glob.glob("/usr/local/lib/python3.12/dist-packages/aiohttp-*.dist-info"); vs = [os.path.basename(p)[8:-10] for p in d]; print("aiohttp dist-info in system site:", vs); tv = lambda s: tuple(int(x) for x in s.split(".")[:3]); sys.exit(0 if len(vs) == 1 and (3, 14, 3) <= tv(vs[0]) < (4, 0, 0) else 1)'

# Same treatment, same reason, for the rest of the packages requirements.trtllm.txt
# floors. The comment at the top of that file says naming a package there is enough
# to refresh the bundled copy in place. For these it is not: those installs run with
Comment thread
dagil-nvidia marked this conversation as resolved.
# VIRTUAL_ENV set, so they land in /opt/dynamo/venv and the base image's copy stays
# on disk under dist-packages, which is where the image inventory reads. The floors
# and the shipped versions disagreed on every one of them:
#
# pillow floor >=12.3.0 bundled 12.2.0
# mistune floor >=3.3.0 bundled 3.2.1
# tornado floor >=6.5.6 bundled 6.5.5
# jupyter-server floor >=2.20.0 bundled 2.18.2
# jupyterlab floor >=4.5.10 bundled 4.5.7
# gitpython floor >=3.1.58 bundled 3.1.50
# soupsieve floor >=2.8.4 bundled 2.8.3
#
# aiohttp was the only floor in that file that took, and it took because of the
# explicit system-interpreter install above rather than because of the floor.
#
# Named packages only, and --no-deps keeps that literal: without it pip's default
# only-if-needed strategy will upgrade a transitive dependency whenever a newly
# selected release wants one the base image does not satisfy, which both re-solves
# part of upstream's graph and leaves that dependency's old metadata behind (it is
# not in the whiteout list, which names only the seven). These are patch-level
# bumps within the same major, so the base image's existing dependencies satisfy
Comment thread
dagil-nvidia marked this conversation as resolved.
Outdated
# them.
#
# Mirrored by the pre_runtime whiteout below for the same dist-info-rename reason,
# and re-asserted after the overlay -- see the post-overlay guard near the end of
# this file for why the in-stage guard cannot cover the whiteout.
#
# The guard normalizes distribution names before comparing (PEP 503: runs of
# -_. collapse and case folds), because the on-disk directories do not agree on
# spelling -- jupyter_server-*.dist-info and GitPython-*.dist-info both appear.
# It requires exactly one dist-info per package and a version at or above the
# floor, so a venv-only install, a missed whiteout, or an old copy surviving
# beside the new one all fail the build here rather than in a scan afterwards.
RUN /usr/bin/python3 -m pip install --break-system-packages --upgrade --no-deps \
Comment thread
dagil-nvidia marked this conversation as resolved.
Outdated
"pillow>=12.3.0" \
"mistune>=3.3.0" \
"tornado>=6.5.6" \
"jupyter-server>=2.20.0" \
"jupyterlab>=4.5.10" \
"gitpython>=3.1.58" \
"soupsieve>=2.8.4" && \
/usr/bin/python3 -c 'import os, re, sys; D = "/usr/local/lib/python3.12/dist-packages"; W = {"pillow": (12, 3, 0), "mistune": (3, 3, 0), "tornado": (6, 5, 6), "jupyter-server": (2, 20, 0), "jupyterlab": (4, 5, 10), "gitpython": (3, 1, 58), "soupsieve": (2, 8, 4)}; norm = lambda s: re.sub(r"[-_.]+", "-", s).lower(); tv = lambda s: tuple(int(x) for x in re.findall(r"\d+", s)[:3]); stems = [d[:-10].rsplit("-", 1) for d in os.listdir(D) if d.endswith(".dist-info") and "-" in d[:-10]]; found = {k: [] for k in W}; [found[norm(n)].append(v) for n, v in stems if norm(n) in found]; print("system-site dist-info:", found); bad = [(k, v) for k, v in sorted(found.items()) if len(v) != 1 or tv(v[0]) < W[k]]; print("FAILED:", bad) if bad else None; sys.exit(1 if bad else 0)'
Comment thread
dagil-nvidia marked this conversation as resolved.
Outdated

# Pull /workspace_src (incl. LICENSE) from the transport stage and
# wire up the launch screen in a single RUN — saves the standalone workspace COPY layer.
RUN --mount=type=bind,from=workspace_files,source=/workspace_src,target=/tmp/workspace_src \
Expand Down Expand Up @@ -394,7 +440,22 @@ RUN rm -rf /workspace /home/ubuntu \
/usr/local/lib/python3.12/dist-packages/aiohappyeyeballs-* \
/usr/local/lib/python3.12/dist-packages/attr \
/usr/local/lib/python3.12/dist-packages/attrs \
/usr/local/lib/python3.12/dist-packages/attrs-* && \
/usr/local/lib/python3.12/dist-packages/attrs-* \
/usr/local/lib/python3.12/dist-packages/PIL \
/usr/local/lib/python3.12/dist-packages/pillow.libs \
/usr/local/lib/python3.12/dist-packages/pillow-* \
/usr/local/lib/python3.12/dist-packages/mistune \
/usr/local/lib/python3.12/dist-packages/mistune-* \
/usr/local/lib/python3.12/dist-packages/tornado \
/usr/local/lib/python3.12/dist-packages/tornado-* \
/usr/local/lib/python3.12/dist-packages/jupyter_server \
/usr/local/lib/python3.12/dist-packages/jupyter_server-* \
/usr/local/lib/python3.12/dist-packages/jupyterlab \
/usr/local/lib/python3.12/dist-packages/jupyterlab-* \
Comment thread
dagil-nvidia marked this conversation as resolved.
/usr/local/lib/python3.12/dist-packages/git \
/usr/local/lib/python3.12/dist-packages/[Gg]it[Pp]ython-* \
/usr/local/lib/python3.12/dist-packages/soupsieve \
/usr/local/lib/python3.12/dist-packages/soupsieve-* && \
! /usr/bin/python3 -c "import cv2" 2>/dev/null && \
! /usr/bin/python3 -c "import wandb" 2>/dev/null
Comment thread
dagil-nvidia marked this conversation as resolved.
COPY --from=runtime_full / /
Expand All @@ -416,6 +477,20 @@ RUN --mount=type=bind,source=./container/compliance/enumerate_bundled_decoders.p
/usr/bin/python3 /tmp/enumerate_bundled_decoders.py "$lib"; \
done

# Post-overlay guard for the system-site floor whiteouts above, for the same
# reason DALI has one: the in-stage assertion runs inside runtime_full, before
# `COPY --from=runtime_full / /`, so by construction it cannot observe a whiteout
# mistake. A duplicate only exists after the overlay re-adds the base image's
# copy beside the upgraded one, and the metadata directory rename is what makes
# the copy survive. Two real cases were shipped past the in-stage guard before
# this existed: a case-sensitive `GitPython-*` that never matched the base
# image's lowercase `gitpython-*.dist-info`, and `PIL.libs` for a directory
# auditwheel actually names `pillow.libs`.
Comment thread
dagil-nvidia marked this conversation as resolved.
#
# Same normalized comparison as the in-stage guard, re-run here where the
# duplicate can appear. Exactly one dist-info per package, at or above the floor.
RUN /usr/bin/python3 -c 'import os, re, sys; D = "/usr/local/lib/python3.12/dist-packages"; W = {"pillow": (12, 3, 0), "mistune": (3, 3, 0), "tornado": (6, 5, 6), "jupyter-server": (2, 20, 0), "jupyterlab": (4, 5, 10), "gitpython": (3, 1, 58), "soupsieve": (2, 8, 4)}; norm = lambda s: re.sub(r"[-_.]+", "-", s).lower(); tv = lambda s: tuple(int(x) for x in re.findall(r"\d+", s)[:3]); stems = [d[:-10].rsplit("-", 1) for d in os.listdir(D) if d.endswith(".dist-info") and "-" in d[:-10]]; found = {k: [] for k in W}; [found[norm(n)].append(v) for n, v in stems if norm(n) in found]; print("post-overlay system-site dist-info:", found); bad = [(k, v) for k, v in sorted(found.items()) if len(v) != 1 or tv(v[0]) < W[k]]; print("FAILED:", bad) if bad else None; sys.exit(1 if bad else 0)'
Comment thread
dagil-nvidia marked this conversation as resolved.
Outdated

# Mirrors runtime_full's ENV — must stay in sync. Re-declaration is required
# because `FROM ${RUNTIME_IMAGE}` here does not inherit runtime_full's config.
# dev/local-dev create their own venv in a later stage, so the venv ENV is left
Expand Down
Loading