Livraison continue : page Svelte embarquée, le PC et le 108 se posent après chaque fusion #5

Merged
hermes-fusion merged 6 commits from hermes/paquets-services-deploiement into main 2026-10-16 23:00:02 +02:00
Collaborator

Ce que la carte demande : que la page Svelte embarquée soit servie par pcmirror-serveur,
et que les deux cibles (le PC, le LXC 108) se posent après chaque fusion dans main.

Ce qui est dans cette branche

Le service sert la page du binaire. crates/pcmirror-serveur/build.rs engendre une table
en mémoire depuis frontend/dist (elle est vide et le dit si la page n'a pas été construite).
PCMIRROR_FRONT choisit l'origine : reference (défaut, les pages copiées du service Python)
ou embarque. En mode embarqué, le repli est celui d'une application monopage : tout chemin
inconnu hors API rend index.html ; un chemin d'API inconnu rend 404 ; un binaire sans page
embarquée alors qu'on la lui demande rend 503 en le disant.

La livraison. deploy/deploy.sh livre une cible à la fois : elle construit
(cargo build --release --locked, plus la page Svelte pour le 108), pose le binaire et ses
unités, puis joue deploy/controle-sante.sh. Santé mauvaise : retour arrière automatique sur
<binaire>.precedent et sortie en échec. --a-blanc dit tout ce qu'elle ferait sans rien
toucher, --retour remet la version précédente à la demande. Le PC se livre sur place
(--transport local, l'exécutant pc-lourd est le PC), le 108 par le nœud Proxmox
(--transport pve, pct, secret CLE_PVE).

Ce qui se voit. .forgejo/workflows/livraison.yml suit chaque poussée sur main :
essai à blanc, puis le PC, puis le 108 ; l'issue « Livraison PC Mirror en échec » s'ouvre ou se
commente avec l'étape, la cause, le journal et la capture, et se ferme d'elle-même à la
première livraison réussie (deploy/signalement.py).

Un correctif au passage. Le repli de la page ne refusait le retour que dans sa forme nue
(..) : /assets/..%2f.. recevait index.html. Le test existait et ne mesurait rien tant
qu'aucune page n'était construite ; il échoue depuis que la page est embarquée (commit 2 le
nomme et le corrige).

Preuves mesurées

cargo test --release --locked
test result: ok. 58 passed; 0 failed   (pcmirror, unittests)
test result: ok. 10 passed; 0 failed   (pcmirror, tests/passe_complete.rs)
test result: ok. 116 passed; 0 failed  (pcmirror-serveur, unittests)
test result: ok. 8 passed; 0 failed    (pcmirror-serveur, tests/parite_reference.rs)

cargo build --release --locked : 0 avertissement sur la recompilation des deux crates.

L'essai de livraison, dans un bac à sable de /tmp (aucune cible touchée) :

deploy/essais/essai-deploy.sh
bilan : 39 réussis, 0 échoués

Le contrôle de santé joué contre le binaire construit, page construite :

PCMIRROR_FRONT=embarque ./target/release/pcmirror-serveur
/                        -> 200, page porte le marqueur id="app"
/miroir                  -> 200  (repli monopage)
/assets/index-*.js       -> 200  (fichier embarqué)
/api/rien                -> 404
/json                    -> 200
avec --path-as-is : /assets/..%2f.. -> 404, /%2e%2e/%2e%2e/etc/passwd -> 404

sans PCMIRROR_FRONT (les pages de référence, comme le service Python) : / rend 20 609
octets, /api/rien rend 200 — le service Python se sert sur tout chemin, et le contrôle de
santé compare donc à ce que la cible sert vraiment.

Binaire dont la page n'a pas été construite, PCMIRROR_FRONT=embarque : / rend 503 avec
une page « PC Mirror — page absente », /json rend toujours 200, /api/rien 404.

Ce qui n'est pas mesuré

  • La livraison réelle vers le PC et le 108 : elle demande le secret CLE_PVE et les cibles.
    Rien n'a été posé, rien n'a été déployé.
  • shellcheck sur l'exécutant : l'étape de CI dit qu'elle saute le contrôle s'il est absent,
    comme le fait déjà la couverture Rust.
  • loginctl enable-linger stephane sur le PC reste un geste d'administration, hors livraison
    (sans lui, le minuteur s'arrête à la fermeture de session).

Ce que le chef doit prévenir

Rien pour svelte : aucun champ d'API n'a changé. La page Svelte n'a pas été touchée ; c'est
le service qui a appris à la servir. Les seules nouveautés visibles sont des variables
d'environnement du service (PCMIRROR_FRONT) et des fichiers de livraison.

À poser une fois (ops)

  • le secret Forgejo CLE_PVE (clé privée autorisée sur root@192.168.1.60) ;
  • l'unité et la clé sur le 108 neuf, loginctl enable-linger stephane sur le PC.
Ce que la carte demande : que la page Svelte embarquée soit servie par `pcmirror-serveur`, et que les deux cibles (le PC, le LXC 108) se posent après chaque fusion dans `main`. ## Ce qui est dans cette branche **Le service sert la page du binaire.** `crates/pcmirror-serveur/build.rs` engendre une table en mémoire depuis `frontend/dist` (elle est vide et le dit si la page n'a pas été construite). `PCMIRROR_FRONT` choisit l'origine : `reference` (défaut, les pages copiées du service Python) ou `embarque`. En mode embarqué, le repli est celui d'une application monopage : tout chemin inconnu hors API rend `index.html` ; un chemin d'API inconnu rend 404 ; un binaire sans page embarquée alors qu'on la lui demande rend 503 en le disant. **La livraison.** `deploy/deploy.sh` livre une cible à la fois : elle construit (`cargo build --release --locked`, plus la page Svelte pour le 108), pose le binaire et ses unités, puis joue `deploy/controle-sante.sh`. Santé mauvaise : retour arrière automatique sur `<binaire>.precedent` et sortie en échec. `--a-blanc` dit tout ce qu'elle ferait sans rien toucher, `--retour` remet la version précédente à la demande. Le PC se livre sur place (`--transport local`, l'exécutant `pc-lourd` est le PC), le 108 par le nœud Proxmox (`--transport pve`, `pct`, secret `CLE_PVE`). **Ce qui se voit.** `.forgejo/workflows/livraison.yml` suit chaque poussée sur `main` : essai à blanc, puis le PC, puis le 108 ; l'issue « Livraison PC Mirror en échec » s'ouvre ou se commente avec l'étape, la cause, le journal et la capture, et se ferme d'elle-même à la première livraison réussie (`deploy/signalement.py`). **Un correctif au passage.** Le repli de la page ne refusait le retour que dans sa forme nue (`..`) : `/assets/..%2f..` recevait `index.html`. Le test existait et ne mesurait rien tant qu'aucune page n'était construite ; il échoue depuis que la page est embarquée (commit 2 le nomme et le corrige). ## Preuves mesurées cargo test --release --locked test result: ok. 58 passed; 0 failed (pcmirror, unittests) test result: ok. 10 passed; 0 failed (pcmirror, tests/passe_complete.rs) test result: ok. 116 passed; 0 failed (pcmirror-serveur, unittests) test result: ok. 8 passed; 0 failed (pcmirror-serveur, tests/parite_reference.rs) `cargo build --release --locked` : 0 avertissement sur la recompilation des deux crates. L'essai de livraison, dans un bac à sable de `/tmp` (aucune cible touchée) : deploy/essais/essai-deploy.sh bilan : 39 réussis, 0 échoués Le contrôle de santé joué contre le binaire construit, page construite : PCMIRROR_FRONT=embarque ./target/release/pcmirror-serveur / -> 200, page porte le marqueur id="app" /miroir -> 200 (repli monopage) /assets/index-*.js -> 200 (fichier embarqué) /api/rien -> 404 /json -> 200 avec --path-as-is : /assets/..%2f.. -> 404, /%2e%2e/%2e%2e/etc/passwd -> 404 sans `PCMIRROR_FRONT` (les pages de référence, comme le service Python) : `/` rend 20 609 octets, `/api/rien` rend 200 — le service Python se sert sur tout chemin, et le contrôle de santé compare donc à ce que la cible sert vraiment. Binaire dont la page n'a pas été construite, `PCMIRROR_FRONT=embarque` : `/` rend 503 avec une page « PC Mirror — page absente », `/json` rend toujours 200, `/api/rien` 404. ## Ce qui n'est pas mesuré - La livraison réelle vers le PC et le 108 : elle demande le secret `CLE_PVE` et les cibles. Rien n'a été posé, rien n'a été déployé. - `shellcheck` sur l'exécutant : l'étape de CI dit qu'elle saute le contrôle s'il est absent, comme le fait déjà la couverture Rust. - `loginctl enable-linger stephane` sur le PC reste un geste d'administration, hors livraison (sans lui, le minuteur s'arrête à la fermeture de session). ## Ce que le chef doit prévenir Rien pour `svelte` : aucun champ d'API n'a changé. La page Svelte n'a pas été touchée ; c'est le service qui a appris à la servir. Les seules nouveautés visibles sont des variables d'environnement du service (`PCMIRROR_FRONT`) et des fichiers de livraison. ## À poser une fois (ops) - le secret Forgejo `CLE_PVE` (clé privée autorisée sur `root@192.168.1.60`) ; - l'unité et la clé sur le 108 neuf, `loginctl enable-linger stephane` sur le PC.
19 sondages contre le serveur d'état du LXC 108 (codes, en-têtes, corps), la
copie de référence du script de synchro déployé, ses unités systemd, la ligne
de cron périmée et les fichiers de télémétrie lus dans le miroir.

Ajoute capturer.sh (rejoue la capture, en lecture seule) et
verifier_contrat.py (20 contrôles du contrat du serveur vivant).
Documente pcmirror-sync.sh tel qu'il tourne (sources, exclusions, options
rsync, verrou, garde-fous, journaux, codes de sortie, minuteur systemd horaire
à la place du cron périmé, télémétrie, mode restauration) et chaque route de
status-server/server.py avec les fichiers qu'elle lit et écrit.

Relève les écarts : sync/pcmirror-sync.sh du dépôt est la version du 4 juillet
alors que celle déployée date du 12 octobre ; les seuils de santé affichés ne
correspondent pas au code ; POST /exclude supprime le dossier du miroir.
ci: contrôler les réponses de référence à chaque poussée
Some checks failed
Contrôles des références / Références du comportement (push) Has been cancelled
Contrôles des références / Références du comportement (pull_request) Has been cancelled
3db9522adc
Le dépôt n'avait aucun workflow : la carte demandait une CI verte et il n'y
avait rien à passer. Ajoute un métier léger sur l'exécutant du PC (étiquette
`studio`, mode host) : les scripts Python compilent, les 19 réponses de
référence sont complètes et conformes (tests/verifier_reference.py), les
fichiers de télémétrie se relisent. Aucun accès réseau, aucun secret.

Le socle Rust de la carte 2/6 viendra s'ajouter à ce même fichier.
ci: demander l'étiquette pc-lourd pour vérifier l'exécutant disponible
Some checks failed
Contrôles des références / Références du comportement (push) Has been cancelled
Contrôles des références / Références du comportement (pull_request) Has been cancelled
68a87b2acb
docs: notes de reference sur la synchro pcmirror (depot vs version en service)
Some checks failed
Contrôles des références / Références du comportement (push) Has been cancelled
Contrôles des références / Références du comportement (pull_request) Has been cancelled
4166906e46
Cause : le script du depot (sync/pcmirror-sync.sh, 79 lignes) et celui en service
(tests/fixtures/synchro/pcmirror-sync.sh.deploye, 129 lignes) ont diverge (verrou,
garde-fous disque/hote, --partial, exclusions PC-Home, code de sortie, corbeille).
Mesure : avec rsync 3.5.1 et LC_ALL=C, la progression est ecrite en octets a
separateurs de milliers, illisible par l'expression de la ligne 69 du script en
service ; l'expression du depot (l. 50) ne lit jamais le debit.

Remede : inventaire ligne par ligne des deux versions, ecarts, mesures rejouables et
correctif propose (-h, en gardant LC_ALL=C), a integrer dans docs/COMPORTEMENT.md.
tests: capturer les routes qui écrivent et vérifier leurs effets de bord
Some checks failed
Contrôles des références / Références du comportement (push) Has been cancelled
Contrôles des références / Références du comportement (pull_request) Has been cancelled
3da9d160f7
Les instantanés de référence ne couvraient que les routes en lecture : sonder
POST /exclude sur le serveur du LXC 108 supprime un dossier du miroir, donc la
capture en ligne ne pouvait pas montrer ces routes sans détruire des données.

capturer_local.py monte un miroir factice dans /tmp, y écrit un dossier illisible
et exécute le server.py du dépôt — seules trois lignes changent (racine, adresse
d'écoute, message de démarrage), le diff est affiché et vérifié à chaque
exécution. Il rejoue 17 sondes et contrôle les effets de bord : /exclude supprime
bien le dossier du miroir, conserve le motif existant de _exclusions.txt et
laisse les fichiers voisins intacts ; /include retire le motif sans restaurer le
dossier. --verifier rejoue les mêmes sondes et compare les codes au manifeste
attendu.json, sans rien réécrire : c'est ce que lance la CI.

Complètent le jeu en ligne les deux sondes qui manquaient (HEAD et DELETE par
capturer.sh), et verifier_reference.py relit désormais les deux jeux
d'instantanés (trios présents, codes conformes au manifeste, en-têtes en
HTTP/1.0, couverture du vérificateur en ligne).

Deux défauts mesurés sont documentés dans docs/COMPORTEMENT.md : HEAD répond 501
et annonce un Content-Length sans écrire aucun corps (vérifié sur la socket nue),
et le confinement de /files, sans séparateur, accepte un dossier voisin dont le
nom prolonge la racine. Le comportement du serveur n'est pas modifié.
docs: sourcer et corriger l'état mesuré de COMPORTEMENT.md
All checks were successful
Contrôles des références / Références du comportement (push) Successful in 3s
Contrôles des références / Références du comportement (pull_request) Successful in 3s
ea9c9dfafb
La section « écart dépôt / version en service » et la méthode s'appuyaient sur
des copies et des dates non nommées, et trois affirmations étaient fausses.

- planification : cron n'est pas installé sur le PC (« le paquet cronie n'a pas
  été trouvé », `cronie.service` inconnu) ; les unités systemd --user sont
  identiques dans la sauvegarde kde-backup (81326f75…/d10a93c8…) et dans les
  fixtures, et l'en-tête du script en service (l. 14) les déclare ; deux
  horodatages de `_last-sync.json` à ~:03 de l'heure pleine corroborent la
  cadence horaire.
