# 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.