stage-28 fix: deploy.sh pre-trusts the Gitea SSH host key (first-clone)

A fresh prod box has never SSH'd to gitea.neuronetz.ai before, so the
first 'git clone' failed with 'Host key verification failed'. The
script now parses the git remote URL to extract host+port, and on the
prod box does an ssh-keyscan into ~/.ssh/known_hosts before the clone
when the entry is missing. TOFU — if you want to verify the fingerprint
out-of-band, pre-populate known_hosts manually and the script will see
the entry and skip the scan.

Also: if the clone still fails after the host key is trusted (likely a
missing SSH key on Gitea side), the script now prints a clear hint
pointing at where to register it. Supports both ssh://user@host:port/
and user@host: URL forms.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
m17hr1l
2026-05-25 15:32:44 +02:00
parent 61b7b8ef20
commit 2c2ead6149

View File

@@ -53,6 +53,17 @@ fi
GIT_URL=$(git config --get "remote.${GIT_REMOTE}.url") \
|| fail "no remote '${GIT_REMOTE}' configured locally"
# Parse the git URL to pull out the SSH host + port so the prod box can
# pre-trust the Gitea host key before its first clone. Supports both
# ssh://user@host:port/path and user@host:path
GIT_HOST=""; GIT_PORT="22"
if [[ "$GIT_URL" =~ ^ssh://[^@]+@([^:/]+)(:([0-9]+))?/ ]]; then
GIT_HOST="${BASH_REMATCH[1]}"
[[ -n "${BASH_REMATCH[3]:-}" ]] && GIT_PORT="${BASH_REMATCH[3]}"
elif [[ "$GIT_URL" =~ ^[^@]+@([^:]+): ]]; then
GIT_HOST="${BASH_REMATCH[1]}"
fi
# ── 1. local push ───────────────────────────────────────────────────────
say "pushing ${B}${BRANCH}${Z} to ${B}${GIT_REMOTE}${Z}"
git push "${GIT_REMOTE}" "${BRANCH}" || fail "git push failed — fix and retry"
@@ -72,15 +83,41 @@ set -euo pipefail
HOST_PATH="${REMOTE_PATH}"
BRANCH="${BRANCH}"
GIT_URL="${GIT_URL}"
GIT_HOST="${GIT_HOST}"
GIT_PORT="${GIT_PORT}"
COMPOSE_PROFILES="${COMPOSE_PROFILES}"
prn() { printf ' · %s\n' "\$*"; }
# 2a. ensure dir + working tree
# 2a. pre-trust the Gitea SSH host key so the first clone doesn't fail with
# 'Host key verification failed'. This is TOFU — we accept whatever the
# server currently presents. If you want to verify the fingerprint
# manually, do so once and place it in ~/.ssh/known_hosts yourself.
if [[ -n "\$GIT_HOST" ]]; then
mkdir -p ~/.ssh && chmod 700 ~/.ssh
KH_ENTRY="[\$GIT_HOST]:\$GIT_PORT"
if ! ssh-keygen -F "\$KH_ENTRY" -f ~/.ssh/known_hosts >/dev/null 2>&1; then
prn "adding \$KH_ENTRY to ~/.ssh/known_hosts (first time on this prod box)"
ssh-keyscan -T 5 -p "\$GIT_PORT" "\$GIT_HOST" 2>/dev/null >> ~/.ssh/known_hosts \
|| { echo "[deploy] could not reach \$GIT_HOST:\$GIT_PORT from this box" >&2; exit 1; }
chmod 600 ~/.ssh/known_hosts
fi
fi
# 2b. ensure dir + working tree
if [[ ! -d "\$HOST_PATH/.git" ]]; then
prn "no working tree at \$HOST_PATH — cloning"
prn "no working tree at \$HOST_PATH — cloning \$GIT_URL"
mkdir -p "\$(dirname "\$HOST_PATH")"
git clone "\$GIT_URL" "\$HOST_PATH"
if ! git clone "\$GIT_URL" "\$HOST_PATH"; then
cat >&2 <<HINT
[deploy] git clone failed. Two likely causes:
• This prod box has no SSH key registered in Gitea for this user.
Run on prod: cat ~/.ssh/id_*.pub (or ssh-keygen -t ed25519 if none)
Then in Gitea: Settings → SSH Keys → add it.
• The repo URL is wrong / private and you're not a collaborator.
HINT
exit 1
fi
fi
cd "\$HOST_PATH"