v0.12.7: mandatory HDD backup, pre-dump, restore for all apps

Fix 1: HDD data backup is now mandatory for all deployed apps.
resolveAppBackupPaths() iterates ListDeployedStacks() directly — no
longer reads GetAppBackupMap() or checks the Enabled flag. DiscoverAppData()
drops backupPrefs parameter; BackupEnabled is set from HasHDDData.
Five dead settings methods removed: IsAppBackupEnabled, SetAppBackup,
GetAppBackupMap, SetAppBackupBulk, GetAppBackupPrefs.

Fix 2: Cross-drive backup now triggers a fresh DB dump (DumpStackDB)
before running. DBDumper interface added to crossdrive.go; Manager
implements it; SetDBDumper wired in main.go. Non-fatal — proceeds with
user data backup even if DB dump fails.

Fix 3: Restore dropdown shows ALL deployed apps (not just HDD+enabled).
restore.go rewritten: always restores config+DB, adds user data if hasHDD.
UI shows restore type banner (full / config+DB / config only) with
color-coded styling. Snapshot API clarified for non-HDD apps.

Fix 4: "Docker kötetek" → "Konfiguráció" — named volumes are not in
the restic backup paths; compose files + app.yaml are what's backed up.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-18 10:38:51 +01:00
parent 263b58dea0
commit 6c1762141a
11 changed files with 225 additions and 124 deletions
+23 -4
View File
@@ -281,7 +281,7 @@
</div>
<!-- Volume layer -->
<div class="backup-layer-row">
<span class="layer-label">Docker kötetek</span>
<span class="layer-label">Konfiguráció</span>
<span class="layer-badge">Auto</span>
{{if .VolumeLastRun}}
<span class="layer-last">Utolsó: {{.VolumeLastRun}}
@@ -450,9 +450,7 @@
<select id="restore-app" class="restore-select" onchange="onRestoreAppChange()">
<option value="">— Válasszon —</option>
{{range .Backup.AppDataInfo}}
{{if and .HasHDDData .BackupEnabled}}
<option value="{{.StackName}}">{{.DisplayName}}</option>
{{end}}
<option value="{{.StackName}}" data-has-hdd="{{.HasHDDData}}" data-has-db="{{.HasDBDump}}">{{.DisplayName}}</option>
{{end}}
</select>
</div>
@@ -462,6 +460,8 @@
<option value="">— Válasszon alkalmazást —</option>
</select>
</div>
<div id="restore-type-info" class="restore-info" style="display:none;margin-bottom:0.5rem">
</div>
<div id="restore-no-snapshots" class="restore-warning" style="display:none;">
Még nincs mentés felhasználói adattal.
</div>
@@ -606,16 +606,35 @@ function onRestoreAppChange() {
var appName = sel.value;
var snapSel = document.getElementById('restore-snapshot');
var noSnaps = document.getElementById('restore-no-snapshots');
var typeInfo = document.getElementById('restore-type-info');
document.getElementById('restore-confirm-cb').checked = false;
document.getElementById('restore-btn').disabled = true;
noSnaps.style.display = 'none';
typeInfo.style.display = 'none';
if (!appName) {
snapSel.innerHTML = '<option value="">— Válasszon alkalmazást —</option>';
return;
}
// Determine restore type from data attributes
var opt = sel.options[sel.selectedIndex];
var hasHDD = opt.getAttribute('data-has-hdd') === 'true';
var hasDB = opt.getAttribute('data-has-db') === 'true';
if (hasHDD) {
typeInfo.innerHTML = '🔄 Teljes visszaállítás: adatbázis + konfiguráció + felhasználói adatok a kiválasztott pillanatképből.';
typeInfo.className = 'restore-info';
} else if (hasDB) {
typeInfo.innerHTML = ' Adatbázis és konfiguráció visszaállítása — az alkalmazásnak nincs külön felhasználói adata.';
typeInfo.className = 'restore-info restore-info-partial';
} else {
typeInfo.innerHTML = ' Csak konfiguráció visszaállítása (compose fájlok, beállítások).';
typeInfo.className = 'restore-info restore-info-partial';
}
typeInfo.style.display = 'block';
snapSel.innerHTML = '<option value="">— Betöltés... —</option>';
fetch('/api/backup/snapshots?stack=' + encodeURIComponent(appName))
@@ -1921,6 +1921,21 @@ a.stat-card:hover {
line-height: 1.4;
}
/* --- Backup page: Restore type info banners --- */
.restore-info {
padding: 0.5rem 0.75rem;
border-radius: 6px;
font-size: 0.85rem;
background: rgba(59, 130, 246, 0.1);
border: 1px solid rgba(59, 130, 246, 0.3);
color: #93c5fd;
}
.restore-info-partial {
background: rgba(251, 191, 36, 0.1);
border-color: rgba(251, 191, 36, 0.3);
color: #fcd34d;
}
/* --- Backup page: Restore section --- */
.restore-section {
display: flex;