Files
system_update/docs/design/tache2/50-erreurs.md
T
gilles 0fbca06d3d docs: roadmap tâches 1.9-8 (briefs, gates de validation, designs tâche 2) + plans d'implémentation
Cartographie complète (liste_taches/coherence_taches), briefs tacheN + gates
validation_tacheN, design tâche 2 (docs/design/tache2/), specs/plans jalon 1-2
et tâche 1.9/2 (Phase 1, Phase 2, SJ-0→3). Validations consignées (1.9 , 2-8 🟡).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 19:50:25 +02:00

78 lines
6.6 KiB
Markdown

# 50 — Taxonomie des erreurs + stratégie de remédiation
> Axe C + livrable §4.4. Codes d'erreur normalisés alignés sur `SnapshotError.kind` (`40-contrats-json.md`) et `apt_errors.kind` (`tache1.9.md`).
---
## 1. Principes
- **L'exit code ne suffit jamais** à déclarer un succès (APT comme Docker). On corrèle exit code + sections parsées + diff réel + lignes importantes.
- **Statut normalisé** : `ok` | `warning` | `error`. `warning` = succès partiel ou effet à surveiller (suppressions de paquets, held back, orphans removed, conteneur unhealthy).
- **Capture des lignes pertinentes** : seules les lignes d'erreur utiles (`E:`, `W:`, `dpkg:`, `Error`, etc.) sont remontées ; le log brut complet reste archivé.
- **Pas d'auto-réparation dangereuse non validée** : on **propose** une remédiation, on ne l'exécute pas automatiquement (`dpkg --configure -a`, `rm /var/lib/dpkg/lock`, etc. exigent validation explicite).
- **Nettoyage des secrets** : toute ligne d'erreur exposant une URL d'auth, un token ou un chemin de credential est nettoyée avant UI/MCP (voir `70-securite.md`).
---
## 2. Taxonomie APT / dpkg
| `kind` | Détection (lignes/exit) | Sévérité | Remédiation proposée (non auto) |
|---|---|---|---|
| `apt_lock_busy` | `Could not get lock /var/lib/dpkg/lock`, `E: Unable to acquire the dpkg frontend lock` | error | Attendre la fin d'un apt/unattended-upgrades concurrent ; relancer. |
| `dpkg_interrupted` | `dpkg was interrupted`, `dpkg --configure -a` | error | Proposer `dpkg --configure -a` **avec validation explicite**. |
| `repo_unreachable` | `Failed to fetch`, `Could not resolve`, `Connection timed out`, `E: Some index files failed to download` | error | Vérifier réseau/proxy apt-cacher-ng/dépôt ; retenter. |
| `gpg_key_error` | `NO_PUBKEY`, `EXPKEYSIG`, `signatures couldn't be verified` | error | Vérifier/mettre à jour la clé du dépôt ; ne pas désactiver la vérif. |
| `package_conflict` | `Depends:`, `but it is not going to be installed`, `held broken packages` | warning/error | Examiner le conflit ; éventuel `dist-upgrade` ; validation. |
| `disk_space_low` | `E: You don't have enough free space`, `No space left on device` | error | Libérer de l'espace (`apt-get clean`), vérifier `/`, `/var`, `/boot`. |
| `packages_held` | `apt-mark showhold` non vide / présents en dist-upgrade absents d'upgrade | warning | Information : paquets retenus ; nécessite dist-upgrade ou hold explicite. |
| `packages_removed` | `Remv ` en simulation/diff | warning | Suppression de paquets ⇒ confirmation UI obligatoire. |
| `human_interaction_required` | timeout d'inactivité atteint, prompt conffile/debconf/needrestart/apt-listchanges détecté | error | Reprise manuelle ; ne pas forcer ; lignes importantes fournies. |
| `kernel_partial_config` | `needrestart` signale services à redémarrer, `reboot-required` | warning | Planifier `reboot_verified`. |
| `apt_unknown_error` | exit ≠ 0 sans motif identifié | error | Consulter le log brut archivé. |
### Gestion des interactions humaines (couverture §7)
- Upgrades réels : `DEBIAN_FRONTEND=noninteractive`, `apt-get -y`, `-o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold`.
- Justification politique par défaut : **conserver les fichiers de config locaux** quand dpkg ne peut pas trancher (ne pas écraser une config distante).
- Prompts potentiels (conffile, debconf, apt-listchanges, needrestart, service restart, maintainer script) = **risques de blocage à détecter**, jamais des dialogues exposés dans le terminal.
- **Timeout d'inactivité** (`inactivityTimeout`, défaut 600 s) et/ou **timeout global** → classer l'exécution en erreur contrôlée `human_interaction_required` si une action reste bloquée. Le backend (couche SSH) détecte l'absence de nouvelles données et coupe proprement, en marquant l'exécution.
---
## 3. Taxonomie Docker (alignée §6 de la validation)
| `kind` | Détection | Sévérité | Remédiation |
|---|---|---|---|
| `docker_not_installed` | `docker: command not found`, exit 127 | error | Proposer profil `docker_official`. |
| `compose_not_found` | dossier/fichier compose absent, `no configuration file provided` | error | Vérifier `composeRoots`/chemin du stack. |
| `compose_config_invalid` | `docker compose config --quiet` exit ≠ 0 | error | Corriger le fichier compose ; stack reste `candidate`. |
| `registry_auth_failed` | `unauthorized`, `denied`, `pull access denied` | error | Vérifier l'auth registry **sur la machine** (jamais lire les creds) ; message nettoyé. |
| `pull_failed` | `Error response from daemon`, `manifest unknown`, timeout | warning/error | Vérifier réseau/tag/registry ; retenter. |
| `image_inspect_failed` | `No such image`, exit ≠ 0 sur inspect | warning | Image absente localement ; relancer pull-check. |
| `up_failed` | `docker compose up` exit ≠ 0 | error | Examiner logs du service ; conserver l'ancien conteneur. |
| `container_unhealthy` | health `unhealthy` après up | warning | Surveiller ; proposer rollback manuel. |
| `prune_failed` | `docker image prune` exit ≠ 0 | warning | Vérifier l'état du daemon. |
| `disk_space_low` | `no space left on device` pendant pull/up | error | Prune sûr, libérer de l'espace. |
---
## 4. Taxonomie réseau / post-install (couverture §8)
| `kind` | Sévérité | Remédiation |
|---|---|---|
| `network_config_invalid` | error | Restaurer la sauvegarde `/etc/network/interfaces.su.bak.*`. |
| `interface_not_found` | error | Vérifier `interfaceName` (sonde `machine_probe`). |
| `dns_config_failed` | warning | Vérifier `resolvconf`/`dnsNameservers`. |
| `reconnect_failed` | error | La webapp retente sur `reconnectHost` ; rollback si échec. |
| `hostname_failed` | error | Vérifier droits / `hostnamectl`. |
| `sudo_setup_failed` | error | Reprendre `bootstrap_root` depuis un contexte root. |
---
## 5. Robustesse, idempotence, reprise
- **Idempotence** : les templates de détection (`update-analyze`, `docker_scan`, `inspect`, `pull-check`) sont rejouables sans effet de bord applicatif (pull-check écrit dans le cache images mais ne démarre rien — rejouable).
- **Opérations longues** : voir `90-questions-investigation.md` Q6. MVP : `nohup` + fichier exit-code pour les actions applicatives longues (full-upgrade, docker apply), reboot vérifié via boot_id ; refresh reste synchrone court.
- **Reprise** : une exécution coupée laisse un état lisible (sections déjà émises + exit-code sur disque côté machine). Le backend peut relire l'état au lieu de tout relancer.
- **Verrous** : `machine_locks` (`tache1.9.md`) empêche deux actions concurrentes destructives sur une même machine (`apt`, `docker`, `reboot`, `exclusive`).