empreintes muettes, courses de premier demarrage, collision de noms

Quatre meta/empreinte.yml declaraient leurs valeurs A LA RACINE, sans la cle
`setops_empreinte:` : collabora, nextcloud, web_dorsal, web_frontal. Le lecteur
les voyait vides et rendait {0,0,0} — en silence. collab-01 s'est retrouvee avec
1 coeur / 1 Go pour porter Nextcloud ET Collabora, et a cesse de repondre en SSH
faute de memoire. Corrigee : 4c/5632Mo. Une garde refuse desormais cette forme.

Un fichier qui existe mais ne dit rien est pire qu'un fichier absent : le repli
aurait donne des valeurs sensees.

Deux courses de premier demarrage :
- le clone rend la main avant que son .conf existe -> attente active sur l'API ;
- le verrou dpkg frappait hors de `common_packages` -> `lock_timeout` pose en
  module_defaults sur les 30 playbooks de groupe, une declaration au lieu de 30.

Au passage, j'ai failli livrer pire que le defaut : une URL coupee avec `>-`
inserait une ESPACE en son milieu. Le lint passait, la requete non.

Enfin : `proxmox_kvm` identifie une VM par son NOM. Une VM heritee homonyme lui
a fait rapporter `ok` sans rien cloner — un deploiement peut donc PARAITRE
reussi alors qu'aucune VM n'existe. Touche D-37 directement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Daniel Allaire 2026-08-07 16:22:38 -04:00
parent 6699935dc7
commit cc6026641f
37 changed files with 344 additions and 20 deletions

View file

