Skip to content

feat: shared read-only toolchain volumes (one copy of Go/Rust/JDK for all projects) - #20

Open
ai-anant wants to merge 1 commit into
cyfinoid:mainfrom
ai-anant:feat/shared-toolchain-volumes
Open

feat: shared read-only toolchain volumes (one copy of Go/Rust/JDK for all projects)#20
ai-anant wants to merge 1 commit into
cyfinoid:mainfrom
ai-anant:feat/shared-toolchain-volumes

Conversation

@ai-anant

@ai-anant ai-anant commented Aug 2, 2026

Copy link
Copy Markdown

Summary

Go/Rust/Java toolchains were baked into every project image — golang-go apt (~1 GB), rustup stable + compiled cargo-audit (~1.5–2 GB), default-jdk (~400 MB), each rebuilt per project. This PR moves them to one shared named volume (aidc_toolchains), populated once and mounted read-only into every project container at /opt/toolchains.

This is the core of the "mount snapshots of pre-verified tools as shared read-only memory, one copy of Python serves 10,000 sandboxes" idea from https://x.com/AlexJonesax/status/2083617647342600591:

  • One copy of Go/Rust/JDK serves all projects — no per-project download/install.
  • Read-only mount — agents can't tamper with the shared toolchain.
  • Revoke once, stops everywheredocker volume rm aidc_toolchains && aidc tools install repopulates and a bad toolchain disappears from every container.

Changes

  • templates/devcontainer/Dockerfile.toolchain.tmpl (new) — per-toolchain store image:
    • go: Go 1.26.5 tarball + gosec (prebuilt via go install)
    • rust: rustup stable (minimal profile) + cargo-audit (prebuilt via cargo install)
    • java: Temurin 21 (pinned jdk-21.0.12+8)
    • Installs into /opt/toolchains-store/<lang>, writes a .aidc-ready marker, and when run with the volume mounted copies the toolchain into it. Pinned versions; content-hashed image tag (aidc-toolchain-store-<lang>:<hash>).
  • lib/aidc.sh
    • aidc tools install [go|rust|java|all] — build store image once + populate volume once.
    • aidc tools status — show which shared toolchains are installed.
    • aidc::ensure_toolchain_volumes — auto-ensures the toolchains a project needs; wired into cmd_up, cmd_rebuild, cmd_rescan, ensure_container_running before the compose build.
    • AIDC_TOOLCHAIN_VOLUME env override for the volume name.
  • templates/devcontainer/Dockerfile.tmplgo/rust/java toolchain arms are now no-ops (the volume provides them); ENV PATH + GOROOT/RUSTUP_HOME/JAVA_HOME point at /opt/toolchains/*.
  • templates/devcontainer/compose.yaml.tmplaidc_toolchains named volume mounted read_only at /opt/toolchains.
  • README.md / docs/install.md — document aidc tools and the shared-volume model.

Verification (measured)

  • Store image for go builds; volume populates; go version go1.26.5 linux/arm64 runs from the mounted volume; go, gofmt, gosec all present; .aidc-ready marker written.
  • Read-only enforced: touch /opt/toolchains/go/evilRead-only file system.
  • bash -n (bash 5 + 3.2), shellcheck -x, bash-3.2 compat, tests/resolve-oauth-token.test.sh (7/7) — clean.

Merge note

Touches the same toolchain block as #15/#16/#17/#18 — expect small conflicts if merged before those; the toolchain arms are self-contained per PR. AIDC_AGENTS/AIDC_BASE_IMAGE interactions are documented in the respective PRs.

Closes #9

… all projects)

Go/Rust/Java toolchains were baked into every project image (~1-2GB each,
compiled from source for gosec/cargo-audit). Move them to ONE shared
named volume (aidc_toolchains), populated once and mounted READ-ONLY into
every project container at /opt/toolchains — the 'mount snapshots of
pre-verified tools as shared read-only memory' idea.

- templates/devcontainer/Dockerfile.toolchain.tmpl (new): builds a store
  image per toolchain (go1.26.5 + gosec, rustup stable + cargo-audit,
  Temurin 21 + nothing) into /opt/toolchains-store, then copies into the
  volume when run. Pinned versions; content-hashed image tag.
- lib/aidc.sh: aidc tools <install [go|rust|java|all]|status> manages the
  volume; ensure_toolchain_volumes auto-populates on up/rebuild/rescan and
  before tool commands.
- Dockerfile.tmpl: go/rust/java arms are now no-ops (volume provides them);
  PATH + GOROOT/RUSTUP_HOME/JAVA_HOME point at /opt/toolchains.
- compose.yaml.tmpl: aidc_toolchains volume mounted read_only at
  /opt/toolchains.

Verified end-to-end: store image builds, volume populates, go1.26.5 +
gosec run from the mounted volume, and the read-only mount rejects writes.

Refs cyfinoid#9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Image size: share Go/Rust/Java toolchains via a shared read-only volume instead of baking into every image

1 participant