#!/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 .bak. 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 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 ;; -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 " [ -n "$AUTHOR" ] || die "missing -a " [ -n "$BASEURL" ] || die "missing -u , 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" \ ${NFVER:+-N "$NFVER"} ${ACCEPT_EULA} PACK_FORCE="" (( KEEP_PACK )) || PACK_FORCE="--force" 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} else sg minecraft -c "$(printf '%q ' "$HERE/packwiz-setup.sh" -n "$NAME" -a "$AUTHOR" \ -m "$MCVER" -u "$BASEURL" -s "$SHARE" -p "$PORT" ${PACK_FORCE})" fi if (( WAS_ACTIVE )); then step "Restarting minecraft.service" sudo systemctl start minecraft.service fi step "Done" cat <