This commit is contained in:
@@ -12,7 +12,7 @@ import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/fonu/fonu/internal/settings"
|
||||
"github.com/havline/havline/internal/settings"
|
||||
)
|
||||
|
||||
// 保留份数的边界:0/负数按默认值处理,上限防止把磁盘塞满
|
||||
@@ -23,7 +23,7 @@ const (
|
||||
|
||||
// archiveNamePattern 备份命名格式(Export 用 CreateTemp 生成,后缀是随机数字)。
|
||||
// List / Path 都按它过滤,避免把 backups 目录里任意文件当成备份读写或删除。
|
||||
var archiveNamePattern = regexp.MustCompile(`^fonu-backup-\d{8}-\d{6}-\d+\.tar\.gz$`)
|
||||
var archiveNamePattern = regexp.MustCompile(`^havline-backup-\d{8}-\d{6}-\d+\.tar\.gz$`)
|
||||
|
||||
// Archive 留在磁盘上的一份备份
|
||||
type Archive struct {
|
||||
@@ -104,7 +104,7 @@ func (s *Service) Remove(name string) error {
|
||||
}
|
||||
|
||||
// Verify 回读归档并返回条目数:确认这份备份不是写了一半的残件,
|
||||
// 同时要求包内必须有 fonu.db(否则多半不是 Fonu 的备份)。
|
||||
// 同时要求包内必须有 havline.db(否则多半不是 Havline 的备份)。
|
||||
func (s *Service) Verify(ctx context.Context, path string) (int, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
@@ -133,12 +133,12 @@ func (s *Service) Verify(ctx context.Context, path string) (int, error) {
|
||||
return count, err
|
||||
}
|
||||
count++
|
||||
if header.Name == "fonu.db" {
|
||||
if header.Name == "havline.db" {
|
||||
hasDatabase = true
|
||||
}
|
||||
}
|
||||
if !hasDatabase {
|
||||
return count, fmt.Errorf("备份里没有 fonu.db,可能不是 Fonu 的备份")
|
||||
return count, fmt.Errorf("备份里没有 havline.db,可能不是 Havline 的备份")
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/fonu/fonu/internal/notify"
|
||||
"github.com/fonu/fonu/internal/settings"
|
||||
"github.com/havline/havline/internal/notify"
|
||||
"github.com/havline/havline/internal/settings"
|
||||
)
|
||||
|
||||
// AutoInterval 自动备份间隔。scheduler 启动时会先跑一轮,靠「最新备份是否还在间隔内」
|
||||
|
||||
@@ -31,7 +31,7 @@ func TestDueForBackup(t *testing.T) {
|
||||
|
||||
func TestExportVerifyRoundTrip(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(dir, "fonu.db"), []byte("db"), 0o600); err != nil {
|
||||
if err := os.WriteFile(filepath.Join(dir, "havline.db"), []byte("db"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
svc := New(dir)
|
||||
@@ -62,7 +62,7 @@ func TestExportVerifyRoundTrip(t *testing.T) {
|
||||
|
||||
func TestVerifyRejectsGarbage(t *testing.T) {
|
||||
svc := New(t.TempDir())
|
||||
path := filepath.Join(svc.backupsDir(), "fonu-backup-20260925-000000-1.tar.gz")
|
||||
path := filepath.Join(svc.backupsDir(), "havline-backup-20260925-000000-1.tar.gz")
|
||||
if err := os.MkdirAll(svc.backupsDir(), 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -80,9 +80,9 @@ func TestListPruneAndPath(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, name := range []string{
|
||||
"fonu-backup-20260923-100000-1.tar.gz",
|
||||
"fonu-backup-20260924-100000-2.tar.gz",
|
||||
"fonu-backup-20260925-100000-3.tar.gz",
|
||||
"havline-backup-20260923-100000-1.tar.gz",
|
||||
"havline-backup-20260924-100000-2.tar.gz",
|
||||
"havline-backup-20260925-100000-3.tar.gz",
|
||||
} {
|
||||
if err := os.WriteFile(filepath.Join(svc.backupsDir(), name), []byte("x"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -100,7 +100,7 @@ func TestListPruneAndPath(t *testing.T) {
|
||||
if len(archives) != 3 {
|
||||
t.Fatalf("应只列出 3 份备份,实际 %d", len(archives))
|
||||
}
|
||||
if archives[0].Name != "fonu-backup-20260925-100000-3.tar.gz" {
|
||||
if archives[0].Name != "havline-backup-20260925-100000-3.tar.gz" {
|
||||
t.Fatalf("应按时间倒序,实际首条 %s", archives[0].Name)
|
||||
}
|
||||
|
||||
@@ -116,12 +116,12 @@ func TestListPruneAndPath(t *testing.T) {
|
||||
}
|
||||
|
||||
// 名称校验:不能让备份名把读写带出备份目录
|
||||
for _, name := range []string{"../fonu.db", "notes.txt", "", "fonu-backup-x.tar.gz"} {
|
||||
for _, name := range []string{"../havline.db", "notes.txt", "", "havline-backup-x.tar.gz"} {
|
||||
if _, err := svc.Path(name); err == nil {
|
||||
t.Fatalf("非法备份名应拒绝:%q", name)
|
||||
}
|
||||
}
|
||||
if err := svc.Remove("fonu-backup-20260920-100000-9.tar.gz"); err == nil {
|
||||
if err := svc.Remove("havline-backup-20260920-100000-9.tar.gz"); err == nil {
|
||||
t.Fatal("删除不存在的备份应报错")
|
||||
}
|
||||
if _, err := svc.Prune(0); err != nil {
|
||||
|
||||
@@ -35,7 +35,7 @@ func (s *Service) Export(ctx context.Context) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
// CreateTemp 保证同一秒内多次导出不会覆盖已有备份(文件名带随机后缀)
|
||||
file, err := os.CreateTemp(s.backupsDir(), fmt.Sprintf("fonu-backup-%s-*.tar.gz", time.Now().Format(backupTimeFmt)))
|
||||
file, err := os.CreateTemp(s.backupsDir(), fmt.Sprintf("havline-backup-%s-*.tar.gz", time.Now().Format(backupTimeFmt)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -59,7 +59,7 @@ func (s *Service) writeArchive(ctx context.Context, file *os.File, outPath strin
|
||||
|
||||
gw := gzip.NewWriter(file)
|
||||
tw := tar.NewWriter(gw)
|
||||
for _, entry := range []string{"fonu.db", "certs", "nginx", "cloudflared/tunnels"} {
|
||||
for _, entry := range []string{"havline.db", "certs", "nginx", "cloudflared/tunnels"} {
|
||||
if err := addToArchive(ctx, tw, s.dataDir, entry); err != nil {
|
||||
discard()
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user