fix: fix: stop baking credentials into git remote URLs — use clean URLs + existing credential helper everywhere (#604)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d076528193
commit
5c4ea7373a
10 changed files with 336 additions and 72 deletions
|
|
@ -42,42 +42,20 @@ init_state_dir() {
|
|||
log "Initialized state directory"
|
||||
}
|
||||
|
||||
# Configure git credential helper for password-based HTTP auth.
|
||||
# Forgejo 11.x rejects API tokens for git push (#361); password auth works.
|
||||
# This ensures all git operations (clone, fetch, push) from worktrees use
|
||||
# password auth without needing tokens embedded in remote URLs.
|
||||
configure_git_creds() {
|
||||
# Source shared git credential helper library (#604).
|
||||
# shellcheck source=lib/git-creds.sh
|
||||
source "${DISINTO_BAKED}/lib/git-creds.sh"
|
||||
|
||||
# Wrapper that calls the shared configure_git_creds with agent-specific paths,
|
||||
# then repairs any legacy baked-credential URLs in existing clones.
|
||||
_setup_git_creds() {
|
||||
configure_git_creds "/home/agent" "gosu agent"
|
||||
if [ -n "${FORGE_PASS:-}" ] && [ -n "${FORGE_URL:-}" ]; then
|
||||
_forge_host=$(printf '%s' "$FORGE_URL" | sed 's|https\?://||; s|/.*||')
|
||||
_forge_proto=$(printf '%s' "$FORGE_URL" | sed 's|://.*||')
|
||||
# Determine the bot username from FORGE_TOKEN identity (or default to dev-bot)
|
||||
_bot_user=$(curl -sf -H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_URL}/api/v1/user" 2>/dev/null | jq -r '.login // empty') || _bot_user=""
|
||||
_bot_user="${_bot_user:-dev-bot}"
|
||||
|
||||
# Write a static credential helper script (git credential protocol)
|
||||
cat > /home/agent/.git-credentials-helper <<CREDEOF
|
||||
#!/bin/sh
|
||||
# Auto-generated git credential helper for Forgejo password auth (#361)
|
||||
# Only respond to "get" action; ignore "store" and "erase".
|
||||
[ "\$1" = "get" ] || exit 0
|
||||
# Read and discard stdin (git sends protocol/host info)
|
||||
cat >/dev/null
|
||||
echo "protocol=${_forge_proto}"
|
||||
echo "host=${_forge_host}"
|
||||
echo "username=${_bot_user}"
|
||||
echo "password=${FORGE_PASS}"
|
||||
CREDEOF
|
||||
chmod 755 /home/agent/.git-credentials-helper
|
||||
chown agent:agent /home/agent/.git-credentials-helper
|
||||
|
||||
gosu agent bash -c "git config --global credential.helper '/home/agent/.git-credentials-helper'"
|
||||
log "Git credential helper configured for ${_bot_user}@${_forge_host} (password auth)"
|
||||
log "Git credential helper configured (password auth)"
|
||||
fi
|
||||
|
||||
# Set safe.directory to work around dubious ownership after container restart
|
||||
# (https://github.com/disinto-admin/disinto/issues/517)
|
||||
gosu agent bash -c "git config --global --add safe.directory '*'"
|
||||
# Repair legacy clones with baked-in stale credentials (#604).
|
||||
_GIT_CREDS_LOG_FN=log repair_baked_cred_urls /home/agent/repos
|
||||
}
|
||||
|
||||
# Configure tea CLI login for forge operations (runs as agent user).
|
||||
|
|
@ -272,7 +250,7 @@ pull_factory_repo() {
|
|||
}
|
||||
|
||||
# Configure git and tea once at startup (as root, then drop to agent)
|
||||
configure_git_creds
|
||||
_setup_git_creds
|
||||
configure_tea_login
|
||||
|
||||
# Bootstrap ops repos from forgejo into container volumes (#586)
|
||||
|
|
|
|||
|
|
@ -45,17 +45,48 @@ if [ -d /opt/disinto ] && [ ! -d /opt/disinto/.git ] && [ -n "$(ls -A /opt/disin
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Shallow clone at the pinned version (inject token to support auth-required Forgejo)
|
||||
# Set HOME early so credential helper and git config land in the right place.
|
||||
export HOME=/home/agent
|
||||
mkdir -p "$HOME"
|
||||
|
||||
# Configure git credential helper before cloning (#604).
|
||||
# /opt/disinto does not exist yet so we cannot source lib/git-creds.sh;
|
||||
# inline a minimal credential-helper setup here.
|
||||
if [ -n "${FORGE_PASS:-}" ] && [ -n "${FORGE_URL:-}" ]; then
|
||||
_forge_host=$(printf '%s' "$FORGE_URL" | sed 's|https\?://||; s|/.*||')
|
||||
_forge_proto=$(printf '%s' "$FORGE_URL" | sed 's|://.*||')
|
||||
_bot_user=""
|
||||
if [ -n "${FORGE_TOKEN:-}" ]; then
|
||||
_bot_user=$(curl -sf -H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_URL}/api/v1/user" 2>/dev/null | jq -r '.login // empty') || _bot_user=""
|
||||
fi
|
||||
_bot_user="${_bot_user:-dev-bot}"
|
||||
|
||||
cat > "${HOME}/.git-credentials-helper" <<CREDEOF
|
||||
#!/bin/sh
|
||||
[ "\$1" = "get" ] || exit 0
|
||||
cat >/dev/null
|
||||
echo "protocol=${_forge_proto}"
|
||||
echo "host=${_forge_host}"
|
||||
echo "username=${_bot_user}"
|
||||
echo "password=${FORGE_PASS}"
|
||||
CREDEOF
|
||||
chmod 755 "${HOME}/.git-credentials-helper"
|
||||
git config --global credential.helper "${HOME}/.git-credentials-helper"
|
||||
git config --global --add safe.directory '*'
|
||||
fi
|
||||
|
||||
# Shallow clone at the pinned version — use clean URL, credential helper
|
||||
# supplies auth (#604).
|
||||
if [ ! -d /opt/disinto/.git ]; then
|
||||
_auth_url=$(printf '%s' "$FORGE_URL" | sed "s|://|://token:${FORGE_TOKEN}@|")
|
||||
echo "edge: cloning ${FORGE_URL}/${FORGE_REPO} (branch ${DISINTO_VERSION:-main})..." >&2
|
||||
if ! git clone --depth 1 --branch "${DISINTO_VERSION:-main}" "${_auth_url}/${FORGE_REPO}.git" /opt/disinto; then
|
||||
if ! git clone --depth 1 --branch "${DISINTO_VERSION:-main}" "${FORGE_URL}/${FORGE_REPO}.git" /opt/disinto; then
|
||||
echo >&2
|
||||
echo "FATAL: failed to clone ${FORGE_URL}/${FORGE_REPO}.git (branch ${DISINTO_VERSION:-main})" >&2
|
||||
echo "Likely causes:" >&2
|
||||
echo " - Forgejo at ${FORGE_URL} is unreachable from the edge container" >&2
|
||||
echo " - Repository '${FORGE_REPO}' does not exist on this forge" >&2
|
||||
echo " - FORGE_TOKEN is invalid or has no read access to '${FORGE_REPO}'" >&2
|
||||
echo " - FORGE_TOKEN/FORGE_PASS is invalid or has no read access to '${FORGE_REPO}'" >&2
|
||||
echo " - Branch '${DISINTO_VERSION:-main}' does not exist in '${FORGE_REPO}'" >&2
|
||||
echo "Workaround: bind-mount a local git checkout into /opt/disinto." >&2
|
||||
echo "Sleeping 60s before exit to throttle the restart loop..." >&2
|
||||
|
|
@ -64,11 +95,13 @@ if [ ! -d /opt/disinto/.git ]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
# Set HOME so that claude OAuth credentials and session.lock are found at the
|
||||
# same in-container path as in disinto-agents (/home/agent/.claude), which makes
|
||||
# flock cross-serialize across containers on the same host inode.
|
||||
export HOME=/home/agent
|
||||
mkdir -p "$HOME"
|
||||
# Repair any legacy baked-credential URLs in /opt/disinto (#604).
|
||||
# Now that /opt/disinto exists, source the shared lib.
|
||||
if [ -f /opt/disinto/lib/git-creds.sh ]; then
|
||||
# shellcheck source=/opt/disinto/lib/git-creds.sh
|
||||
source /opt/disinto/lib/git-creds.sh
|
||||
_GIT_CREDS_LOG_FN="echo" repair_baked_cred_urls /opt/disinto
|
||||
fi
|
||||
|
||||
# Ensure log directory exists
|
||||
mkdir -p /opt/disinto-logs
|
||||
|
|
|
|||
|
|
@ -84,6 +84,15 @@ export DISINTO_CONTAINER=1
|
|||
export HOME="${HOME:-/home/agent}"
|
||||
export USER="${USER:-agent}"
|
||||
|
||||
# Configure git credential helper so reproduce/triage agents can clone/push
|
||||
# without needing tokens embedded in remote URLs (#604).
|
||||
if [ -f "${DISINTO_DIR}/lib/git-creds.sh" ]; then
|
||||
# shellcheck source=lib/git-creds.sh
|
||||
source "${DISINTO_DIR}/lib/git-creds.sh"
|
||||
# shellcheck disable=SC2119 # no args intended — uses defaults
|
||||
configure_git_creds
|
||||
fi
|
||||
|
||||
FORGE_API="${FORGE_URL}/api/v1/repos/${FORGE_REPO}"
|
||||
|
||||
# Load project name from TOML
|
||||
|
|
|
|||
|
|
@ -23,6 +23,15 @@ log() {
|
|||
printf '[%s] runner: %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$*"
|
||||
}
|
||||
|
||||
# Configure git credential helper so formulas can clone/push without
|
||||
# needing tokens embedded in remote URLs (#604).
|
||||
if [ -f "${FACTORY_ROOT}/lib/git-creds.sh" ]; then
|
||||
# shellcheck source=lib/git-creds.sh
|
||||
source "${FACTORY_ROOT}/lib/git-creds.sh"
|
||||
# shellcheck disable=SC2119 # no args intended — uses defaults
|
||||
configure_git_creds
|
||||
fi
|
||||
|
||||
# ── Argument parsing ─────────────────────────────────────────────────────
|
||||
|
||||
action_id="${1:-}"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue