Packwiz-Abdelpak-hosting-kit/deploy.sh

135 lines
5.2 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# One-shot deploy: systemd service + packwiz pack + player setup guides.
#
# ./deploy.sh -n "Opengames" -a themiro -u https://games.abdelbaki.eu/mods \
# -N 21.1.72 --accept-eula
#
# Runs, in order:
# 1. mc-service-setup.sh (root) — minecraft user, NeoForge, systemd units
# 2. packwiz-setup.sh (you) — pack, mod index from the mirror, guides
#
# Safe to re-run. Each run snapshots the dataset, stops the server if it was
# running, rebuilds config and the pack from scratch, and starts it back up.
# The world and $SHARE/mods are never touched; an existing pack is moved aside
# to <pack>.bak.<timestamp> rather than deleted.
#
# --keep-pack keep the existing pack instead of rebuilding it
# --no-snapshot skip the pre-deploy ZFS snapshot
#
# Run as your normal user; it calls sudo for the parts that need it.
set -euo pipefail
NAME=""; AUTHOR=""; BASEURL=""; NFVER="latest"; MCVER="1.21.1"
SHARE="/minecraft"; XMX="10G"; XMS="10G"; ACCEPT_EULA=""; PORT="25565"; KEEP_PACK=0; SNAPSHOT=1; HTTP_PORT="18080"; HTTP_BIND="0.0.0.0"; SCHEME=""
HERE="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
die() { echo "error: $*" >&2; exit 1; }
step() { printf '\n\033[1m=== %s ===\033[0m\n\n' "$*"; }
usage() { awk 'NR>1 && /^#/ {sub(/^# ?/,""); print; next} NR>1 {exit}' "$0"; exit "${1:-0}"; }
while [ $# -gt 0 ]; do
case "$1" in
-n|--name) NAME="${2:-}"; shift 2 ;;
-a|--author) AUTHOR="${2:-}"; shift 2 ;;
-u|--base-url) BASEURL="${2:-}"; shift 2 ;;
-N|--neoforge) NFVER="${2:-}"; shift 2 ;;
-m|--mc) MCVER="${2:-}"; shift 2 ;;
-s|--share) SHARE="${2:-}"; shift 2 ;;
-p|--port) PORT="${2:-}"; shift 2 ;;
-H|--http-port) HTTP_PORT="${2:-}"; shift 2 ;;
-B|--http-bind) HTTP_BIND="${2:-}"; shift 2 ;;
-S|--scheme) SCHEME="${2:-}"; shift 2 ;;
-X|--xmx) XMX="${2:-}"; shift 2 ;;
-x|--xms) XMS="${2:-}"; shift 2 ;;
--accept-eula) ACCEPT_EULA="--accept-eula"; shift ;;
--keep-pack) KEEP_PACK=1; shift ;;
--no-snapshot) SNAPSHOT=0; shift ;;
-h|--help) usage 0 ;;
*) echo "unknown option: $1" >&2; usage 1 ;;
esac
done
[ "$(id -u)" -ne 0 ] || die "run this as your normal user, not root — it sudos where needed"
[ -n "$NAME" ] || die "missing -n <pack name>"
[ -n "$AUTHOR" ] || die "missing -a <author>"
[ -n "$BASEURL" ] || die "missing -u <mirror base url>, e.g. https://games.abdelbaki.eu/mods"
for s in mc-service-setup.sh packwiz-setup.sh mc-refresh-restart.sh; do
[ -x "$HERE/$s" ] || die "missing or not executable: $HERE/$s"
done
# Fail early rather than halfway through, since step 1 makes system changes.
sudo -v || die "sudo is required"
# ------------------------------------------------------------ re-run prep ---
# Re-running is expected: a run that failed partway leaves a half-applied state,
# and later runs change settings that only take effect on a fresh start. So take
# a snapshot, stop the server, redeploy, and put it back how it was.
#
# World data and $SHARE/mods are never touched by any of this.
WAS_ACTIVE=0
if systemctl is-active --quiet minecraft.service 2>/dev/null; then
WAS_ACTIVE=1
fi
if (( SNAPSHOT )) && mountpoint -q "$SHARE" && command -v zfs >/dev/null; then
DATASET="$(findmnt -no SOURCE "$SHARE" 2>/dev/null || true)"
if [ -n "$DATASET" ] && [ "$(findmnt -no FSTYPE "$SHARE")" = zfs ]; then
SNAP="$DATASET@predeploy-$(date +%Y%m%d%H%M%S)"
step "Snapshotting $SNAP"
sudo zfs snapshot "$SNAP" \
&& echo "roll back with: sudo zfs rollback $SNAP" \
|| die "zfs snapshot failed — pass --no-snapshot to deploy anyway"
fi
fi
if (( WAS_ACTIVE )); then
step "Stopping minecraft.service for redeploy"
sudo systemctl stop minecraft.service
fi
step "1/2 Minecraft systemd service"
sudo "$HERE/mc-service-setup.sh" \
-s "$SHARE" -A "$USER" -X "$XMX" -x "$XMS" -m "$MCVER" -p "$PORT" -H "$HTTP_PORT" -B "$HTTP_BIND" \
${NFVER:+-N "$NFVER"} ${ACCEPT_EULA}
PACK_FORCE=""
(( KEEP_PACK )) || PACK_FORCE="--force"
PACK_SCHEME=""
[ -z "$SCHEME" ] || PACK_SCHEME="-S $SCHEME"
step "2/2 packwiz pack and player guides"
# The admin group membership from step 1 isn't active in this shell yet, so run
# the pack setup under the new group explicitly rather than telling you to log
# out and back in.
if id -nG "$USER" | tr ' ' '\n' | grep -qx minecraft; then
"$HERE/packwiz-setup.sh" -n "$NAME" -a "$AUTHOR" -m "$MCVER" -u "$BASEURL" -s "$SHARE" -p "$PORT" ${PACK_FORCE} ${PACK_SCHEME}
else
sg minecraft -c "$(printf '%q ' "$HERE/packwiz-setup.sh" -n "$NAME" -a "$AUTHOR" \
-m "$MCVER" -u "$BASEURL" -s "$SHARE" -p "$PORT" ${PACK_FORCE} ${PACK_SCHEME})"
fi
if (( WAS_ACTIVE )); then
step "Restarting minecraft.service"
sudo systemctl start minecraft.service
fi
step "Done"
cat <<EOF
Start the server:
sudo systemctl start minecraft
journalctl -u minecraft -f
Keep it in sync after adding mods to $SHARE/mods:
$HERE/mc-refresh-restart.sh
Edit the config block at the top of mc-refresh-restart.sh first — it needs
PACK_DIR, BASE_URL and PACK_URL pointed at what this run just created.
EOF