← back to Exo Cluster Watchdog

harden-peer.sh

63 lines

#!/bin/bash
# harden-peer.sh — run this ON a peer exo node (mac1 / mac2), logged in AS the
# auto-login GUI user (the account exo runs under — the one with ~/exo).
# Makes exo NEVER stay off:
#   1) installs a per-user exo-keepalive LaunchAgent (KeepAlive + RunAtLoad)
#      -> exo auto-starts at login/boot and respawns within seconds if it crashes
#   2) sets pmset autorestart=1 (auto power-on after a power blip) + never sleep
# Idempotent + reversible (writes one plist + one run script under $HOME).
set -euo pipefail

USER_HOME="$HOME"
EXO_DIR="$USER_HOME/exo"
UV="$USER_HOME/.local/bin/uv"
LA="$USER_HOME/Library/LaunchAgents"
KEEP_DIR="$USER_HOME/Projects/exo-keepalive"
LABEL="com.steve.exo-keepalive"

[ -d "$EXO_DIR" ] || { echo "ERROR: no $EXO_DIR here — run this as the user that owns exo"; exit 1; }
[ -x "$UV" ] || { echo "ERROR: no uv at $UV"; exit 1; }
mkdir -p "$LA" "$KEEP_DIR/logs"

# 1a. run script (mirrors macstudio3's pattern)
cat > "$KEEP_DIR/run-exo.sh" <<EOF
#!/bin/bash
export PATH="$USER_HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
cd "$EXO_DIR" || exit 1
exec "$UV" run --extra mlx exo
EOF
chmod +x "$KEEP_DIR/run-exo.sh"

# 1b. LaunchAgent
cat > "$LA/$LABEL.plist" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
  <key>Label</key><string>$LABEL</string>
  <key>ProgramArguments</key><array>
    <string>/bin/bash</string><string>$KEEP_DIR/run-exo.sh</string>
  </array>
  <key>EnvironmentVariables</key><dict>
    <key>HOME</key><string>$USER_HOME</string>
    <key>PATH</key><string>$USER_HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
  </dict>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
  <key>ThrottleInterval</key><integer>15</integer>
  <key>StandardOutPath</key><string>$KEEP_DIR/logs/out.log</string>
  <key>StandardErrorPath</key><string>$KEEP_DIR/logs/err.log</string>
</dict></plist>
EOF

UIDN=$(id -u)
launchctl bootout "gui/$UIDN/$LABEL" 2>/dev/null || true
launchctl bootstrap "gui/$UIDN" "$LA/$LABEL.plist"
launchctl enable "gui/$UIDN/$LABEL"
echo "OK: exo-keepalive installed + loaded for $(whoami) (HOME=$USER_HOME)"
launchctl list | grep "$LABEL" || echo "WARN: not showing in launchctl list yet"

# 2. power resilience (needs sudo — will prompt)
echo "--- setting pmset autorestart + never-sleep (sudo) ---"
sudo pmset -a autorestart 1 sleep 0 disablesleep 1 && echo "OK: pmset autorestart=1, sleep=0" || echo "WARN: pmset needs sudo — run: sudo pmset -a autorestart 1 sleep 0"
echo "DONE. exo on $(hostname) will now auto-start on boot and respawn on crash."