fuzzyworld

fuzzyworld-tools / files / server / truenas / mirror-all.sh

mirror-all.sh

2.1 KB · history · blame

1#!/bin/sh
2# Backup mirror of every DreamHost repo, run on TrueNAS from a cron job (System → Advanced → Cron Jobs).
3#
4# mirror-all.sh /mnt/<pool>/git-mirrors
5#
6# DEST is a ZFS dataset (snapshotted by a periodic snapshot task). DEST/.ssh/id_ed25519 is a key that
7# DreamHost only lets run server/mirror-only (fetch + list), so this box can read repos but never write.
8# New repos are cloned with --mirror; existing ones get `remote update --prune`. Repos that disappear
9# from DreamHost are kept here (this is a backup) and listed in the summary. Each mirror's config
10# carries fuzzyworld.visibility, so a restore keeps the private/public marking.
11set -u
12DEST=${1:?usage: mirror-all.sh /mnt/<pool>/git-mirrors}
13HOST=${FW_MIRROR_HOST:-fuzzygamer@iad1-shared-b7-30.dreamhost.com}
14SSH="ssh -i $DEST/.ssh/id_ed25519 -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=$DEST/.ssh/known_hosts"
15export GIT_SSH_COMMAND="$SSH"
16LOG=$DEST/.logs/mirror-$(date -u +%Y%m%d).log
17mkdir -p "$DEST/.logs"
18exec 3>&2 # keep the cron job's stderr: failures are reported there too
19exec >> "$LOG" 2>&1
20echo "== $(date -u '+%F %T UTC') mirror from $HOST"
21
22names=$($SSH "$HOST" list) || { echo "FAIL: cannot list repos on $HOST"; echo "git mirror: cannot list repos on $HOST (log: $LOG)" >&3; exit 1; }
23ok=0; failed=0
24for name in $names; do
25 m="$DEST/$name.git"
26 if [ -d "$m" ]; then
27 git -C "$m" remote update --prune >/dev/null 2>&1 && r=0 || r=1
28 else
29 git clone --quiet --mirror "$HOST:git/$name.git" "$m" && r=0 || r=1
30 fi
31 if [ $r = 0 ]; then
32 v=$($SSH "$HOST" "visibility $name") && git -C "$m" config fuzzyworld.visibility "$v"
33 ok=$((ok + 1))
34 else
35 echo "FAIL: $name"; failed=$((failed + 1))
36 fi
37done
38gone=""
39for m in "$DEST"/*.git; do
40 [ -d "$m" ] || continue
41 n=$(basename "$m" .git)
42 echo "$names" | tr ' ' '\n' | grep -qxF "$n" || gone="$gone $n"
43done
44echo "mirrored $ok, failed $failed${gone:+, kept but no longer on DreamHost:$gone}"
45echo "== done $(date -u '+%F %T UTC')"
46[ $failed = 0 ] || { echo "git mirror: $failed repo(s) failed (log: $LOG)" >&3; exit 1; }