Commit Graph
43 Commits
Author SHA1 Message Date
devopsandClaude Sonnet 5 f48860fcd8 fix(tmux-host): lanzar claude con --remote-control al recrear la sesion
Sin la flag, la sesion de tmux-host nunca queda visible como
controlable remotamente en claude.ai: remoteEnabled quedaba en false
porque nadie la pedia. Confirmado en vivo que --remote-control si
empareja (aparecio como sesion activa "zimaos-quizzical") mientras el
proceso se mantiene vivo.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:16:00 +00:00
devopsandClaude Sonnet 5 955eec6e75 fix(tmux-host): lanzar claude al recrear la sesion + backoff de arranque
check_tmux_session() recreaba la sesion tmux "lab" tras un reinicio del
NAS pero nunca lanzaba `claude` adentro -- quedaba un shell vacio hasta
que alguien entraba a mano. Confirmado en vivo tras un corte de luz real
(2026-09-19): la sesion SI se recreaba sola, pero Claude Code no.

Se agrega wait_for_workdir() con backoff (hasta 120s por defecto) antes
de tocar el log o crear la sesion, para el caso de un reinicio completo
del host donde /media/HDD-Storage puede tardar en montarse mas de lo
que tarda Docker en arrancar este contenedor -- antes eso fallaba en
silencio y ese arranque no dejaba rastro en el log.

Probado en un contenedor descartable aparte (tmux-host-test): stop+start
desde cero recreo la sesion con claude corriendo, sin intervencion.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-19 20:15:37 +00:00
devopsandClaude Sonnet 5 9d04c73b20 feat: bumpear APP_VERSION al promover a producción
Complementa el cambio en apps-registry (footer lee process.env.APP_VERSION
para mostrar la versión real desplegada) -- sin esto, promover a
Producción actualizaría la imagen pero dejaría el footer mostrando la
versión vieja.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_012Y4df3Z7odr9Cg8F2nw6uV
2026-09-14 04:04:17 +00:00
devopsandClaude Sonnet 5 3640cd5754 feat: script de promoción manual de Staging a Producción
Contraparte del cambio en apps-registry/.gitea/workflows/build.yaml:
desde ahora el CI solo actualiza Staging automáticamente en cada push.
Este script lee la versión actual en
workloads/ecommerce-staging/frontend/patches/deployment.yaml y la
aplica a workloads/ecommerce/frontend/patches/deployment.yaml (con
confirmación interactiva), commiteando y pusheando a apps-registry.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_012Y4df3Z7odr9Cg8F2nw6uV
2026-09-14 02:46:06 +00:00
devopsandClaude Sonnet 5 78b97bdd59 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
2026-09-06 17:16:41 +00:00
devops 40cb058fd4 Merge fix/lab-session-tmux-persistente into main
Merge local directo (sin PR de Gitea) por acuerdo del usuario; ver
feedback_git_fix_branches en memoria del proyecto para el porque de
este flujo estandar.
2026-08-27 22:18:47 -05:00
devops 0bf571cb93 feat: agrega lab-session.sh para reconectar a la sesion tmux persistente
Punto de entrada unico para adjuntarse (o crear si no existe) a la
sesion "lab" dentro del contenedor tmux-host, donde corre Claude Code
de forma persistente ante cortes de SSH/cambios de dispositivo.
2026-08-27 22:12:46 -05:00
devops acf7521990 Merge fix/adr0006-meilisearch-secrets into main 2026-08-26 15:00:07 -05:00
devops 9c0a111f82 create-commerce-secrets.sh: agregar MEILI_MASTER_KEY/MEILISEARCH_API_KEY
Fase 1 de la Etapa 2 del ADR 0006 (apps-registry): el StatefulSet de
Meilisearch lee MEILI_MASTER_KEY del secret commerce-secrets, y el
plugin de Medusa leera MEILISEARCH_API_KEY con el mismo valor (Fase 2,
distinto nombre de env var por cada lado, mismo secret).

