server: add watchdog fail-safes
This commit is contained in:
parent
4e96c271ed
commit
67cddf6a99
31
scripts/daemon/lesavka-hw-watchdog.py
Normal file
31
scripts/daemon/lesavka-hw-watchdog.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import signal
|
||||||
|
import time
|
||||||
|
|
||||||
|
path = os.environ.get("LESAVKA_WATCHDOG_DEV", "/dev/watchdog")
|
||||||
|
interval = float(os.environ.get("LESAVKA_WATCHDOG_INTERVAL", "5"))
|
||||||
|
|
||||||
|
fd = os.open(path, os.O_WRONLY)
|
||||||
|
|
||||||
|
running = True
|
||||||
|
|
||||||
|
|
||||||
|
def handle(_sig, _frame):
|
||||||
|
global running
|
||||||
|
running = False
|
||||||
|
|
||||||
|
|
||||||
|
signal.signal(signal.SIGTERM, handle)
|
||||||
|
signal.signal(signal.SIGINT, handle)
|
||||||
|
|
||||||
|
try:
|
||||||
|
while running:
|
||||||
|
os.write(fd, b"\0")
|
||||||
|
time.sleep(interval)
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
os.write(fd, b"V")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
os.close(fd)
|
||||||
13
scripts/daemon/lesavka-hw-watchdog.service
Normal file
13
scripts/daemon/lesavka-hw-watchdog.service
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Lesavka hardware watchdog
|
||||||
|
ConditionPathExists=/dev/watchdog
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/local/bin/lesavka-hw-watchdog.py
|
||||||
|
Restart=always
|
||||||
|
RestartSec=2
|
||||||
|
KillMode=process
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
10
scripts/daemon/lesavka-watchdog.service
Normal file
10
scripts/daemon/lesavka-watchdog.service
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Lesavka reboot watchdog
|
||||||
|
ConditionPathExists=!/etc/lesavka/no-reboot
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/bin/lesavka-watchdog.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
23
scripts/daemon/lesavka-watchdog.sh
Normal file
23
scripts/daemon/lesavka-watchdog.sh
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
HEARTBEAT=/etc/lesavka/watchdog.touch
|
||||||
|
MAX_AGE_SEC=${LESAVKA_WATCHDOG_MAX_AGE:-840}
|
||||||
|
|
||||||
|
if [[ -f /etc/lesavka/no-reboot ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
now=$(date +%s)
|
||||||
|
if [[ ! -f "$HEARTBEAT" ]]; then
|
||||||
|
logger -t lesavka-watchdog "no heartbeat file; rebooting"
|
||||||
|
systemctl --no-wall reboot
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mtime=$(stat -c %Y "$HEARTBEAT" 2>/dev/null || echo 0)
|
||||||
|
age=$((now - mtime))
|
||||||
|
if (( age > MAX_AGE_SEC )); then
|
||||||
|
logger -t lesavka-watchdog "heartbeat stale (${age}s); rebooting"
|
||||||
|
systemctl --no-wall reboot
|
||||||
|
fi
|
||||||
11
scripts/daemon/lesavka-watchdog.timer
Normal file
11
scripts/daemon/lesavka-watchdog.timer
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Lesavka reboot watchdog timer
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnBootSec=15min
|
||||||
|
OnUnitActiveSec=15min
|
||||||
|
AccuracySec=30s
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
@ -157,6 +157,8 @@ sudo install -Dm755 "$SRC_DIR/server/target/release/lesavka-server" /usr/local/b
|
|||||||
sudo install -Dm755 "$SRC_DIR/server/target/release/lesavka-uvc" /usr/local/bin/lesavka-uvc
|
sudo install -Dm755 "$SRC_DIR/server/target/release/lesavka-uvc" /usr/local/bin/lesavka-uvc
|
||||||
sudo install -Dm755 "$SRC_DIR/scripts/daemon/lesavka-core.sh" /usr/local/bin/lesavka-core.sh
|
sudo install -Dm755 "$SRC_DIR/scripts/daemon/lesavka-core.sh" /usr/local/bin/lesavka-core.sh
|
||||||
sudo install -Dm755 "$SRC_DIR/scripts/daemon/lesavka-uvc.sh" /usr/local/bin/lesavka-uvc.sh
|
sudo install -Dm755 "$SRC_DIR/scripts/daemon/lesavka-uvc.sh" /usr/local/bin/lesavka-uvc.sh
|
||||||
|
sudo install -Dm755 "$SRC_DIR/scripts/daemon/lesavka-watchdog.sh" /usr/local/bin/lesavka-watchdog.sh
|
||||||
|
sudo install -Dm755 "$SRC_DIR/scripts/daemon/lesavka-hw-watchdog.py" /usr/local/bin/lesavka-hw-watchdog.py
|
||||||
|
|
||||||
echo "==> 6a. Systemd units - lesavka-core"
|
echo "==> 6a. Systemd units - lesavka-core"
|
||||||
cat <<'UNIT' | sudo tee /etc/systemd/system/lesavka-core.service >/dev/null
|
cat <<'UNIT' | sudo tee /etc/systemd/system/lesavka-core.service >/dev/null
|
||||||
@ -243,6 +245,57 @@ User=root
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
UNIT
|
UNIT
|
||||||
|
|
||||||
|
echo "==> 6d. Systemd units - watchdogs"
|
||||||
|
cat <<'UNIT' | sudo tee /etc/systemd/system/lesavka-watchdog.service >/dev/null
|
||||||
|
[Unit]
|
||||||
|
Description=Lesavka reboot watchdog
|
||||||
|
ConditionPathExists=!/etc/lesavka/no-reboot
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/bin/lesavka-watchdog.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
UNIT
|
||||||
|
|
||||||
|
cat <<'UNIT' | sudo tee /etc/systemd/system/lesavka-watchdog.timer >/dev/null
|
||||||
|
[Unit]
|
||||||
|
Description=Lesavka reboot watchdog timer
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnBootSec=15min
|
||||||
|
OnUnitActiveSec=15min
|
||||||
|
AccuracySec=30s
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
UNIT
|
||||||
|
|
||||||
|
cat <<'UNIT' | sudo tee /etc/systemd/system/lesavka-hw-watchdog.service >/dev/null
|
||||||
|
[Unit]
|
||||||
|
Description=Lesavka hardware watchdog
|
||||||
|
ConditionPathExists=/dev/watchdog
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/local/bin/lesavka-hw-watchdog.py
|
||||||
|
Restart=always
|
||||||
|
RestartSec=2
|
||||||
|
KillMode=process
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
UNIT
|
||||||
|
|
||||||
|
sudo install -d /etc/lesavka
|
||||||
|
sudo touch /etc/lesavka/watchdog.touch
|
||||||
|
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable --now lesavka-hw-watchdog
|
||||||
|
sudo systemctl enable --now lesavka-watchdog.timer
|
||||||
|
|
||||||
if [[ -n ${LESAVKA_ALLOW_GADGET_RESET:-} ]] || ! is_attached_state "$UDC_STATE"; then
|
if [[ -n ${LESAVKA_ALLOW_GADGET_RESET:-} ]] || ! is_attached_state "$UDC_STATE"; then
|
||||||
sudo systemctl restart lesavka-uvc
|
sudo systemctl restart lesavka-uvc
|
||||||
echo "✅ lesavka-uvc installed and restarted..."
|
echo "✅ lesavka-uvc installed and restarted..."
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user