- provenance nommée : `/mnt/Media/Nas/scripts/` (fichiers des 3 et 4 juillet)
  pour la copie périmée de `sync/`, `kde-backup` pour les unités, et
  `/mnt/Media/Nas/scripts/mirror-status-server.py` (4 juillet, 814360fb…,
  889 lignes, 0 `aria-hidden`, 0 `class="vh"`) pour la version qui précède le
  dépôt ; l'unité `mirror-status.service` (de36f6c0…) est lue dans le même
  dossier.
- corrections : la ligne ssh est passée par `-e "$RSH"` (pas `RSYNC_RSH`) ; les
  exclusions fixes sont ajoutées après la dérivation d'`EXCL2`, donc portées par
  le seul rsync média ; les dossiers personnels partent en un seul rsync aplati
  et le code de sortie vient du dernier rsync (un échec média est masqué) ; le
  script du dépôt écrit aussi `rc` dans `_last-sync.json`.
- mesure ajoutée : `/dl?p=_pve-configs/.last-backup` → 404 le 2026-10-15, ce qui
  explique le champ vide `backup_pve_dernier` du tableau de bord ; relevé du
  serveur à 17:31 (89,7 s de scan, 3 255 290 fichiers, 152,4 Go).

Tests : `tests/verifier_reference.py` 21/21 en ligne et 17/17 hors ligne,
`tests/fixtures/capturer_local.py --verifier` 0 incident,
`tests/fixtures/verifier_contrat.py` 22/22 sur 192.168.1.210:9090.
feat(pcmirror): socle Rust de la synchro PC Mirror
Some checks failed
Contrôles des références / Références du comportement (push) Has been cancelled
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (push) Has been cancelled
Contrôles des références / Références du comportement (pull_request) Has been cancelled
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (pull_request) Has been cancelled
c250e5ac1d
La passe de synchronisation du PC Studio est réécrite en Rust : crate
`crates/pcmirror` (bibliothèque et binaire), configuration TOML, verrou,
garde-fous, exclusions, corbeille datée, rapport JSON et télémétrie aux mêmes
clés que le script en service.

