feat(tmux-host): Dockerfile con WORKDIR fijo + healthcheck cada 30 min
Reemplaza el docker run inline (alpine sh -c "apk add ...") por una imagen construida desde scripts/tmux-host/Dockerfile, con WORKDIR en la raiz del lab para que docker exec y lab-session.sh ya arranquen posicionados ahi sin cd manual. Agrega scripts/tmux-host/healthcheck.sh (via entrypoint.sh, background del propio contenedor): cada 30 min chequea conectividad real (curl a gitea.cruzcloud.net) y la existencia de la sesion tmux "lab". La red solo se loguea+notifica por Telegram (nunca se intenta corregir desde el contenedor); la sesion tmux si se recrea sola si falta. Log persistente en /DATA/AppData/k3d-lab-v3/tmux-host/logs/health.log. Reusa el bot/chat_id de Telegram ya configurado en scripts/lab-agent/. Validado en un contenedor descartable (tmux-host-test, intervalo de 60s): confirmado WORKDIR correcto via docker exec, creacion inicial de la sesion y recreacion automatica tras un kill-session manual. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_012xyPak6HWFmBCqXrvFsejL
This commit is contained in:
1 parent
40cb058fd4
commit
78b97bdd59
4 files changed
+132
-1
No files matched your search
Executable
+94
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env bash
|
||||
# Chequeo de salud de tmux-host, corre en background dentro del propio
|
||||
# contenedor (ver entrypoint.sh). Cada HEALTHCHECK_INTERVAL_SEC (30 min
|
||||
# por defecto):
|
||||
#
|
||||
# a) Conectividad de red real (curl a gitea.cruzcloud.net). Si falla,
|
||||
# SOLO se registra en el log y se notifica por Telegram (si el canal
|
||||
# del lab-agent ya esta configurado) -- nunca se intenta "arreglar"
|
||||
# la red del host desde aca, eso puede ser un problema de
|
||||
# hardware/BIOS fuera del alcance del contenedor.
|
||||
# b) Existencia de la sesion tmux "lab". Si no existe (crash, o el
|
||||
# contenedor se acaba de recrear), SI se recrea automaticamente --
|
||||
# es solo recuperar el propio entorno de trabajo, no tocar
|
||||
# infraestructura externa.
|
||||
#
|
||||
# Todo evento (chequeo ok, falla, accion tomada) queda en LOG_FILE, que
|
||||
# vive bajo /DATA (persistente, sobrevive a recrear el contenedor) y no
|
||||
# solo en el stdout del contenedor.
|
||||
#
|
||||
# set -u sin 'e': un check individual que falle no debe matar el loop
|
||||
# completo -- el siguiente ciclo tiene que seguir corriendo igual.
|
||||
set -uo pipefail
|
||||
|
||||
WORKDIR="/DATA/AppData/k3d-lab-v3/lab-cruzcloud"
|
||||
SESSION="lab"
|
||||
LOG_DIR="/DATA/AppData/k3d-lab-v3/tmux-host/logs"
|
||||
LOG_FILE="${LOG_DIR}/health.log"
|
||||
# Reusa el mismo canal de Telegram que ya configuro scripts/lab-agent/ --
|
||||
# una sola fuente de verdad para el bot token / chat id, en vez de
|
||||
# duplicar credenciales entre los dos agentes del lab.
|
||||
LAB_AGENT_ENV="${WORKDIR}/scripts/lab-agent/lab-agent.env"
|
||||
NETWORK_CHECK_URL="https://gitea.cruzcloud.net/"
|
||||
INTERVAL_SEC="${HEALTHCHECK_INTERVAL_SEC:-1800}"
|
||||
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
log() {
|
||||
echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
notify_telegram() {
|
||||
local title="$1" message="$2"
|
||||
if [[ ! -f "$LAB_AGENT_ENV" ]]; then
|
||||
log "NOTIFY omitida: no existe ${LAB_AGENT_ENV}"
|
||||
return 0
|
||||
fi
|
||||
local token_file chat_id token resp
|
||||
token_file="$(grep -E '^TELEGRAM_BOT_TOKEN_FILE=' "$LAB_AGENT_ENV" | cut -d= -f2-)"
|
||||
chat_id="$(grep -E '^TELEGRAM_CHAT_ID=' "$LAB_AGENT_ENV" | cut -d= -f2-)"
|
||||
if [[ -z "$token_file" || ! -r "$token_file" || -z "$chat_id" ]]; then
|
||||
log "NOTIFY omitida: canal de Telegram del lab-agent no esta configurado todavia"
|
||||
return 0
|
||||
fi
|
||||
token="$(<"$token_file")"
|
||||
resp="$(curl -s -m 10 -X POST "https://api.telegram.org/bot${token}/sendMessage" \
|
||||
--data-urlencode "chat_id=${chat_id}" \
|
||||
--data-urlencode "text=🤖 tmux-host healthcheck
|
||||
${title}
|
||||
──────────────
|
||||
${message}" 2>&1)"
|
||||
token=""
|
||||
[[ "$resp" == *'"ok":true'* ]] || log "WARN: fallo al notificar por Telegram: ${resp}"
|
||||
}
|
||||
|
||||
check_network() {
|
||||
local code
|
||||
code="$(curl -sL -o /dev/null -w '%{http_code}' --max-time 10 "$NETWORK_CHECK_URL" 2>/dev/null || echo "000")"
|
||||
if [[ "$code" == "000" ]]; then
|
||||
log "RED: sin conectividad real (curl ${NETWORK_CHECK_URL} sin respuesta). No se intenta corregir desde el contenedor."
|
||||
notify_telegram "Sin conectividad" "curl ${NETWORK_CHECK_URL} no respondio desde tmux-host (posible falla de red del host/NAS, ej. hardware/BIOS). El contenedor NO intenta corregir esto, solo lo registra."
|
||||
else
|
||||
log "RED: ok (curl ${NETWORK_CHECK_URL} -> HTTP ${code})"
|
||||
fi
|
||||
}
|
||||
|
||||
check_tmux_session() {
|
||||
if tmux has-session -t "$SESSION" 2>/dev/null; then
|
||||
log "TMUX: sesion '${SESSION}' ok"
|
||||
return
|
||||
fi
|
||||
log "TMUX: sesion '${SESSION}' no existe -- recreando en ${WORKDIR}"
|
||||
if tmux new-session -d -s "$SESSION" -c "$WORKDIR" 2>>"$LOG_FILE"; then
|
||||
log "TMUX: sesion '${SESSION}' recreada exitosamente"
|
||||
else
|
||||
log "TMUX: ERROR al recrear la sesion '${SESSION}'"
|
||||
fi
|
||||
}
|
||||
|
||||
log "=== healthcheck inicio (intervalo=${INTERVAL_SEC}s) ==="
|
||||
while true; do
|
||||
check_network
|
||||
check_tmux_session
|
||||
sleep "$INTERVAL_SEC"
|
||||
done
|
||||
Reference in new issue
Block a user