deploy: persistent systemd unit running a pinned release binary with Restart=on-failure + boot enable, plus a liveness timer that restarts the daemon if a register round-trip stops answering
This commit is contained in:
parent
b022189fa5
commit
2aaa5ac091
4 changed files with 76 additions and 0 deletions
19
deploy/echoircd-dev.service
Normal file
19
deploy/echoircd-dev.service
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
[Unit]
|
||||||
|
Description=echoIRCd (production) — native Rust ircd
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=debian
|
||||||
|
WorkingDirectory=/home/debian/irc/ircd/echoIRCd
|
||||||
|
LimitNOFILE=200000
|
||||||
|
# runs a PINNED release binary (bin/echoircd), not target/debug — so a stray
|
||||||
|
# `cargo build` never changes what a restart would launch. Deploy = copy a fresh
|
||||||
|
# `cargo build --release` binary over bin/echoircd, then `systemctl restart`.
|
||||||
|
ExecStart=/home/debian/irc/ircd/echoIRCd/bin/echoircd /home/debian/irc/ircd/echoIRCd/echoircd.conf
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=2
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
8
deploy/echoircd-liveness.service
Normal file
8
deploy/echoircd-liveness.service
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
[Unit]
|
||||||
|
Description=echoIRCd liveness probe — restart the daemon if it stops responding
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
# a hung (but not exited) daemon isn't caught by Restart=on-failure; this probe
|
||||||
|
# does a real register round-trip and restarts the service if it doesn't answer.
|
||||||
|
ExecStart=/home/debian/irc/ircd/echoIRCd/scripts/liveness.sh 6767
|
||||||
10
deploy/echoircd-liveness.timer
Normal file
10
deploy/echoircd-liveness.timer
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Run the echoIRCd liveness probe periodically
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnBootSec=2min
|
||||||
|
OnUnitActiveSec=2min
|
||||||
|
AccuracySec=15s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
39
scripts/liveness.sh
Executable file
39
scripts/liveness.sh
Executable file
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# echoIRCd liveness probe: do a real NICK/USER register round-trip on the plaintext
|
||||||
|
# port and, if the daemon doesn't answer with a 001 welcome, restart it. Catches a
|
||||||
|
# hung core (process alive but not serving), which Restart=on-failure alone can't.
|
||||||
|
# Run by echoircd-liveness.timer.
|
||||||
|
set -u
|
||||||
|
PORT="${1:-6767}"
|
||||||
|
|
||||||
|
if python3 - "$PORT" <<'PY'
|
||||||
|
import socket, sys, time
|
||||||
|
port = int(sys.argv[1])
|
||||||
|
try:
|
||||||
|
s = socket.create_connection(("127.0.0.1", port), timeout=5)
|
||||||
|
s.settimeout(5)
|
||||||
|
s.sendall(b"NICK livecheck\r\nUSER lc 0 * :liveness\r\n")
|
||||||
|
data = b""
|
||||||
|
end = time.time() + 6
|
||||||
|
while time.time() < end:
|
||||||
|
d = s.recv(4096)
|
||||||
|
if not d:
|
||||||
|
break
|
||||||
|
data += d
|
||||||
|
if b" 001 " in data:
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
s.sendall(b"QUIT :liveness\r\n")
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
s.close()
|
||||||
|
sys.exit(0 if b" 001 " in data else 1)
|
||||||
|
except OSError:
|
||||||
|
sys.exit(1)
|
||||||
|
PY
|
||||||
|
then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "echoircd liveness: no 001 from 127.0.0.1:${PORT} within timeout — restarting echoircd-dev.service"
|
||||||
|
systemctl restart echoircd-dev.service
|
||||||
Loading…
Add table
Add a link
Reference in a new issue