feat(post-install): identity_network reboote et rebascule l'IP en BDD (tâche 4)

- updateMachine accepte name/hostname/port (correction d'identité réseau)
- rebootAndRebind : reboot sur l'ancienne connexion → attente du retour sur la
  NOUVELLE IP (verifyReboot avec host cible) → maj BDD (hostname + nom) si OK.
  Sécurité : BDD inchangée si la machine ne revient pas (récupération console/backups)
- execute post_install : si identity_network + reboot coché + succès, déclenche
  rebootAndRebind et joint le RebootResult ; statut error si reconnexion échoue

tsc 0 · 113 tests · build OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 19:12:39 +02:00
parent 3ea2e66359
commit 1530409d3b
3 changed files with 77 additions and 7 deletions
+21 -4
View File
@@ -52,6 +52,7 @@ function archiveExecution(args: {
importantLines: string[];
docker?: ExecutionResult["docker"];
postInstall?: ExecutionResult["postInstall"];
reboot?: ExecutionResult["reboot"];
errors?: ExecutionResult["errors"];
}): ExecutionResult {
const { machineId, machineName, executionId, action, startedAt, status, raw, importantLines } = args;
@@ -68,6 +69,7 @@ function archiveExecution(args: {
rawLogRef: rawLogPath, reportRef: reportPath,
...(args.docker ? { docker: args.docker } : {}),
...(args.postInstall ? { postInstall: args.postInstall } : {}),
...(args.reboot ? { reboot: args.reboot } : {}),
...(args.errors && args.errors.length ? { errors: args.errors } : {}),
};
writeFileSync(reportPath, buildReportMarkdown(result, machineName), "utf8");
@@ -340,7 +342,7 @@ export async function runAction(
// --- SJ-8 : post-install (profil + champs de formulaire) ---
if (action === "post_install") {
if (!opts?.profileId) throw new Error("post_install requiert un profileId");
const { runPostInstall } = await import("./postInstall.js");
const { runPostInstall, rebootAndRebind } = await import("./postInstall.js");
try {
const o = await runPostInstall(machineId, opts.profileId, opts.values ?? {}, () => {});
const r = o.result;
@@ -351,10 +353,25 @@ export async function runAction(
...(r.networkChange ? [` réseau : ${r.networkChange.oldEndpoint ?? "?"}${r.networkChange.newEndpoint ?? "?"} (reconnexion ${r.networkChange.reconnectHost ?? "?"})`] : []),
...(r.errors?.map((e) => ` [${e.kind}] ${e.message}`) ?? []),
];
outputHub.publish(machineId, `\n===SU:DONE status=${o.status}===\n`);
// identity_network + reboot coché + succès : reboote, attend la nouvelle IP, corrige la BDD.
let rebootResult: ExecutionResult["reboot"];
const newHost = r.networkChange?.reconnectHost ?? r.networkChange?.newEndpoint ?? null;
if (o.status === "ok" && opts.profileId === "identity_network" && opts.values?.rebootAfterInstall && newHost) {
const newName = opts.values?.newHostname != null ? String(opts.values.newHostname) : null;
rebootResult = await rebootAndRebind(machineId, newHost, newName, () => {});
important.push(
rebootResult.status === "ok"
? ` reboot vérifié → machine basculée sur ${newHost} (BDD mise à jour)`
: ` reboot/reconnexion : ${rebootResult.status} (BDD inchangée)`,
);
}
const finalStatus: ExecutionStatus = rebootResult && rebootResult.status !== "ok" ? "error" : o.status;
outputHub.publish(machineId, `\n===SU:DONE status=${finalStatus}===\n`);
return archiveExecution({
machineId, machineName: m.name, executionId, action, startedAt, status: o.status, raw: o.raw,
importantLines: important, postInstall: r, errors: r.errors,
machineId, machineName: m.name, executionId, action, startedAt, status: finalStatus, raw: o.raw,
importantLines: important, postInstall: r, reboot: rebootResult, errors: r.errors,
});
} catch (err) {
return archiveExecution({ machineId, machineName: m.name, executionId, action, startedAt, status: "error", raw: "", importantLines: [`[ERREUR] ${(err as Error).message}`] });