v1.8.0: Refonte UX update firmware (progress bar live + streaming logs)

L'ancien flow etait un AJAX bloquant qui attendait ~90s sans aucun
retour visuel autre qu'un spinner.

Nouveau flow:
- Backend: launcher.php lance update_firmware.sh en background
  (route update_firmware_start) et expose une route de polling
  incremental (update_firmware_progress) avec offset.
- Frontend: progress bar Bootstrap animee + label de l'etape en
  cours + timer mm:ss / estimation, plus streaming des logs
  toutes les 700ms.
- Sous-etape Step 3c (la plus longue): interpolation fine de la
  progression en comptant les 'Started X' (services demarres).
- Logs techniques masques par defaut dans <details>, ouverts
  automatiquement en cas d'echec pour faciliter le debug.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
PaulVua
2026-05-12 17:53:44 +02:00
parent 5d7aac38e1
commit 7338381c98
4 changed files with 323 additions and 50 deletions

View File

@@ -418,7 +418,7 @@ if ($type == "update_firmware") {
// Execute the comprehensive update script
$command = 'sudo /var/www/nebuleair_pro_4g/update_firmware.sh 2>&1';
$output = shell_exec($command);
// Return the output as JSON for better web display
header('Content-Type: application/json');
echo json_encode([
@@ -428,6 +428,71 @@ if ($type == "update_firmware") {
]);
}
// Start firmware update in background, returns immediately so the UI can poll progress.
// Output is written to a temp log file. A 'done' marker file is created when finished.
if ($type == "update_firmware_start") {
$logFile = '/tmp/nebuleair_firmware_update.log';
$doneFile = '/tmp/nebuleair_firmware_update.done';
// Reset previous run markers
@file_put_contents($logFile, '');
@unlink($doneFile);
// Launch in background:
// - run the update script, capture stdout/stderr into log
// - append "EXIT_CODE=N" so the UI can detect success/failure
// - touch the done file so the UI knows the run finished
// - detach all stdio from PHP so this call returns immediately
$cmd = '(sudo /var/www/nebuleair_pro_4g/update_firmware.sh > '
. escapeshellarg($logFile) . ' 2>&1; '
. 'echo "EXIT_CODE=$?" >> ' . escapeshellarg($logFile) . '; '
. 'touch ' . escapeshellarg($doneFile) . ') > /dev/null 2>&1 &';
shell_exec($cmd);
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'started_at' => time(),
'log_file' => $logFile
]);
exit;
}
// Poll firmware update progress. The UI sends the byte offset it has already read,
// we return any new content since that offset and whether the run has finished.
if ($type == "update_firmware_progress") {
$logFile = '/tmp/nebuleair_firmware_update.log';
$doneFile = '/tmp/nebuleair_firmware_update.done';
$offset = isset($_GET['offset']) ? (int)$_GET['offset'] : 0;
$content = '';
$newOffset = $offset;
if (file_exists($logFile)) {
$size = filesize($logFile);
if ($size > $offset) {
$fp = fopen($logFile, 'r');
if ($fp) {
fseek($fp, $offset);
$content = fread($fp, $size - $offset);
fclose($fp);
}
$newOffset = $size;
}
}
$done = file_exists($doneFile);
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'content' => $content,
'offset' => $newOffset,
'done' => $done
]);
exit;
}
if ($type == "upload_firmware") {
// Firmware update via ZIP file upload (offline mode)
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {