container-addon: OS-agnostic python3 install + docs/support-matrix#121
container-addon: OS-agnostic python3 install + docs/support-matrix#121sumit-badsara wants to merge 1 commit into
Conversation
Broaden OS support for the container hooks add-on and document it. - devcontainer-feature: drop the glibc-only dependsOn on the official python feature and install python3 best-effort across apt/apk/dnf/ microdnf/yum (mirroring the existing curl install), guarded with `|| true` so a failed package install never aborts the build. This adds Alpine (musl) plus broad Linux support. The existing python3 safety-net warning is kept (now fires only if install truly failed), and the description is updated to drop the external-feature claim. - container-addon/README.md: new docs covering the two delivery methods (Feature + COPY --from add-on), a supported-base-images matrix, the credential mount patterns (single-user vs su/sudo via link-unbound.sh, incl. the 0600-perm caveat), an OS-agnostic consumer Dockerfile, and Windows/distroless/other-tools out-of-scope notes. - container-addon/consumer.Dockerfile.example: minimal OS-agnostic COPY --from consumer example, referenced from the README. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| # the build under `set -e` — the safety-net warning below fires only if it truly failed. | ||
| if ! command -v python3 >/dev/null 2>&1; then | ||
| echo "unbound-hooks: WARNING — python3 not found on PATH despite the python dependency;" >&2 | ||
| if command -v apt-get >/dev/null 2>&1; then apt-get update 2>&1 && apt-get install -y --no-install-recommends python3 2>&1 || true |
There was a problem hiding this comment.
The python3 apt-get block uses
apt-get update 2>&1 (verbose) while the existing curl block on line 40 uses apt-get update -qq (quiet). On a Debian/Ubuntu base that lacks python3, the update output streams to the build log at full verbosity, inconsistent with the curl install below. Aligning to -qq keeps build noise uniform and matches the established pattern.
| if command -v apt-get >/dev/null 2>&1; then apt-get update 2>&1 && apt-get install -y --no-install-recommends python3 2>&1 || true | |
| if command -v apt-get >/dev/null 2>&1; then apt-get update -qq && apt-get install -y -qq --no-install-recommends python3 2>&1 || true |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| elif command -v dnf >/dev/null 2>&1; then dnf install -y python3 curl; \ | ||
| elif command -v microdnf >/dev/null 2>&1; then microdnf install -y python3 curl; \ | ||
| elif command -v yum >/dev/null 2>&1; then yum install -y python3 curl; \ |
There was a problem hiding this comment.
The apt-get branch cleans up package lists (
rm -rf /var/lib/apt/lists/*), but the dnf, microdnf, and yum branches leave their cache in the image layer. On RHEL/Fedora/CentOS bases this can add tens of MBs to the final image. The same omission exists in the matching snippet in container-addon/README.md.
| elif command -v dnf >/dev/null 2>&1; then dnf install -y python3 curl; \ | |
| elif command -v microdnf >/dev/null 2>&1; then microdnf install -y python3 curl; \ | |
| elif command -v yum >/dev/null 2>&1; then yum install -y python3 curl; \ | |
| elif command -v dnf >/dev/null 2>&1; then dnf install -y python3 curl && dnf clean all; \ | |
| elif command -v microdnf >/dev/null 2>&1; then microdnf install -y python3 curl && microdnf clean all; \ | |
| elif command -v yum >/dev/null 2>&1; then yum install -y python3 curl && yum clean all; \ |
Summary
Broadens the container add-on's OS support and documents it.
OS-agnostic python3 (drops the glibc-only
dependsOn): the Feature previously depended onghcr.io/devcontainers/features/python, which is glibc-only and therefore excludes Alpine. This replaces that dependency with a best-effort package-manager install ofpython3ininstall.sh— mirroring the existing best-effortcurlinstall — acrossapt/apk/dnf/microdnf/yum. Installs are guarded with|| trueso a failed package install never aborts the build underset -euo pipefail. The existing python3 safety-net warning is kept (it now fires only if the install truly failed), and thedependsOnblock is removed fromdevcontainer-feature.jsonwith thedescriptionupdated to reflect the best-effort install. Net effect: adds Alpine (musl) + broad Linux support with no external feature dependency. Theversionfield is intentionally untouched (CI rewrites it from the release tag).New docs + support matrix (
container-addon/README.md): what the add-on is, the two delivery methods (devcontainer Feature +COPY --fromadd-on), a supported-base-images matrix (Debian/Ubuntu, RHEL/Fedora/CentOS, Alpine ✅; distroless ❌), credential mount patterns (single-user vs any-user/su-sudo via the bundledlink-unbound.sh, including the 0600-perm caveat), and an OS-agnostic consumer Dockerfile snippet.New OS-agnostic consumer example (
container-addon/consumer.Dockerfile.example): minimalCOPY --fromconsumer that installs python3 + curl across package managers, referenced from the README.Out of scope (documented): Windows containers (different managed-settings path
C:\ProgramData\ClaudeCode\…, no POSIXsh,pythonnotpython3— separate future track), distroless (no package manager), and other AI tools beyond Claude Code (Cursor/Codex/Copilot hooks exist in this repo but aren't packaged here yet).Stacking
This is a distinct PR stacked on top of
feat/container-addon-symlink-creds(PR #120) — the symlink-creds branch is used only as the base to keep this diff clean (it bundleslink-unbound.sh, which the docs reference). The base should move tomainafter the symlink PR merges.Validation
bash -n/sh -noninstall.sh,link-unbound.sh, and the consumer DockerfileRUNbody — all pass.devcontainer-feature.json, bothmanaged-settings.json).unbound.py(CI copies the canonical hook in at publish time).claude-code/hooks/unbound.pyis untouched.🤖 Generated with Claude Code
Greptile Summary
This PR replaces the glibc-only
dependsOnPython Feature with a self-contained best-effortpython3install block ininstall.sh, extending Alpine/musl support to the devcontainer Feature. It also adds a README and consumer Dockerfile example documenting the OS support matrix, credential mount patterns, and out-of-scope cases.install.sh: New python3 install block (apt/apk/dnf/microdnf/yum, guarded with|| true) mirrors the existing curl pattern;dependsOnis cleanly removed fromdevcontainer-feature.json.container-addon/README.md+consumer.Dockerfile.example: New documentation covering supported bases, credential mount patterns (single-user and su-sudo), and a minimal OS-agnostic consumer Dockerfile snippet.Confidence Score: 4/5
Safe to merge; the logic is correct and the
|| trueguards are properly scoped around the full&&chains underset -euo pipefail.The install block correctly mirrors the established curl pattern, the
dependsOnremoval is clean, and the safety-net warning is preserved. The two findings are a verbosity inconsistency inapt-get updateflags and missing dnf/yum cache cleanup in the consumer example — both affect build log noise and image layer size rather than correctness.The apt-get verbosity in
install.shand the dnf/yum cleanup gap inconsumer.Dockerfile.example(and the matching README snippet) are worth a second look before this ships as a reference example.Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[install.sh runs at image build] --> B{python3 on PATH?} B -- yes --> E{curl on PATH?} B -- no --> C{Detect package manager} C -- apt-get --> C1[apt-get install python3 with true] C -- apk --> C2[apk add python3 with true] C -- dnf/microdnf/yum --> C3[pkg install python3 with true] C -- none --> C4[no-op] C1 & C2 & C3 & C4 --> E2{python3 on PATH now?} E2 -- no --> W1[WARNING: hooks fail open] E2 -- yes --> E W1 --> E E -- no --> H{Detect package manager for curl} H -- apt-get --> H1[apt-get install curl with true] H -- apk/dnf/etc --> H2[pkg install curl with true] H1 & H2 --> I{curl on PATH?} I -- no --> W2[WARNING: gateway calls fail open] I -- yes --> G[Install hook + managed-settings + link-unbound.sh] W2 --> G E -- yes --> GReviews (1): Last reviewed commit: "container-addon: make Feature OS-agnosti..." | Re-trigger Greptile