127 lines
4.7 KiB
Bash
Executable File
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
|