brintos

brintos / brintos-fs-go public Read only

1
1

git-edge: repo rename poisons the pooled mount — git access wedges on "does not appear to be a git repository" until the edge restarts #3

Closed jdbrinton opened this issue · 1 comment
jdbrinton jdbrinton commented

Observed live on production after renaming brintos/brintos-fsbrintos/brintos-fs-go (2026-07-13 ~07:18 UTC):

$ git ls-remote git@git.brintos.io:brintos/brintos-fs-go.git HEAD
fatal: '/tmp/git-edge-mnt-4020514352/fff12299-….git' does not appear to be a git repository

Web/API access to the repo is fine; only the git protocol path is broken, persisting 40+ minutes after the rename (well past the 12-minute pool idleTTL).

Cause

pool.go keys pool entries by repo id but binds each mount's API client to the slug captured at mount time:

repoClient := apiClient.Repo(owner, repo)   // pool.go:165 — owner/name, not id
c, err := cache.Open(repoClient, cache.Options{
    DBPath: filepath.Join(config.CacheDir(), "repos", e.repoID, "meta.db"), // id-keyed
    ...

After a rename, requests arriving under the new slug resolve to the same repo id, hit the existing pooled entry, and its mount keeps issuing /fs/* calls under the old slug — every one 404s, the mirror poisons with negatives, and git-http-backend/upload-pack sees an empty dir. The wedge outlives idleTTL in practice: each incoming attempt refreshes e.lastUsed (and any ref leaked by the failing SSH path would pin e.refs > 0), so steady probing keeps the corpse alive indefinitely. Recovery requires a git-edge restart or maintenance unmount.

Suggested fixes (any one suffices)

  1. Resolve the slug per mount from the repo id at bring-up, or have /api/internal/git/mount-token return the canonical slug and re-check it when acquiring a pooled entry (unmount on mismatch).
  2. Have the rename path (update_repo) notify git-edge to drop the repo's pool entry (there is already a secret-gated maintenance endpoint).
  3. Key the API client by repo id server-side (id-addressed /fs/* routes), making the edge rename-proof.

Until fixed: after renaming any git repo, bounce git-edge (or hit the maintenance unmount) before git access resumes.

jdbrinton jdbrinton commented

Resolved by the new C git-edge (repo brintos/git-edge, submodule misc/git-edge), which replaces brintos-fs-go/cmd/git-edge and is now deployed to production and validated live.

The rename wedge is fixed by design: the mount pool stores each entry's slug and, on a pool hit where the canonical owner/repo (returned fresh by /api/internal/git/auth every request) differs, it retires the stale entry (unmount now if idle, else doom + unmount on ref-drain) and remounts under the new slug — with generation-unique mountpoints so a retired mount and its replacement never collide. No brintos-web change; transport/client-agnostic (HTTP + SSH).

Validated end-to-end against the live API: renamed a repo mid-session and git access continued under the new slug (old slug 404s cleanly) — exactly where the Go edge wedged. brintos-fs-go is being retired.

jdbrinton closed this as completed