Cells: Validate SSH routing for Git pull and push on staging

Why

Epic &13532 delivers Topology Service-based SSH routing for Git pull and push across Cells. The roadmap covers implementation but has no explicit end-to-end validation step. This issue tracks locally-runnable (client-side) verification against staging before production rollout.

What

Verify Git-over-SSH pull, push, and LFS operations are correctly routed to the right cell via the Topology Service, using tests that can be run from a local terminal against staging.gitlab.com.

Setup

Assumes an SSH key is already configured for staging.gitlab.com.

export GL_HOST=staging.gitlab.com
export GL_REPO=your-group/your-project   # repo on a known cell
export GIT_TRACE=1 GIT_TRACE_PACKET=1    # verbose Git protocol tracing

Test scenarios

1. Clone over SSH (upload-pack routing)

rm -rf /tmp/clone-test && \
  git clone "git@${GL_HOST}:${GL_REPO}.git" /tmp/clone-test 2>&1 | tee /tmp/clone.log
test -d /tmp/clone-test/.git && echo "CLONE OK" || echo "CLONE FAILED"

2. Pull / fetch over SSH

cd /tmp/clone-test
git fetch --all --prune -v 2>&1 | tee /tmp/fetch.log
git pull -v 2>&1 | tee /tmp/pull.log
echo "Exit: $?"

3. Push over SSH (receive-pack routing)

cd /tmp/clone-test
BRANCH="cells-ssh-test-$(date +%s)"
git checkout -b "$BRANCH"
echo "ssh routing test $(date -u)" >> ssh-routing-test.txt
git add ssh-routing-test.txt
git commit -m "test: cells ssh routing push validation"
git push -u origin "$BRANCH" 2>&1 | tee /tmp/push.log
echo "Push exit: $?"

# Cleanup after verification
# git push origin --delete "$BRANCH"

4. SSH auth via public key → cell routing (SSHFingerprint claim)

# Confirm the server authenticates you and welcomes the right user
ssh -T -v "git@${GL_HOST}" 2>&1 \
  | grep -Ei "Server accepts key|Offering public key|Welcome to GitLab"

5. Non-Git SSH commands (user-scoped endpoints)

# whoami-style check: verifies user-scoped routing without a repo context
ssh -T "git@${GL_HOST}" 2>&1 | head

6. Repo-scoped endpoint (Git LFS authenticate)

# git-lfs-authenticate exercises repo-scoped SSH routing
ssh "git@${GL_HOST}" "git-lfs-authenticate ${GL_REPO}.git download" 2>&1 | tee /tmp/lfs.log

7. Git operations on LFS repositories

# Requires git-lfs installed locally: git lfs version
export GL_LFS_REPO=your-group/your-lfs-project   # a repo with LFS tracking

# --- Clone an LFS repo over SSH and confirm objects download ---
rm -rf /tmp/lfs-test && \
  git clone "git@${GL_HOST}:${GL_LFS_REPO}.git" /tmp/lfs-test 2>&1 | tee /tmp/lfs-clone.log
cd /tmp/lfs-test
git lfs install --local
git lfs pull 2>&1 | tee /tmp/lfs-pull.log
# Confirm pointers resolved to real objects (not the small pointer text files)
git lfs ls-files
echo "LFS clone/pull exit: $?"

# --- Push a new LFS-tracked file over SSH ---
BRANCH="cells-lfs-test-$(date +%s)"
git checkout -b "$BRANCH"
git lfs track "*.bin"
head -c 5M /dev/urandom > sample.bin
git add .gitattributes sample.bin
git commit -m "test: cells lfs push validation"
git push -u origin "$BRANCH" 2>&1 | tee /tmp/lfs-push.log
echo "LFS push exit: $?"

# Verify the object was uploaded via LFS, not stored in Git
git lfs ls-files | grep sample.bin && echo "TRACKED AS LFS OK"

# Cleanup after verification
# git push origin --delete "$BRANCH"

8. Target cell unreachable / misconfigured

# Confirm a clean, user-facing error (no hang) when a repo maps to a bad cell
timeout 30 git clone "git@${GL_HOST}:broken-group/unreachable-repo.git" /tmp/unreachable 2>&1 \
  | tee /tmp/unreachable.log
echo "Exit: $? (expect non-zero with a clear message, no 30s timeout)"