@ -2,6 +2,56 @@
## 2026-08-06 — le chemin nord-sud devient dérivable
### Quatre empreintes muettes — et une VM qui en est morte
`collab-01` a cessé de répondre en SSH. Le symptôme ressemblait à un problème réseau ; la
cause était un fichier YAML mal formé depuis des semaines.
**Quatre `meta/empreinte.yml` déclaraient leurs valeurs à la racine**, sans la clé
`setops_empreinte:` : collabora, nextcloud, web_dorsal, web_frontal. `charger_empreinte_role`
les lisait comme vides et rendait `{0,0,0}`**en silence**. Les VM concernées recevaient le
minimum du socle.
`collab-01` s'est donc retrouvée avec **1 cœur / 1 Go** pour porter Nextcloud *et* Collabora.
L'installation de PHP 8.4, nginx et Redis a épuisé la mémoire, et sshd n'a plus pu forker.
Après correction : **4 cœurs / 5 632 Mo**. `web-dorsal-01` passe de 1024 à 2048 Mo.
**Un fichier qui existe mais ne dit rien est pire qu'un fichier absent** : le repli aurait
donné des valeurs sensées. Une garde refuse désormais cette forme, en nommant le fichier — et
elle distingue « pas d'empreinte » de « empreinte illisible », qui n'appellent pas la même
réponse.
Les deux VM ont été redimensionnées à chaud (arrêt propre, `config PUT`, redémarrage). Elles
sont dans la couche `apps` — la dernière — donc rien ne dépendait d'elles.
### Deux courses de premier démarrage, corrigées à la racine
**Le clone rend la main avant que sa configuration existe.** Sur un stockage lent, `qm clone`
retourne et le `.conf` n'est pas encore écrit ; la tâche suivante échouait sur
« Configuration file … does not exist ». Une attente active interroge l'API jusqu'à 150 s.
Au passage, j'ai failli livrer pire que le défaut : pour raccourcir une ligne trop longue, je
l'avais coupée avec `>-` — qui replie les retours en **espaces**, insérant une espace au milieu
de l'URL. Le lint passait, la requête aurait échoué. L'URL est assemblée dans une variable.
**Le verrou dpkg frappait hors de `common_packages`.** J'y avais mis `lock_timeout` hier, mais
chaque autre rôle installant des paquets restait exposé — `serveur_nextcloud` en a fait les
frais. Il est désormais posé en `module_defaults` sur les **30 playbooks de groupe** : toute
tâche `apt` du play en hérite, y compris celles des rôles inclus. Une déclaration au lieu de
trente.
### Une collision de noms qui rapportait `ok`
`web-frontal-01` ne se créait pas : une VM héritée portait déjà ce nom (`911401`, arrêtée,
adressage `192.168.15.x` de l'ancien monde). **`proxmox_kvm` identifie par le nom, l'a trouvée,
et a rapporté `ok` sans rien cloner.**
C'est plus grave que l'échec : un déploiement peut *paraître* réussi alors qu'aucune VM n'a été
créée. Ça touche directement D-37 — les noms courts sont volontairement identiques d'un tenant
à l'autre, et un parc hérité qui partage un nom crée exactement cette collision silencieuse.
La VM héritée a été renommée.
### `resoudre_idp` — le nom inventé était dans **quatre** rôles
`forge-01` a échoué sur `serveur_forgejo_oidc_discovery`, qui pointait

View file

@ -2,6 +2,13 @@
- name: Appliquer l'intégration client_backup
hosts: client_backup
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
roles:
- client_backup

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe client_journal
hosts: client_journal
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe client_metrique
hosts: client_metrique
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe client_pki
hosts: client_pki
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe client_smtp
hosts: client_smtp
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe client_unbound
hosts: client_unbound
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_backup
hosts: serveur_backup
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
roles:
- serveur_backup

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_collabora
hosts: serveur_collabora
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_debian
hosts: serveur_debian
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_dovecot
hosts: serveur_dovecot
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_durci
hosts: serveur_durci
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_forgejo
hosts: serveur_forgejo
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_grafana
hosts: serveur_grafana
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_icinga
hosts: serveur_icinga
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_icingaweb2
hosts: serveur_icingaweb2
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_keycloak
hosts: serveur_keycloak
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_loki
hosts: serveur_loki
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_nextcloud
hosts: serveur_nextcloud
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_nginx
hosts: serveur_nginx
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_oauth2_proxy
hosts: serveur_oauth2_proxy
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:
- name: Vérifier que la cible est Debian

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_openldap
hosts: serveur_openldap
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_postfix
hosts: serveur_postfix
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_postgresql
hosts: serveur_postgresql
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_powerdns
hosts: serveur_powerdns
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_prometheus
hosts: serveur_prometheus
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_redis
hosts: serveur_redis
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_rspamd
hosts: serveur_rspamd
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_step_ca
hosts: serveur_step_ca
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_web_dorsal
hosts: serveur_web_dorsal
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -2,6 +2,13 @@
- name: Appliquer le groupe serveur_web_frontal
hosts: serveur_web_frontal
become: true
# Le verrou dpkg est tenu par les maj automatiques de Debian, par vagues, plusieurs
# minutes apres le premier demarrage. Pose ICI plutot que dans chaque role : toute
# tache apt du play en herite, y compris celles des roles inclus.
module_defaults:
ansible.builtin.apt:
lock_timeout: 300
gather_facts: true
pre_tasks:

View file

@ -183,6 +183,30 @@
# L'API de CLONAGE ignore `cores` et `memory` : le clone herite du gabarit, et le
# plan est contredit sans un mot. Mesure du 2026-08-06 : plan 1 coeur / 1024 Mo,
# VM creee avec 2 / 2048 — ceux du gabarit. Il faut donc les reposer APRES le clone.
# Le clone COMPLET rend la main avant que sa configuration ne soit ecrite : sur
# un stockage lent, `qm clone` retourne, et le `.conf` n'existe pas encore. La
# tache suivante echouait alors sur « Configuration file ... does not exist ».
# Observe deux fois sur quinze clones (2026-08-07) — une course, pas un hasard.
- name: Attendre que la configuration du clone existe
vars:
# Assemblee dans une variable : un `>-` replie les retours en ESPACES, ce qui
# inserait une espace au milieu de l'URL. Le lint passait, la requete non.
proxmox_api_racine: "https://{{ proxmox_api_host_effectif }}:{{ proxmox_api_port_effectif | default(8006, true) }}"
ansible.builtin.uri:
url: "{{ proxmox_api_racine }}/api2/json/nodes/{{ proxmox_clone_noeud }}/qemu/{{ proxmox_clone_vmid | int }}/config"
method: GET
headers:
Authorization: >-
PVEAPIToken={{ proxmox_api_user_effectif }}!{{ proxmox_api_token_id_effectif }}={{ proxmox_api_token_secret_effectif }}
validate_certs: "{{ proxmox_validate_certs | default(false) | bool }}"
status_code: 200
register: proxmox_clone_conf
until: proxmox_clone_conf.status == 200
retries: 30
delay: 5
changed_when: false
no_log: true
- name: Appliquer le gabarit de calcul du plan (le clonage ne le fait pas)
community.general.proxmox_kvm:
api_host: "{{ proxmox_api_host_effectif }}"

View file

@ -1,6 +1,13 @@
---
# Empreinte de dimensionnement (propriété du rôle). Collabora exécute des cœurs
# LibreOffice à la demande : mémoire notable, image conteneur ~1.5 Go.
coeurs: 2
memoire_mo: 2048
disque_go: 10
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
#
# LA CLE `setops_empreinte:` EST OBLIGATOIRE. Declarees a la racine, ces valeurs
# etaient lues comme absentes : `charger_empreinte_role` rendait {0,0,0} et la VM
# recevait le MINIMUM. collab-01 s'est retrouvee avec 1 coeur / 1 Go pour porter
# Nextcloud ET Collabora — elle a cesse de repondre en SSH (2026-08-07).
setops_empreinte:
coeurs: 2
memoire_mo: 2048
disque_go: 10

View file

@ -1,6 +1,13 @@
---
# Empreinte de dimensionnement du logiciel (propriété du rôle). Additionnée au socle SE
# par scripts/inventory_rules.py. Nextcloud + PHP-FPM : mémoire modérée, disque data croissant.
coeurs: 2
memoire_mo: 2048
disque_go: 20
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
#
# LA CLE `setops_empreinte:` EST OBLIGATOIRE. Declarees a la racine, ces valeurs
# etaient lues comme absentes : `charger_empreinte_role` rendait {0,0,0} et la VM
# recevait le MINIMUM. collab-01 s'est retrouvee avec 1 coeur / 1 Go pour porter
# Nextcloud ET Collabora — elle a cesse de repondre en SSH (2026-08-07).
setops_empreinte:
coeurs: 2
memoire_mo: 2048
disque_go: 20

View file

@ -1,6 +1,13 @@
---
# Empreinte de dimensionnement (propriete du role). Webapp dynamique (runtime
# Python/Node + service) : memoire moderee. Ajuster selon les apps hebergees.
coeurs: 1
memoire_mo: 1024
disque_go: 10
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
#
# LA CLE `setops_empreinte:` EST OBLIGATOIRE. Declarees a la racine, ces valeurs
# etaient lues comme absentes : `charger_empreinte_role` rendait {0,0,0} et la VM
# recevait le MINIMUM. collab-01 s'est retrouvee avec 1 coeur / 1 Go pour porter
# Nextcloud ET Collabora — elle a cesse de repondre en SSH (2026-08-07).
setops_empreinte:
coeurs: 1
memoire_mo: 1024
disque_go: 10

View file

@ -1,6 +1,13 @@
---
# Empreinte de dimensionnement (propriete du role). Site statique servi par
# nginx : tres leger (pas de runtime, pas de BD).
coeurs: 1
memoire_mo: 512
disque_go: 10
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
#
# LA CLE `setops_empreinte:` EST OBLIGATOIRE. Declarees a la racine, ces valeurs
# etaient lues comme absentes : `charger_empreinte_role` rendait {0,0,0} et la VM
# recevait le MINIMUM. collab-01 s'est retrouvee avec 1 coeur / 1 Go pour porter
# Nextcloud ET Collabora — elle a cesse de repondre en SSH (2026-08-07).
setops_empreinte:
coeurs: 1
memoire_mo: 512
disque_go: 10

View file

@ -621,6 +621,18 @@ def charger_empreinte_role(racine_roles: Path, groupe: str) -> dict | None:
emp = (data or {}).get("setops_empreinte") or {}
if not isinstance(emp, dict):
raise ValueError(f"{fichier}: 'setops_empreinte' doit etre une table.")
# Un fichier qui declare les valeurs A LA RACINE au lieu de sous
# `setops_empreinte:` etait lu comme VIDE : la VM recevait le minimum, en
# silence. Quatre roles etaient dans ce cas, et `collab-01` s'est retrouvee
# avec 1 coeur / 1 Go pour porter Nextcloud ET Collabora — elle a cesse de
# repondre en SSH (2026-08-07). Un fichier qui existe mais ne dit rien est
# pire qu'un fichier absent : le repli, lui, aurait donne des valeurs sensees.
if not emp and any(c in (data or {}) for c in CHAMPS_EMPREINTE):
raise ValueError(
f"{fichier}: les valeurs sont declarees a la racine ; elles doivent "
f"etre sous la cle `setops_empreinte:`. Sans elle, l'empreinte est lue "
f"comme nulle et la VM recoit le minimum."
)
return {cle: int(emp.get(cle, 0)) for cle in CHAMPS_EMPREINTE}