Skip to content

calque real --pip is silently ignored in docker-mode/Dockerfile-build path — only HostMode ever consumes it #196

Description

@scttfrdmn

Context

Found via a real calque real --script .../blending_app.py --function inspect_netcdf_bundle --instance g6.2xlarge --item-file ... --pip xarray --pip netCDF4 --i-understand-this-spends-money run against real AWS. inspect_netcdf_bundle's resolved image (blending_image) has real .run_commands(...) build steps beyond a bare pullable ref, so internal/image.NeedsBuild correctly routed this to the on-instance Dockerfile-build path.

The Dockerfile built successfully (its OWN pip3 install google-cloud-storage step ran fine), but the actual docker run failed immediately:

LEAK[unhandled_case] item 0 failed in payload: No module named 'xarray'

despite passing --pip xarray --pip netCDF4 explicitly.

Root cause

internal/exec/bootstrap.go's Command(): b.PipPackages is ONLY ever read inside the if b.HostMode { ... } branch (confirmed by grep — zero other references). Once buildDockerfile/plain-docker-mode is selected instead of HostMode, PipPackages is silently dropped on the floor — no leak, no warning, nothing. The flag's own help text (cmd/calque/main.go) doesn't say it's HostMode-only:

"third-party Python package to install via uv on the instance before running a --script-picked unit's REAL body (calque#148), repeatable — needed when the script's own pip_install(...) chain wasn't statically resolvable"

That description reads as applying regardless of execution mode — a caller has no way to know --pip does nothing once their script's resolved image needs a docker build/pull instead of HostMode.

Why this matters

This is exactly the situation --pip's own doc comment says it's FOR ("the script's own pip_install(...) chain wasn't statically resolvable") — inspect_netcdf_bundle's real dependency (xarray) comes from a requirements.txt installed via a git-clone .run_commands() step, which calque correctly can't statically resolve into a .pip_install(...) list. --pip is the documented escape hatch for exactly this case, and it doesn't work in docker-mode at all.

Ask

Either:

  1. Make --pip also apply in docker-mode/buildDockerfile mode — e.g. render an extra RUN pip3 install --no-cache-dir <packages> layer in the generated Dockerfile (internal/image.Render) when PipPackages is non-empty, or inject a pip3 install line into the docker run invocation itself before warmd starts.
  2. At minimum, leak loudly when --pip was supplied but the resolved path is docker-mode/buildDockerfile (not HostMode) — "‑-pip packages ignored: this run resolved to docker-mode, not host-mode; --pip has no effect here" — so a caller gets an honest signal instead of a downstream No module named 'X' crash that looks like a payload bug.

Real repro: testdata/scripts/ likely needs a new fixture whose resolved image has .run_commands(...)-only build steps (not a bare pip_install(...) chain) combined with a --pip-supplied dependency the body actually imports, to regression-test whichever fix lands.

Same root file/mechanism as calque#194/#195, all found in the same real-AWS session — worth checking bootstrap.go's docker-mode branch as a whole for other HostMode-only assumptions while addressing this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions