Files
system_update/docs/superpowers/plans/2026-06-06-tache2-sj8-post-install.md
T
gilles e6f4ae470b feat(post-install): moteur de profils + bootstrap + identité/réseau (tâche 2 SJ-8)
- templates custom/bootstrap-root + identity-network (sortie structurée parsable,
  sauvegardes, échec contrôlé, jamais de coupure réseau sans reconnexion)
- postInstall: registre de manifestes (champs typés + defaults/defaultFrom),
  validateProfileValues + maskSecretValues + buildPostInstallResult (TDD),
  renderProfile/previewProfile (masquage secrets), runPostInstall (SSH)
- execute: RunActionOpts.profileId/values + branche post_install (bloc postInstall)
- action_requests: post_install accepté, payload profileId/values transmis à approve
- routes: GET /profiles, POST .../preview (script masqué + validation),
  POST .../run (action_request si requiresConfirmation, sinon direct)

Champs = formulaire (pas de question SSH interactive) ; secrets jamais sérialisés ;
identity_network exige confirmation. tsc 0 · 101 tests · build OK · boot OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 08:02:32 +02:00

2.8 KiB

Tâche 2 — SJ-8 : Post-install (moteur de profils + bootstrap + identité/réseau)

Statut : backend implémenté (2026-06-06). tsc 0 · 101 tests · build OK · boot OK. Réf. design : docs/design/tache2/30-scripts-custom.md, 40-contrats-json.md §4, 80-sous-jalons.md SJ-8. Non testé en live (post-install destructif : modifie sudo/réseau d'une vraie machine).

Périmètre livré

Moteur de profils post-install non interactif : tout choix devient un champ de formulaire validé côté backend ; preview avec masquage des secrets ; exécution SSH + parsing PostInstallResult ; confirmation explicite (action_request) pour les profils à risque.

Composants

  • Templates templates/custom/bootstrap-root.sh.tpl (sudo + ca-certificates + curl, ajout groupe sudo) et identity-network.sh.tpl (hostname + IP statique, sauvegarde des fichiers, jamais de coupure sans reconnexion planifiée). Sortie structurée parsable (PKG_INSTALLED=, FILE_MODIFIED=, OLD/NEW_ENDPOINT=, REBOOT_REQUESTED=1, ERR=).
  • server/services/postInstall.ts :
    • registre PROFILES (manifestes : id, label, risk, requiresConfirmation, fields[] avec types string|hostname|ipv4|ipv4_cidr|ipv4_list|select|bool|int|path|secret, default/defaultFrom).
    • validateProfileValues (requis + formats IPv4/CIDR/hostname) — TDD.
    • maskSecretValues (champs secret********) — TDD ; previewProfile masque avant rendu.
    • buildPostInstallResult (parse → filesModified/packagesInstalled/networkChange/reboot/errors) — TDD.
    • renderProfile / runPostInstall (valide puis SSH, statut ok/error).
  • execute.ts : RunActionOpts.profileId/values, branche post_install (archiveExecution + bloc postInstall).
  • actionRequests.ts : post_install accepté ; payload transporte profileId/values ; approve les repasse à runAction.
  • Routes : GET /api/profiles, POST /machines/:id/profiles/:id/preview (script masqué + validation), POST /machines/:id/profiles/:id/run (→ action_request si requiresConfirmation, sinon exécution directe).

Sécurité / invariants

  • Aucune question interactive SSH ; échec contrôlé si décision manquante.
  • Secrets jamais sérialisés : previewProfile masque, variablesUsed = non sensible only.
  • identity_network (network_change) exige confirmation explicite via action_request.
  • Reconnexion réseau : OLD/NEW_ENDPOINT + RECONNECT_REQUIRED remontés ; reboot via reboot_verified (futur).

Reste (SJ-9 + tâche 4)

SJ-9 : profils base_tools, network_tools, docker_official, sharing, vm_guest_tools (+ install-package-groups). Persistance install_profiles/machine_profile_state/ script_variables_presets et catalogue détaillé = tâche 4. UI (formulaires de profils, preview) = tâche 3.