Skip to content

Run fetch and update in separate containers behind isolated_fetch_update - #647

Draft
v-robaiken wants to merge 1 commit into
mainfrom
robaiken/isolated-fetch-update
Draft

Run fetch and update in separate containers behind isolated_fetch_update#647
v-robaiken wants to merge 1 commit into
mainfrom
robaiken/isolated-fetch-update

Conversation

@v-robaiken

@v-robaiken v-robaiken commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

CLI half of running fetch and update in separate containers (ADR 0051). Pairs with dependabot/dependabot-core#15862 — they need to land together.

This only moves the clone. No file stripping, no serialization, no credential changes.

What it does

Behind the isolated_fetch_update experiment, runIsolated clones in one container and updates in another. The clone travels on a Docker volume mounted at DEPENDABOT_REPO_CONTENTS_PATH in both, so it's made once instead of twice.

Each side gets its own proxy on its own network, so the update container has no route to the fetch proxy. Credentials are identical for both today — the seam is marked at the call site.

--local populates the fetch container only. Debug shells, the OTel collector and use_case_insensitive_filesystem are rejected under the split rather than silently misbehaving.

Combined mode drops the bin/run fetch_files && prefix. That was a no-op stub, so this is byte-identical to today, and it avoids fetching twice now that core makes it real.

Drive-by bugfix

RunCmd was dropping the tail of every container's output — Prefixer.WriteTo doesn't flush pending data at EOF and io.Copy only calls it once. Running bin/run twice used to mask it, which is what the "unless I echo here the json doesn't output" comment in input.txt was working around. Happy to split this out if preferred.

Testing

New testdata/scripts/isolated.txt asserts the clone crosses the volume. Full script suite passes except proxy, which also fails on main.

Verified against the real gomod image and dependabot-fixtures/go-modules-lib: one git clone in both topologies, zero contents API calls from the update container, identical create_pull_request payloads.

Not a security boundary yet

The update container still calls the target repo twice — branch validation from the duplicate FileFetcherCommand run, and PR name prefixing — so its credential can't be dropped. The same git_source credential also serves dependency metadata lookups, so it can't simply be deleted.

With the experiment on, the CLI clones in one updater container and updates in
another. The clone travels between them on a Docker volume mounted at
DEPENDABOT_REPO_CONTENTS_PATH in both, so it is made once rather than twice.
Each side gets its own proxy on its own network pair, so the update container
has no route to the fetch proxy and the two credential sets can diverge later.
They are identical for now; the call site marks the seam.

`--local` populates the fetch container only. Debug shells, the OpenTelemetry
collector and use_case_insensitive_filesystem are rejected rather than silently
misbehaving under the split.

Combined mode drops the `bin/run fetch_files &&` prefix. That entrypoint used to
be a no-op stub, so this is byte-identical to today, and it avoids fetching
twice now that dependabot-core makes it do real work.

Also fixes container output being truncated: RunCmd piped through io.Copy and
prefixer, but Prefixer.WriteTo returns without writing pending data at EOF and
io.Copy only calls WriteTo once, so the tail of every command was dropped.
Running `bin/run` twice used to mask it, which is what the "unless I echo here
the json doesn't output" comment in input.txt was working around.
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.

1 participant