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>
12 KiB
10 — Templates APT : inventaire, sémantique et pseudo-shell
Axe A + livrables §4.1 et §4.2. Cohérent avec
templates/apt/check.sh.tpl,full-upgrade.sh.tpl,reboot.sh.tplexistants, la convention===SU:XXX===,LC_ALL=C,DEBIAN_FRONTEND=noninteractive, exécution soussudo -S(server/ssh/client.ts).
1. Sémantique APT clarifiée (manpage apt-get)
| Commande | Effet | Peut supprimer ? | Peut installer du nouveau ? |
|---|---|---|---|
apt-get update |
Resynchronise les index de paquets. Ne modifie aucun paquet installé. | non | non |
apt-get -s upgrade |
Simulation : installe les nouvelles versions des paquets installés sans jamais supprimer ni installer de nouveaux paquets. Les paquets dont l'upgrade exigerait une suppression/installation restent held back. | non | non |
apt-get -s dist-upgrade / full-upgrade |
Simulation : gère intelligemment les changements de dépendances, peut installer de nouveaux paquets et en supprimer pour satisfaire les dépendances. | oui | oui |
apt-get autoremove |
Retire les dépendances automatiquement installées et devenues inutiles. | oui | non |
apt-get clean |
Vide le cache local /var/cache/apt/archives. N'affecte pas l'état des paquets. |
non | non |
apt full-upgrade(commandeapt) ≡apt-get dist-upgrade(commandeapt-get). On utilise toujoursapt-geten script (non interactif, stable), jamaisapt(UI humaine). L'UI parle d'« full-upgrade » comme alias convivial ; la commande système estapt-get dist-upgrade.
Lignes documentées parsées : Inst <pkg> [<cur>] (<target> <origin> [<arch>]), Conf <pkg>, Remv <pkg>. Le log brut complet reste archivé ; seules ces lignes + E:/W:/dpkg:/reboot-required alimentent Hermes.
Sources : apt-get https://manpages.debian.org/apt-get · dpkg https://manpages.debian.org/dpkg · dpkg-query https://manpages.debian.org/dpkg-query · apt-listchanges https://manpages.debian.org/bookworm/apt-listchanges/apt-listchanges.1.en.html · needrestart https://manpages.debian.org/bookworm/needrestart/needrestart.1.en.html
2. Inventaire des templates APT
| Template | Action (ActionType) |
Rôle | Type | OS ciblés | Destructif ? | Marqueurs |
|---|---|---|---|---|---|---|
apt/update-analyze.sh.tpl |
apt_update_analyze |
Refresh index + simulation upgrade et dist-upgrade + reboot-check. Tâche de fond, non destructif. Remplace/étend l'actuel check.sh.tpl. |
snapshot | tous | non | ===SU:APT_UPDATE===, ===SU:APT_SIM_UPGRADE===, ===SU:APT_SIM_DISTUPGRADE===, ===SU:APT_HELD===, ===SU:REBOOT===, ===SU:EXIT=N=== |
apt/upgrade.sh.tpl |
apt_upgrade |
Applique l'upgrade simple (sans suppression volontaire). Snapshot dpkg avant/après. | action | tous | oui (modif paquets) | ===SU:DPKG_BEFORE===, ===SU:APT_UPGRADE===, ===SU:DPKG_AFTER===, ===SU:REBOOT===, ===SU:EXIT=N=== |
apt/full-upgrade.sh.tpl |
apt_full_upgrade |
Applique apt-get dist-upgrade. Conserve l'existant (jalon 1) en l'enrichissant du diff dpkg. |
action | tous | oui (peut supprimer) | idem upgrade + ===SU:APT_FULLUPGRADE=== |
apt/autoremove.sh.tpl |
apt_autoremove |
Retire les dépendances inutiles, avec simulation préalable affichée. | action | tous | oui (supprime) | ===SU:APT_SIM_AUTOREMOVE===, ===SU:DPKG_BEFORE===, ===SU:APT_AUTOREMOVE===, ===SU:DPKG_AFTER===, ===SU:EXIT=N=== |
apt/clean.sh.tpl |
apt_clean |
Vide le cache des paquets téléchargés. Action séparée, peu risquée. | action | tous | non (cache only) | ===SU:APT_CLEAN===, ===SU:EXIT=N=== |
apt/reboot-check.sh.tpl |
(intégré au refresh) | Vérifie /run/reboot-required, /var/run/reboot-required, liste reboot-required.pkgs, état needrestart -b. |
snapshot | tous | non | ===SU:REBOOT=== |
apt/reboot.sh.tpl |
reboot_verified |
Lit boot_id avant, planifie le reboot, émet un marqueur parsable avant coupure SSH. Conserve l'existant en ajoutant boot_id. |
action | tous | oui (reboot) | ===SU:BOOT_ID_BEFORE===, ===SU:REBOOT_NOW=== |
Compatibilité jalon 1 :
apt_full_upgradeetrebootrestent des actions valides.check.sh.tpln'est pas supprimé ;update-analyze.sh.tplest son successeur enrichi (le refresh peut basculer dessus sans casser le parsing existant — voir §6 ci-dessous).
3. Variables de rendu (Mustache)
Étend TemplateVars (extension proposée, voir 40-contrats-json.md). Variables utilisées par les templates APT :
aptProxy string|null proxy apt-cacher-ng injecté à l'exécution (mode runtime)
osProfile string debian | ubuntu | proxmox | raspbian
machineKind string physical | vm | proxmox_host | lxc | raspberry_pi | workstation
confValues bool true => --force-confdef --force-confold (défaut)
inactivityTimeout int secondes; 0 = désactivé (défaut 600)
Les sections Mustache {{#aptProxy}}…{{/aptProxy}} restent identiques à l'existant.
4. Pseudo-shell des templates clés
4.1 apt/update-analyze.sh.tpl (refresh + analyse, non destructif)
#!/bin/sh
# Refresh index + simulations upgrade/dist-upgrade + reboot-check.
# Exécuté entier sous sudo par la couche SSH. Non destructif.
export LC_ALL=C
export DEBIAN_FRONTEND=noninteractive
{{#aptProxy}}export http_proxy="{{aptProxy}}"; export https_proxy="{{aptProxy}}"
{{/aptProxy}}
echo "===SU:APT_UPDATE==="
apt-get update -qq 2>&1
UPD=$?
echo "===SU:APT_SIM_UPGRADE==="
apt-get -s -y upgrade 2>&1
echo "===SU:APT_SIM_DISTUPGRADE==="
apt-get -s -y dist-upgrade 2>&1
echo "===SU:APT_HELD==="
# Paquets retenus (held back) : présents en dist-upgrade mais pas en upgrade.
apt-mark showhold 2>/dev/null
echo "===SU:REBOOT==="
if [ -f /run/reboot-required ] || [ -f /var/run/reboot-required ]; then
echo "REBOOT_REQUIRED=1"
[ -f /var/run/reboot-required.pkgs ] && sed 's/^/PKG=/' /var/run/reboot-required.pkgs
else
echo "REBOOT_REQUIRED=0"
fi
# needrestart en mode batch/list si présent (jamais interactif).
command -v needrestart >/dev/null 2>&1 && needrestart -b 2>/dev/null | grep -E '^NEEDRESTART-(KSTA|SVC)' || true
echo "===SU:EXIT=${UPD}==="
Le backend parse :
- section
APT_SIM_UPGRADE→ listeupgrade(paquetsInst), - section
APT_SIM_DISTUPGRADE→ listedist-upgrade(inclutInstnouveaux +Remvsuppressions), held=APT_HELD(et/ou paquets présents en dist-upgrade absents d'upgrade),REBOOT_REQUIRED+PKG=→ reboot requis + paquets concernés.
Statut snapshot APT : ok si rien ; updates_available si Inst non vides ; warning si dist-upgrade implique des Remv ou des held ; error si APT_UPDATE échoue (dépôt injoignable, clé GPG…).
4.2 apt/full-upgrade.sh.tpl (application, avec diff dpkg)
#!/bin/sh
export LC_ALL=C
export DEBIAN_FRONTEND=noninteractive
{{#aptProxy}}export http_proxy="{{aptProxy}}"; export https_proxy="{{aptProxy}}"
{{/aptProxy}}
echo "===SU:DPKG_BEFORE==="
dpkg-query -W -f='${binary:Package}\t${Version}\t${Architecture}\n' 2>/dev/null
echo "===SU:APT_FULLUPGRADE==="
apt-get -y \
-o Dpkg::Options::=--force-confdef \
-o Dpkg::Options::=--force-confold \
dist-upgrade 2>&1
CODE=$?
echo "===SU:DPKG_AFTER==="
dpkg-query -W -f='${binary:Package}\t${Version}\t${Architecture}\n' 2>/dev/null
echo "===SU:REBOOT==="
if [ -f /run/reboot-required ] || [ -f /var/run/reboot-required ]; then echo "REBOOT_REQUIRED=1"; else echo "REBOOT_REQUIRED=0"; fi
echo "===SU:EXIT=${CODE}==="
Le backend compare DPKG_BEFORE et DPKG_AFTER (clé = package+arch) → installed / upgraded / removed / unchanged, versions finales réelles. L'exit code seul ne suffit pas : un paquet annoncé en simulation mais resté inchangé est signalé comme anomalie.
Politique non interactive justifiée :
--force-confdef+--force-confoldconservent les fichiers de config locaux quand dpkg ne peut pas trancher, pour ne pas écraser une configuration distante. Les prompts (conffile, debconf, apt-listchanges, needrestart) sont traités comme risques de blocage à détecter (timeout d'inactivité), pas comme dialogues à exposer. Voir50-erreurs.md(human_interaction_required).
4.3 apt/autoremove.sh.tpl
#!/bin/sh
export LC_ALL=C
export DEBIAN_FRONTEND=noninteractive
echo "===SU:APT_SIM_AUTOREMOVE==="
apt-get -s -y autoremove 2>&1 # prévisualisation des Remv
echo "===SU:DPKG_BEFORE==="
dpkg-query -W -f='${binary:Package}\t${Version}\t${Architecture}\n' 2>/dev/null
echo "===SU:APT_AUTOREMOVE==="
apt-get -y autoremove 2>&1
CODE=$?
echo "===SU:DPKG_AFTER==="
dpkg-query -W -f='${binary:Package}\t${Version}\t${Architecture}\n' 2>/dev/null
echo "===SU:EXIT=${CODE}==="
Confirmation UI explicite requise (action qui supprime des paquets).
4.4 apt/clean.sh.tpl
#!/bin/sh
export LC_ALL=C
echo "===SU:APT_CLEAN==="
BEFORE=$(du -sb /var/cache/apt/archives 2>/dev/null | awk '{print $1}')
apt-get clean 2>&1
AFTER=$(du -sb /var/cache/apt/archives 2>/dev/null | awk '{print $1}')
echo "FREED_BYTES=$((BEFORE - AFTER))"
echo "===SU:EXIT=0==="
4.5 apt/reboot.sh.tpl (reboot vérifié — capture boot_id)
#!/bin/sh
export LC_ALL=C
echo "===SU:BOOT_ID_BEFORE==="
cat /proc/sys/kernel/random/boot_id 2>/dev/null
echo "===SU:REBOOT_NOW==="
# Reboot différé pour laisser le canal SSH se fermer proprement.
nohup sh -c 'sleep 2; reboot' >/dev/null 2>&1 &
echo "reboot planifié"
Le backend orchestre la vérification (hors template) : il a lu boot_id avant, attend la coupure SSH, retente la connexion (délai adaptatif), relit boot_id via runPlain (cat /proc/sys/kernel/random/boot_id). Reboot ok seulement si la machine revient ET boot_id a changé. Statuts d'échec : reboot_command_failed, ssh_never_went_down, machine_did_not_return, boot_id_unchanged, timeout. Champs résultat : beforeBootId, afterBootId, requestedAt, sshWentDownAt, sshCameBackAt, waitedSeconds, status, errors. Délai adaptatif par machine : lastRebootDurationSeconds → nextRecommendedWaitSeconds (avec marge). Voir 40-contrats-json.md (RebootResult).
5. Spécificités par profil OS (détail dans 60-profils-os-machine.md)
- Debian : avant de proposer firmware/drivers propriétaires, vérifier la présence des composants
contrib,non-free,non-free-firmware(templateapt/check-components.sh.tpl, lecture seule). Pas d'activation automatique. - Ubuntu :
ubuntu-drivers devices(lecture) pour proposer des drivers (NVIDIA/GPU) — proposition uniquement, jamais installé par défaut. - Proxmox : profil dédié. Vérifier dépôts PVE (
pve-no-subscriptionvsenterprise), meta-packageproxmox-ve, kernel PVE, Ceph éventuel, puisapt-get dist-upgrade. Ne jamais traiter comme une Debian générique. - Raspberry Pi OS : profil dédié. Attention firmware/kernel, vérifier l'espace disque avant upgrade, utiliser
full-upgrade.
Le template le plus spécifique disponible sous templates/<profil>/<commande>.sh.tpl est choisi, sinon fallback templates/apt/<commande>.sh.tpl (profil base).
6. Compatibilité et migration (non-régression jalon 1)
- L'actuel
check.sh.tplproduit===SU:UPDATE===/===SU:SIMULATE===/===SU:REBOOT===/===SU:END===. Le nouveauupdate-analyze.sh.tplajoute des sections sans supprimer la sémantique : le parsing actuel (extractSection(raw, "===SU:SIMULATE===", "===SU:REBOOT===")) peut être conservé en parallèle pendant la migration. - Recommandation MVP : introduire
update-analyze.sh.tplcomme nouveau template et faire pointer le refresh dessus dans un sous-jalon dédié, en gardantcheck.sh.tpljusqu'à bascule validée. Aucune rupture du flux prouvé en prod. full-upgrade.sh.tpletreboot.sh.tplexistants restent fonctionnels ; on ajoute les sectionsDPKG_BEFORE/AFTERetBOOT_ID_BEFORE(extension, pas remplacement de marqueurs).