Consola de mantenimiento y coordinación eléctrica — 2026-10-19¶
Autorización: aplicar las prioridades de review-next-20261019.md, con agentes.
Fuente consola ~/Dev/homelab-maint; runtime CT212 /opt/homelab-maint.
No se han ejecutado apagados, evacuaciones, reinicios de nodos, cortes Meross,
pruebas de batería ni cambios de estado HA para probar estos cambios.
Aplicado en consola¶
- Timeout cubre consumo de stdout y espera del proceso. Al vencer o abortar, termina el grupo local, escala a SIGKILL y recoge el proceso. Se advierte que una operación remota que ya arrancó exige comprobar su estado remoto.
- Exclusión mutua de tareas; no se pueden ejecutar transiciones simultáneas.
- Transiciones L1–L4 fallidas conservan el último nivel confirmado y muestran
CAMBIO PARCIAL/FALLIDOen la UI ytransition.status=partial_or_faileden API. La transición exige el nivel de origen correcto. - Preflight L1 antes de cualquier mutación: Vera, Alertmanager CT217, Docker VM208 y los tres schedulers RunWisp accesibles.
- Silencios dirigidos al propietario CT217, con autor propio
homelab-maint; la salida sólo expira silencios de ese autor. Ya no expira todos los silencios. - Fallos de RunWisp y de las llamadas a HA dejan de quedar ocultos por
echo. Pausar escritores que están corriendo propaga el error real dedocker pause. - Evacuación pmx51 comprueba quórum, afinidades estrictas y memoria antes de tocar flags o HA. Usa límites configurados y reserva de 2 GiB; no presupone recuperación balloon. El timeout de vaciado ahora falla explícitamente.
- Reinicio local es una operación distinta: exige
shutdown_policy=conditional; indica interrupción local de servicios estrictos, sin prometer evacuación. - Salir de evacuación respeta
failbackindividual; ya no espera que HAOS y todos los recursos vuelvan forzosamente a pmx51. - Despliegue falla si la API no responde o está malformada; no interpreta error como cero tareas. Guarda rollback y copia sólo fuentes explícitas, sin borrar estado, logs, virtualenv ni ficheros runtime desconocidos.
Despliegue: API running=[], código original comparado con fuente, snapshot
/opt/homelab-maint-rollback-20261019T*, copia selectiva y reinicio sólo consola.
Después: API accesible, running=[], nivel L0. No se sobrescribieron state/logs.
Validación: cinco pruebas locales aisladas (éxito, timeout con salida, timeout
silencioso, aborto y guardas de afinidad/capacidad) correctas. El PID del proceso
terminado deja de existir. Sintaxis Python/YAML y diff sin errores.
Preflight L1 real y reinicio-local reales pasan, ambos sólo lectura. Preflight
real evacuación termina rc1 con ct:110,ct:172,ct:217,ct:218 estrictos, antes de
mutaciones. No se pulsaron las acciones de mantenimiento para verificarlo.
SAI: evidencia adicional y límite de activación¶
El código Proxmox instalado (PVE/HA/LRM.pm) confirma que conditional congela
HA al reiniciar, pero permite failover al apagar. Paralelizar pct/qm conservando
el script viejo no basta: podría competir con HA. Existe también la operación
nativa ha-manager crm-command disarm-ha freeze|ignore y arm-ha, que tampoco
se ha ejecutado porque requiere una recuperación coordinada del armado.
NUT tiene NOTIFYCMD upssched, pero NOTIFYFLAG ONLINE sólo SYSLOG+WALL y no EXEC;
no hay hook ONLINE activo para restaurar una política temporal. Cambiar a freeze
sin restauración comprobada modificaría el comportamiento normal tras el corte.
El role power_safety tampoco gestiona actualmente shutdown_policy.
Meross usa /config/packages/pmx50_autorrecuperacion.yaml: sólo consulta el boolean
local, conectividad y límite temporal, sin comprobar bandera de mantenimiento ni
NUT. No se ha activado un apagado nuevo hasta coordinar también esa guarda.
Los MCP HA de escritura/servicios y hab no están expuestos en esta sesión. Las
instrucciones de /config/AGENTS.md requieren write_config_safe y call_service,
y prohíben sustituirlos por shell cuando el perfil no los expone. No se han leído
secretos ni estado interno HA.
Propuesta de activación pendiente: inhibir autoencendido y Meross antes de operar,
serializar cambio de política, conservar conditional y demás propiedades HA,
establecer freeze sólo durante parada por energía, delegar la parada a LRM y
pve-guests, y restaurar conditional únicamente con estado OL verificable y
reconciliación del peer. Debe soportar primario caído, quorum ausente, doble
notificación y pérdida de alimentación durante la restauración. No convertir
desired=started a stopped persistentemente. No se ha ensayado autonomía ni
acreditado protección física de los dos NAS.
Guardas eléctricas independientes aplicadas después¶
Sin cambiar NUT, HA ni Meross:
bin/maintenance-preflight powerofflee el boolean de autorrecuperación por API y comprueba ambos flags. Si Meross no está explícitamente off o la lectura falla, bloquea la parada intencionada. Insertado antes dep51-poweroff. Prueba read-only actual: rc1 por Meross on, sin cambiar el boolean ni flags.node-autowake.shahora bloquea WoL cuando NUT confirma OB/LB/FSD o existe/run/ups-shutdown-in-progress, además del flag persistente de mantenimiento. Si NUT no responde o el primario está caído, conserva la recuperación previa: impedir WoL en ese caso anularía la recuperación de pmx50, que aloja NUT. No permite inferir energía segura cuando NUT está desconocido; la coordinación Meross/SAI completa sigue pendiente. El nuevo flag de apagado está preparado para un futuro coordinador; el SHUTDOWNCMD actual aún no lo establece.- Template de power_safety y ambos runtimes sincronizados mediante inserción
acotada, sin regenerar ni sobrescribir otras líneas. Rollback en cada nodo:
/usr/local/bin/node-autowake.sh.pre-energy-guard-20261019. - Ocho fixtures aisladas correctas: OL, desconocido y fallo del primario
conservan WoL simulado; OB, LB, FSD, bandera manual y bandera de apagado
lo impiden. Los mocks
sustituyen ping, upsc y etherwake; no hubo paquete WoL real ni consulta de
batería como prueba de corte.
bash -ncorrecto en ambos nodos.
Total de pruebas de esta actuación: 5 consola + 8 autowake = 13 correctas. La secuencia nueva de apagado UPS queda sin activar por la dependencia Meross pendiente y la restauración freeze/conditional aún no acreditada. El script SHUTDOWNCMD sigue siendo el anterior; estas guardas no lo sustituyen.