summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xalma-weekly.sh40
-rwxr-xr-xarchmirror-iso.sh2
-rwxr-xr-xarchmirror-repos.sh6
-rwxr-xr-xarchmirror-sync.sh4
-rwxr-xr-xarchupdate.sh11
-rwxr-xr-xcheck-archweb.sh20
-rwxr-xr-xhistory.sh32
-rwxr-xr-xlastsyncarch.sh25
-rwxr-xr-xmirror-alma.sh9
-rwxr-xr-xmirror-arch-iso.sh8
-rwxr-xr-xmirror-arch-lastsync.sh7
-rwxr-xr-xmirror-arch-repos.sh8
-rwxr-xr-xmirror-archlinux.sh9
-rwxr-xr-xmirror-backup.sh8
-rwxr-xr-xmirror-debian.sh7
-rw-r--r--mirror-delay-check.sh23
-rwxr-xr-xmirror-gentoo.sh9
-rwxr-xr-xmirror-hbsd.sh9
-rw-r--r--mirror-portage.sh28
-rwxr-xr-xmirror-rocky.sh9
-rwxr-xr-xmirror-slackware.sh9
-rwxr-xr-xmirror-void.sh9
-rwxr-xr-xmirror-watchdog.sh29
-rwxr-xr-xmirror-weekly.sh53
-rwxr-xr-xmonitor.sh8
-rwxr-xr-xportage-timestamp.sh24
-rwxr-xr-xrebootvalidate.sh51
-rwxr-xr-xsign-mirror.sh38
-rwxr-xr-xstatus.sh103
-rwxr-xr-xthebigone.sh33
30 files changed, 623 insertions, 8 deletions
diff --git a/alma-weekly.sh b/alma-weekly.sh
new file mode 100755
index 0000000..a875d13
--- /dev/null
+++ b/alma-weekly.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# alma-weekly.sh
+# Summarize AlmaLinux client demographics across the past 7 days
+
+LOGDIR="/var/log/mirrors"
+OUTFILE="$LOGDIR/alma-weekly-$(date +%F).log"
+
+echo "=== AlmaLinux Weekly Summary ($(date)) ===" > "$OUTFILE"
+
+# Gather the last 7 daily logs
+FILES=$(ls -1t $LOGDIR/alma-summary-*.log 2>/dev/null | head -n 7)
+
+if [ -z "$FILES" ]; then
+ echo "No alma-summary logs found in $LOGDIR" >> "$OUTFILE"
+ exit 1
+fi
+
+# Roll up requests + unique clients per release
+awk '
+/requests/ {
+ reqs[$2]+=$1
+ clients[$2]+=$4
+}
+END {
+ for (r in reqs) {
+ printf "%-6s %10d requests %6d unique clients (7-day total)\n", r, reqs[r], clients[r]
+ }
+}' $FILES | sort -k2 -nr >> "$OUTFILE"
+
+echo "" >> "$OUTFILE"
+echo "=== Top 10 Clients by Requests (7-day total) ===" >> "$OUTFILE"
+
+# Top talkers (IP + release) across all 7 days
+awk '
+$2 ~ /^[0-9]/ {
+ count[$2" "$3]+=$1
+}
+END {
+ for (k in count) print count[k], k
+}' $FILES | sort -nr | head -n 10 >> "$OUTFILE"
diff --git a/archmirror-iso.sh b/archmirror-iso.sh
index bd0c3e5..b49e262 100755
--- a/archmirror-iso.sh
+++ b/archmirror-iso.sh
@@ -2,7 +2,7 @@
# /usr/local/sbin/archmirror-iso.sh
set -euo pipefail
UPSTREAM="rsync://mirror.csclub.uwaterloo.ca/archlinux/iso/"
-DST="/brimstone3/mirror-stage/arch-repos/iso"
+DST="/brimstone2a/mirror/archlinux/iso/"
LOG="/var/log/mirrors/arch-iso.log"
mkdir -p "$DST"
diff --git a/archmirror-repos.sh b/archmirror-repos.sh
index f15504a..395e28a 100755
--- a/archmirror-repos.sh
+++ b/archmirror-repos.sh
@@ -2,11 +2,11 @@
# /usr/local/sbin/archmirror-repos.sh
set -euo pipefail
UPSTREAM="rsync://mirror.csclub.uwaterloo.ca/archlinux/"
-STAGE="/brimstone3/mirror-stage/arch-repos"
-LIVE="/brimstone1/mirror/archlinux"
+STAGE="/brimstone3a/mirror-stage/arch-repos"
+LIVE="/brimstone2a/mirror/archlinux/"
LOG="/var/log/mirrors/arch-repos.log"
-mkdir -p "$STAGE" "$LIVE"
+#mkdir -p "$STAGE" "$LIVE"
rsync -rtlH --safe-links --delete-delay --delay-updates \
--exclude iso/ --exclude other/ \
diff --git a/archmirror-sync.sh b/archmirror-sync.sh
index 35b02da..fca6a02 100755
--- a/archmirror-sync.sh
+++ b/archmirror-sync.sh
@@ -8,8 +8,8 @@ set -euo pipefail
UPSTREAM="${UPSTREAM:-rsync://mirror.csclub.uwaterloo.ca/archlinux/}"
# Local paths
-LIVE="${LIVE:-/brimstone1/mirror/archlinux}" # served path (symlink target)
-STAGE="${STAGE:-/brimstone3/mirror-stage/archlinux}" # staging path
+LIVE="${LIVE:-/brimstone2a/mirror/archlinux}" # served path (symlink target)
+STAGE="${STAGE:-/brimstone3a/mirror-stage/archlinux}" # staging path
LOGDIR="${LOGDIR:-/var/log/mirrors}"
LOCK="${LOCK:-/var/log/archmirror.lock}"
diff --git a/archupdate.sh b/archupdate.sh
new file mode 100755
index 0000000..8cf3d92
--- /dev/null
+++ b/archupdate.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+URL="https://stygian.failzero.net/mirror/archlinux/lastupdate"
+LOG="/var/log/mirror_health.log"
+
+for ipopt in -4 -6; do
+ if curl $ipopt -fsS "$URL" >/dev/null; then
+ echo "$(date) [$ipopt] OK" >> $LOG
+ else
+ echo "$(date) [$ipopt] FAIL" >> $LOG
+ fi
+done
diff --git a/check-archweb.sh b/check-archweb.sh
new file mode 100755
index 0000000..c46adb6
--- /dev/null
+++ b/check-archweb.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+#
+# check-archweb.sh
+# Quick filter for Archweb IPv6 probes against /lastupdate
+#
+
+LOG=/var/log/nginx/stygian_access.log
+
+if [[ ! -f "$LOG" ]]; then
+ echo "Log file not found: $LOG"
+ exit 1
+fi
+
+echo "=== IPv6 Archweb checks for /lastupdate ==="
+sudo awk '
+ $1 ~ /\[::/ && $7 ~ /lastupdate/ {
+ printf "%-40s %-30s %-5s %-40s %s\n", $1, $4, $6, $7, $9
+ }
+' "$LOG" | tail -20
+
diff --git a/history.sh b/history.sh
new file mode 100755
index 0000000..63b2ad4
--- /dev/null
+++ b/history.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# alma-stats.sh
+# Summarize AlmaLinux clients per release (daily demographic snapshot)
+
+LOGFILE="/var/log/nginx/stygian_access.log"
+OUTFILE="/var/log/mirrors/alma-summary-$(date +%F).log"
+
+echo "=== AlmaLinux Mirror Client Summary ($(date)) ===" > "$OUTFILE"
+
+awk '$0 ~ /libdnf/ && $7 ~ /alma/ {
+ ip=$1
+ split($7,a,"/")
+ ver=a[3]
+ key=ip" "ver
+ count[key]++
+}
+END {
+ for (k in count) print count[k], k
+}' "$LOGFILE" | sort -nr >> "$OUTFILE"
+
+# Add a little breakdown by release (ignoring IPs)
+echo "" >> "$OUTFILE"
+echo "=== Totals by Release ===" >> "$OUTFILE"
+
+awk '$0 ~ /libdnf/ && $7 ~ /alma/ {
+ split($7,a,"/")
+ ver=a[3]
+ count[ver]++
+}
+END {
+ for (v in count) print count[v], v
+}' "$LOGFILE" | sort -nr >> "$OUTFILE"
diff --git a/lastsyncarch.sh b/lastsyncarch.sh
new file mode 100755
index 0000000..499fb95
--- /dev/null
+++ b/lastsyncarch.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# check-arch-lastupdate.sh
+# Compare local Arch mirror's lastupdate with upstream
+
+LOCAL_URL="https://stygian.failzero.net/mirror/archlinux/lastupdate"
+UPSTREAM_URL="https:///mirror.csclub.uwaterloo.ca/archlinux/lastupdate"
+
+# Grab values
+local_val=$(curl -s "$LOCAL_URL")
+upstream_val=$(curl -s "$UPSTREAM_URL")
+
+# Convert to human-readable
+local_hr=$(date -d @"$local_val" 2>/dev/null)
+upstream_hr=$(date -d @"$upstream_val" 2>/dev/null)
+
+echo "=== Arch Lastupdate Check ==="
+echo "Local: $local_val ($local_hr)"
+echo "Upstream: $upstream_val ($upstream_hr)"
+
+# Compare
+if [[ "$local_val" == "$upstream_val" ]]; then
+ echo "[OK] Mirror is up to date."
+else
+ echo "[WARN] Mirror is out of sync!"
+fi
diff --git a/mirror-alma.sh b/mirror-alma.sh
new file mode 100755
index 0000000..039d941
--- /dev/null
+++ b/mirror-alma.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# /usr/local/sbin/mirror-gentoo.sh
+
+LOG="/var/log/mirrors/alma-mirror-sync.log"
+DEST="/mnt/brimstone/mirror/alma"
+
+EC=$?
+echo "EXITCODE:$EC" >>"$LOG"
+exit $EC
diff --git a/mirror-arch-iso.sh b/mirror-arch-iso.sh
new file mode 100755
index 0000000..33564ec
--- /dev/null
+++ b/mirror-arch-iso.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+LOG="/var/log/mirrors/arch-mirror-iso.log"
+LOCK="/var/lock/arch-iso.lock"
+
+# Longer jitter is fine, this runs once nightly
+sleep $((RANDOM % 600))
+exec flock -n "$LOCK" \
+ /usr/local/sbin/archmirror-iso.sh >> "$LOG" 2>&1
diff --git a/mirror-arch-lastsync.sh b/mirror-arch-lastsync.sh
new file mode 100755
index 0000000..aa5c55e
--- /dev/null
+++ b/mirror-arch-lastsync.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+LOG="/var/log/mirrors/arch-lastsync.log"
+LOCK="/var/lock/arch-lastsync.lock"
+
+# Keep it lightweight, no jitter (it just updates lastsync)
+exec flock -n "$LOCK" \
+ /usr/local/sbin/arch-lastsync.sh >> "$LOG" 2>&1
diff --git a/mirror-arch-repos.sh b/mirror-arch-repos.sh
new file mode 100755
index 0000000..f52d06b
--- /dev/null
+++ b/mirror-arch-repos.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+LOG="/var/log/mirrors/arch-mirror-repos.log"
+LOCK="/var/lock/arch-repos.lock"
+
+# Short jitter, since this runs every 5 min
+sleep $((RANDOM % 60))
+exec flock -n "$LOCK" \
+ /usr/local/sbin/archmirror-repos.sh >> "$LOG" 2>&1
diff --git a/mirror-archlinux.sh b/mirror-archlinux.sh
new file mode 100755
index 0000000..c892680
--- /dev/null
+++ b/mirror-archlinux.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# /usr/local/sbin/mirror-gentoo.sh
+
+LOG="/var/log/mirrors/archlinux-mirror-sync.log"
+DEST="/mnt/brimstone/mirror/archlinux"
+
+EC=$?
+echo "EXITCODE:$EC" >>"$LOG"
+exit $EC
diff --git a/mirror-backup.sh b/mirror-backup.sh
index c46ed2b..ee9d265 100755
--- a/mirror-backup.sh
+++ b/mirror-backup.sh
@@ -17,8 +17,12 @@ tar -czf "$ARCHIVE" \
/etc/rsyncd.conf \
/etc/rsyncd.motd \
/etc/mirror-gpg \
- /usr/local/bin/mirror-verify.sh \
- /usr/local/bin/mirror-backup.sh \
+ /usr/local/sbin/*.sh \
+ /mnt/brimstone/mirror/index.html \
+ /etc/nginx/sites-available/stygian.conf \
+ /etc/nginx/nginx.conf \
+ /usr/local/sbin/mirror-verify.sh \
+ /usr/local/sbin/mirror-backup.sh \
/etc/systemd/system/rsyncd.service \
/etc/systemd/system/mirror-verify.* \
/etc/cron.d/*mirror* 2>/dev/null || true
diff --git a/mirror-debian.sh b/mirror-debian.sh
new file mode 100755
index 0000000..d4a81e8
--- /dev/null
+++ b/mirror-debian.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+LOG="/var/log/ftpsync/cron.log"
+LOCK="/var/lock/debian.lock"
+
+sleep $((RANDOM % 600))
+exec flock -n "$LOCK" \
+ /root/archvsync/bin/ftpsync sync:all > /var/log/mirrors/therealdebian.log
diff --git a/mirror-delay-check.sh b/mirror-delay-check.sh
new file mode 100644
index 0000000..7d9b565
--- /dev/null
+++ b/mirror-delay-check.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+# Upstream (Arch Geo CDN points to a Tier-1 close to you)
+UPSTREAM="https://geo.mirror.pkgbuild.com/lastsync"
+
+# Your mirror (the VIP that Arch probes)
+MIRROR="https://stygian.failzero.net/mirror/archlinux/lastsync"
+
+# Log file
+LOGFILE="/var/log/mirrors/delay.log"
+mkdir -p "$(dirname "$LOGFILE")"
+
+# Fetch timestamps (seconds since epoch)
+u=$(curl -fsS "$UPSTREAM" || echo 0)
+m=$(curl -fsS "$MIRROR" || echo 0)
+
+if [[ "$u" =~ ^[0-9]+$ && "$m" =~ ^[0-9]+$ ]]; then
+ delay_min=$(( (u - m) / 60 ))
+ echo "$(date -Is) upstream=$u mirror=$m delay=${delay_min}m" >> "$LOGFILE"
+else
+ echo "$(date -Is) error fetching lastsync" >> "$LOGFILE"
+fi
diff --git a/mirror-gentoo.sh b/mirror-gentoo.sh
new file mode 100755
index 0000000..3e1bf48
--- /dev/null
+++ b/mirror-gentoo.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# /usr/local/sbin/mirror-gentoo.sh
+
+LOG="/var/log/mirrors/gentoo-mirror-sync.log"
+DEST="/mnt/brimstone/mirror/gentoo"
+
+EC=$?
+echo "EXITCODE:$EC" >>"$LOG"
+exit $EC
diff --git a/mirror-hbsd.sh b/mirror-hbsd.sh
new file mode 100755
index 0000000..f983790
--- /dev/null
+++ b/mirror-hbsd.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# /usr/local/sbin/mirror-gentoo.sh
+
+LOG="/var/log/mirrors/hbsd-mirror-sync.log"
+DEST="/mnt/brimstone/mirror/hardenedbsd"
+
+EC=$?
+echo "EXITCODE:$EC" >>"$LOG"
+exit $EC
diff --git a/mirror-portage.sh b/mirror-portage.sh
new file mode 100644
index 0000000..57a6190
--- /dev/null
+++ b/mirror-portage.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+# sync-portage.sh – wrapper for Gentoo Portage rsync mirror
+#
+
+RSYNC_OPTS="-avH --partial --delete --delete-delay \
+ --safe-links --hard-links --numeric-ids \
+ --timeout=300 --contimeout=60 --info=progress2"
+
+TARGET="/brimstone1a/mirror/gentoo/portage"
+SOURCE="rsync://masterportage.gentoo.org"
+
+LOGFILE="/var/log/portage-sync.log"
+STATUSFILE="/var/www/mirror-status/portage.lastsync"
+
+# Run rsync and log output
+rsync $RSYNC_OPTS "$SOURCE" "$TARGET" >> "$LOGFILE" 2>&1
+RC=$?
+
+# If rsync succeeded, update freshness marker
+if [ $RC -eq 0 ]; then
+ date -u +%s > "$STATUSFILE"
+ echo "$(date -u) : sync OK" >> "$LOGFILE"
+else
+ echo "$(date -u) : sync FAILED with code $RC" >> "$LOGFILE"
+fi
+
+exit $RC
diff --git a/mirror-rocky.sh b/mirror-rocky.sh
new file mode 100755
index 0000000..2157465
--- /dev/null
+++ b/mirror-rocky.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# /usr/local/sbin/mirror-gentoo.sh
+
+LOG="/var/log/mirrors/rocky-mirror-sync.log"
+DEST="/mnt/brimstone/mirror/rocky"
+
+EC=$?
+echo "EXITCODE:$EC" >>"$LOG"
+exit $EC
diff --git a/mirror-slackware.sh b/mirror-slackware.sh
new file mode 100755
index 0000000..8e31099
--- /dev/null
+++ b/mirror-slackware.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# /usr/local/sbin/mirror-gentoo.sh
+
+LOG="/var/log/mirrors/slackware-mirror-sync.log"
+DEST="/mnt/brimstone/mirror/slackware"
+
+EC=$?
+echo "EXITCODE:$EC" >>"$LOG"
+exit $EC
diff --git a/mirror-void.sh b/mirror-void.sh
new file mode 100755
index 0000000..6a41a27
--- /dev/null
+++ b/mirror-void.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# /usr/local/sbin/mirror-gentoo.sh
+
+LOG="/var/log/mirrors/void-mirror-sync.log"
+DEST="/mnt/brimstone/mirror/void"
+
+EC=$?
+echo "EXITCODE:$EC" >>"$LOG"
+exit $EC
diff --git a/mirror-watchdog.sh b/mirror-watchdog.sh
new file mode 100755
index 0000000..b0f4c43
--- /dev/null
+++ b/mirror-watchdog.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# Mirror watchdog: scans /var/lock for stale rsync locks
+# Logs results to /var/log/mirror-watchdog.log
+#
+
+LOGFILE="/var/log/mirror-watchdog.log"
+LOCKDIR="/var/lock"
+MAXAGE=10800 # 3 hours in seconds
+
+echo "[$(date '+%F %T')] Running mirror watchdog..." >> "$LOGFILE"
+
+for lock in gentoo hbsd void slackware rocky debian arch-repos arch-iso; do
+ LOCKFILE="$LOCKDIR/${lock}.lock"
+
+ if [ -f "$LOCKFILE" ]; then
+ AGE=$(( $(date +%s) - $(stat -c %Y "$LOCKFILE") ))
+ if [ "$AGE" -gt "$MAXAGE" ]; then
+ echo "[$(date '+%F %T')] WARNING: $LOCKFILE is stale (age: ${AGE}s)" >> "$LOGFILE"
+ else
+ echo "[$(date '+%F %T')] OK: $LOCKFILE present (age: ${AGE}s)" >> "$LOGFILE"
+ fi
+ else
+ echo "[$(date '+%F %T')] OK: $LOCKFILE not found" >> "$LOGFILE"
+ fi
+done
+
+echo "[$(date '+%F %T')] Watchdog run complete." >> "$LOGFILE"
+echo >> "$LOGFILE"
diff --git a/mirror-weekly.sh b/mirror-weekly.sh
new file mode 100755
index 0000000..7a5c134
--- /dev/null
+++ b/mirror-weekly.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# mirror-weekly.sh
+# Summarize weekly client activity across Alma, Rocky, Arch, Gentoo
+
+LOGDIR="/var/log/nginx/"
+OUTDIR="/var/log/mirrors"
+OUTFILE="$OUTDIR/mirror-weekly-$(date +%F).log"
+
+mkdir -p "$OUTDIR"
+
+echo "=== Mirror Weekly Summary ($(date)) ===" > "$OUTFILE"
+
+# Which distros to track (pattern, label)
+declare -A DISTROS=(
+ [alma]="alma AlmaLinux"
+ [rocky]="rocky RockyLinux"
+ [archlinux]="arch ArchLinux"
+ [gentoo]="gentoo Gentoo"
+)
+
+for key in "${!DISTROS[@]}"; do
+ label=${DISTROS[$key]}
+ echo "" >> "$OUTFILE"
+ echo "=== $label ===" >> "$OUTFILE"
+
+ # Requests + unique clients
+ awk -v pat="$key" '
+ $7 ~ pat {
+ reqs++
+ ips[$1]=1
+ }
+ END {
+ printf "%d requests, %d unique clients\n", reqs, length(ips)
+ }' "$LOGDIR"/stygian_access.log >> "$OUTFILE"
+
+ # Top 5 IPs
+ awk -v pat="$key" '
+ $7 ~ pat { count[$1]++ }
+ END {
+ for (ip in count) print count[ip], ip
+ }' "$LOGDIR"/stygian_access.log | sort -nr | head -n 5 >> "$OUTFILE"
+done
+
+echo "" >> "$OUTFILE"
+echo "=== Totals Across All Distros ===" >> "$OUTFILE"
+
+awk '$7 ~ /(alma|rocky|archlinux|gentoo)/ {
+ total++
+ ips[$1]=1
+}
+END {
+ printf "%d requests across all, %d unique clients total\n", total, length(ips)
+}' "$LOGDIR"/stygian_access.log >> "$OUTFILE"
diff --git a/monitor.sh b/monitor.sh
new file mode 100755
index 0000000..16befe0
--- /dev/null
+++ b/monitor.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+echo "=== Stygian Mirror Health ==="
+echo -n "Load: "
+uptime | awk -F'load average:' '{print $2}'
+echo -n "Net throughput: "
+vnstat -tr 5 | grep 'rx\|tx'
+echo "ZFS I/O:"
+zpool iostat -v 5 2 | tail -n +4
diff --git a/portage-timestamp.sh b/portage-timestamp.sh
new file mode 100755
index 0000000..cbe006d
--- /dev/null
+++ b/portage-timestamp.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# try-portage-timestamp.sh
+# Loop through Gentoo rsync mirrors and grab timestamp.chk
+
+MIRRORS=(
+ rsync://rsync.gentoo.org/gentoo-portage/metadata/timestamp.chk
+ rsync://rsync1.de.gentoo.org/gentoo-portage/metadata/timestamp.chk
+ rsync://rsync.uk.gentoo.org/gentoo-portage/metadata/timestamp.chk
+ rsync://rsync.fr.gentoo.org/gentoo-portage/metadata/timestamp.chk
+ rsync://rsync.us.gentoo.org/gentoo-portage/metadata/timestamp.chk
+)
+
+for SRC in "${MIRRORS[@]}"; do
+ echo "Trying $SRC ..."
+ OUT=$(rsync --no-motd "$SRC" /dev/stdout 2>/dev/null)
+ if [[ -n "$OUT" ]]; then
+ echo ">>> Success from $SRC"
+ echo "$OUT"
+ exit 0
+ fi
+done
+
+echo "!!! No mirror returned a timestamp.chk"
+exit 1
diff --git a/rebootvalidate.sh b/rebootvalidate.sh
new file mode 100755
index 0000000..f6506e6
--- /dev/null
+++ b/rebootvalidate.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# rebootvalidate.sh - Validate ZFS pools, datasets, and bind mounts after reboot
+
+# === CONFIG ===
+# List the bind mount TARGETS you expect to be present under /mnt/brimstone/mirror
+EXPECTED_BINDS=(
+ "/mnt/brimstone/mirror/archlinux"
+ "/mnt/brimstone/mirror/rocky"
+ "/mnt/brimstone/mirror/debian"
+ "/mnt/brimstone/mirror/slackware"
+ "/mnt/brimstone/mirror/gentoo"
+ "/mnt/brimstone/mirror/hardenedbsd"
+ "/mnt/brimstone/mirror/void"
+ "/mnt/brimstone/mirror/crux"
+ "/mnt/brimstone/mirror/alma"
+ "/mnt/brimstone/mirror/kitten"
+)
+
+echo "=== Checking ZFS Pools ==="
+zpool status | grep -E "pool|state|errors"
+if zpool status | grep -q "ONLINE"; then
+ echo "[OK] All pools appear ONLINE."
+else
+ echo "[WARN] Some pools are not ONLINE."
+fi
+echo
+
+echo "=== Checking ZFS Datasets ==="
+zfs list -o name,mountpoint,mounted | grep -v "legacy"
+if zfs list -o mounted | grep -q "no"; then
+ echo "[WARN] One or more datasets are not mounted."
+else
+ echo "[OK] All datasets mounted."
+fi
+echo
+
+echo "=== Checking Bind Mounts ==="
+for target in "${EXPECTED_BINDS[@]}"; do
+ if findmnt -no TARGET,SOURCE "$target" >/tmp/mntcheck 2>/dev/null; then
+ tgt=$(awk '{print $1}' /tmp/mntcheck)
+ src=$(awk '{print $2}' /tmp/mntcheck)
+
+ if [[ "$tgt" == "$target" ]]; then
+ echo "[OK] $target is bound to $src"
+ else
+ echo "[FAIL] $target exists but unexpected source: $src"
+ fi
+ else
+ echo "[FAIL] Missing bind mount: $target"
+ fi
+done
diff --git a/sign-mirror.sh b/sign-mirror.sh
new file mode 100755
index 0000000..c2002ae
--- /dev/null
+++ b/sign-mirror.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+set -euo pipefail
+
+# sign-mirror.sh
+# Generate detached PGP signature for stygian.failzero.net/mirror
+
+MIRROR_PATH="/mnt/brimstone/mirror/signatures"
+SIGNING_KEY="doc@filenotfound.org"
+BASENAME="SHA256SUMS"
+TS=$(date +"%Y%m%d-%H%M%S")
+CHECKSUM_FILE="$MIRROR_PATH/${BASENAME}-$TS"
+
+echo "[*] Generating $CHECKSUM_FILE..."
+(
+ cd "$MIRROR_PATH"
+ find . -type f -not -xtype l ! -name "SHA256SUMS*" -exec sha256sum {} \;
+) > "$CHECKSUM_FILE"
+
+echo "[*] Signing with GPG key: $SIGNING_KEY"
+gpg --batch --yes --default-key "$SIGNING_KEY" \
+ --armor --detach-sign "$CHECKSUM_FILE"
+
+echo "[*] Verifying signature..."
+gpg --verify "$CHECKSUM_FILE.asc" "$CHECKSUM_FILE"
+
+# Rotate old files, keep last 3
+echo "[*] Rotating old signatures (keeping last 3)..."
+cd "$MIRROR_PATH"
+(ls -1t ${BASENAME}-* 2>/dev/null || true) | tail -n +4 | xargs -r rm -f || true
+(ls -1t ${BASENAME}-*.asc 2>/dev/null || true) | tail -n +4 | xargs -r rm -f || true
+
+# Update symlinks to latest
+echo "[*] Updating symlinks..."
+LATEST=$(ls -1t ${BASENAME}-* | head -n1)
+ln -sf "$LATEST" "${BASENAME}"
+ln -sf "$LATEST.asc" "${BASENAME}.asc"
+
+echo "[+] Done. Latest signature: ${LATEST}.asc"
diff --git a/status.sh b/status.sh
new file mode 100755
index 0000000..5f58329
--- /dev/null
+++ b/status.sh
@@ -0,0 +1,103 @@
+#!/bin/bash
+# mirror-status.sh
+# Generate a status page for FailZero mirrors
+
+MIRROR_BASE="/mnt/brimstone/mirror"
+STATUS_DIR="/mnt/brimstone/mirror/status"
+STATUS_FILE="$STATUS_DIR/index.html"
+LOG_DIR="/var/log/mirrors"
+
+# List your mirrors (folder name => display name)
+declare -A MIRRORS=(
+ ["archlinux"]="Arch Linux"
+ ["debian"]="Debian"
+ ["gentoo"]="Gentoo"
+ ["hardenedbsd"]="HardenedBSD"
+ ["slackware"]="Slackware"
+ ["void"]="Void Linux"
+ ["rocky"]="Rocky Linux"
+ ["alma"]="AlmaLinux"
+)
+
+mkdir -p "$STATUS_DIR"
+
+cat > "$STATUS_FILE" <<EOF
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>FailZero Mirror Status</title>
+ <style>
+ body { font-family: monospace; background: #111; color: #eee; }
+ h1 { color: #f33; }
+ table { border-collapse: collapse; width: 100%; }
+ th, td { padding: 8px 12px; border: 1px solid #444; }
+ th { background: #222; }
+ tr.ok { background: #1a2; }
+ tr.warn { background: #662; }
+ tr.fail { background: #a22; }
+ </style>
+</head>
+<body>
+ <h1>FailZero Mirror Status</h1>
+ <p>Updated: $(date)</p>
+ <table>
+ <tr><th>Distro</th><th>Last Sync (log)</th></tr>
+EOF
+
+for key in "${!MIRRORS[@]}"; do
+ DISTRO="${MIRRORS[$key]}"
+ DIR="$MIRROR_BASE/$key"
+ LOG="$LOG_DIR/${key}-mirror-sync.log"
+
+ STATUS="FAIL"
+ CLASS="fail"
+ LASTSYNC="no log"
+ FRESHNESS="unknown"
+
+ # 1. Parse rsync log exitcode
+ if [ -f "$LOG" ]; then
+ LASTSYNC=$(stat -c %y "$LOG" | cut -d. -f1)
+ EXITCODE=$(grep "EXITCODE:" "$LOG" | tail -n1 | cut -d: -f2)
+
+ if [ -n "$EXITCODE" ]; then
+ if [ "$EXITCODE" = "0" ]; then
+ STATUS="OK"
+ CLASS="ok"
+ else
+ STATUS="RSYNC FAIL ($EXITCODE)"
+ CLASS="fail"
+ fi
+ else
+ STATUS="NO EXITCODE"
+ CLASS="warn"
+ fi
+ fi
+
+ # 2. Check lastupdate if present (for freshness)
+# if [ -f "$DIR/lastupdate" ]; then
+# TS=$(tr -d '[:space:]' < "$DIR/lastupdate" 2>/dev/null)
+# if [[ "$TS" =~ ^[0-9]+$ ]]; then
+# NOW=$(date +%s)
+# AGE=$(( NOW - TS ))
+# if [ "$AGE" -lt 7200 ]; then
+# FRESHNESS="$((AGE/60)) min ago"
+# elif [ "$AGE" -lt 86400 ]; then
+# FRESHNESS="$((AGE/3600)) hr ago"
+# [ "$STATUS" = "OK" ] && CLASS="warn"
+# else
+# FRESHNESS="$((AGE/86400)) days ago"
+# [ "$STATUS" = "OK" ] && CLASS="warn"
+# fi
+# fi
+# fi
+
+ echo " <tr class=\"$CLASS\"><td>$DISTRO</td><td>$LASTSYNC</td>" >> "$STATUS_FILE"
+done
+
+cat >> "$STATUS_FILE" <<EOF
+ </table>
+ <p style="margin-top:20px;font-size:smaller;">FailZero Infrastructure – Mirror Ops</p>
+</body>
+</html>
+EOF
diff --git a/thebigone.sh b/thebigone.sh
new file mode 100755
index 0000000..c25fa95
--- /dev/null
+++ b/thebigone.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# chain-mirrors.sh
+# Run all mirror syncs sequentially with cleanup (--delete).
+
+LOGDIR="/home/mirror/logs"
+mkdir -p "$LOGDIR"
+
+run_sync() {
+ local name="$1"
+ local cmd="$2"
+
+ echo "[*] Starting $name at $(date)"
+ eval "$cmd" >> "$LOGDIR/${name}-mirror-sync.log" 2>&1
+ local status=$?
+ if [ $status -eq 0 ]; then
+ echo "[+] $name finished successfully at $(date)"
+ else
+ echo "[!] $name FAILED with code $status at $(date)"
+ fi
+}
+
+# Mirrors (adjust to your actual paths/servers)
+run_sync "arch" "rsync -avH --partial --delete --delete-delay --safe-links --hard-links --numeric-ids --timeout=300 --contimeout=60 --info=progress2 rsync://mirror.csclub.uwaterloo.ca/archlinux /brimstone2a/mirror/archlinux"
+run_sync "gentoo" "rsync -avH --partial --safe-links --hard-links --numeric-ids --timeout=300 --contimeout=60 --info=progress2 rsync://masterdistfiles.gentoo.org/gentoo/ /brimstone2a/mirror/gentoo"
+#run_sync "portage" "rsync -avH --partial --delete --delete-delay --safe-links --hard-links --numeric-ids --timeout=300 --contimeout=60 --info=progress2 rsync://rsync.ca.gentoo.org/gentoo-portage/ /brimstone1a/mirror/portage"
+run_sync "slackware" "rsync -avH --partial --delete --delete-delay --safe-links --hard-links --numeric-ids --timeout=300 --contimeout=60 --info=progress2 rsync://rsync.osuosl.org/slackware/ /brimstone2a/mirror/slackware"
+run_sync "hbsd" "rsync -avH --partial --delete --delete-delay --safe-links --hard-links --numeric-ids --timeout=300 --contimeout=60 --info=progress2 rsync://rsync.hardenedbsd.org/all /brimstone2a/mirror/hardenedbsd"
+#run_sync "rocky" "rsync -avH --partial --delete --delete-delay --safe-links --hard-links --numeric-ids --timeout=300 --contimeout=60 --info=progress2 rsync://mirror.dst.ca/rocky /brimstone1a/mirror/rocky"
+run_sync "alma" "rsync -avH --partial --delete --delete-delay --safe-links --hard-links --numeric-ids --timeout=300 --contimeout=60 --info=progress2 rsync://plug-mirror.rcac.purdue.edu/almalinux /brimstone3a/mirror/alma"
+run_sync "void" "rsync -avH --partial --delete --delete-delay --safe-links --hard-links --numeric-ids --timeout=300 --contimeout=60 --info=progress2 rsync://alpha.de.repo.voidlinux.org/voidlinux/ /brimstone3a/mirror/void"
+run_sync "debian" "/root/archvsync/bin/ftpsync sync:all"
+
+echo "[*] All mirrors complete at $(date)"