Nota operativa: este script regenera el secret completo en cada
corrida (JWT_SECRET/COOKIE_SECRET/REVALIDATE_SECRET siempre nuevos).
Para aplicar SOLO estas dos claves nuevas al secret ya en uso en el
cluster real, no correr el script completo -- rotaria credenciales de
postgres/redis/minio ya activas. Se aplico via patch puntual al Secret
en vivo, fuera de este script, para esta vez.
2026-08-26 14:59:52 -05:00
devops 1f25869c4f Merge fix/lab-agent-follow-redirects into main 2026-08-26 13:33:26 -05:00
devops cef3dd3a28 lab-agent: follow redirects on public domain health checks
commerce.cruzcloud.net's root path now 301s to /app (Medusa admin) via
a Traefik Middleware — without -L the check reported a false 404 on an
otherwise healthy service. Generic fix (curl -L) instead of
hardcoding a per-domain path, since routing now owns the redirect.
2026-08-26 13:29:34 -05:00
devops 25276ad5b1 Merge branch 'fix/lab-agent-telegram-horario' into main
Notificaciones vía Telegram (reemplaza ntfy.sh), pausa nocturna
(06:00-23:00 hora local, con doble verificación script+systemd),
timer de systemd activado (cada 60 min, bajado de 15 para reducir
costo), formato con íconos + notificación silenciosa para info +
respuestas en hilo al recuperarse + log adjunto. Incluye el fix de
Environment=HOME= para systemd --user (el manager de devops arranca
con HOME=/DATA, no con el override de shell interactiva). Todo
validado en vivo antes de activar.
2026-08-26 00:29:02 -05:00
devops 09048dd772 Bajar frecuencia del timer a 60 min para reducir costo
OnCalendar cada 60 min en vez de 15 (06:00-22:00 hora local, 17
corridas/día en vez de 68). Aplicado en vivo: unidad actualizada,
timer reiniciado, próxima corrida confirmada vía
systemctl --user list-timers.
2026-08-26 00:27:53 -05:00
devops a2717e922a Activar timer: fix HOME= en la unidad, instrucciones de instalación
El manager de systemd --user de devops arranca con HOME=/DATA (el de
/etc/passwd), no /DATA/AppData/home-devops -- ese override solo se
aplica en una shell interactiva vía /etc/profile.d/zz-devops-home.sh,
que el manager de systemd nunca carga. Sin Environment=HOME=... en
lab-agent.service, claude -p habría buscado las credenciales en
/DATA/.claude/ (no existe) y fallado en cada corrida. Detectado y
corregido en vivo corriendo el servicio manualmente vía
systemctl --user start antes de habilitar el timer.

README documenta la instalación real: unidades en
/DATA/.config/systemd/user/ (no ~/.config/... de una shell
interactiva), loginctl enable-linger devops como único paso con sudo.

Timer activo desde 2026-08-26 (lab-agent.timer, cada 15 min,
06:00-23:00 hora local), tras confirmación explícita y ver el costo
mensual estimado.
2026-08-26 00:25:45 -05:00
devops cd163e6b7c Telegram: notificación silenciosa para info y respuestas en hilo
log() pasa a escribir en stderr (transparente, sigue yendo al mismo
RUN_LOG vía el "exec > tee 2>&1"): necesario para que notify_send
pueda devolver el message_id por stdout sin que un log() interno se
cuele en la captura -- mismo patrón de bug que ya se había corregido
en execute_corrective_action.

notify_send ahora acepta un reply_to_message_id opcional y manda
disable_notification=true para nivel "info" (ruido de rutina no debe
sonar; fallas/acciones/alertas de seguridad sí). Cuando ejecuta una
acción correctiva, el message_id enviado se guarda por recurso en
state.json (attach_telegram_message_id); si ese recurso se recupera
solo en una corrida posterior, compute_eligibility manda un aviso
silencioso como respuesta al mensaje original antes de limpiar el
estado -- agrupa visualmente todo un incidente en un hilo.

