perf(concourse): shell out git clone instead of libgit2's RepoBuilder - #26
Merged
Conversation
The v0.7.21 `[cepler-perf]` lines revealed the entire `in` step lives in libgit2's pack indexing — measured 64.35s for `RepoBuilder::clone` vs ~0s for every other phase including Mixed reset. A parallel concourse git-resource (using the git CLI) cloned the same repo in ~6s in the same build log. This isn't an anomaly — it's the documented libgit2 pack-indexing performance gap. See issues #4674 / #3920 / #2836 in libgit2/libgit2, plus the Guix-devel RFC that walks through the same conclusion we just reached. Root cause per those threads is mmap/munmap inefficiency in `git_mwindow_free_all_locked`, not anything we can patch from cepler. Fix: replace `RepoBuilder::clone` with a `git clone --no-checkout` subprocess. The rest of cepler keeps using libgit2 via `Repository::open` once the fetch is done — only the bulk transfer is shelled out. SSH auth plumbing: * `write_ssh_key` writes the source's `private_key` to `/tmp/cepler-ssh-key-<pid>-<ns>` with 0600 perms (ssh refuses looser). * A `KeyFile` RAII guard removes the tempfile on drop, so a panic between key-write and `git clone` exit can't leak the key on disk. * `GIT_SSH_COMMAND` points ssh at the key file with `-o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null` — matches the prior `CertificatePassthrough` posture (concourse pipelines authenticate via the private_key, not via host-key trust). * Empty `private_key` short-circuits to `None` so local-bare-repo unit tests still work without going through the ssh setup. The Mixed reset stays as defensive insurance. `git clone --no-checkout` already populates the index, so the reset is a no-op there — but it keeps the invariant local to `Repo::clone` and the cost is ~0s. Two new unit tests lock down the SSH-key handling: * `write_ssh_key_round_trips_content_and_perms_and_drop_removes_file` — file exists with 0600 perms while `KeyFile` is alive; gone after `drop`. * `write_ssh_key_returns_none_for_empty_input` — covers the unit-test short-circuit so local-bare-repo clones don't try to set up ssh. The two existing clone tests now exercise the `git` subprocess end-to-end (they pass `private_key: String::new()` so SSH stays out of the way) and continue to pass — which proves `git clone --no-checkout` produces the same WT-empty / index-populated state that libgit2's NONE strategy + Mixed reset did. Expected wall-clock impact on volcano-qa-lana-bank: `in` step drops from ~65-70s (v0.7.21) to ~5-8s. The Mixed reset and selective checkout remain unchanged at sub-second. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
[cepler-perf]timing logs from v0.7.21 (shipped in #25) showed every wall-clock second of theinstep lives in one place:Build #109 — the same build whose log shows a parallel concourse git-resource cloning the same repo in ~6s via the git CLI:
So our 64s is libgit2 doing pack indexing slowly, not a fundamental cost of the operation.
This isn't an anomaly — it's a documented libgit2 limitation:
git clone· #4674Per those threads the bottleneck is mmap/munmap inefficiency in
git_mwindow_free_all_locked, not anything we can patch from cepler.Fix
Replace
RepoBuilder::clonewith agit clone --no-checkoutsubprocess. The rest of cepler keeps using libgit2 viaRepository::open— only the bulk transfer is shelled out.The container image already ships git + openssh via Alpine (see
images/concourse/Dockerfile). Standalone CLI users almost certainly have it too.SSH key handling
The source's
private_keyis now passed to git viaGIT_SSH_COMMANDinstead of libssh2's in-memory key path:write_ssh_keywrites it to/tmp/cepler-ssh-key-<pid>-<ns>with 0600 perms (ssh refuses anything looser).KeyFileRAII guard removes the tempfile on drop, so a panic between key-write andgit cloneexit can't leak the key.GIT_SSH_COMMANDadds-o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null— matches the priorCertificatePassthrough-style trust-on-first-use posture (concourse pipelines authenticate via the key, not via host-key trust).private_keyshort-circuits toNone, so local-bare-repo unit tests keep working without going through ssh setup.Test plan
cargo nextest run— 7/7 pass:clone_skips_working_tree_checkout_but_populates_index,checkout_paths_materialises_only_requested_files) now exercise thegitsubprocess end-to-end against a local bare repo. They provegit clone --no-checkoutproduces the same WT-empty / index-populated state libgit2'sGIT_CHECKOUT_NONE+ Mixed reset did — includingwrite_tree-from-index reproducing HEAD's tree, which is the load-bearing invariantcommit_state_fileonoutdepends on.write_ssh_key_round_trips_content_and_perms_and_drop_removes_file(the file exists with 0600 whileKeyFileis alive; gone afterdrop) andwrite_ssh_key_returns_none_for_empty_input(empty-key short-circuit).cargo clippy --all-targets -- -D warnings— cleannix flake check— passes[cepler-perf] git clone subprocessdrops from ~64s to ~5-8s, mirroring what the parallel git-resource sees todayExpected impact
instep total drops from ~65-70s to ~5-8s on volcano-qa-lana-bank. The Mixed reset stays as defensive insurance (git clone --no-checkoutalready populates the index, so it's a no-op there) — kept for invariant locality at ~0s cost.Trade-offs
gitCLI dependency on PATH. Surfaced clearly in the error message if it's missing.🤖 Generated with Claude Code