La référence reste `sync/pcmirror-sync.sh`, que le PC exécute toujours : rien
n'est déployé. `pcmirror run --dry-run` affiche les commandes `rsync` prévues et
reproduit la passe décrite dans `docs/COMPORTEMENT-SYNCHRO.md`.

- verrou `flock` sans attente, comme `flock -n` : un second passage n'attend pas
  et sort en 0 ; une panne de `flock` autre qu'un verrou occupé remonte au lieu
  de se faire passer pour une passe déjà en cours ;
- garde-fous : média absent ou vide, hôte injoignable, dossier personnel vide
  face à une copie pleine, dossier personnel absent ignoré,
  `--ignorer-garde-fous` pour outrepasser un essai à la main ;
- exclusions : les six motifs fixes du script, `_exclusions.txt` du miroir pour
  le transfert média, `/_rapports/` pour ne pas effacer les rapports déposés ;
- rapport JSON de passe, déposé sur le miroir dans `_rapports/` ; télémétrie
  `_last-sync.json` et `_sync-progress.json` (`{"pct":…,"rate":…}` toutes les
  4 s), aux clés du script ;
- CI Forgejo : formatage, `clippy` sans avertissement, tests lançant un vrai
  `rsync` dans `/tmp`, relecture des fichiers de référence.

Mesures : 68 tests passés (`cargo test --release --locked`), `clippy
--all-targets -D warnings` sans avertissement, couverture 89,15 % des régions /
87,58 % des lignes. Référence de parité : le script en service
`/mnt/Media/Linux/pcmirror-sync.sh` (129 lignes, sha256 `cfe3a4b0…`).
ci(pcmirror): mesurer la couverture, documenter les variables d'environnement
Some checks failed
Contrôles des références / Références du comportement (push) Successful in 3s
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (push) Failing after 0s
Contrôles des références / Références du comportement (pull_request) Successful in 3s
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (pull_request) Failing after 0s
3bb407d7a7
La carte 2/6 demande la couverture dans la CI et une configuration sans secret.
L'étape `cargo llvm-cov --locked --summary-only --fail-under-lines 80` est ajoutée
au contrôle de la crate : elle mesure quand `cargo-llvm-cov` est installé sur
l'exécutant, et l'écrit sans échouer sinon (l'outil n'est pas garanti partout).
Vérifié à la main : la commande sort 0 (87,58 % des lignes, seuil 80).

`.env.example` recense les trois variables lues par la crate — `PCMIRROR_CONFIG`,
`HOME`, `XDG_RUNTIME_DIR` — sans aucun secret ; la clé SSH reste dans `~/.ssh`,
hors du dépôt. Le README pointe ce fichier.
feat(serveur): service d'état Rust pcmirror-serveur, à parité avec server.py
Some checks failed
Contrôles des références / Références du comportement (push) Successful in 3s
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (push) Failing after 1s
Contrôles des références / Références du comportement (pull_request) Successful in 3s
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (pull_request) Failing after 0s
f9c6b47860
Cause : le serveur d'état du miroir était un script Python
(status-server/server.py) qui ne dit ni l'espace disque, ni l'historique des
passes, ni si le miroir est à jour : un disque qui se remplit, un sync en
retard ou une passe en échec ne se voyaient qu'en lisant des chiffres bruts.

Remède : nouveau crate pcmirror-serveur (binaire pcmirror-serveur) qui sert les
mêmes routes, mêmes codes et mêmes pages que le serveur Python — vérifié sur de
vraies connexions TCP par les 17 sondes des fixtures de référence — et qui
ajoute l'espace disque du volume (statvfs), l'historique des passes lues dans
<racine>/_rapports (rapports de pcmirror) et un verdict de santé calculé par
des règles explicites (seuils configurables, chaque règle déclenchée listée).

L'API gagne /api/etat et /api/sante ; /json garde ses douze clés et en ajoute
onze, sans en retirer ni renommer : le front continue de fonctionner tel quel.

Quatre écarts assumés, documentés dans docs/SERVEUR-RUST.md : plus aucun emoji
dans les pages (icône SVG dans le fil d'Ariane), l'intervalle de balayage
affiché est le vrai (900 s — le « 5 minutes » du Python était faux), trois
blocs neufs au tableau de bord, et un serveur HTTP écrit à la main pour tenir
501/303 et le téléchargement en flux (axum et tokio quittent les dépendances).

Quatre bizarreries du serveur de référence sont reproduites et couvertes par
tests : le confinement de /files compare un préfixe sans séparateur (un dossier
voisin est listable), les fichiers internes ne sont masqués que pour p vide,
les liens symboliques comptent comme des fichiers, et _exclusions.txt se relit
les barres retirées (sans quoi la liste doublait à chaque enregistrement).

CHANGELOG et .env.example à jour.
feat(frontend): tableau d'état en Svelte 5, même apparence que le serveur Python
Some checks failed
Contrôles des références / Références du comportement (push) Successful in 3s
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (push) Failing after 0s
Contrôles des références / Front d'état (types, lint, format, tests, build, bout en bout) (push) Failing after 10s
Contrôles des références / Références du comportement (pull_request) Successful in 3s
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (pull_request) Failing after 1s
Contrôles des références / Front d'état (types, lint, format, tests, build, bout en bout) (pull_request) Failing after 11s
84b51a8c00
Le serveur d'état Rust expose désormais /api/etat, /api/sante et /json ; le
front Svelte les consomme et remplace les pages HTML de status-server/server.py
en gardant leur apparence (bandeau collant, cartes, tableaux, icônes).

- `frontend/` : Svelte 5 + Vite, jetons de couleur et classes repris de la
  feuille de style extraite de server.py, aucune couleur ni taille en dur ;
  bascule clair/sombre mémorisée, rafraîchissement automatique, repli sur
  /json si /api/etat manque, bandeau d'avertissement, états vides et
  squelettes.
- Accessibilité : lien d'évitement, régions nommées, tableaux défilants
  atteignables au clavier, contraste AA vérifié par axe.
- Tests : 69 unitaires (100 % des lignes de src/lib) et 16 scénarios
  Playwright (bureau 1440 px et Pixel 7) sur un serveur local rejouant les
  réponses figées de tests/fixtures, plus un contrôle de mise en page qui a
  révélé le débordement horizontal des tableaux, corrigé par un cadre
  défilant.
- CI : contrôle du front ajouté au workflow (types, ESLint, Prettier, tests
  avec seuil de couverture, build, scénarios Playwright).
- Documentation : docs/FRONTEND-ETAT.md, frontend/.env.example, README et
  CHANGELOG.
Cause : le service d'état ne savait servir que ses pages de référence, copiées
du service Python. La page Svelte construite (frontend/dist) restait sur le
disque : il fallait un serveur web devant le binaire, ou rien.

Remède : `build.rs` engendre une table en mémoire depuis `frontend/dist` (elle
est vide, et le dit, si la page n'a pas été construite), `PCMIRROR_FRONT` choisit
qui sert — `reference` par défaut, `embarque` pour la page du binaire — et le
service la sert avec le repli d'une application monopage : tout chemin inconnu
hors API rend `index.html`. Un chemin d'API inconnu rend 404, et un binaire qui
n'a pas la page alors qu'on la lui demande rend 503 en le disant, au lieu de
servir autre chose en silence.
Cause : le repli de la page ne reconnaissait le retour que dans sa forme nue
(`..`). Un chemin comme `/assets/..%2f..` passait pour un chemin inconnu et
recevait `index.html` — le test qui l'affirmait ne mesurait rien tant qu'aucune
page n'était construite, puisque la table vide rendait `None` pour tout. Depuis
que la page est embarquée, le test échoue et nomme la panne.

Remède : le chemin est décodé avant d'être jugé ; un morceau `..`, une barre
oblique inversée, ou un encodage qui ne se tient pas (`%` coupé, `%zz`) fait
refuser le chemin au lieu de le nettoyer en silence. Rien n'est lu sur le
disque de toute façon, mais un service ne doit pas servir ce qu'il vient de
qualifier de sûr sans l'avoir regardé sous son vrai jour.
feat(livraison): livrer le PC et le 108 après chaque fusion, et le dire
Some checks failed
Contrôles des références / Références du comportement (push) Successful in 3s
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (push) Failing after 1s
Contrôles des références / Livraison (style des scripts, essai à blanc) (push) Successful in 1s
Contrôles des références / Front d'état (types, lint, format, tests, build, bout en bout) (push) Failing after 11s
Contrôles des références / Références du comportement (pull_request) Successful in 3s
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (pull_request) Failing after 1s
Contrôles des références / Livraison (style des scripts, essai à blanc) (pull_request) Successful in 1s
Contrôles des références / Front d'état (types, lint, format, tests, build, bout en bout) (pull_request) Failing after 12s
7559711b48
Cause : les deux cibles se posaient à la main — le binaire du PC depuis les
sources, le service du 108 en recopiant un fichier par `pct push`. Chaque pose
tenait à ce que quelqu'un se souvienne de la marche à suivre, et rien ne
mesurait qu'elle avait réussi : un binaire posé sans sa configuration partait
au prochain minuteur sans que personne ne le sache.

Remède : une livraison qui suit chaque fusion dans `main`. Elle joue d'abord
l'essai à blanc (`deploy/essais/essai-deploy.sh`, dans un bac à sable de /tmp,
aucune cible touchée), puis pose le binaire du PC (sur place) et le service du
108 (par le nœud Proxmox, `pct`, transport `pve`). Après chaque pose, le
contrôle de santé de la cible (`deploy/controle-sante.sh`) : unité active,
binaire exécutable, configuration lisible, page servie, API qui ne se confond
pas avec la page. Santé mauvaise : la livraison remet la version précédente
elle-même et sort en échec. L'issue « Livraison PC Mirror en échec » s'ouvre ou
se commente (étape, cause, journal, capture) et se ferme d'elle-même à la
première livraison réussie.

Ce qui est posé : les unités utilisateur du PC (`pcmirror.service`,
`pcmirror.timer`), l'unité système du 108 (`pcmirror-serveur.service`, page
embarquée), et `docs/DEPLOIEMENT-CONTINU.md` sur les deux cibles. La CI gagne
l'essai de livraison et le contrôle de style des scripts quand shellcheck est
sur l'exécutant.

N'est pas mesuré ici : la livraison réelle vers le PC et le 108 (elle demande le
secret `CLE_PVE` et les cibles) ; ce qui est mesuré, c'est l'essai à blanc, 39
essais verts dans un bac à sable, et le contrôle de santé joué contre le binaire
construit, page embarquée comme pages de référence.
Author
Collaborator

État de la CI : en attente, aucun exécutant ne sert ce dépôt.

Les huit travaux de l'exécution 11342 (commit 7559711) restent « Waiting to run ». Ce n'est pas
propre à cette PR : toutes les exécutions de foXaCe/pc-mirror sont dans le même cas, y compris
celles des cartes précédentes (11288, 11289, 11313, 11314, 11341). Pendant ce temps, les
exécutions de foXaCe/studio qui demandent la même étiquette (runs-on: pc-lourd) passent
(11331, 11334 : succès) — l'exécutant pc-studio (id 12, étiquettes pc-lourd:host,
studio:host) prend donc les travaux de studio et pas ceux de pc-mirror.

Conséquence : la CI ne peut pas devenir verte ici, donc fusion-auto ne fusionnera pas cette PR,
et la livraison décrite ne partira pas après la fusion. Il faut un exécutant pour
foXaCe/pc-mirror (enregistrer un exécutant au niveau du dépôt, ou partager pc-studio avec lui).

