Один бинарник 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>
29 lines
1.2 KiB
HTML
29 lines
1.2 KiB
HTML
{{define "title"}}Клиенты — backup-master{{end}}
|
|
{{define "content"}}
|
|
<div class="head">
|
|
<h1>Клиенты</h1>
|
|
<a class="button primary" href="/clients/new">Добавить клиента</a>
|
|
</div>
|
|
{{if .Clients}}
|
|
<div class="table-wrap">
|
|
<table>
|
|
<thead><tr><th>Домен</th><th>Название</th><th>Статус</th><th>Последний бэкап</th><th class="num">Размер</th><th>Агент на связи</th></tr></thead>
|
|
<tbody>
|
|
{{range .Clients}}
|
|
<tr>
|
|
<td><a href="/clients/{{.ID}}">{{.Domain}}</a></td>
|
|
<td>{{if ne .Name .Domain}}{{.Name}}{{end}}</td>
|
|
<td><span class="badge {{.StatusClass}}">{{.StatusText}}</span>{{if and (eq .StatusClass "fail") .LastError}} <span class="muted small" title="{{.LastError}}">{{.LastError}}</span>{{end}}</td>
|
|
<td title="{{ts .LastBackupAt}}">{{ago .LastBackupAt}}</td>
|
|
<td class="num">{{if .LastSize}}{{bytes .LastSize}}{{end}}</td>
|
|
<td title="{{ts .LastSeenAt}}">{{ago .LastSeenAt}}</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{{else}}
|
|
<p class="empty">Клиентов пока нет. Добавьте первый — получите команду установки агента.</p>
|
|
{{end}}
|
|
{{end}}
|