48 lines
2.9 KiB
Bash
Executable File
48 lines
2.9 KiB
Bash
Executable File
#!/bin/bash
|
|
cd /root/keyhunter
|
|
# v7.11: flock — check-then-act guards are not atomic; concurrent invocations
|
|
# (cron + manual) both seeing 0 would double-spawn. -n: second instance exits.
|
|
# v7.13: spawns MUST close fd 200 (200>&-) — an inherited lock fd held by the
|
|
# 39 long-lived lanes/validator would keep the flock forever and silently
|
|
# disable every subsequent keeper tick (Sentinel). Lock outside world-writable
|
|
# /tmp; verify between ticks with: flock -n data/lane_keeper.lock -c true.
|
|
exec 200>/root/keyhunter/data/lane_keeper.lock
|
|
flock -n 200 || exit 0
|
|
# v7.10: one-generation .out rotate at 8MB — PYTHONUNBUFFERED made logs grow
|
|
# between respawns; keep .1 as evidence (Sentinel).
|
|
for _lf in data/*_eternal.out; do
|
|
if [ -f "$_lf" ] && [ "$(stat -c %s "$_lf" 2>/dev/null || echo 0)" -gt 8388608 ]; then
|
|
cp "$_lf" "$_lf.1" && : > "$_lf" # copytruncate NOT mv: lanes hold O_APPEND
|
|
# FDs — mv would leave the writer appending to .1 while .out goes stale
|
|
fi
|
|
done
|
|
# jenkins/dockerhub also renamed to .disabled in canon (off the glob entirely);
|
|
# this list guards stale copies that may linger on the VPS.
|
|
# sourcegraph PAUSED pending user decision (Sentinel flag): continuous Chrome-UA
|
|
# WAF-bypass from the shared VPS IP; yield 6 unvalidated matches (GOOGLE-heavy,
|
|
# 89%-DEAD family). Resume = remove from DISABLED + tighter caps (SLEEP>=600,
|
|
# lower MAX_ITEMS) — or retire. Safer unattended default: paused.
|
|
DISABLED="jenkins_eternal.py dockerhub_eternal.py sourcegraph_eternal.py"
|
|
for f in *_eternal.py; do
|
|
case " $DISABLED " in *" $f "*) continue;; esac
|
|
pgrep -f "$f" > /dev/null || {
|
|
# v7.6: bare-filename pgrep also matches the stagger wrapper (no double-start
|
|
# when keeper runs twice within 30s); .out truncated per respawn (bounded,
|
|
# shows only current incarnation)
|
|
: > "data/${f%.py}.out"
|
|
setsid nohup bash -c "sleep $((RANDOM % 30)); exec env PYTHONUNBUFFERED=1 python3 '$f'" >> "data/${f%.py}.out" 2>&1 < /dev/null 200>&- &
|
|
echo "$(date '+%F %T') respawn $f" >> data/lane_keeper.log
|
|
}
|
|
done
|
|
# v7.1: keep the eternal validator alive with VISIBLE logs.
|
|
# v7.12: ANCHORED interpreter guard — a lingering `bash -c` wrapper's cmdline
|
|
# mentions validator_loop.py and would satisfy any substring guard while the
|
|
# real interpreter is dead (silent no-respawn, observed at bg_168/169).
|
|
# ^python3 matches only the interpreter; keeper's env-startup execs, so the
|
|
# cmdline is exactly "python3 validator_loop.py". Starters MUST use this
|
|
# relative form; pkill keeps the bracket form '[v]alidator_loop\.py'.
|
|
pgrep -f "^python3 (.* )?validator_loop\.py" > /dev/null || { # flag-tolerant anchor (python3 -u / env forms)
|
|
setsid nohup env PYTHONUNBUFFERED=1 python3 validator_loop.py >> data/validator_loop.log 2>&1 < /dev/null 200>&- &
|
|
echo "$(date '+%F %T') respawn validator_loop.py" >> data/lane_keeper.log
|
|
}
|