feat: add query script
This commit is contained in:
parent
977ea6647c
commit
87be4dfafb
3 changed files with 152 additions and 0 deletions
|
|
@ -72,6 +72,10 @@ FORMAT="tar"
|
||||||
COMPRESSION="gzip"
|
COMPRESSION="gzip"
|
||||||
PROGRESS_INTERVAL=5 # default to 5 seconds
|
PROGRESS_INTERVAL=5 # default to 5 seconds
|
||||||
|
|
||||||
|
CHECK_USER=false
|
||||||
|
USER_ACTIVITY_FILE="UserActivity"
|
||||||
|
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
usage() {
|
usage() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
|
@ -86,6 +90,8 @@ Usage: $0 [--reboot] [--sleep <seconds>] [--full] [--destination <path>] [--pure
|
||||||
--pure Use rsync to copy files (no compression, symlinks resolved)
|
--pure Use rsync to copy files (no compression, symlinks resolved)
|
||||||
--format X Archive format: tar or zip (ignored if --pure)
|
--format X Archive format: tar or zip (ignored if --pure)
|
||||||
--compression X Compression for tar (default: gzip)
|
--compression X Compression for tar (default: gzip)
|
||||||
|
--check-user Only run backup if unbackuped user activity exists
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
@ -102,6 +108,8 @@ while [[ $# -gt 0 ]]; do
|
||||||
--format) echo "[DEBUG] Flag: --format $2"; FORMAT="$2"; shift 2 ;;
|
--format) echo "[DEBUG] Flag: --format $2"; FORMAT="$2"; shift 2 ;;
|
||||||
--compression) echo "[DEBUG] Flag: --compression $2"; COMPRESSION="$2"; shift 2 ;;
|
--compression) echo "[DEBUG] Flag: --compression $2"; COMPRESSION="$2"; shift 2 ;;
|
||||||
--progressInterval) echo "[DEBUG] Flag: --progressInterval $2"; PROGRESS_INTERVAL="$2"; shift 2 ;;
|
--progressInterval) echo "[DEBUG] Flag: --progressInterval $2"; PROGRESS_INTERVAL="$2"; shift 2 ;;
|
||||||
|
--check-user) echo "[DEBUG] Flag: --check-user"; CHECK_USER=true; shift ;;
|
||||||
|
|
||||||
--help) usage ;;
|
--help) usage ;;
|
||||||
*) echo "[ERROR] Unknown option: $1"; usage ;;
|
*) echo "[ERROR] Unknown option: $1"; usage ;;
|
||||||
esac
|
esac
|
||||||
|
|
@ -193,6 +201,37 @@ countdown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
check_user_activity() {
|
||||||
|
local activity_file="$DATA_DIR/$SERVER_NAME/$USER_ACTIVITY_FILE"
|
||||||
|
|
||||||
|
if [[ ! -f "$activity_file" ]]; then
|
||||||
|
echo "[WARN] User activity file not found: $activity_file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Find unbackuped login lines
|
||||||
|
if ! grep -E 'was logged in' "$activity_file" | grep -vq '\[backuped\]'; then
|
||||||
|
echo "[INFO] No unbackuped user activity detected."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[INFO] Unbackuped user activity detected."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
mark_user_activity_backuped() {
|
||||||
|
local activity_file="$DATA_DIR/$SERVER_NAME/$USER_ACTIVITY_FILE"
|
||||||
|
|
||||||
|
# Append [backuped] to all unbackuped login lines
|
||||||
|
sed -i \
|
||||||
|
-e '/was logged in/{
|
||||||
|
/\[backuped\]/! s/$/ [backuped]/
|
||||||
|
}' \
|
||||||
|
"$activity_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
do_backup() {
|
do_backup() {
|
||||||
local backup_source=""
|
local backup_source=""
|
||||||
local backup_destination=""
|
local backup_destination=""
|
||||||
|
|
@ -347,6 +386,15 @@ do_backup() {
|
||||||
|
|
||||||
#echo "[DEBUG] FULL=$FULL"
|
#echo "[DEBUG] FULL=$FULL"
|
||||||
|
|
||||||
|
if [[ "$CHECK_USER" == true ]]; then
|
||||||
|
echo "[INFO] Running in --check-user mode"
|
||||||
|
if ! check_user_activity; then
|
||||||
|
echo "[INFO] Skipping backup due to no user activity."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [[ "$FULL" == true ]]; then
|
if [[ "$FULL" == true ]]; then
|
||||||
BACKUP_SOURCE="${SERVER_NAME}"
|
BACKUP_SOURCE="${SERVER_NAME}"
|
||||||
BACKUP_MODE="full server directory"
|
BACKUP_MODE="full server directory"
|
||||||
|
|
@ -374,6 +422,11 @@ if do_backup \
|
||||||
--compression "$COMPRESSION" \
|
--compression "$COMPRESSION" \
|
||||||
--format "$FORMAT"; then
|
--format "$FORMAT"; then
|
||||||
echo "[INFO] Backup finished successfully."
|
echo "[INFO] Backup finished successfully."
|
||||||
|
if [[ "$CHECK_USER" == true ]]; then
|
||||||
|
mark_user_activity_backuped
|
||||||
|
echo "[INFO] User activity marked as backuped."
|
||||||
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
echo "[ERROR] Backup failed!"
|
echo "[ERROR] Backup failed!"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
||||||
34
minecraft/Scripts/minecraft-template-user-activity.sh
Normal file
34
minecraft/Scripts/minecraft-template-user-activity.sh
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DATA_DIR="@DATA_DIR@"
|
||||||
|
SERVER_NAME="@SERVER_NAME@"
|
||||||
|
|
||||||
|
# Provided by systemd Environment
|
||||||
|
QUERY_BIN="${QUERY_BIN:-minecraft-${SERVER_NAME}-query}"
|
||||||
|
|
||||||
|
ACTIVITY_FILE="$DATA_DIR/$SERVER_NAME/UserActivity"
|
||||||
|
TIMESTAMP="$(date '+%Y-%m-%d %H:%M:%S')"
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$ACTIVITY_FILE")"
|
||||||
|
touch "$ACTIVITY_FILE"
|
||||||
|
|
||||||
|
OUTPUT="$($QUERY_BIN || true)"
|
||||||
|
|
||||||
|
PLAYER_LINE="$(echo "$OUTPUT" | grep '^players:' || true)"
|
||||||
|
|
||||||
|
ONLINE="$(echo "$PLAYER_LINE" | awk '{print $2}' | cut -d/ -f1)"
|
||||||
|
|
||||||
|
if [[ -z "$ONLINE" || "$ONLINE" == "0" ]]; then
|
||||||
|
echo "[$TIMESTAMP] No user detected" >> "$ACTIVITY_FILE"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
PLAYERS="$(echo "$PLAYER_LINE" | sed -n 's/.*\[\(.*\)\]/\1/p')"
|
||||||
|
|
||||||
|
IFS=',' read -ra PLAYER_ARRAY <<< "$PLAYERS"
|
||||||
|
|
||||||
|
for player in "${PLAYER_ARRAY[@]}"; do
|
||||||
|
player="$(echo "$player" | xargs)"
|
||||||
|
[[ -n "$player" ]] && echo "[$TIMESTAMP] $player was logged in" >> "$ACTIVITY_FILE"
|
||||||
|
done
|
||||||
|
|
@ -291,6 +291,30 @@ in {
|
||||||
description = "Declarative Minecraft server.properties values.";
|
description = "Declarative Minecraft server.properties values.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# userActivity = {
|
||||||
|
# enable = mkOption {
|
||||||
|
# type = types.bool;
|
||||||
|
# default = false;
|
||||||
|
# description = ''
|
||||||
|
# Enable periodic user activity logging for this server.
|
||||||
|
# Writes to <dataDir>/<server>/UserActivity and is used by
|
||||||
|
# backup --check-user.
|
||||||
|
# '';
|
||||||
|
# };
|
||||||
|
|
||||||
|
# interval = mkOption {
|
||||||
|
# type = types.str;
|
||||||
|
# default = "5min";
|
||||||
|
# example = "1min";
|
||||||
|
# description = ''
|
||||||
|
# How often user activity should be logged.
|
||||||
|
# Uses systemd.time format (e.g. 30s, 1min, 5min).
|
||||||
|
# '';
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
schedules = mkOption {
|
schedules = mkOption {
|
||||||
type = types.attrsOf (types.submodule ({name, ...}: {
|
type = types.attrsOf (types.submodule ({name, ...}: {
|
||||||
options = {
|
options = {
|
||||||
|
|
@ -457,6 +481,46 @@ in {
|
||||||
cfg.servers
|
cfg.servers
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
# systemd.services = lib.mkMerge (
|
||||||
|
# lib.mapAttrsToList (serverName: serverCfg:
|
||||||
|
# lib.mkIf serverCfg.userActivity.enable {
|
||||||
|
# "minecraft-${serverName}-user-activity" = {
|
||||||
|
# description = "Minecraft ${serverName} user activity logger";
|
||||||
|
# serviceConfig = {
|
||||||
|
# Type = "oneshot";
|
||||||
|
# User = cfg.user;
|
||||||
|
# Group = cfg.group;
|
||||||
|
# Environment = [
|
||||||
|
# "QUERY_BIN=${mkScript serverName serverCfg "query"}/bin/minecraft-${serverName}-query"
|
||||||
|
# ];
|
||||||
|
# ExecStart =
|
||||||
|
# "${mkScript serverName serverCfg "user-activity"}/bin/minecraft-${serverName}-user-activity";
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
# }
|
||||||
|
# ) cfg.servers
|
||||||
|
# );
|
||||||
|
|
||||||
|
|
||||||
|
# systemd.timers = lib.mkMerge (
|
||||||
|
# lib.mapAttrsToList (serverName: serverCfg:
|
||||||
|
# lib.mkIf serverCfg.userActivity.enable {
|
||||||
|
# "minecraft-${serverName}-user-activity" = {
|
||||||
|
# description = "Timer for Minecraft ${serverName} user activity logging";
|
||||||
|
# wantedBy = [ "timers.target" ];
|
||||||
|
# timerConfig = {
|
||||||
|
# OnBootSec = "2min";
|
||||||
|
# OnUnitActiveSec = serverCfg.userActivity.interval;
|
||||||
|
# AccuracySec = "30s";
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
# }
|
||||||
|
# ) cfg.servers
|
||||||
|
# );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# this is building the scripts for the user
|
# this is building the scripts for the user
|
||||||
# Those are the prewritten scripts from the ./Script dir
|
# Those are the prewritten scripts from the ./Script dir
|
||||||
environment.systemPackages = lib.flatten (
|
environment.systemPackages = lib.flatten (
|
||||||
|
|
@ -466,6 +530,7 @@ in {
|
||||||
(mkScript serverName serverCfg "backup")
|
(mkScript serverName serverCfg "backup")
|
||||||
(mkScript serverName serverCfg "say")
|
(mkScript serverName serverCfg "say")
|
||||||
(mkScript serverName serverCfg "backup-routine")
|
(mkScript serverName serverCfg "backup-routine")
|
||||||
|
(mkScript serverName serverCfg "user-activity")
|
||||||
])
|
])
|
||||||
cfg.servers
|
cfg.servers
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue