Utoljára aktív 2 weeks ago Unlisted

Flujo de actualización de alloy: check-all, digest compare, policy apply, SSE (Episodio #834)

updates-flow.sh Eredeti
1#!/usr/bin/env bash
2# ═══════════════════════════════════════════════════════════════════════════
3# updates-flow.sh — Demo del flujo de actualización de alloy
4# Para el Episodio #834 — atareao con Linux
5# ═══════════════════════════════════════════════════════════════════════════
6# Muestra el flujo completo: check-all → digest compare → policy apply → SSE
7# ═══════════════════════════════════════════════════════════════════════════
8
9set -e
10
11VERDE='\033[0;32m'
12AMARILLO='\033[1;33m'
13AZUL='\033[0;34m'
14ROJO='\033[0;31m'
15GRIS='\033[0;90m'
16NC='\033[0m'
17
18echo -e "${AZUL}╔══════════════════════════════════════════════════════════════╗${NC}"
19echo -e "${AZUL}║ 🔄 alloy — Flujo de actualización ║${NC}"
20echo -e "${AZUL}║ Fase 1: Check (bloqueante, devuelve respuesta) ║${NC}"
21echo -e "${AZUL}║ Fase 2: Policy apply (background, SSE progress) ║${NC}"
22echo -e "${AZUL}╚══════════════════════════════════════════════════════════════╝${NC}"
23echo ""
24
25# ── Fase 1: Check ────────────────────────────────────────────────────────
26echo -e "${VERDE}═══ Fase 1: Check All ═══${NC}"
27echo ""
28echo -e "${GRIS}El backend:${NC}"
29echo " 1. Obtiene todos los contenedores (fetch_containers)"
30echo " 2. Para cada contenedor (en paralelo, semáforo 4 conexiones):"
31echo " a. Parsear referencia de imagen → (registry, repo, tag)"
32echo " b. Solicitar token Bearer a auth.docker.io"
33echo " c. Consultar manifest en registry-1.docker.io/v2/{repo}/manifests/{tag}"
34echo " d. Extraer config.digest del manifest"
35echo " e. Comparar short_digest(local) vs short_digest(remote)"
36echo " 3. Persistir has_update en SQLite"
37echo " 4. Construir lista de pendientes"
38echo " 5. Lanzar apply_policies_background en tokio::spawn"
39echo " 6. Devolver respuesta JSON con has_update flags"
40echo ""
41
42# ── Fase 2: Policy Apply ─────────────────────────────────────────────────
43echo -e "${VERDE}═══ Fase 2: Policy Apply (background) ═══${NC}"
44echo ""
45echo -e "${GRIS}Para cada contenedor pendiente:${NC}"
46echo ""
47echo " ┌─ [PullRestart] ──────────────────────────────────────────────┐"
48echo " │ 1. tag_backup_image() (si rollback_on_failure=true) │"
49echo " │ 2. pull_image() → docker.create_image() │"
50echo " │ 3. recreate_container() → stop + rename + create + start │"
51echo " │ 4. verify_container_healthy() (si rollback) │"
52echo " │ ├── OK → continue │"
53echo " │ └── FAIL → rollback_container() (restaurar imagen) │"
54echo " │ 5. cleanup_old_image() (si cleanup_old_image=true) │"
55echo " └──────────────────────────────────────────────────────────────┘"
56echo ""
57echo " ┌─ [PullRestartStack] ─────────────────────────────────────────┐"
58echo " │ 1. resolve_compose_file() → labels del contenedor │"
59echo " │ 2. docker compose -f <file> pull │"
60echo " │ 3. docker compose -f <file> up -d │"
61echo " └──────────────────────────────────────────────────────────────┘"
62echo ""
63echo " ┌─ [Pull] ─────────────────────────────────────────────────────┐"
64echo " │ 1. pull_image() → solo descargar, sin reiniciar │"
65echo " └──────────────────────────────────────────────────────────────┘"
66echo ""
67
68# ── Políticas ────────────────────────────────────────────────────────────
69echo -e "${VERDE}═══ Políticas de actualización ═══${NC}"
70echo ""
71printf " %-25s %s\n" "None" "No hacer nada"
72printf " %-25s %s\n" "Pull" "Solo descargar imagen"
73printf " %-25s %s\n" "PullRestart" "Descargar + reiniciar contenedor"
74printf " %-25s %s\n" "PullRestartStack" "Descargar + recrear stack completo"
75echo ""
76
77# ── Resolución de políticas ──────────────────────────────────────────────
78echo -e "${VERDE}═══ Resolución de políticas ═══${NC}"
79echo ""
80echo " 1. Se mira el label del contenedor (alloy_update_policy)"
81echo " 2. Si no tiene label, se busca en update_policies (SQLite)"
82echo " 3. Si no hay política específica, se usa la política global (settings)"
83echo " 4. PullRestartStack resuelve el archivo compose desde los labels:"
84echo " a. com.docker.compose.project → nombre del proyecto"
85echo " b. com.docker.compose.config.files → ruta al compose file"
86echo " c. com.docker.compose.working_dir → directorio del proyecto"
87echo ""
88
89# ── Rollback ─────────────────────────────────────────────────────────────
90echo -e "${VERDE}═══ Rollback automático ═══${NC}"
91echo ""
92echo -e "${GRIS}Si rollback_on_failure=true y el contenedor no arranca:${NC}"
93echo ""
94echo " 1. tag_backup_image() → etiqueta la imagen actual como backup"
95echo " 2. pull_image() → descarga la nueva imagen"
96echo " 3. recreate_container() → crea contenedor con nueva imagen"
97echo " 4. verify_container_healthy() → espera a que responda"
98echo " ├── OK → todo bien, cleanup de imagen anterior"
99echo " └── FAIL → rollback:"
100echo " ├── remove contenedor nuevo"
101echo " ├── restaurar nombre del backup"
102echo " ├── restart contenedor con imagen anterior"
103echo " └── notificar fallo"
104echo ""
105
106# ── SSE Progress ─────────────────────────────────────────────────────────
107echo -e "${VERDE}═══ SSE Progress (tiempo real) ═══${NC}"
108echo ""
109echo -e "${GRIS}Eventos emitidos durante el proceso:${NC}"
110echo ""
111echo " event: update-progress"
112echo " data: {\"container\":\"nginx\",\"status\":\"🔍 PullRestart\",\"done\":false}"
113echo ""
114echo " event: update-progress"
115echo " data: {\"container\":\"nginx\",\"status\":\"📥 Pulling...\",\"done\":false}"
116echo ""
117echo " event: update-progress"
118echo " data: {\"container\":\"nginx\",\"status\":\"✅ actualizado + reiniciado\",\"done\":true}"
119echo ""
120echo " event: notification"
121echo " data: {\"container\":\"nginx\",\"status\":\"🔄 actualizado\",\"timestamp\":\"2026-08-29T12:00:00Z\"}"
122echo ""
123
124# ── Comandos curl ────────────────────────────────────────────────────────
125echo -e "${VERDE}═══ Comandos para probar ═══${NC}"
126echo ""
127echo " # Check individual"
128echo " curl -X POST http://localhost:3066/api/check-update/nginx \\"
129echo " -H \"Cookie: session=TU_TOKEN\""
130echo ""
131echo " # Update individual"
132echo " curl -X POST http://localhost:3066/api/update/nginx \\"
133echo " -H \"Cookie: session=TU_TOKEN\""
134echo ""
135echo " # Check All (masivo)"
136echo " curl -X POST http://localhost:3066/api/check-all \\"
137echo " -H \"Cookie: session=TU_TOKEN\""
138echo ""
139echo " # SSE updates (tiempo real)"
140echo " curl -N http://localhost:3066/api/updates \\"
141echo " -H \"Cookie: session=TU_TOKEN\""
142echo ""
143echo " # Historial"
144echo " curl http://localhost:3066/api/history \\"
145echo " -H \"Cookie: session=TU_TOKEN\""
146echo ""