summaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md118
1 files changed, 118 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e4c83a6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,118 @@
+# umbrella
+
+A safety-critical game server admin daemon written in C11. Monitors
+multiple server processes via log file tailing, RCON, and A2S probing,
+and exposes a Unix socket for CLI clients to attach, send commands, and
+receive real-time output.
+
+## Features
+
+- Live log tailing via inotify with symlink resolution
+- Pluggable per-unit output filters (any stdin→stdout executable)
+- RCON command dispatch (Valve protocol)
+- A2S health probing (Valve UDP)
+- systemd unit state queries over D-Bus
+- Ring buffer — 500 lines × 1024 bytes per unit, replayed on attach
+- Reload without restart via SIGHUP
+
+## Build
+
+```bash
+# Dependencies: libyaml-dev, libsystemd-dev
+make
+sudo make install
+```
+
+Compiler flags: `-Wall -Wextra -Wpedantic -std=c11 -D_GNU_SOURCE -O2`
+
+## Install layout
+
+| Path | Purpose |
+|------|---------|
+| `/usr/local/sbin/umbrella` | Daemon |
+| `/usr/local/bin/umbrella-cli` | CLI client |
+| `/etc/umbrella/umbrella.conf` | Daemon config |
+| `/etc/umbrella/units/*.yaml` | Unit descriptors |
+| `/usr/lib/umbrella/filters/` | Bundled log filters |
+| `/run/umbrella/umbrella.sock` | Unix socket |
+| `/run/umbrella/umbrella.pid` | PID file |
+| `/var/log/umbrella/umbrella.log` | Daemon log |
+
+## Unit descriptor format
+
+```yaml
+name: tf2 # used in CLI commands
+display: "TF2 — novemen"
+service: tf2-server.service # systemd unit for state queries
+
+console:
+ type: rcon # rcon | stdin
+ host: 127.0.0.1
+ port: 27015
+ password_env: TF_RCON_PASSWORD # or: password: plaintext
+
+health:
+ type: a2s # a2s | tcp | none
+ host: 127.0.0.1
+ port: 27015
+ timeout_ms: 5000
+
+logs:
+ - /path/to/logs/current.log # up to 4 paths; symlinks resolved
+
+# Optional filter — any executable reading stdin, writing stdout
+log_filter: /usr/lib/umbrella/filters/source.py
+
+broadcast_cmd: "say {msg}" # template for !broadcast
+
+actions:
+ update: /path/to/update.sh
+ restart: /usr/bin/systemctl restart tf2-server.service
+```
+
+## Bundled filters
+
+| Filter | Targets |
+|--------|---------|
+| `source.py` | TF2, GMod, CS2 — strips `server_cvar`/stuck spam, strips timestamp prefix |
+| `minecraft.py` | vanilla/Paper/Spigot — strips keepAlive/autosave noise, strips `[HH:MM:SS] [thread]` prefix |
+| `terraria.py` | vanilla/tModLoader — strips blank lines and mod-loading spam |
+
+Custom filters: any executable at any path that reads stdin and flushes
+stdout after each write works. Python, shell, compiled binary — anything.
+
+## Log file setup
+
+srcds and most dedicated servers create new log files per session.
+Point `logs:` at a stable symlink and update it on each server start:
+
+```bash
+# In your startup script / ExecStartPre:
+ln -sf /srv/game/logs/L0222000.log /srv/game/logs/current.log
+# Then SIGHUP umbrella so it re-resolves the symlink:
+kill -HUP $(cat /run/umbrella/umbrella.pid)
+```
+
+With `sv_log_onefile 1` (Source engine), the log file is fixed for the
+server's lifetime, so the symlink only needs updating on restarts.
+
+## CLI usage
+
+```bash
+umbrella-cli list
+umbrella-cli status <unit>
+umbrella-cli attach <unit> # live output; Ctrl+D to detach
+umbrella-cli tail <unit> # dump ring buffer and exit
+umbrella-cli input <unit> <cmd> # send RCON command or stdin line
+umbrella-cli action <unit> <name> # run a named action script
+umbrella-cli broadcast <message> # send to all units' broadcast_cmd
+```
+
+## Reload
+
+```bash
+kill -HUP $(cat /run/umbrella/umbrella.pid)
+```
+
+Reloads unit YAML files, restarts log tails and filter subprocesses.
+Running processes are not touched.