From d34d5047540236a4f81bba8de01e2dc4463f87cf Mon Sep 17 00:00:00 2001 From: nxshock Date: Wed, 5 Apr 2023 21:13:13 +0500 Subject: [PATCH 1/6] Update klauspost/compress dependency provides little compression ratio increase --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dc75287..c3f3191 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/BurntSushi/toml v1.2.1 - github.com/klauspost/compress v1.16.3 + github.com/klauspost/compress v1.16.4 github.com/stretchr/testify v1.8.2 github.com/tidwall/match v1.1.1 ) diff --git a/go.sum b/go.sum index cc9c001..e54a948 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= -github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= +github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= From 465cfae874788e2ad8fa914503eaf3423e5b11af Mon Sep 17 00:00:00 2001 From: nxshock Date: Fri, 7 Apr 2023 14:58:30 +0500 Subject: [PATCH 2/6] Add usage and basic config examples --- README.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e91e1fb..01bcd33 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,58 @@ # backuper - + +## Usage + +### Incremental backup + +```sh +backuper i +``` + +### Full backup + +```sh +backuper f +``` + +### Search files in backup + +```sh +backuper s +``` + +### Recover files from backup + +```sh +backuper r +``` + +Examples: + +```sh +# Recover Go files relevant as of 01.01.2023 to /home/user/go directory +backuper r config.conf "*.go" "01.01.2023" "/home/user/go" +``` + +### Test backup for errors + +```sh +backuper t +``` + +## Basic config example + +Backup config files from `/etc` and sqlite files from `/var`: + +```toml +FileName = "backup" + +[[Patterns]] +Path = "/etc" +FileNamePatternList = ["*.conf", "*.toml", "*.ini", "*.yaml"] +Recursive = true + +[[Patterns]] +Path = "/var" +FileNamePatternList = ["*.sqlite"] +Recursive = true +``` From ca8193ad0691c2a0b57304e4fc6e8c5ba03ef1df Mon Sep 17 00:00:00 2001 From: nxshock Date: Sat, 8 Apr 2023 14:01:16 +0500 Subject: [PATCH 3/6] Fix typo --- utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.go b/utils.go index f0ef4d8..a6566b0 100644 --- a/utils.go +++ b/utils.go @@ -32,7 +32,7 @@ func sizeToApproxHuman(s int64) string { return fmt.Sprintf("%d B", s) } -// clean убирает невозможнын комбинации символов из пути +// clean убирает невозможные комбинации символов из пути func clean(s string) string { s = strings.ReplaceAll(s, ":", "") s = strings.ReplaceAll(s, `\\`, `\`) From dc3eb7d9ef414d72dbae37fde3c9f6fc82af082c Mon Sep 17 00:00:00 2001 From: nxshock Date: Sat, 8 Apr 2023 14:01:44 +0500 Subject: [PATCH 4/6] Remove uncompleted file on any error --- index.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/index.go b/index.go index 9ce9947..f613319 100644 --- a/index.go +++ b/index.go @@ -62,7 +62,8 @@ func (index Index) Save(fileName string) error { enc, err := zstd.NewWriter(f, zstd.WithEncoderLevel(zstd.SpeedBestCompression)) if err != nil { - f.Close() // TODO: удалить частичный файл? + f.Close() + os.Remove(fileName) return err } @@ -82,7 +83,8 @@ func (index Index) Save(fileName string) error { err := csvWriter.Write([]string{fileName, historyItem.ArchiveFileName, strconv.Itoa(int(historyItem.ModificationTime.Unix()))}) if err != nil { enc.Close() - f.Close() // TODO: удалить частичный файл? + f.Close() + os.Remove(fileName) return err } } @@ -91,13 +93,15 @@ func (index Index) Save(fileName string) error { csvWriter.Flush() if err := csvWriter.Error(); err != nil { enc.Close() - f.Close() // TODO: удалить частичный файл? + f.Close() + os.Remove(fileName) return err } err = enc.Close() if err != nil { - f.Close() // TODO: удалить частичный файл? + f.Close() + os.Remove(fileName) return err } From 3a37c29de49109c729b048d735a4cd2784824a38 Mon Sep 17 00:00:00 2001 From: nxshock Date: Sat, 8 Apr 2023 14:02:36 +0500 Subject: [PATCH 5/6] Autodetect datetime format --- main.go | 23 +++-------------------- utils.go | 15 +++++++++++++++ utils_test.go | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/main.go b/main.go index 2b9a74f..0b1f8ca 100644 --- a/main.go +++ b/main.go @@ -4,7 +4,6 @@ import ( "log" "os" "path/filepath" - "time" ) func init() { @@ -56,25 +55,9 @@ func main() { log.Fatalln(err) } - var t time.Time - switch len(os.Args[4]) { - case len("02.01.2006"): - t, err = time.Parse("02.01.2006 15:04", os.Args[4]) - if err != nil { - config.fatalln("time parse error:", err) - } - case len("02.01.2006 15:04"): - t, err = time.Parse("02.01.2006 15:04", os.Args[4]) - if err != nil { - config.fatalln("time parse error:", err) - } - case len("02.01.2006 15:04:05"): - t, err = time.Parse("02.01.2006 15:04:05", os.Args[4]) - if err != nil { - config.fatalln("time parse error:", err) - } - default: - config.fatalln(`wrong time format, must be ["DD.MM.YYYY", "DD.MM.YYYY hh:mm", "DD.MM.YYYY hh:mm:ss"]`) + t, err := parseTime(os.Args[4]) + if err != nil { + config.fatalln(err) } plan, err := config.extractionPlan(os.Args[3], t) diff --git a/utils.go b/utils.go index a6566b0..7ec8a8c 100644 --- a/utils.go +++ b/utils.go @@ -1,9 +1,11 @@ package main import ( + "errors" "fmt" "path/filepath" "strings" + "time" "github.com/tidwall/match" ) @@ -71,3 +73,16 @@ func isFilePathMatchPatterns(patterns []string, fileName string) bool { return false } + +func parseTime(s string) (time.Time, error) { + switch len(s) { + case len("02.01.2006"): + return time.ParseInLocation("02.01.2006", s, time.Local) + case len("02.01.2006 15:04"): + return time.ParseInLocation("02.01.2006 15:04", s, time.Local) + case len("02.01.2006 15:04:05"): + return time.ParseInLocation("02.01.2006 15:04:05", s, time.Local) + } + + return time.Time{}, errors.New("unknown time format") +} diff --git a/utils_test.go b/utils_test.go index 6bad3fc..3769cd4 100644 --- a/utils_test.go +++ b/utils_test.go @@ -2,6 +2,7 @@ package main import ( "testing" + "time" "github.com/stretchr/testify/assert" ) @@ -10,3 +11,21 @@ func TestSizeToApproxHuman(t *testing.T) { assert.Equal(t, "1.0 KiB", sizeToApproxHuman(1024)) assert.Equal(t, "1.1 KiB", sizeToApproxHuman(1126)) } + +func TestParseTime(t *testing.T) { + tests := []struct { + input string + expected time.Time + }{ + {"02.01.2006", time.Date(2006, 01, 02, 0, 0, 0, 0, time.Local)}, + {"02.01.2006 15:04", time.Date(2006, 01, 02, 15, 4, 0, 0, time.Local)}, + {"02.01.2006 15:04:05", time.Date(2006, 01, 02, 15, 4, 5, 0, time.Local)}, + } + + for _, test := range tests { + got, err := parseTime(test.input) + assert.NoError(t, err) + + assert.Equal(t, test.expected, got) + } +} From d334256d0bcfbf4ffc1b76953910e02ecfc53017 Mon Sep 17 00:00:00 2001 From: nxshock Date: Tue, 11 Apr 2023 10:40:24 +0500 Subject: [PATCH 6/6] Fix skipping file access error --- backuper.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backuper.go b/backuper.go index e162dc8..30c8960 100644 --- a/backuper.go +++ b/backuper.go @@ -46,6 +46,8 @@ func (b *Config) fileList(fileNames chan FileInfo) { if b.StopOnAnyError { return fmt.Errorf("get file info error: %v", err) } + + return nil } file := FileInfo{