69 lines
3.4 KiB
Shell
Executable file
69 lines
3.4 KiB
Shell
Executable file
#!/bin/sh
|
|
# post_start hook of the server: brings Forgejo to what this repository declares, on every start:
|
|
# - the admin account ($FORGEJO_ADMIN_USER), password from fnox.toml (FORGEJO_ADMIN_PASSWORD);
|
|
# - its SSH keys: every line of authorized_keys (missing ones added, none removed);
|
|
# - the organisation $FORGEJO_ORG (public), which owns the repositories; the admin owns the org;
|
|
# - the repositories ($FORGEJO_REPOS) under it, with the visibility $FORGEJO_REPOS_PRIVATE
|
|
# (true|false); one still under the admin is transferred, one that does not exist yet is created
|
|
# and, when a pre-Forgejo bare repo /srv/git/<name>.git exists, filled from it (all refs);
|
|
# - robots.txt (keeps crawlers off archives, history, blame and raw files).
|
|
# Idempotent: a second run changes nothing.
|
|
set -eu
|
|
cd /hydrate
|
|
# Started as root: only root reads the host key. Decrypt the one password, then continue as `git`
|
|
# (Forgejo refuses to run as root); the key never reaches the git user.
|
|
if [ "$(id -u)" = 0 ]; then
|
|
FORGEJO_ADMIN_PASSWORD="$(FNOX_AGE_KEY="$(cat /run/secrets/age_key)" fnox get FORGEJO_ADMIN_PASSWORD)"
|
|
export FORGEJO_ADMIN_PASSWORD
|
|
exec su -p -s /bin/sh git -c /hydrate/hydrate.sh
|
|
fi
|
|
export HOME=/var/lib/gitea/git
|
|
for _ in $(seq 1 90); do curl -fsS -o /dev/null http://127.0.0.1:3000/api/healthz 2>/dev/null && break; sleep 1; done
|
|
PW="$FORGEJO_ADMIN_PASSWORD"
|
|
U="$FORGEJO_ADMIN_USER"
|
|
F="forgejo --config $GITEA_APP_INI --work-path /var/lib/gitea"
|
|
|
|
if $F admin user list --admin | awk 'NR>1 {print $2}' | grep -qx "$U"; then
|
|
$F admin user change-password --username "$U" --password "$PW" --must-change-password=false >/dev/null
|
|
echo "admin $U: password synced"
|
|
else
|
|
$F admin user create --admin --username "$U" --email "$FORGEJO_ADMIN_EMAIL" --password "$PW" --must-change-password=false >/dev/null
|
|
echo "admin $U: created"
|
|
fi
|
|
|
|
API=http://127.0.0.1:3000/api/v1
|
|
api() { curl -fsS -u "$U:$PW" -H 'Content-Type: application/json' "$@"; }
|
|
|
|
existing_keys="$(api "$API/user/keys" | tr ',' '\n' | sed -n 's/.*"key":"\([^"]*\)".*/\1/p' | awk '{print $2}')"
|
|
grep -v '^\s*\(#\|$\)' authorized_keys | while read -r type body comment; do
|
|
if printf '%s\n' "$existing_keys" | grep -qxF "$body"; then continue; fi
|
|
api -X POST "$API/user/keys" -d "{\"title\":\"${comment:-$type}\",\"key\":\"$type $body\"}" >/dev/null
|
|
echo "ssh key added: ${comment:-$type}"
|
|
done
|
|
|
|
O="$FORGEJO_ORG"
|
|
if ! api -o /dev/null "$API/orgs/$O" 2>/dev/null; then
|
|
api -X POST "$API/orgs" -d "{\"username\":\"$O\",\"visibility\":\"public\"}" >/dev/null
|
|
echo "organisation $O: created"
|
|
fi
|
|
|
|
mkdir -p /var/lib/gitea/custom/public
|
|
cp /hydrate/robots.txt /var/lib/gitea/custom/public/robots.txt
|
|
|
|
for r in $FORGEJO_REPOS; do
|
|
if ! api -o /dev/null "$API/repos/$O/$r" 2>/dev/null; then
|
|
if api -o /dev/null "$API/repos/$U/$r" 2>/dev/null; then
|
|
api -X POST "$API/repos/$U/$r/transfer" -d "{\"new_owner\":\"$O\"}" >/dev/null
|
|
echo "repository $r: transferred to $O"
|
|
else
|
|
api -X POST "$API/orgs/$O/repos" -d "{\"name\":\"$r\",\"private\":$FORGEJO_REPOS_PRIVATE,\"default_branch\":\"main\"}" >/dev/null
|
|
echo "repository $O/$r: created"
|
|
if [ -d "/srv/git/$r.git" ]; then
|
|
git -C "/srv/git/$r.git" push -q --mirror "http://$U:$PW@127.0.0.1:3000/$O/$r.git"
|
|
echo "repository $O/$r: filled from /srv/git/$r.git"
|
|
fi
|
|
fi
|
|
fi
|
|
api -X PATCH "$API/repos/$O/$r" -d "{\"private\":$FORGEJO_REPOS_PRIVATE}" >/dev/null
|
|
done
|
|
echo "hydrated"
|