Packwiz-Abdelpak-hosting-kit/install.sh

205 lines
6.3 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Single entry point for deploying from removable media.
#
# ./install.sh reads deploy.conf next to this script
# ./install.sh -c other.conf reads a different config
# ./install.sh --check verify prerequisites and exit
#
# Copies itself off read-only media, installs prerequisites, and runs the
# deploy. Everything is configured in deploy.conf, so there are no flags to
# remember at the console.
set -euo pipefail
HERE="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
CONF="$HERE/deploy.conf"
CHECK_ONLY=0
WORKDIR=""
die() { printf '\n\033[1;31merror:\033[0m %s\n\n' "$*" >&2; exit 1; }
step() { printf '\n\033[1m=== %s ===\033[0m\n\n' "$*"; }
info() { echo ">>> $*"; }
warn() { echo " warning: $*" >&2; }
while [ $# -gt 0 ]; do
case "$1" in
-c|--config) CONF="${2:-}"; shift 2 ;;
--check) CHECK_ONLY=1; shift ;;
-w|--workdir) WORKDIR="${2:-}"; shift 2 ;;
-h|--help) awk 'NR>1 && /^#/ {sub(/^# ?/,""); print; next} NR>1 {exit}' "$0"; exit 0 ;;
*) die "unknown option: $1" ;;
esac
done
[ "$(id -u)" -ne 0 ] || die "run this as your normal user, not root — it calls sudo itself"
# ------------------------------------------------------------------ config ---
[ -f "$CONF" ] || die "no config at $CONF
Copy deploy.conf.example to deploy.conf and edit it first."
# shellcheck source=/dev/null
. "$CONF"
for v in PACK_NAME AUTHOR MIRROR_URL SHARE; do
[ -n "${!v:-}" ] || die "$v is not set in $CONF"
done
MC_VERSION="${MC_VERSION:-1.21.1}"
NEOFORGE="${NEOFORGE:-latest}"
MC_PORT="${MC_PORT:-25565}"
HTTP_PORT="${HTTP_PORT:-18080}"
HTTP_BIND="${HTTP_BIND:-0.0.0.0}"
XMX="${XMX:-10G}"
XMS="${XMS:-$XMX}"
ACCEPT_EULA="${ACCEPT_EULA:-no}"
START_SERVER="${START_SERVER:-no}"
CAP_ZFS_ARC="${CAP_ZFS_ARC:-}"
# ------------------------------------------------------------- prequisites ---
step "Checking prerequisites"
MISSING=()
need() { command -v "$1" >/dev/null || MISSING+=("$2"); }
need curl curl
need go golang
need python3 python3
need zfs zfs
need findmnt util-linux
need mkfifo coreutils
# Any java is not enough: NeoForge 21.1.x needs 21 exactly.
if ! ls /usr/lib/jvm/java-21-openjdk*/bin/java >/dev/null 2>&1; then
MISSING+=(java-21-openjdk-headless)
fi
if [ "${#MISSING[@]}" -gt 0 ]; then
info "missing: ${MISSING[*]}"
if (( CHECK_ONLY )); then
die "prerequisites missing (see above)"
fi
info "installing with dnf"
sudo dnf install -y "${MISSING[@]}" \
|| die "could not install: ${MISSING[*]}
Install them by hand and re-run."
else
info "all present"
fi
if ls /usr/lib/jvm/java-21-openjdk*/bin/java >/dev/null 2>&1; then
info "java 21 present: $(ls -d /usr/lib/jvm/java-21-openjdk*/bin/java | head -1)"
else
die "Java 21 is still missing after the install step.
sudo dnf install java-21-openjdk-headless"
fi
if ! mountpoint -q "$SHARE"; then
die "$SHARE is not a mountpoint — the ZFS dataset is not mounted.
Import and mount the pool first:
sudo zpool import -a && sudo zfs mount -a
Then re-run. Deploying onto an unmounted path would fill the root disk."
fi
info "$SHARE is mounted ($(findmnt -no SOURCE "$SHARE"))"
if (( CHECK_ONLY )); then
step "Prerequisites OK"
exit 0
fi
# --------------------------------------------------------------- workspace ---
# The media is very likely read-only, and the deploy needs somewhere writable
# for the go build and the pack. Copy the kit onto the host first.
if [ -z "$WORKDIR" ]; then
if [ -w "$HERE" ]; then
WORKDIR="$HERE"
else
WORKDIR="$HOME/mc-packwiz-deploy"
info "media is read-only — copying the kit to $WORKDIR"
mkdir -p "$WORKDIR"
cp -f "$HERE"/*.sh "$HERE"/*.py "$WORKDIR"/ 2>/dev/null || true
cp -f "$CONF" "$WORKDIR/deploy.conf"
chmod +x "$WORKDIR"/*.sh "$WORKDIR"/*.py 2>/dev/null || true
fi
fi
cd "$WORKDIR"
[ -x ./deploy.sh ] || die "deploy.sh not found in $WORKDIR"
# ----------------------------------------------------------------- zfs arc ---
if [ -n "$CAP_ZFS_ARC" ]; then
if [ ! -f /etc/modprobe.d/zfs.conf ] || ! grep -q zfs_arc_max /etc/modprobe.d/zfs.conf; then
step "Capping the ZFS ARC at $CAP_ZFS_ARC bytes"
echo "options zfs zfs_arc_max=$CAP_ZFS_ARC" | sudo tee /etc/modprobe.d/zfs.conf >/dev/null
warn "the ARC cap needs a reboot (and 'sudo dracut --force') to take effect"
else
info "ZFS ARC already capped in /etc/modprobe.d/zfs.conf"
fi
fi
# ------------------------------------------------------------------ deploy ---
EULA_FLAG=""
case "${ACCEPT_EULA,,}" in
yes|true|1) EULA_FLAG="--accept-eula" ;;
*) die "ACCEPT_EULA is not set to yes in $CONF.
Read https://aka.ms/MinecraftEULA, then set ACCEPT_EULA=\"yes\" to accept it." ;;
esac
step "Deploying $PACK_NAME"
./deploy.sh \
-n "$PACK_NAME" \
-a "$AUTHOR" \
-u "$MIRROR_URL" \
-m "$MC_VERSION" \
-N "$NEOFORGE" \
-s "$SHARE" \
-p "$MC_PORT" \
-H "$HTTP_PORT" \
-B "$HTTP_BIND" \
-X "$XMX" \
-x "$XMS" \
$EULA_FLAG
# ------------------------------------------------------------------- start ---
case "${START_SERVER,,}" in
yes|true|1)
step "Starting Minecraft"
sudo systemctl start minecraft
sleep 3
if systemctl is-active --quiet minecraft; then
info "minecraft.service is running"
else
warn "minecraft.service did not come up — journalctl -u minecraft -n 50"
fi
;;
esac
# ------------------------------------------------------------------- done ----
SITE="${MIRROR_URL%/*}"
HOSTONLY="$(sed -e 's#^[a-z]*://##' -e 's#/.*##' -e 's#:.*##' <<<"$SITE")"
[ "$MC_PORT" = "25565" ] && SHOWN="$HOSTONLY" || SHOWN="$HOSTONLY:$MC_PORT"
step "Done"
cat <<EOF
Kit installed in: $WORKDIR
Pack HTTP server: ${HTTP_BIND}:${HTTP_PORT} (proxy / -> this)
Players connect to: $SHOWN
Setup guides: $SITE/setup-windows-packwiz.html
$SITE/setup-linux-packwiz.html
Still to do by hand:
1. Point your reverse proxy at ${HTTP_BIND}:${HTTP_PORT}
2. Drop mod jars into $SHARE/mods
3. Run $WORKDIR/mc-refresh-restart.sh to register them
sudo systemctl start minecraft
journalctl -u minecraft -f
echo "op YourName" | sudo tee /run/minecraft/console
EOF