From 17e89057dbc9dcba5fb27f09cc3088c7efd739d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aure=CC=81lie=20Delhaie?= Date: Wed, 13 Apr 2022 19:44:14 +0200 Subject: [PATCH] First version --- .idea/.gitignore | 8 +++++ .idea/archiver.iml | 9 +++++ .idea/modules.xml | 8 +++++ README.md | 3 ++ go.mod | 3 ++ main.go | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 121 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/archiver.iml create mode 100644 .idea/modules.xml create mode 100644 README.md create mode 100644 go.mod create mode 100644 main.go diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/archiver.iml b/.idea/archiver.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/archiver.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..f027caf --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..1a1739e --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# archiver + +This script allows to copy a folder to make a backup, I compress it in a .tar.gz file and I send it on a remote server with rsync diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..a67aac6 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module archiver + +go 1.18 diff --git a/main.go b/main.go new file mode 100644 index 0000000..3a9ba27 --- /dev/null +++ b/main.go @@ -0,0 +1,90 @@ +package main + +import ( + "errors" + "flag" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "time" +) + +func main() { + path := flag.String("path", "", "Path to the folder to archive") + backupFolder := flag.String("backup", "./archive", "Path to the backup folder") + count := flag.Int("count", 3, "Number of backup to keep in the archive") + flag.Parse() + if len(*path) == 0 { + fmt.Println("missing --path argument") + os.Exit(2) + } + if *count < 1 { + fmt.Println("--count must be greater than 0") + os.Exit(3) + } + if _, err := os.Stat(*path); err != nil { + err = os.MkdirAll(*path, 0750) + if err != nil { + fmt.Println(err) + os.Exit(4) + } + } + absSourcePath, err := filepath.Abs(*path) + if err != nil { + fmt.Println(err) + os.Exit(5) + } + absDstPath, err := filepath.Abs(*backupFolder) + if err != nil { + fmt.Println(err) + os.Exit(5) + } + if err := makeBackup(absSourcePath, absDstPath, *count); err != nil { + fmt.Println(err) + os.Exit(7) + } +} + +// makeBackup make a backup +func makeBackup(source, dst string, count int) error { + err := cleanOldBackup(dst, count-1) + if err != nil { + return err + } + name := time.Now().Format("2006_01_02__15_04_05") + output, err := exec.Command("cp", "-r", source, filepath.Join(dst, name)).CombinedOutput() + if err != nil { + return errors.New(string(output)) + } + return nil +} + +// cleanOldBackup clean up old archives so as not to exceed the quota +func cleanOldBackup(backupFolder string, count int) error { + files, err := ioutil.ReadDir(backupFolder) + if err != nil { + return err + } + for len(files) > count { + oldestTime := time.Now() + var oldestFile os.FileInfo + for _, file := range files { + + if file.ModTime().Before(oldestTime) { + oldestFile = file + oldestTime = file.ModTime() + } + } + err = os.RemoveAll(filepath.Join(backupFolder, oldestFile.Name())) + if err != nil { + return err + } + files, err = ioutil.ReadDir(backupFolder) + if err != nil { + return err + } + } + return nil +}