Validado en vivo con el canario desechable: acción real -> message_id
capturado en state.json -> parcheado a imagen sana -> reply en hilo
confirmado al recuperarse, silencioso.
2026-08-26 00:21:02 -05:00
devops c273056771 Notificaciones vía Telegram, pausa nocturna y unidades systemd
Reemplaza ntfy.sh por Telegram Bot API (preferencia del usuario, no
reduce el costo — el costo real es de la API de Claude/Sonnet, no del
canal). Texto plano sin parse_mode: el motivo que devuelve Claude es
texto libre y puede traer caracteres que rompen el parser Markdown de
Telegram. Token en TELEGRAM_BOT_TOKEN_FILE (dueño devops, no root-only
-- el servicio corre como devops por el login de suscripción, mismo
criterio ya aplicado a GITEA_TOKEN_FILE). Validado en vivo: entrega
confirmada con el mismo código de notify_send().

Agrega pausa nocturna (ACTIVE_HOURS_START/END, default 06:00-23:00
hora local) para no acumular costo de API sin necesidad: el script
chequea el horario ANTES de tocar kubectl/docker/curl o invocar
claude -p, no solo antes de notificar. Nota documentada: esta ventana
no se solapa con COMMERCE_BACKEND_WINDOW_* (00:00-06:00), por lo que
medusa-deploy queda efectivamente inalcanzable para auto-restart en la
práctica -- pendiente de decisión aparte.

