c7446f2d6a
R-225 — an unread store said '0 pillanatkép / 0 / 50 GB' above a card stating it held backups under another key. An SFTP listing found snapshot f3d9cd67 and 12 535 KB really there; snapshot_count and repo_size_bytes were simply ABSENT and the zero value spoke for them. StatsKnown is now NAMED, for the same reason OffsiteInventory.Empty is: zero is what an unread store and an empty one both look like, and on the wire 'absent' and '0' are the same bytes. The fill bar renders only when the fill is known — a 0%-wide bar is a picture of emptiness, and a picture is a claim. A measured zero still says zero. R-227 — WHICH LAYER ANSWERS: traefik, and this repo generates its config. But traefik v3 serves no static files, so a branded proxy page needs a new always-up container for every 502 on the box — out of proportion, and scoped in the report rather than built. Shipped instead: the unlock posts via fetch and answers a gateway failure in Hungarian without leaving the page. Progressive enhancement — with no JS the plain POST is unchanged and still shows the proxy's error, which the report says plainly rather than implying otherwise. R-228 — the set-aside history was recorded in orphaned_renamed_to and read by nobody: a census found zero references in any template or handler, while 12 535 KB sat at that path. It is surfaced as two facts and stops. It does NOT promise the history can be reopened, because it cannot be by anyone today (R-199's inventory is unbuilt) — and the set-aside CONFIRMATION copy was corrected for the same reason: 'a helyreállítási kód nélkül többé nem lesznek megnyithatók' implied that WITH the code they could be. The field's own comment called it 'recovery-code-recoverable', which was the same over-promise in the code. Tests: scenarios F, G, H as render tests per branch of each gate. Red-proofs, each demonstrated failing then restored: remove the StatsKnown guards (F, 'R-225 RETURNED: an unread store reports a snapshot COUNT of zero'), delete the set-aside block (H). The F assertion on the fill bar is scoped to the bar's own container — a bare width:0% search matched unrelated elements and would have passed for the wrong reason. 28 packages ok, vet clean, all controller gates OK (the emoji gate caught a warning sign in a template comment).
323 lines
23 KiB
HTML
323 lines
23 KiB
HTML
{{define "backups_remote"}}
|
||
{{template "layout_start" .}}
|
||
|
||
<div class="page-header">
|
||
<h2>Biztonsági mentés — Távoli mentés</h2>
|
||
<span class="domain-badge">{{.Domain}}</span>
|
||
</div>
|
||
|
||
{{template "backups_flash" .}}
|
||
|
||
{{if .RecoveryOffer}}
|
||
<!-- R-193: the PERMANENT entry point. Bound to RecoveryOffer, never to the postpone flag — a
|
||
customer who clicked "Most nem" once must not lose the route to their own data. -->
|
||
<div class="alert alert-warning">
|
||
<strong>A korábbi, házon kívüli mentéseid visszaszerezhetők.</strong>
|
||
Ezt a gépet újratelepítették, és a Felhom központi rendszere őriz hozzá egy lezárt csomagot. A
|
||
helyreállítási kódoddal feloldhatod a korábbi mentéseidet, és megnézheted, mi van bennük.
|
||
<div class="form-actions" style="margin-top:.5rem">
|
||
<a href="/recovery" class="btn btn-primary">Adatok visszaszerzése</a>
|
||
</div>
|
||
</div>
|
||
{{end}}
|
||
|
||
{{if not .Backup}}
|
||
{{template "backups_empty" .}}
|
||
{{else}}
|
||
|
||
<!-- Felhom-offsite status card (v0.124.0, decision 2): three honest states from LOCAL data only —
|
||
display + opt-in pointers, NEVER a state change (no form, no button in this card). State 3
|
||
(applied + apps toggled) is the existing status block below; the card renders nothing then. -->
|
||
{{if and (not .OffboxConfigured) .OffsiteHubEnabled}}
|
||
<!-- R-70 (v0.161.0): hub-managed offsite is provisioned for this box — "igényelhető" would be a
|
||
lie (it is already ordered) and the bare empty state hid the pre-apply window (DIAG-f10). -->
|
||
<div class="alert alert-info" style="margin-bottom:1rem" id="felhom-offsite-card">Felhom offsite tárhely kiépítve — a beállítás automatikus, folyamatban. Ha egy napon belül nem áll be, jelezd az üzemeltetőnek.</div>
|
||
{{else if not .OffboxConfigured}}
|
||
<div class="alert alert-info" style="margin-bottom:1rem" id="felhom-offsite-card">Felhom offsite tárhely — igényelhető szolgáltatás. Titkosított, házon kívüli másolat a mentéseidről. Érdeklődj az üzemeltetőnél.</div>
|
||
{{else if eq .OffboxToggledCount 0}}
|
||
<div class="alert alert-info" style="margin-bottom:1rem" id="felhom-offsite-card">Aktív — nincs kijelölt alkalmazás</div>
|
||
{{end}}
|
||
|
||
<!-- Off-box (NAS) backup — Part B: encrypted restic repo over SFTP (the off-site 3-2-1 leg). -->
|
||
<h3 id="offbox-section" class="backup-tier-divider">Távoli mentés (3. mentés) — titkosított, offsite</h3>
|
||
<p class="form-hint" style="margin:-0.25rem 0 1rem">Az alkalmazás-mentések titkosított másolata egy távoli tárolóra — saját NAS vagy Felhom offsite tárhely — restic + SFTP kapcsolaton. A tároló csak titkosított adatot lát. Ez a 3-2-1 szabály „1 off-site" lába — független a helyi másodpéldánytól és a teljes rendszermentéstől.</p>
|
||
<div class="card" style="margin-bottom:1.5rem">
|
||
{{if .Offbox}}
|
||
<div class="stats-grid backup-page-cards">
|
||
<div class="stat-card {{if or (eq .Offbox.LastStatus "error") (eq .Offbox.LastStatus "incomplete")}}stat-warn{{end}}">
|
||
<div class="stat-value" id="offbox-status-value" style="font-size:1.15rem">{{if eq .Offbox.LastStatus "ok"}}✓ Rendben{{else if eq .Offbox.LastStatus "incomplete"}}! Hiányos{{else if eq .Offbox.LastStatus "error"}}✗ Hiba{{else if eq .Offbox.LastStatus "running"}}Fut…{{else}}–{{end}}</div>
|
||
<div class="stat-label">Utolsó távoli mentés{{if .Offbox.LastRun}}<br><span class="relative-time">{{timeAgoStr .Offbox.LastRun}}</span>{{end}}</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-value" style="font-size:1.15rem">{{if and .Offbox.StatsKnown .Offbox.RepoSizeHuman}}{{.Offbox.RepoSizeHuman}}{{else}}–{{end}}</div>
|
||
<div class="stat-label">Tároló méret · {{if .Offbox.StatsKnown}}{{.Offbox.SnapshotCount}} pillanatkép{{else}}a pillanatképek száma még ismeretlen{{end}}</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-value" style="font-size:1.05rem">{{if .Offbox.Enabled}}{{.Offbox.User}}@{{.Offbox.Host}}{{else}}Kikapcsolva{{end}}</div>
|
||
<div class="stat-label">{{if .Offbox.Enabled}}{{.Offbox.RepoPath}}{{else}}A távoli mentés ki van kapcsolva{{end}}</div>
|
||
</div>
|
||
</div>
|
||
{{if and .Offbox.Enabled (gt .Offbox.QuotaGB 0)}}
|
||
<!-- R-225: the BAR renders only when the fill is known. A 0%-wide bar over an unread store is a
|
||
picture of emptiness, and a picture is a claim. -->
|
||
<!-- SLICE 4: soft-quota usage bar (shared model; quota_gb from the hub descriptor). -->
|
||
<div id="offbox-quota-bar" style="max-width:560px;margin:.5rem 0">
|
||
<div class="stat-label" style="margin-bottom:.25rem">Tárhelykeret: {{if .Offbox.StatsKnown}}{{if .Offbox.RepoSizeHuman}}{{.Offbox.RepoSizeHuman}}{{else}}0{{end}} / {{.Offbox.QuotaGB}} GB ({{.OffboxQuotaPct}}%){{else}}még nem tudjuk, mennyi van a tárolóban — legfeljebb {{.Offbox.QuotaGB}} GB{{end}}</div>
|
||
{{if .Offbox.StatsKnown}}<div style="background:var(--border,#334);border-radius:4px;height:8px;overflow:hidden">
|
||
<div style="height:8px;border-radius:4px;width:{{.OffboxQuotaPct}}%;background:{{if ge .OffboxQuotaPct 100}}var(--crit,#e5484d){{else if ge .OffboxQuotaPct 80}}var(--warn,#f5a524){{else}}var(--ok,#30a46c){{end}}"></div>
|
||
</div>{{end}}
|
||
</div>
|
||
{{end}}
|
||
{{/* R-228 — THE SET-ASIDE HISTORY IS SAID OUT LOUD.
|
||
The customer chose "I do not want the old data", was told it would be KEPT and not deleted,
|
||
and then it vanished from every screen: the box recorded exactly where it went
|
||
(OrphanedRenamedTo) and showed that to nobody. Measured 2026-08-05 (CAMPAIGN-11 F7) —
|
||
12 535 KB at a path with zero references in any template or handler.
|
||
|
||
NOTE — IT STATES TWO FACTS AND STOPS. It does NOT promise the history can be reopened, because it
|
||
cannot be: serving a superseded package is an unbuilt link (R-199's inventory). A conditional
|
||
promise that turns out false is worse here than saying less — the R-202 lesson. */}}
|
||
{{if .Offbox.OrphanedRenamedTo}}
|
||
<div class="alert alert-info" style="margin-top:.75rem">
|
||
<p><strong>A korábbi mentéseid félre vannak téve — nem töröltük őket.</strong></p>
|
||
<p class="form-hint">Amikor új mentési kulcsot kapott a géped, a régebbi előzményt átmozgattuk
|
||
a távoli tárhelyen, és ott is maradt. <strong>Megnyitni innen egyelőre nem lehet</strong>, és
|
||
ez nem a kódodon múlik. Ha szükséged van rá, keresd a Felhom ügyfélszolgálatát.</p>
|
||
</div>
|
||
{{end}}
|
||
{{if .Offbox.LastError}}<p class="form-hint" style="color:var(--crit)">Utolsó hiba: {{.Offbox.LastError}}</p>{{end}}
|
||
{{/* Part E: display pick — a stale zero-toggle warning is replaced once the selection
|
||
changed (neutral color: the replacement is reassurance, not a deviation). */}}
|
||
{{if .OffboxWarningDisplay}}<p class="form-hint"{{if eq .OffboxWarningDisplay .Offbox.LastWarning}} style="color:var(--warn)"{{end}}>{{.OffboxWarningDisplay}}</p>{{end}}
|
||
{{/* v0.142.0 offsite-repo continuity: the ORPHANED card replaces the raw restic error banner. The
|
||
remote holds backups written under a previous, no-longer-available key (reinstall shape). A
|
||
reset moves the old history aside (never deletes) and starts a fresh repo under the current key. */}}
|
||
{{if eq .Offbox.RepoState "orphaned"}}
|
||
<div class="card" style="border-left:3px solid var(--crit,#e5484d);margin:.75rem 0;padding:.75rem 1rem" id="offbox-orphan-card">
|
||
<p style="margin:0 0 .35rem;font-weight:600">A távoli tároló másik kulccsal készült mentéseket tartalmaz</p>
|
||
<p class="form-hint" style="margin:0 0 .5rem">A távoli tárhelyen lévő mentések egy korábbi, már nem elérhető kulccsal készültek (jellemzően újratelepítés után). Emiatt új mentés jelenleg nem írható a tárolóba. A meglévő mentések nem sérültek — a hozzájuk tartozó helyreállítási kóddal később visszaállíthatók lehetnek.</p>
|
||
<button type="button" class="btn btn-sm btn-outline" id="orphan-reveal" onclick="var c=document.getElementById('orphan-confirm');c.style.display='block';this.style.display='none'">Új távoli mentés indítása…</button>
|
||
<div id="orphan-confirm" style="display:none;margin-top:.6rem">
|
||
<p class="form-hint" style="margin:0 0 .5rem">A régi előzmény <strong>félretéve marad</strong> (nem törlődik), és a hozzá tartozó helyreállítási kóddal később visszaállítható lehet. Egy üres, új tároló jön létre a mostani kulccsal, és a következő mentés ide készül.</p>
|
||
<form method="POST" action="/backup/offbox/reset" style="display:inline">{{.CSRFField}}
|
||
<input type="hidden" name="confirm" value="1">
|
||
<button type="submit" class="btn btn-sm btn-primary">Megerősítés — új távoli mentés indítása</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
{{end}}
|
||
{{/* Escrow ceremony card (v0.127.0): the customer-driveable wizard replaced the manual-confirm
|
||
button (that deprecated endpoint stays for legacy blobs; its button is gone). States:
|
||
awaiting (v0.138.0: ceremony done, hub confirm pending) → info; awaiting timed out → warn +
|
||
re-ceremony CTA; pending → CTA; escrowed+stale → warning + re-ceremony CTA; escrowed clean →
|
||
secondary link; agent too old → the honest version note, no CTA. */}}
|
||
{{if .OffboxCeremonyAwaiting}}
|
||
{{/* v0.138.0: the report-cycle gap between a completed ceremony and the hub-verified flip.
|
||
Info (blue) accent — NOT a warning: nothing is wrong, the confirmation is simply in flight. */}}
|
||
<div class="card" style="border-left:3px solid var(--blue);margin:.75rem 0;padding:.75rem 1rem">
|
||
<p style="margin:0 0 .35rem"><strong>Helyreállítási kód létrehozva</strong></p>
|
||
<p class="form-hint" style="margin:0">A helyreállítási csomag elküldve a központba, megerősítésre vár — ez általában néhány másodperc, legfeljebb 15 perc.</p>
|
||
</div>
|
||
{{else if .OffboxCeremonyTimedOut}}
|
||
{{/* v0.138.0: the confirmation never arrived within two report cycles + slack — degrade to a
|
||
warning with the re-ceremony CTA, never an indefinite "waiting". */}}
|
||
<div class="card" style="border-left:3px solid var(--warn);margin:.75rem 0;padding:.75rem 1rem">
|
||
<p class="form-hint" style="color:var(--warn);margin:0 0 .5rem">A megerősítés nem érkezett meg a várt időn belül. Ellenőrizze az internetkapcsolatot, majd készítsen új helyreállítási kódot.</p>
|
||
{{if .EscrowAgentOK}}
|
||
<a href="/backup/escrow" class="btn btn-sm btn-primary">Új helyreállítási kód készítése</a>
|
||
{{else}}
|
||
<p class="form-hint" style="margin:0">A funkcióhoz az ügynök frissítése szükséges — a frissítés automatikusan megérkezik.</p>
|
||
{{end}}
|
||
</div>
|
||
{{else if and .OffboxConfigured (ne .Offbox.EscrowState "escrowed")}}
|
||
<div class="card" style="border-left:3px solid var(--warn);margin:.75rem 0;padding:.75rem 1rem">
|
||
<p style="margin:0 0 .35rem"><strong>Helyreállítási kód szükséges</strong></p>
|
||
<p class="form-hint" style="margin:0 0 .5rem">A távoli mentések csak akkor állíthatók vissza egy teljes meghibásodás után, ha létrehozza a helyreállítási kódot.</p>
|
||
{{if .EscrowAgentOK}}
|
||
<a href="/backup/escrow" class="btn btn-sm btn-primary">Helyreállítási kód létrehozása</a>
|
||
{{else}}
|
||
<p class="form-hint" style="margin:0">A funkcióhoz az ügynök frissítése szükséges — a frissítés automatikusan megérkezik.</p>
|
||
{{end}}
|
||
</div>
|
||
{{else if and .OffboxConfigured .EscrowStale}}
|
||
<div class="card" style="border-left:3px solid var(--warn);margin:.75rem 0;padding:.75rem 1rem">
|
||
<p class="form-hint" style="color:var(--warn);margin:0 0 .5rem">A letétben lévő helyreállítási csomag nem fedi a jelenlegi távoli mentési jelszót. Hozzon létre új helyreállítási kódot.</p>
|
||
{{if .EscrowAgentOK}}
|
||
<a href="/backup/escrow" class="btn btn-sm btn-primary">Új helyreállítási kód készítése</a>
|
||
{{else}}
|
||
<p class="form-hint" style="margin:0">A funkcióhoz az ügynök frissítése szükséges — a frissítés automatikusan megérkezik.</p>
|
||
{{end}}
|
||
</div>
|
||
{{else if .OffboxConfigured}}
|
||
{{/* v0.127.1: the re-ceremony CTA is a real secondary button (outline, NOT primary — escrowed
|
||
is a healthy state; available-not-urgent, unlike the stale variant above). */}}
|
||
<div style="margin:.5rem 0">
|
||
<p class="form-hint" style="margin:0 0 .4rem">A helyreállítási kód letétbe helyezve.</p>
|
||
{{if .EscrowAgentOK}}<a href="/backup/escrow" class="btn btn-sm btn-outline">Új helyreállítási kód készítése</a>{{end}}
|
||
</div>
|
||
{{end}}
|
||
{{if .OffboxConfigured}}
|
||
<div class="schedule-actions" style="margin-top:1rem">
|
||
<form method="POST" action="/backup/offbox/run" style="display:inline">{{.CSRFField}}
|
||
<button type="submit" class="btn btn-sm btn-primary">Távoli mentés most</button>
|
||
</form>
|
||
</div>
|
||
<!-- v0.147.0 (4c): live progress for a MANUAL run — total bytes, percent and which app is being
|
||
pushed, parsed from restic's --json status stream. Hidden until a run reports progress; the
|
||
nightly run never populates it. -->
|
||
<div id="offbox-progress" class="alert alert-info" style="display:none;margin-top:.75rem">
|
||
<span id="offbox-progress-text"></span>
|
||
<div class="progress-bar-task" style="margin-top:.5rem">
|
||
<div id="offbox-progress-bar" class="progress-fill" style="width:0%"></div>
|
||
</div>
|
||
</div>
|
||
<h4 style="margin-top:1.25rem">Mely alkalmazások mentődnek a távoli tárolóra?</h4>
|
||
{{if and .OffboxApps (eq .Offbox.EscrowState "escrowed") (eq .OffboxToggledCount 0)}}
|
||
<p class="form-hint">Nincs távoli mentésre jelölt alkalmazás — jelölj ki legalább egyet.</p>
|
||
{{end}}
|
||
{{if .OffboxApps}}
|
||
<div class="app-row-list">
|
||
{{range .OffboxApps}}
|
||
{{template "app_list_row" dict "Slug" .Slug "Name" .DisplayName}}
|
||
<form method="POST" action="/backup/offbox/toggle" style="display:inline">{{$.CSRFField}}
|
||
<input type="hidden" name="app" value="{{.Name}}">
|
||
<input type="hidden" name="enabled" value="{{if .Enabled}}false{{else}}true{{end}}">
|
||
<button type="submit" class="btn btn-xs {{if .Enabled}}btn-outline{{else}}btn-primary{{end}}">{{if .Enabled}}Távoli mentés kikapcsolása{{else}}Távoli mentés bekapcsolása{{end}}</button>
|
||
</form>
|
||
{{if $.OffboxBlockedSet}}{{if index $.OffboxBlockedSet .Name}}
|
||
<span class="form-hint" style="display:block;margin-top:.25rem">A teljes mentés túllépné a tárhelykeretet — csak a konfiguráció és az adatbázis kerül mentésre.</span>
|
||
{{end}}{{end}}
|
||
{{template "app_list_row_end"}}
|
||
{{end}}
|
||
</div>
|
||
{{else}}<p class="form-hint">Nincs telepített alkalmazás.</p>{{end}}
|
||
{{end}}
|
||
{{else}}
|
||
{{if .OffsiteHubEnabled}}
|
||
<p class="form-hint">Felhom offsite tárhely kiépítve — a beállítás automatikus, folyamatban. Ha egy napon belül nem áll be, jelezd az üzemeltetőnek.</p>
|
||
{{else}}
|
||
<p class="form-hint">Még nincs beállítva távoli mentési cél.</p>
|
||
{{end}}
|
||
{{end}}
|
||
|
||
<details style="margin-top:1rem">
|
||
<summary class="btn btn-xs btn-primary" style="cursor:pointer;display:inline-block">Távoli mentési cél beállítása</summary>
|
||
<form method="POST" action="/backup/offbox/config" style="margin-top:.75rem;padding:1rem;border:1px solid var(--border,#ddd);border-radius:6px;max-width:560px">{{.CSRFField}}
|
||
<div class="form-row"><label>Cél címe (IP vagy hosztnév — NAS vagy SFTP-kiszolgáló)</label><input type="text" name="host" class="form-input" value="{{if .Offbox}}{{.Offbox.Host}}{{end}}" placeholder="pl. 192.168.0.10"></div>
|
||
<div class="form-row"><label>SSH port</label><input type="number" name="port" class="form-input" value="{{if .Offbox}}{{.Offbox.Port}}{{else}}22{{end}}"></div>
|
||
<div class="form-row"><label>Felhasználó</label><input type="text" name="user" class="form-input" value="{{if .Offbox}}{{.Offbox.User}}{{end}}" placeholder="pl. felhom"></div>
|
||
<div class="form-row"><label>Tároló útvonala a célgépen</label><input type="text" name="repo_path" class="form-input" value="{{if .Offbox}}{{.Offbox.RepoPath}}{{end}}" placeholder="pl. /volume1/felhom-backup/repo"></div>
|
||
<div class="form-row"><label><input type="checkbox" name="enabled" {{if .Offbox}}{{if .Offbox.Enabled}}checked{{end}}{{else}}checked{{end}}> Napi automatikus távoli mentés engedélyezve</label></div>
|
||
<div class="form-row"><label>SSH privát kulcs {{if .OffboxConfigured}}(üresen hagyva változatlan){{end}}</label>
|
||
<textarea name="ssh_key" class="form-input" rows="4" autocomplete="off" placeholder="-----BEGIN OPENSSH PRIVATE KEY-----"></textarea>
|
||
<span class="form-hint">A kulcsot 0600-as fájlba írjuk; sosem naplózzuk és nem tároljuk a beállításokban.</span></div>
|
||
<div class="form-row"><label>A célgép ismert-host sora (known_hosts) {{if .OffboxConfigured}}(üresen hagyva változatlan){{end}}</label>
|
||
<textarea name="known_hosts" class="form-input" rows="2" autocomplete="off" placeholder="nas.local ssh-ed25519 AAAA…"></textarea>
|
||
<span class="form-hint">A host-kulcs rögzítése (no blind TOFU). Lekérdezhető: <span class="mono">ssh-keyscan -p <port> <host></span></span></div>
|
||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||
</form>
|
||
</details>
|
||
</div>
|
||
{{end}}
|
||
|
||
<script>
|
||
/* Part C (v0.142.0) + 4c (v0.147.0): poll the run status, render live progress for a manual run, and
|
||
reload once it reaches a terminal state so the customer sees Rendben/Hiba + fresh numbers WITHOUT a
|
||
manual reload.
|
||
|
||
v0.147.0 changed WHEN polling starts. It used to begin only if the page already rendered "Fut…",
|
||
which loses a race the manual trigger always runs: the POST redirects and this page renders before
|
||
the detached goroutine has written LastStatus=running, so the poll never armed and the customer
|
||
watched a static page during the very run they had just started. Now it always arms and gives up
|
||
after GRACE quiet ticks if nothing is (or ever was) in flight. */
|
||
(function(){
|
||
var v = document.getElementById('offbox-status-value');
|
||
var box = document.getElementById('offbox-progress');
|
||
var text = document.getElementById('offbox-progress-text');
|
||
var bar = document.getElementById('offbox-progress-bar');
|
||
var GRACE = 5; // ~15s of quiet before concluding nothing is running
|
||
var quiet = 0;
|
||
var sawRunning = (v && v.textContent.indexOf('Fut') >= 0);
|
||
|
||
var timer = setInterval(function(){
|
||
fetch('/backup/offbox/status',{headers:{'Accept':'application/json'}})
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
if(!d) return;
|
||
var p = d.progress || {};
|
||
var running = (d.status === 'running') || p.active;
|
||
|
||
if(running){
|
||
sawRunning = true; quiet = 0;
|
||
if(p.active && box){
|
||
/* Only claim a percentage once restic has told us a total — before the scan finishes,
|
||
percent is 0 of 0, and a bar pinned at 0% reads as "stuck" rather than "measuring". */
|
||
/* A run is not only the per-app loop: the shares leg and the retention/prune step follow
|
||
it and can dominate the wall clock (40 of 57 seconds, measured). Name them, or the
|
||
card freezes on the last app's finished counters for that whole tail. */
|
||
/* The dump pre-phase runs BEFORE the per-app loop (R-44): it refreshes every app's
|
||
database dump so the snapshot pairs this run's files with this run's DB. On an app
|
||
with a large database it can dominate the early wall clock, and an unnamed silent
|
||
stretch at the start reads as a hang. */
|
||
if(p.phase === 'dump'){
|
||
text.textContent = 'Adatbázisok mentése a pillanatképhez…';
|
||
bar.style.width = '100%';
|
||
box.className = 'alert alert-info'; box.style.display = '';
|
||
return;
|
||
}
|
||
if(p.phase === 'retention'){
|
||
text.textContent = 'Karbantartás: régi mentések rendezése a távoli tárolón…';
|
||
bar.style.width = '100%';
|
||
box.className = 'alert alert-info'; box.style.display = '';
|
||
return;
|
||
}
|
||
if(p.phase === 'shares'){
|
||
text.textContent = 'Megosztott mappák mentése…';
|
||
bar.style.width = '100%';
|
||
box.className = 'alert alert-info'; box.style.display = '';
|
||
return;
|
||
}
|
||
var label = p.current_app ? ('Mentés: ' + p.current_app) : 'Mentés folyamatban';
|
||
if(p.bytes_done > 0){
|
||
/* Bytes are genuinely moving — the informative case. */
|
||
label += ' — ' + Math.round(p.percent) + '% (' + p.done_human + ' / ' + p.total_human + ')';
|
||
bar.style.width = Math.max(0, Math.min(100, p.percent)) + '%';
|
||
} else if(p.total_files > 0){
|
||
/* No bytes moving. restic 0.14 only counts a file into bytes_done/files_done when it
|
||
COMPLETES, so an app dominated by one big archive freezes both counters — measured
|
||
on the demo box: immich at 1 of 46 files, 0 bytes, for 42 seconds while restic
|
||
worked through a single ~430MB volume tar. A percentage cannot move in that window,
|
||
so do not pretend: name the file being processed and the elapsed time, which is
|
||
what actually tells the customer it is alive. */
|
||
var fpct = Math.round((p.files_done / p.total_files) * 100);
|
||
label += ' — ' + p.files_done + ' / ' + p.total_files + ' fájl'
|
||
+ (p.total_human ? ' (' + p.total_human + ')' : '');
|
||
if(p.current_file){
|
||
var base = p.current_file.split('/').pop();
|
||
label += ' · feldolgozás alatt: ' + base;
|
||
}
|
||
if(p.elapsed_sec > 0){ label += ' · ' + p.elapsed_sec + ' mp'; }
|
||
bar.style.width = Math.max(0, Math.min(100, fpct)) + '%';
|
||
} else {
|
||
label += ' — a mentendő adatok felmérése…';
|
||
bar.style.width = '0%';
|
||
}
|
||
text.textContent = label;
|
||
box.style.display = '';
|
||
}
|
||
return;
|
||
}
|
||
|
||
/* Not running. Terminal only if we ever saw it running — otherwise this is the pre-start
|
||
race (or a page nobody triggered anything from). */
|
||
if(sawRunning){ clearInterval(timer); location.reload(); return; }
|
||
if(++quiet >= GRACE){ clearInterval(timer); }
|
||
})
|
||
.catch(function(){ /* transient — keep polling */ });
|
||
}, 3000);
|
||
})();
|
||
</script>
|
||
|
||
{{template "layout_end" .}}
|
||
{{end}}
|