Files
hcornet bc18f93196
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m44s
build / Garde-fou (push) Successful in 10m44s
build / Images Harbor (web, Dockerfile) (push) Successful in 13m25s
Import d'un pack par la route de fusion, champs fermes, correction des champs vides
2026-09-11 21:15:23 +02:00

5.6 KiB

Conventions et revue avant livraison

Ce fichier existe pour que le projet reste cohérent d'une version à l'autre, et pour qu'une anomalie soit trouvée sur le poste de développement plutôt qu'après soixante minutes de construction.

Revue avant chaque livraison

Dans cet ordre, sans exception, y compris pour un correctif d'une ligne :

python -m ruff check .            # analyse statique, zéro signalement toléré
python -m pytest -q               # la suite complète
node --check enclume/static/*.js  # syntaxe des scripts
sh tests/interface.sh             # l'editeur, dans un DOM headless
sh -n docker/*.sh                 # syntaxe des scripts shell
python -c "import yaml,glob;[yaml.safe_load(open(f)) for f in glob.glob('catalog/**/*.yml',recursive=True)]"
docker compose -f compose.yaml config > /dev/null

Puis, dans un environnement vierge — c'est ce qui a manqué le jour où requests a cassé la CI :

python -m venv /tmp/vierge && /tmp/vierge/bin/pip install -r requirements.txt pytest
/tmp/vierge/bin/python -m pytest -q

Et enfin la revue humaine, qui ne s'automatise pas :

  • toute ressource référencée par un gabarit existe-t-elle réellement ? (un test le vérifie désormais, parce que l'oubli a déjà eu lieu)
  • les noms d'hôte, de dépôt et de domaine cités dans la documentation et les exemples sont-ils encore les bons ? Ni ruff ni les tests ne lisent le Markdown.
  • une variable nouvelle est-elle présente dans .env.example, dans compose.yaml et documentée ?
  • une valeur venant de l'utilisateur peut-elle contenir un caractère qui casse le format où on l'insère ? Point-virgule pour le CLAPI, @ et : pour une URL de connexion, guillemet simple pour le shell, % pour un fichier ini lu par configparser. Quatre incidents sur ce seul motif — c'est le premier endroit où regarder.
  • une modification a-t-elle réellement été appliquée ? Une correction annoncée en 1.11.1 n'avait jamais pris : le texte recherché avait changé entre-temps. Relire le fichier après l'édition, et faire passer un test par le chemin réel, pas seulement par la couche voisine.
  • une valeur déjà encodée traverse-t-elle un second format qui réinterprète son encodage ? C'est la variante du piège précédent : %40 est correct dans une URL, et devient une interpolation dans un ini.
  • ce qui est écrit en base a-t-il traversé strip_secrets ?

Un principe : le moins de saisie libre possible

Chaque champ de texte libre est une occasion de faute de frappe qui ne se verra qu'au déploiement sur le central. Un champ nouveau doit donc, dans l'ordre de préférence :

  1. une liste fermée quand les valeurs possibles sont connues et finies — un fuseau horaire, un type de commande, une version SNMP ;
  2. une liste ouverte avec suggestions quand des valeurs existent déjà sur le central que nous ne connaissons pas — un modèle parent, un groupe d'hôtes, une commande de vérification ;
  3. la saisie libre seulement pour ce qui est propre à l'utilisateur : un nom, une description, un seuil.

Et quand une valeur juste est majoritairement la même, elle est préremplie. Un projet vide part avec /usr/lib/centreon/plugins, generic-active-host-custom et Central : l'utilisateur corrige si son installation diffère, il ne devine pas.

Nommage

Objet Règle Exemple
Modules Python français, minuscules, sans accent routes_donnees.py
Fonctions et variables français, snake_case utilisateur_courant, _repertoire_catalogue
Classes français, PascalCase Soumission, Prerequis
Variables d'environnement préfixe ENCLUME_, majuscules ENCLUME_DB_MOTDEPASSE
Routes d'API français, pluriel /api/soumissions, /api/partages
Identifiants HTML français, kebab-case btn-serveur-ouvrir, filtre-statut
Fichiers statiques français editeur.js, moderation.js
Tables français, pluriel utilisateurs, partages
Packs du catalogue <famille>-<techno>[-<protocole>] os-linux-snmp, hw-dell-idrac-snmp
Modèles d'hôte générés <Famille>-<Techno>-custom OS-Linux-SNMP-custom
Modèles de service <Famille>-<Techno>-<Sonde> OS-Linux-SNMP-Cpu
Images <registre>/enclume/<composant> .../enclume/catalog-sync
Branches de soumission pack/<id>-<numéro> pack/app-rabbitmq-7

Les commentaires et la documentation sont en français. Le code source reste sans accents, par choix, pour éviter toute question d'encodage dans les conteneurs.

Versions

Sémantique stricte, parce que la rétention Harbor et le retour arrière s'y appuient :

  • correctif (1.1.2) : rien de nouveau, rien qui change de nom
  • mineure (1.2.0) : fonctionnalité, nouvelle variable, migration de schéma
  • majeure (2.0.0) : rupture pour qui héberge déjà — variable supprimée, format de projet incompatible

Une migration de schéma n'ajoute que des colonnes et des tables. Une suppression attend la version suivante, sinon revenir à l'image précédente casse l'application.

Coût de construction

L'arm64 passe par l'émulation QEMU et coûte l'essentiel du temps de construction. Il n'est donc produit que sur un tag de version ; un simple push sur main ne construit que l'amd64. Le cache de couches vit dans Harbor, à côté des images : tant que requirements.txt ne change pas, l'installation des dépendances est reprise du cache.

Conséquence pratique : itérer sur main est rapide, publier une version reste lent. Autant grouper les corrections avant de taguer.