From 2c7704b6f9fec3b54c2ab39b0edbf3f0a0b585ef Mon Sep 17 00:00:00 2001 From: Bastian de Byl Date: Thu, 22 Jan 2026 23:11:54 -0500 Subject: [PATCH] feat: add zomboid world reset via systemd path unit Deploy systemd path unit that watches for trigger file from Discord bot and executes world reset script to delete saves and restart server. Co-Authored-By: Claude Opus 4.5 --- .../templates/zomboid/world-reset.sh.j2 | 57 +++++++++++++++++++ .../zomboid/zomboid-world-reset.path.j2 | 9 +++ .../zomboid/zomboid-world-reset.service.j2 | 8 +++ 3 files changed, 74 insertions(+) create mode 100644 ansible/roles/podman/templates/zomboid/world-reset.sh.j2 create mode 100644 ansible/roles/podman/templates/zomboid/zomboid-world-reset.path.j2 create mode 100644 ansible/roles/podman/templates/zomboid/zomboid-world-reset.service.j2 diff --git a/ansible/roles/podman/templates/zomboid/world-reset.sh.j2 b/ansible/roles/podman/templates/zomboid/world-reset.sh.j2 new file mode 100644 index 0000000..d0d4696 --- /dev/null +++ b/ansible/roles/podman/templates/zomboid/world-reset.sh.j2 @@ -0,0 +1,57 @@ +#!/bin/bash +# Zomboid World Reset Script +# Triggered by systemd path unit when discord bot requests reset + +set -e + +LOGFILE="{{ podman_home }}/.local/share/volumes/zomboid/logs/world-reset.log" +TRIGGER_FILE="{{ podman_home }}/.local/share/volumes/gregtime/data/zomboid-reset.trigger" +SERVER_NAME="{{ zomboid_server_names[zomboid_server_mode] }}" +SAVES_PATH="{{ podman_home }}/.local/share/volumes/zomboid/data/Saves/Multiplayer/${SERVER_NAME}" +DB_PATH="{{ podman_home }}/.local/share/volumes/zomboid/data/db/${SERVER_NAME}.db" + +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOGFILE" +} + +# Ensure XDG_RUNTIME_DIR is set for systemctl --user +export XDG_RUNTIME_DIR="/run/user/$(id -u)" + +log "World reset triggered" + +# Read requester info from trigger file if available +# Note: Must use podman unshare because file is owned by container's UID (232071) +if podman unshare test -f "$TRIGGER_FILE"; then + REQUESTER=$(podman unshare cat "$TRIGGER_FILE") + log "Requested by: $REQUESTER" + podman unshare rm -f "$TRIGGER_FILE" +fi + +# Stop server +log "Stopping zomboid service..." +systemctl --user stop zomboid.service || true +sleep 5 + +# Delete world (using podman unshare to work within user namespace) +log "Deleting world saves at: $SAVES_PATH" +if [[ -d "$SAVES_PATH" ]]; then + podman unshare rm -rf "$SAVES_PATH" + log "World saves deleted" +else + log "No world saves found at $SAVES_PATH" +fi + +# Delete player database +log "Deleting player database at: $DB_PATH" +if [[ -f "$DB_PATH" ]]; then + podman unshare rm -f "$DB_PATH" + log "Player database deleted" +else + log "No database found at $DB_PATH" +fi + +# Start server +log "Starting zomboid service..." +systemctl --user start zomboid.service + +log "World reset complete - new world will generate on first connection" diff --git a/ansible/roles/podman/templates/zomboid/zomboid-world-reset.path.j2 b/ansible/roles/podman/templates/zomboid/zomboid-world-reset.path.j2 new file mode 100644 index 0000000..ba3dcb9 --- /dev/null +++ b/ansible/roles/podman/templates/zomboid/zomboid-world-reset.path.j2 @@ -0,0 +1,9 @@ +[Unit] +Description=Watch for Zomboid world reset trigger + +[Path] +PathExists={{ podman_home }}/.local/share/volumes/gregtime/data/zomboid-reset.trigger +Unit=zomboid-world-reset.service + +[Install] +WantedBy=default.target diff --git a/ansible/roles/podman/templates/zomboid/zomboid-world-reset.service.j2 b/ansible/roles/podman/templates/zomboid/zomboid-world-reset.service.j2 new file mode 100644 index 0000000..f26b39a --- /dev/null +++ b/ansible/roles/podman/templates/zomboid/zomboid-world-reset.service.j2 @@ -0,0 +1,8 @@ +[Unit] +Description=Zomboid World Reset Service + +[Service] +Type=oneshot +ExecStart={{ podman_home }}/bin/zomboid-world-reset.sh +StandardOutput=journal +StandardError=journal