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>
This commit is contained in:
commit
1d44d067e9
53 files changed
+7278
No files matched your search
@@ -0,0 +1,44 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCronPaths(t *testing.T) {
|
||||
text := `# m h dom mon dow command
|
||||
SHELL=/bin/bash
|
||||
17 4 * * * RESTART_CMD='x-ui restart' /usr/local/bin/update-geosite.sh >> /var/log/ipcheck-update.log 2>&1
|
||||
0 5 * * 1 /var/scripts/update-geodata.sh >> /var/log/update-geodata.log 2>&1
|
||||
@reboot sleep 60 && bash /usr/local/sbin/ban.sh
|
||||
0 */6 * * * bash /usr/local/sbin/ban.sh >/dev/null 2>&1
|
||||
`
|
||||
got := cronPaths(text)
|
||||
for _, want := range []string{"/usr/local/bin/update-geosite.sh", "/var/scripts/update-geodata.sh", "/usr/local/sbin/ban.sh"} {
|
||||
if !slices.Contains(got, want) {
|
||||
t.Errorf("нет %s в %v", want, got)
|
||||
}
|
||||
}
|
||||
for _, bad := range []string{"/var/log/ipcheck-update.log", "/var/log/update-geodata.log", "/dev/null", "/bin/bash"} {
|
||||
if slices.Contains(got, bad) {
|
||||
t.Errorf("лишний путь %s в %v", bad, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDBKind(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"postgres:17-alpine": "postgres",
|
||||
"docker.io/mongo": "mongo",
|
||||
"docker.io/library/mongo@sha256:abc": "mongo",
|
||||
"mariadb:11": "mariadb",
|
||||
"mongo-express": "",
|
||||
"ghcr.io/stoatchat/api:v0.15.5": "",
|
||||
"valkey/valkey:9-alpine": "",
|
||||
}
|
||||
for img, want := range cases {
|
||||
if got := dbKind(img); got != want {
|
||||
t.Errorf("dbKind(%q) = %q, want %q", img, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user