Agrega unidades systemd de usuario (lab-agent/systemd/*.service,
*.timer) con límites de CPU/memoria: OnCalendar cada 15 min dentro del
horario activo, corre como devops (systemctl --user), sin habilitar
todavía -- requiere confirmación explícita tras ver el costo mensual
estimado (~US$60-65, documentado en agente-monitoreo.md).
2026-08-26 00:00:56 -05:00
devops 61a951f576 Merge branch 'fix/lab-agent-diagnostico-headless' into main
Agente headless de diagnóstico/corrección del lab (lab-agent), con
lista blanca aprobada, decisión de Claude sin acceso a herramientas
(claude -p --allowedTools "" + json-schema, el wrapper ejecuta y
revalida), y prueba end-to-end validada en vivo 2026-08-26.
2026-08-25 23:15:37 -05:00
devops ad53cff1e7 Rediseñar auth a login de suscripción y corregir bugs de la prueba e2e
Auth: ANTHROPIC_API_KEY_FILE queda vacío por defecto — claude -p usa el
login de suscripción ya activo (~/.claude/.credentials.json) en vez de
una API key root-only. Se descartó ese diseño en vivo al confirmar que
no había API key real disponible; además elimina la necesidad de crear
secretos root-only vía sudo. Consecuencia: el futuro servicio systemd
debe correr como devops, no root. CLAUDE_BIN/KUBECTL_BIN se agregan por
ruta absoluta (ninguno está en el PATH de root/systemd).

Bugs encontrados y corregidos durante la prueba end-to-end contra el
cluster real (deployment canario desechable):
- execute_corrective_action se invocaba en un subshell ($()), perdiendo
  sus variables de resultado (LAST_ACTION_*) -> crash "unbound
  variable". Ahora usa el exit status de la función, invocada directo.
- DRY_RUN marcaba blocked=true en state.json como si la acción hubiera
  sido real, contaminando una corrida real posterior sobre el mismo
  recurso. Ahora el estado solo se actualiza fuera de DRY_RUN.

También: GITEA_TOKEN_FILE pasa a /DATA (dueño devops, sin sudo), y
media.cruzcloud.net se excluye de PUBLIC_DOMAINS (uso personal, no es
parte del lab).

Prueba e2e completa documentada en apps-registry:
docs/arquitectura/agente-monitoreo.md.
2026-08-25 23:11:24 -05:00
devops 5c1cb3aa5e Agregar lab-agent: wrapper headless de diagnóstico/corrección (Paso 2)
Invoca claude -p con --allowedTools "" y --json-schema para que el
modelo solo devuelva una decisión estructurada, nunca ejecute comandos
directamente. Se descartó dar un Bash tool con patrón por prefijo tras
confirmar en vivo que --allowedTools "Bash(cmd)" también permite
"cmd && inyectado" (coincidencia por prefijo, no exacta) — inseguro
para comandos root-capaces como kubectl/docker. El wrapper bash es el
único ejecutor, y revalida cada decisión contra su propio cálculo de
elegibilidad (umbral 10min, rate limit 30min, ventana horaria para
medusa-deploy, bloqueo tras intento sin recuperación) antes de actuar.

Validado en vivo (dry-run) contra el cluster real hasta el paso de
invocar claude -p, que falla correctamente por falta del secreto
ANTHROPIC_API_KEY_FILE (no creado a propósito, ver README).
2026-08-25 22:18:31 -05:00
devops e08d03b7f4 Merge fix/migrate-legacy-collections-fase5-etapa2
Add script to migrate legacy collections + cybertron-sentinel category (Fase 5 Etapa 2 sub-fase 1).
2026-08-24 15:46:54 -05:00
devops 781bc459dd Add script to migrate legacy collections + cybertron-sentinel category
Documents and makes repeatable the Admin API writes for Fase 5 Etapa 2
sub-fase 1: assign real Medusa collections (Toy Story, Intensamente,
Lilo & Stitch, Universo Marvel, Reino de Frozen) to 9 legacy products,
and the missing "Figuras de accion" category to cybertron-sentinel.
Categories for the 17 legacy products were already correct and are
untouched.
2026-08-24 15:45:14 -05:00
devopsandClaude Sonnet 5 200a56de05 fix(k3s): ajustar MTU de flannel.1 a 1400 para eliminar blackhole PMTUD cross-node
Confirmado empiricamente: el limite real esta entre payload interno 1420
(OK) y 1450 (100% perdida sin ICMP, blackhole real). k3s no expone
--flannel-mtu en esta version, asi que se aplica en vivo sobre la interfaz
de cada nodo (no persiste en config, se reaplica en cada start/create).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_011FqYP3Wf1W63Qmh7qgXAAT
2026-08-16 23:00:37 -05:00
devops 208d307e5a fix(gitea-runner): limites de recursos reales para el runner
El contenedor gitea-runner se creaba sin ningun limite de CPU/memoria
(docker run plano), compitiendo directamente con gitea (que ademas
tenia cpu-shares=90, muy por debajo del default de Docker de 1024).

Causa raiz confirmada en vivo el 2026-08-15: durante un build pesado
de commerce-backend, tanto gitea como gitea-runner se reiniciaron
solos (ExitCode=0, RestartCount=0 en ambos -- restart limpio disparado
externamente, no un crash) coincidiendo con 502 Bad Gateway del runner
y memoria del host casi agotada. Mismo patron ya visto y documentado
en incidentes anteriores (2026-07-30, 2026-08-11).

Se agrega --cpu-shares 512 (menos prioridad relativa que gitea) y
--memory 8g / --memory-swap 10g al runner. El fix de cpu-shares de
gitea (90 -> 1024) va en docker-compose.yml, fuera de este repo -- no
tengo acceso de escritura root a ese archivo, queda para aplicar
manualmente.

Este cambio solo afecta a la proxima creacion del contenedor
(create_gitea_runner_container es idempotente); no se aplica solo al
contenedor que ya esta corriendo.
2026-08-15 15:02:01 -05:00
devops b11cb0384c Merge pull request 'feat: provisionar REVALIDATE_SECRET compartido entre Medusa y el storefront' (#2) from fix/revalidate-secret-scripts into main 2026-08-13 21:06:02 +00:00
devops 0a3cee288f feat: provisionar REVALIDATE_SECRET compartido entre Medusa y el storefront
Necesario para que el subscriber revalidate-storefront.ts (repo
apps-registry, rama fix/medusa-price-instant-revalidate) pueda llamar
a POST /api/revalidate en el storefront con autenticación.

create-commerce-secrets.sh genera el valor y lo imprime (única
excepción a "no imprimir credenciales") porque hay que pegarlo tal
cual en create-storefront-secret.sh: ambos secrets necesitan el mismo
valor.
2026-08-13 16:03:00 -05:00
devops 04dcab4bc3 Merge pull request 'fix(medusa): agregar sslmode=disable al DATABASE_URL generado' (#1) from fix/medusa-database-url-sslmode into main 2026-08-10 06:30:36 +00:00
devops 4078c66e1f fix(medusa): agregar sslmode=disable al DATABASE_URL generado
Postgres corre sin SSL configurado (imagen postgres:17-alpine estandar,
sin certificados). El cliente pg de Medusa intenta negociar SSL por
defecto al no encontrar sslmode explicito en la URL, lo que cuelga 10s
y hace fallar el initContainer migrations con CrashLoopBackOff.

Verificado con un pod efimero usando la imagen real de la app: con
sslmode=disable la migracion conecta al instante y corre exitosamente.
2026-08-09 02:04:06 -05:00
devops f27f07083c docs(playbooks): agregar playbook de fix repoURL http/https en apps-registry
Documenta el flujo reproducible ejecutado el 2026-08-09: deteccion de
inconsistencia, rama, commit, intento SSH fallido por proxy Cloudflare,
fallback a HTTPS con credential helper, push y merge del PR.
2026-08-09 00:51:11 -05:00
devops 920b9517f2 fase 1 2026-07-31 23:40:49 -05:00
devops 77780af646 Update deploy-lab.sh 2026-07-18 20:38:55 +00:00
devops 54d5e15b90 Upload files to "root" 2026-07-18 20:37:21 +00:00
devops 6acb4879aa Update README.md 2026-07-18 03:40:01 +00:00
devops fc9dfb9374 Update deploy-lab.sh 2026-07-18 03:39:35 +00:00
devops b2c6e28068 Update README.md 2026-07-18 01:04:35 +00:00
devops 62385a475b Update deploy-lab.sh 2026-07-18 01:03:47 +00:00
devops 6cf2191eb3 Update README.md 2026-07-17 13:56:11 +00:00
devops 5b1a63ab2e Update deploy-lab.sh 2026-07-17 13:55:35 +00:00
devops b047e5d543 Añadir README.md 2026-07-12 04:05:50 +00:00
devops c74aba7684 Actualizar deploy-lab.sh 2026-07-12 04:04:31 +00:00
devops 228bec84c6 Actualizar deploy-lab.sh 2026-07-12 03:48:26 +00:00
devops e72f764f22 Actualizar deploy-lab.sh 2026-07-12 03:47:15 +00:00
devops 0ebcafe010 Actualizar deploy-lab.sh 2026-07-12 02:44:05 +00:00
devops 677a3c45ef Añadir deploy-lab.sh
Persistencia Real: Al usar los volúmenes -v hacia /DATA/AppData/..., los datos de ArgoCD no desaparecerán nunca aunque borres el clúster.

Modo "Insecure": He automatizado el patch de server.insecure, eliminando la fricción con los certificados SSL de tu Nginx Proxy Manager.

Idempotencia: El script intenta borrar el clúster y recrearlo, asegurando que siempre partas de un estado limpio pero con tus datos intactos en el disco.

Recuperación automática: Al incluir el docker update --restart=always, si ZimaOS se reinicia, todos los componentes del clúster volverán a subir solos sin intervención manual.
2026-07-12 02:21:36 +00:00