Files
scripts/unraid-1/install.sh
T

127 lines
4.7 KiB
Bash
Executable File

#!/bin/bash
# unraid-1 installer — sets up the unraid box with the standard fleet of
# containers (garage S3, basement UI, watchtower, host-agent).
#
# Usage on the unraid console:
# bash <(curl -sL https://git.docker.pq.io/pq/scripts/raw/branch/main/unraid-1/install.sh)
#
# What it does:
# 1. Validates this is an unraid host with the array started.
# 2. Confirms the "s3" share exists (parity-protected; you create it).
# 3. mkdir's /mnt/user/appdata/garage/{meta,} and /mnt/user/s3/data.
# 4. Generates 3 garage secrets (rpc, admin, metrics) → secrets.env (preserved).
# 5. Fetches garage.toml → /mnt/user/appdata/garage/garage.toml.
# 6. Fetches 4 unraid container templates (garage / basement / watchtower /
# host-agent), substitutes secrets where needed, writes them to
# /boot/config/plugins/dockerMan/templates-user/my-*.xml.
#
# After: Unraid UI → Docker → Add Container → Template dropdown → Apply each.
#
# Idempotent: re-running keeps existing secrets and garage.toml. FORCE=1
# rotates the garage secrets (you'll then need to re-Apply garage + basement).
set -euo pipefail
BASE="${UNRAID1_INSTALL_BASE:-https://git.docker.pq.io/pq/scripts/raw/branch/main/unraid-1}"
APPDATA=/mnt/user/appdata/garage
DATADIR=/mnt/user/s3/data
TEMPLATE_DIR=/boot/config/plugins/dockerMan/templates-user
TOML_DEST="$APPDATA/garage.toml"
SECRETS="$APPDATA/secrets.env"
say() { printf "install.sh: %s\n" "$*"; }
die() { printf "install.sh: %s\n" "$*" >&2; exit 1; }
# ── Sanity ──
[ -d /boot/config/plugins/dockerMan ] || die "no /boot/config/plugins/dockerMan — not an unraid host?"
[ -d /mnt/user ] || die "/mnt/user missing — is the array started?"
[ -d /mnt/user/s3 ] || die "share /mnt/user/s3 missing. Create it in unraid UI first (Shares → Add Share → 's3', cache:yes recommended), then re-run."
mkdir -p "$APPDATA/meta" "$DATADIR" "$TEMPLATE_DIR"
# ── garage.toml ──
if [ -f "$TOML_DEST" ] && [ "${FORCE:-}" != "1" ]; then
say "$TOML_DEST exists — keeping (FORCE=1 to overwrite)"
else
say "fetching $BASE/garage.toml"
curl -fsSL "$BASE/garage.toml" -o "$TOML_DEST"
fi
# ── Secrets ──
if [ -f "$SECRETS" ] && [ "${FORCE:-}" != "1" ]; then
say "reusing existing secrets at $SECRETS (FORCE=1 to rotate)"
# shellcheck disable=SC1090
. "$SECRETS"
else
GARAGE_RPC_SECRET=$(openssl rand -hex 32)
GARAGE_ADMIN_TOKEN=$(openssl rand -hex 32)
GARAGE_METRICS_TOKEN=$(openssl rand -hex 32)
umask 077
cat > "$SECRETS" <<EOF
GARAGE_RPC_SECRET=$GARAGE_RPC_SECRET
GARAGE_ADMIN_TOKEN=$GARAGE_ADMIN_TOKEN
GARAGE_METRICS_TOKEN=$GARAGE_METRICS_TOKEN
EOF
say "generated secrets → $SECRETS"
fi
# ── Templates ──
# Fetch each, optionally sed-substitute __PLACEHOLDER__ secrets, write to
# templates-user/. Secrets are hex chars only — safe in sed delimiters.
fetch_template() {
local src=$1 dest=$2 tmp
shift 2
tmp=$(mktemp)
say "fetching $src"
curl -fsSL "$src" -o "$tmp"
if [ "$#" -gt 0 ]; then
sed "$@" "$tmp" > "$dest"
else
cp "$tmp" "$dest"
fi
rm -f "$tmp"
say "wrote $dest"
}
fetch_template \
"$BASE/garage.template.xml" \
"$TEMPLATE_DIR/my-garage.xml" \
-e "s|__GARAGE_RPC_SECRET__|$GARAGE_RPC_SECRET|" \
-e "s|__GARAGE_ADMIN_TOKEN__|$GARAGE_ADMIN_TOKEN|" \
-e "s|__GARAGE_METRICS_TOKEN__|$GARAGE_METRICS_TOKEN|"
fetch_template \
"$BASE/basement.template.xml" \
"$TEMPLATE_DIR/my-basement.xml" \
-e "s|__GARAGE_ADMIN_TOKEN__|$GARAGE_ADMIN_TOKEN|"
fetch_template \
"$BASE/watchtower.template.xml" \
"$TEMPLATE_DIR/my-watchtower.xml"
fetch_template \
"$BASE/host-agent.template.xml" \
"$TEMPLATE_DIR/my-host-agent.xml"
cat <<'EOF'
────────────────────────────────────────
Done. Apply each template in Unraid UI → Docker → Add Container → Template dropdown:
1. "my-garage" → Apply. Initialise cluster after first start:
docker exec garage /garage status # copy node id
docker exec garage /garage layout assign -z dc1 -c 1T <node-id>
docker exec garage /garage layout apply --version 1
Smoke test from your laptop:
aws --endpoint-url https://s3.pq.io --region garage s3 ls
2. "my-basement" → Apply. Reachable at https://basement.pq.io.
3. "my-watchtower" → Apply. Auto-updates the labelled containers above + below.
4. "my-host-agent" → Apply. Pushes node/cadvisor/smartctl metrics to your
Prometheus (defaults to docker-1.internal.pq.io:9090).
────────────────────────────────────────
EOF