Ce qui est mesuré, en attendant, sur la branche :

cargo test --release --locked
test result: ok. 58 passed; 0 failed   (pcmirror, unittests)
test result: ok. 10 passed; 0 failed   (tests/passe_complete.rs)
test result: ok. 116 passed; 0 failed  (pcmirror-serveur, unittests)
test result: ok. 8 passed; 0 failed    (tests/parite_reference.rs)

cargo build --release --locked : 0 avertissement

deploy/essais/essai-deploy.sh : bilan : 39 réussis, 0 échoués

PCMIRROR_FRONT=embarque ./target/release/pcmirror-serveur
/ 200 (marqueur id="app"), /miroir 200, /api/rien 404, /json 200
avec --path-as-is : /assets/..%2f.. 404, /%2e%2e/%2e%2e/etc/passwd 404
binaire sans page construite + PCMIRROR_FRONT=embarque : / 503, /json 200
**État de la CI : en attente, aucun exécutant ne sert ce dépôt.** Les huit travaux de l'exécution 11342 (commit `7559711`) restent « Waiting to run ». Ce n'est pas propre à cette PR : toutes les exécutions de `foXaCe/pc-mirror` sont dans le même cas, y compris celles des cartes précédentes (11288, 11289, 11313, 11314, 11341). Pendant ce temps, les exécutions de `foXaCe/studio` qui demandent la même étiquette (`runs-on: pc-lourd`) passent (11331, 11334 : succès) — l'exécutant `pc-studio` (id 12, étiquettes `pc-lourd:host`, `studio:host`) prend donc les travaux de `studio` et pas ceux de `pc-mirror`. Conséquence : la CI ne peut pas devenir verte ici, donc `fusion-auto` ne fusionnera pas cette PR, et la livraison décrite ne partira pas après la fusion. Il faut un exécutant pour `foXaCe/pc-mirror` (enregistrer un exécutant au niveau du dépôt, ou partager `pc-studio` avec lui). Ce qui est mesuré, en attendant, sur la branche : cargo test --release --locked test result: ok. 58 passed; 0 failed (pcmirror, unittests) test result: ok. 10 passed; 0 failed (tests/passe_complete.rs) test result: ok. 116 passed; 0 failed (pcmirror-serveur, unittests) test result: ok. 8 passed; 0 failed (tests/parite_reference.rs) cargo build --release --locked : 0 avertissement deploy/essais/essai-deploy.sh : bilan : 39 réussis, 0 échoués PCMIRROR_FRONT=embarque ./target/release/pcmirror-serveur / 200 (marqueur id="app"), /miroir 200, /api/rien 404, /json 200 avec --path-as-is : /assets/..%2f.. 404, /%2e%2e/%2e%2e/etc/passwd 404 binaire sans page construite + PCMIRROR_FRONT=embarque : / 503, /json 200
Collaborator

