phase 4.5: notifications 3/3 relevees, backup+restauration photos prouves, double-run photos mesure, n8n mesure
This commit is contained in:
@@ -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**).
|
||||
@@ -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 |
|
||||
|
||||
@@ -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="")
|
||||
|
||||
Reference in New Issue
Block a user