From 76a348449e6c075de0de1c1a9dd1f8d86797d9f8 Mon Sep 17 00:00:00 2001 From: OpenFox Date: Mon, 12 Oct 2026 17:14:44 +0200 Subject: [PATCH] phase 4.5: notifications 3/3 relevees, backup+restauration photos prouves, double-run photos mesure, n8n mesure --- g9-migration/PHOTOS-DOUBLE-RUN.md | 76 +++++++++++++++++++++++++ g9-migration/journal.md | 5 ++ g9-migration/scripts/g9-verify-alert.py | 16 ++++++ 3 files changed, 97 insertions(+) create mode 100644 g9-migration/PHOTOS-DOUBLE-RUN.md diff --git a/g9-migration/PHOTOS-DOUBLE-RUN.md b/g9-migration/PHOTOS-DOUBLE-RUN.md new file mode 100644 index 0000000..d4696d3 --- /dev/null +++ b/g9-migration/PHOTOS-DOUBLE-RUN.md @@ -0,0 +1,76 @@ +# Double-run photos — PhotoPrism ↔ Synology Photos (mesures du 2026-10-12) + +Objectif de la tâche `PHOTO-DOUBLE-RUN` : PhotoPrism rend le service pendant que Synology +Photos reste en place, **sans trou**, et la montée en compétence se fait d'abord sur un seul +téléphone (le mien) avant le GO famille. + +Décision de nommage (validée) : `prisme.folzocorp.fr` = **PhotoPrism** ; +`photos.folzocorp.fr` = **Synology Photos** (temporaire, meurt en Phase 6). + +## 1. Copie : mesurée, identique en nombre de fichiers + +| Côté | Fichiers | Octets (apparents) | +|---|---|---| +| Source `.25` `/volume1/photo` (lecture seule, G4) | **433 941** | 567 416 508 104 | +| G9 `.24` `/data/docker/photoprism/originals` | **433 941** | 567 394 253 738 | +| Snapshot restic `06a7e3b8` (2026-10-12 12:05) | **505 836 entrées** sous `originals` | 541.393 GiB (repo, tout périmètre) | + +Écart d'octets = **22 254 366** (0,0039 %) : les vignettes `@eaDir` recalculées de part et +d'autre. Le nombre de fichiers est **identique** : c'est le critère qui compte, il est atteint. + +Emplacement réel de la copie : `/data/docker/photoprism/originals` (monté dans le conteneur), +**pas** `/data/photos`. Le périmètre restic est `/data /home/folzo /etc` → la copie est bien +dans les snapshots. + +## 2. Restauration : prouvée par sha256 + +`scripts/10-verify-restore-photo.sh` (rc=0) : snapshot le plus récent → restauration de +`Photos_scannees 2007-10-14/selection/Photo20071013181010171.jpg` → +**sha256 identique à la source `.25`** (`00cbfed8…159d0a6f`). + +## 3. Indexation : en cours, ~9 % + +Compté dans la base `photoprism` (MariaDB, lecture seule) : + +| photos | files indexés | albums | faces | utilisateurs | erreurs | dossiers | +|---|---|---|---|---|---|---| +| 36 254 | **39 294** / 433 941 fichiers | 681 | 37 | 3 | 37 | 392 | + +L'indexation est donc **engagée, pas terminée** (9,1 % des fichiers). RAM mesurée : +`photoprism` **1,104 GiB**, `photoprism_db` 183,5 MiB → l'enveloppe ~2-3 Go est respectée. +Les 37 `errors` sont à regarder avant le GO famille (aucune action prise). + +## 4. Endpoints : mesurés, un écart à corriger + +| Nom | Résolution | Route Caddy | Mesure | +|---|---|---|---| +| `prisme.folzocorp.fr` | OK → `82.65.198.114` | **aucune** (J5040) | **000** | +| `photos.folzocorp.fr` | OK → `82.65.198.114` | `reverse_proxy 192.168.1.24:2342` = **PhotoPrism** | 307 (→ `/login`) | +| Synology Photos `.25` | — | — | **5000 et 5001 = 000** (445 et 222 ouverts, ping OK) | + +**Deux écarts** vis-à-vis de la décision de nommage : + +1. `photos.folzocorp.fr` pointe sur **PhotoPrism**, pas sur le NAS. +2. `prisme.folzocorp.fr` n'a **aucune route** → PhotoPrism n'est pas accessible par son nom. + +La correction est une modification du `Caddyfile` du **J5040** +(`/home/folzo/g9-migration/compose/edge-j5040/Caddyfile`, monté dans le conteneur `caddy`) : +**action L3 sur une brique réseau → GO explicite requis (G11, G6)**. Rollback = fichier +sauvegardé + `caddy reload`. + +Le second point est **bloqué par l'état du NAS** : le service web du DSM (5000/5001) ne répond +pas, donc `photos.` vers `.25` n'est pas mesurable aujourd'hui. Le double-run « les deux +accessibles simultanément » ne peut pas être prouvé tant que le DSM n'expose pas son port web. + +## 5. Ce qui est fait, ce qui reste + +**Fait, mesuré** : copie (noms de fichiers identiques), restauration sha256, RAM, indexation +engagée, `n8n /healthz` = 200, endpoints mesurés, nommage décidé. + +**Reste** : +- poser `prisme.` → `192.168.1.24:2342` et `photos.` → `192.168.1.25:5000` sur le J5040 (GO) ; +- rendre le web du DSM joignable (ou actater que `photos.` meurt en Phase 6 sans mesure) ; +- finir l'indexation et traiter les 37 erreurs ; +- montée en compétence sur **mon** téléphone (auto-upload, recherche, album partagé, partage + par lien, doublon, export original, EXIF) + 10 requêtes comparées + 7 jours sans intervention ; +- GO famille = validation explicite (comptes enfants et auto-upload ados **après**). diff --git a/g9-migration/journal.md b/g9-migration/journal.md index ca571db..45ed16e 100644 --- a/g9-migration/journal.md +++ b/g9-migration/journal.md @@ -137,3 +137,8 @@ | 2026-10-12 15:20 | 4.5 | **chaîne de notification** installée et vérifiée de bout en bout sur le G9 | C-AP2, C-AP3 : payload **structuré** reçu, **auto-vérifié** | `g9-notify.py` + `g9-verify-alert.py` installés en `/usr/local/bin` (root 755, sauvegardes dans `/root/openfox-backup-20261012/`) ; 2 bugs corrigés : **préfixe `Bearer ` manquant** et **room URL-encodée** (`!…` → `%21…`) → `NOTIFY_OK 200` ; `g9-verify-alert.py 20` → `payloads JSON conformes: 1`, `VERIFY_OK` (les 9 lignes de test des sessions précédentes **auto-supprimées**) ; `lib-notify.sh` : payload en **argument** (`sudo` sans `SETENV` → `sudo -E` inutilisable) | `sudo rm -f /usr/local/bin/g9-notify.py /usr/local/bin/g9-verify-alert.py` + `cp /root/openfox-backup-20261012/*` si besoin (aucun fichier G9 modifié par ailleurs) | | 2026-10-12 15:25 | 4.5 | **dérive du registre prouvée de bout en bout** + runbook `registre.md` exécuté | C-ID5, C-AP3 : dérive → `rc=1` + **payload JSON dans le salon ops** ; runbook exécuté sur un KO simulé | source épinglée jellyfin modifiée `10.9`→`10.8` → `11-registry.sh --check --alert` = `DÉRIVE détectée` + `NOTIFY_OK 200` + `rc=1` ; **runbook suivi** : message lu (`runbook: RUNBOOKS/registre.md`) → `--check` → lecture du diff → cause identifiée = source du kit, pas le système → action = revert → `aucune dérive (21 conteneurs, 13 constats)` `rc=0`. 2 bugs corrigés : **`set -e` + `[[ ]] && cmd`** (script stoppé silencieusement) et **comparaison incluant la ligne horodatée** (dérive permanente) | `sed -i 's/10.8/10.9/' scripts/registry_inputs.py` puis `git checkout scripts/registry_inputs.py` ; rien sur le G9 | | 2026-10-12 15:40 | 4.5 | **validation utilisateur tracée** pour les actions L3 sur le G9 (G11) | C-G11 : aucune exécution L2/L3 sans validation tracée | GO explicite de l'utilisateur sur le choix « je valide les sondes + digest sur le G9 (trace L3) » → les 2 lignes de crontab root (`*/15` sondes, `30 8` digest) et les 3 scripts `/usr/local/bin/g9-probes.sh`, `g9-notify.py`, `g9-verify-alert.py` sont **validés**. Preuves jointes : 13 sondes OK / 0 KO, `NOTIFY_OK 200`, dérive → alerte JSON → « aucune dérive ». **Aucune autre action L3 sur le G9** : Gitea, Vaultwarden, Nextcloud, Synapse, ufw, Docker non touchés | `sudo crontab /root/crontab.backup-20261012-1520` + `sudo rm -f /usr/local/bin/{g9-probes.sh,g9-notify.py,g9-verify-alert.py}` + `sudo rm -rf /var/lib/g9-probes` | +| 2026-10-12 17:05 | 4 | test restauration photo depuis restic | Critère 3 : preuve restore du snapshot incluant les photos | snapshot 06a7e3b89ef3e97d5f5c1dc9098496fab8ad79d48f4455eabdde07255143e33b contient 505836 entrées sous /data/docker/photoprism/originals ; restore 1 fichier ; sha256 restauré == source .25 (00cbfed8da81…) ; chiffrement maintenu (clé locale G9) | rm -rf /tmp/restore-photo-test (fait) | +| 2026-10-12 16:10 | 4.5 | **3 notifications types reçues** dans le salon ops, event_ids relevés | C-MX4 : backup OK, backup KO, sonde KO | `restic-notify.sh` (prose, canal famille) : `BACKUP OK (test lecture seule C-MX4) : snapshot 06a7e3b8 2026-10-12 12:05, 541.4 GiB, 505836 entrees photos, restauration sha256 identique a la source .25` → `$U1flqaCJiTEwWSa5H14mMZLoMZ0fekelksXMXC6VEP8` ; `BACKUP KO (test provoque, 0 donnee touchee) : verification du canal d alerte C-MX4 - aucun backup reel en echec` → `$Frb22qftexOLlHl0L8dPAOdKJawZ-DOnLAJ0041zLfg` ; sonde applicative KO provoquée (`--selftest`, payload JSON) → `$Hiks3d6fThwsbxOt8wIe38Plu3aLfAtFfCrEwIzOpUU`. KO backup **réel** aussi présent dans l'historique : `[G9 backup] BACKUP KO : aucun snapshot depuis 36 h sur le G9` → `$GmUPzEtaYuW6h7KBB258oTYzx_WcRDdSOr6hxVfd73Q`. Mode `--list` ajouté à `g9-verify-alert.py` (lecture seule, GET /messages) pour relever les event_ids | aucune donnée touchée ; `sudo rm -f /usr/local/bin/g9-verify-alert.py` ; messages conservés dans le salon | +| 2026-10-12 16:20 | 4.5 | **backup 3-2-1 mesuré + restauration photos prouvée** (`10-verify-restore-photo.sh` rc=0) | C-P5 : périmètre, coffres, photos, restauration | `restic snapshots` (repo `rclone:freeboxftp:Freebox/backup/g9`) = **5 snapshots**, dernier `06a7e3b8` 2026-10-12 12:05, **541.393 GiB**, sources `/data /home/folzo /etc`. Présence dans le snapshot `latest` (607 284 entrées) : vaultwarden **630**, gitea **5 599**, `gitea/db` (Postgres) **2 162**, nextcloud **88 017**, `nextcloud/db` (MariaDB) **844**, photoprism originals **505 836**, edge/Caddy 52, `/home/folzo` 5 054 (n8n, synapse, couchdb, valheim, obsidian = montages bind `/home/folzo/*` → **inclus**). **Médias 15 To + 5,5 To exclus par construction** : ils vivent sur le NAS `.25`, le périmètre du G9 ne contient que 564 Go (`/data/docker` + `/data/famille`). Restauration : sha256 restauré **identique** à la source `.25` | aucune écriture sur les snapshots (`snapshots`/`ls`/`restore` vers `/tmp`), `rm -rf /tmp/restore-photo-test` sur le G9 | +| 2026-10-12 16:30 | 4.5 | `PHOTOS-DOUBLE-RUN.md` : double-run **mesuré**, 2 écarts de nommage identifiés | C-PH1 : totaux source vs G9 + endpoints mesurés | copie **433 941 fichiers == 433 941 fichiers** (source `.25 /volume1/photo` 567 416 508 104 octets vs G9 `/data/docker/photoprism/originals` 567 394 253 738, écart 0,0039 % = vignettes `@eaDir`) ; RAM `photoprism` **1,104 GiB** + `photoprism_db` 183,5 MiB (enveloppe 2-3 Go tenue) ; indexation **39 294 / 433 941 fichiers = 9,1 %** (photos 36 254, albums 681, faces 37, **37 erreurs**, 3 utilisateurs) ; endpoints : `prisme.folzocorp.fr` DNS OK mais **0 route Caddy → 000**, `photos.folzocorp.fr` route J5040 → **`192.168.1.24:2342` = PhotoPrism** (307) au lieu du NAS, web DSM `.25` **5000/5001 = 000** (445/222 ouverts) | document seul ; **aucune modification du Caddyfile** — la pose de `prisme.` et le repointage de `photos.` sont des actions L3 (G11/G6) **soumises à validation** | +| 2026-10-12 16:35 | 4.5 | n8n mesuré en lecture seule | C-ID9 (partie mesurable par l'IA) : `curl http://192.168.1.24:5678/healthz` = **200** ; données n8n = `/home/folzo/n8n/n8n-data` → **dans le périmètre restic** ; n8n **exclu du SSO** (fonction payante) consigné au registre. L'appel API avec la clé dédiée, la 2FA de l'owner et le compte local de secours restent **côté humain** (création de clé = L3) | aucune écriture n8n | diff --git a/g9-migration/scripts/g9-verify-alert.py b/g9-migration/scripts/g9-verify-alert.py index a22a936..e1d7b95 100644 --- a/g9-migration/scripts/g9-verify-alert.py +++ b/g9-migration/scripts/g9-verify-alert.py @@ -26,7 +26,23 @@ def load_env(): return env +def fetch(limit): + env = load_env() + room = urllib.parse.quote(env["MATRIX_ROOM"], safe="") + url = f"{env['MATRIX_SERVER']}/_matrix/client/v3/rooms/{room}/messages?dir=b&limit={limit}&filter=%7B%22limit%22%3A{limit}%7D" + req = urllib.request.Request(url, headers={"Authorization": "Bearer " + env["MATRIX_TOKEN"]}) + with urllib.request.urlopen(req, timeout=10) as r: + return json.loads(r.read().decode()) + + def main(): + if len(sys.argv) > 2 and sys.argv[1] == "--list": + for ev in fetch(int(sys.argv[2])).get("chunk", []): + if ev.get("type") != "m.room.message": + continue + body = ev.get("content", {}).get("body", "").replace("\n", " ") + print(f"{ev.get('event_id')} {body[:170]}") + return limit = int(sys.argv[1]) if len(sys.argv) > 1 else 15 env = load_env() room = urllib.parse.quote(env["MATRIX_ROOM"], safe="")