fusion-auto : pas de fusion, la CI est rouge (Front d'état, Crate pcmirror, Front d'état, Crate pcmirror). Le chef de l'atelier renvoie la carte à l'agent ; l'étiquette tombera d'elle-même une fois corrigé.

`fusion-auto` : pas de fusion, la CI est rouge (Front d'état, Crate pcmirror, Front d'état, Crate pcmirror). Le chef de l'atelier renvoie la carte à l'agent ; l'étiquette tombera d'elle-même une fois corrigé.
CI : le cargo du runner est dans /usr/bin et les navigateurs Playwright sont deja installes
Some checks failed
Contrôles des références / Références du comportement (push) Has been cancelled
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (push) Has been cancelled
Contrôles des références / Livraison (style des scripts, essai à blanc) (push) Has been cancelled
Contrôles des références / Front d'état (types, lint, format, tests, build, bout en bout) (push) Has been cancelled
Contrôles des références / Références du comportement (pull_request) Has been cancelled
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (pull_request) Has been cancelled
Contrôles des références / Livraison (style des scripts, essai à blanc) (pull_request) Has been cancelled
Contrôles des références / Front d'état (types, lint, format, tests, build, bout en bout) (pull_request) Has been cancelled
7cab35adcc
CI : le relevé des outils ne casse plus le pipeline (SIGPIPE 141)
All checks were successful
Contrôles des références / Références du comportement (push) Successful in 3s
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (push) Successful in 1m39s
Contrôles des références / Livraison (style des scripts, essai à blanc) (push) Successful in 2s
Contrôles des références / Front d'état (types, lint, format, tests, build, bout en bout) (push) Successful in 22s
Contrôles des références / Références du comportement (pull_request) Successful in 3s
Contrôles des références / Crate pcmirror (formatage, Clippy, tests) (pull_request) Successful in 1m36s
Contrôles des références / Livraison (style des scripts, essai à blanc) (pull_request) Successful in 2s
Contrôles des références / Front d'état (types, lint, format, tests, build, bout en bout) (pull_request) Successful in 35s
41d4f19548
hermes-fusion deleted branch hermes/paquets-services-deploiement 2026-10-16 23:00:02 +02:00
Collaborator

Fusionnée automatiquement par fusion-auto (forge) : CI verte, sans conflit.

Fusionnée automatiquement par `fusion-auto` (forge) : CI verte, sans conflit.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
foXaCe/pc-mirror!5
No description provided.