Files
deploy-felhom-compose/controller/internal/setup/templates/setup_restore_exec.html
T
admin 80b756f0e4 fix: mount drives after restore + poll-based redirect
Restore flow now calls MountDrivesFromLayout() after writing config,
which mounts drives by UUID and adds fstab entries. Previously drives
from the infra backup were never mounted, causing "Adattároló nem
elérhető" warnings.

Post-restore redirect now polls until the controller responds instead
of using a fixed 5-second timeout that was too short for container
restart.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 15:07:38 +01:00

92 lines
3.7 KiB
HTML

{{define "setup_restore_exec"}}
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Visszaállítás folyamatban — Felhom</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body class="login-body">
<div class="setup-container">
<div class="setup-header">
<img src="/static/felhom-logo.svg" alt="Felhom.eu" style="width: 120px;">
<h1>Visszaállítás</h1>
</div>
<div class="setup-card">
<ul class="step-list" id="steps">
<li><span class="spinner"></span> Indítás...</li>
</ul>
</div>
<div id="done-msg" style="display: none;">
<div class="alert alert-info">Visszaállítás sikeres! A vezérlőpult újraindul...</div>
</div>
<div id="error-msg" style="display: none;">
<div class="alert alert-error" id="error-text"></div>
<div style="display: flex; gap: 0.75rem; margin-top: 1rem;">
<a href="/setup/failed" class="btn btn-outline">Tovább</a>
</div>
</div>
</div>
<script>
(function() {
function waitForRestart() {
fetch('/', {redirect: 'follow'})
.then(function(r) {
if (r.ok) {
window.location.href = '/';
} else {
setTimeout(waitForRestart, 2000);
}
})
.catch(function() {
setTimeout(waitForRestart, 2000);
});
}
function poll() {
fetch('/setup/restore/status')
.then(function(r) { return r.json(); })
.then(function(data) {
var list = document.getElementById('steps');
if (data.steps && data.steps.length > 0) {
list.innerHTML = '';
data.steps.forEach(function(step) {
var li = document.createElement('li');
var icon = '';
if (step.status === 'done') icon = '<span class="step-done">&#10003;</span>';
else if (step.status === 'running') icon = '<span class="spinner"></span>';
else if (step.status === 'failed') icon = '<span class="step-failed">&#10007;</span>';
else icon = '<span style="color: var(--text-secondary);">&#9675;</span>';
li.innerHTML = icon + ' ' + step.label;
if (step.error) li.innerHTML += '<br><small style="color: var(--red, #f85149);">' + step.error + '</small>';
list.appendChild(li);
});
}
if (data.error) {
document.getElementById('error-msg').style.display = 'block';
document.getElementById('error-text').textContent = data.error;
return;
}
if (data.done) {
document.getElementById('done-msg').style.display = 'block';
setTimeout(waitForRestart, 3000);
return;
}
setTimeout(poll, 1500);
})
.catch(function() {
// Connection lost — controller is restarting
document.getElementById('done-msg').style.display = 'block';
setTimeout(waitForRestart, 3000);
});
}
poll();
})();
</script>
</body>
</html>
{{end}}