Files
backup-master/internal/server/templates/backup.html
T
mrleo1nidandClaude Opus 5.5 1d44d067e9 backup-master: сервер бэкапов, агент и восстановление VPS
Один бинарник backupctl:
- server: API для агентов и restore, веб-морда (один админ), SQLite,
  ретеншн GFS, heavy-части, уведомления ntfy, раздача agent.sh/restore.sh;
- backup/plan: сбор по каталогу категорий (files/systemd/xui/compose),
  горячие дампы Postgres/Mongo/MySQL, снимок x-ui.db, docker-тома,
  digest образов, проверка crontab, потоковая отправка tar.zst;
- restore: провижининг на основе vps_installer с теми же версиями пакетов,
  recipes 3x-ui/nebula/sing-box нужных версий, восстановление compose
  с заливкой дампов и закреплением образов по digest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 21:52:40 +03:00

31 lines
1.5 KiB
HTML

{{define "title"}}Бэкап #{{.Backup.ID}} — backup-master{{end}}
{{define "content"}}
{{$b := .Backup}}
<p><a href="/clients/{{.Client.ID}}">← {{.Client.Domain}}</a></p>
<div class="head">
<h1>Бэкап #{{.Backup.ID}} <span class="badge {{if eq .Backup.Status "complete"}}ok{{else if eq .Backup.Status "failed"}}fail{{else}}stale{{end}}">{{.Backup.Status}}</span></h1>
{{if eq .Backup.Status "complete"}}
<form method="post" action="/clients/{{.Client.ID}}/restore-token" class="inline">
<input type="hidden" name="csrf" value="{{.CSRF}}">
<input type="hidden" name="backup" value="{{.Backup.ID}}">
<button class="primary">Восстановить из этого бэкапа</button>
</form>
{{end}}
</div>
{{with .Backup.Error}}<p class="error">{{.}}</p>{{end}}
<dl class="facts">
<div><dt>Создан</dt><dd>{{ts .Backup.CreatedAt}}</dd></div>
<div><dt>Размер</dt><dd>{{bytes .Backup.TotalSize}}</dd></div>
<div><dt>Агент</dt><dd>{{.M.AgentVersion}}</dd></div>
<div><dt>Части</dt><dd>{{range .Backup.Parts}}{{if eq .Status "complete"}}<a href="/backups/{{$b.ID}}/parts/{{.Name}}">{{.Name}}</a> {{bytes .Size}}<br>{{else}}<span class="muted">{{.Name}}: {{.Status}}</span><br>{{end}}{{end}}</dd></div>
</dl>
{{if .M.Warnings}}
<details class="warnings" open>
<summary>Предупреждения ({{len .M.Warnings}})</summary>
<ul>{{range .M.Warnings}}<li>{{.}}</li>{{end}}</ul>
</details>
{{end}}
<h2>Манифест</h2>
<pre class="json">{{.Raw}}</pre>
{{end}}