Compare commits

...

2 Commits

Author SHA1 Message Date
f89e7112a4
remove executable 2024-09-08 00:24:03 +02:00
b28009f83b
done with new version 2024-09-08 00:23:20 +02:00
7 changed files with 151 additions and 81 deletions

184
backup.go
View File

@ -1,42 +1,29 @@
package main package main
import ( import (
"archive/zip"
"bufio" "bufio"
"errors"
"fmt" "fmt"
"io/fs" "io"
"log"
"os" "os"
"os/exec" "os/exec"
"path/filepath"
"strings" "strings"
"time"
"github.com/pelletier/go-toml"
) )
func parseEnvironment(key string) string { var backup_locations []string
value := os.Getenv(key)
if value == "" {
log.Panicf("%s is not set\n", key)
}
if _, err := os.Stat(value); err != nil {
if errors.Is(err, fs.ErrNotExist) {
log.Panicf("%s does not point to a valid path\n", key)
}
log.Panicf("trying to stat %s produced an unkown error\n", value)
}
return value
}
func parsePacmanConf() string { func parsePacmanConf() (string, error) {
var err error
var path string var path string
file, err := os.Open("/etc/pacman.conf") file, err := os.Open("/etc/pacman.conf")
if err != nil { if err != nil {
log.Panicln(err) return "", err
} }
defer func() {
if err := file.Close(); err != nil {
log.Panicln(err)
}
}()
scanner := bufio.NewScanner(file) scanner := bufio.NewScanner(file)
for scanner.Scan() { for scanner.Scan() {
@ -48,73 +35,130 @@ func parsePacmanConf() string {
break break
} }
if _, err := os.Stat(path); err != nil { err = file.Close()
if errors.Is(err, fs.ErrNotExist) { if err != nil {
log.Panicln("DBPath in /etc/pacman.conf does not point to a valid path") return "", err
}
log.Panicf("trying to stat %s produced an unkown error\n", path)
} }
return fmt.Sprintf("%s%s", path, "local") return fmt.Sprint(path, "local"), nil
} }
func preBackup() { func zipIt(pathToZip string, pathToFiles string) error {
pacmanDb := parsePacmanConf() var err error
log.Printf("pacmanDb: %s\n", pacmanDb)
tmpPath := "/tmp/update/pre_backup"
output, err := exec.Command("pacman", "--verbose", "--query").Output() zipFile, err := os.Create(pathToZip)
if err != nil { if err != nil {
log.Panicln(err) return err
}
zipWriter := zip.NewWriter(zipFile)
walker := func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
f, err := zipWriter.Create(path[len(pathToFiles):])
if err != nil {
return err
}
_, err = io.Copy(f, file)
if err != nil {
return err
}
return nil
}
err = filepath.Walk(pathToFiles, walker)
if err != nil {
return err
}
err = zipWriter.Close()
if err != nil {
return err
}
err = zipFile.Close()
if err != nil {
return err
}
return nil
}
func backup(when string) error {
var err error
tmpPath := fmt.Sprint("/tmp/update/", when, "_backup")
pacmanDb, err := parsePacmanConf()
if err != nil {
return err
} }
err = os.MkdirAll(tmpPath, 0755) err = os.MkdirAll(tmpPath, 0755)
err = os.WriteFile(fmt.Sprintf("%s/%s", tmpPath, "pre_pacman.txt"), output, 0644)
if err != nil { if err != nil {
log.Panicln(err) return err
} }
defer func() { defer func() {
if r := recover(); r != nil { os.RemoveAll("/tmp/update")
err := os.RemoveAll(tmpPath)
if err != nil {
log.Fatal(err)
}
err = CopyDir(pacmanDb, fmt.Sprintf("%s/%s", tmpPath, pacmanDb))
if err != nil {
log.Panicln(err)
}
log.Println("recovered successfully")
}
}() }()
err = CopyDir(pacmanDb, fmt.Sprintf("%s/%s", tmpPath, pacmanDb)) output, err := exec.Command("pacman", "--verbose", "--query").Output()
if err != nil { if err != nil {
log.Panicln(err) return err
} }
}
func postBackup() { err = os.WriteFile(fmt.Sprint(tmpPath, fmt.Sprint(when, "_pacman.txt")), output, 0644)
/* if err != nil {
* basic logic for post: return err
* create new pkg list and delete all lines which are the same as pre }
*/
panic("unimplemented") if when != "post" {
err = CopyDir(pacmanDb, fmt.Sprint(tmpPath, "/", pacmanDb))
if err != nil {
return err
}
}
current_time := time.Now().Format(time.RFC3339)
pathToZip := fmt.Sprint(tmpPath, "_", current_time, ".zip")
err = zipIt(pathToZip, tmpPath)
if err != nil {
return err
}
for _, backup_location := range backup_locations {
err = CopyFile(pathToZip, fmt.Sprint(backup_location, "/", when, "_backup_", current_time, ".zip"))
if err != nil {
return err
}
}
return nil
} }
func main() { func main() {
// backup_dir := parseEnvironment("UPDATE_BACKUP_DIR") os.RemoveAll("/tmp/update")
cmdlineArg := os.Args[1]
log.Printf("cmdlineArg: %s\n", cmdlineArg)
if cmdlineArg == "pre" { tree, err := toml.LoadFile("/etc/update.toml")
preBackup() if err != nil {
} else if cmdlineArg == "post" { fmt.Println("backup failed for the following reason: ", err)
postBackup() os.Exit(1)
} else { }
log.Panicf("invalid cmdline argument. supplied value was: %s\n", cmdlineArg)
backup_locations = tree.GetArray("backup.locations").([]string)
err = backup(os.Args[1])
if err != nil {
fmt.Println("backup failed for the following reason: ", err)
os.Exit(1)
} }
} }

4
go.mod
View File

@ -1,3 +1,5 @@
module update module backup
go 1.23.0 go 1.23.0
require github.com/pelletier/go-toml v1.9.5

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=

View File

@ -1,10 +1,28 @@
install: help:
@echo "==> Installing update into /usr/local/bin" @echo "Usage: make [OPTION]"
@sudo install -Dm755 update /usr/local/bin/update @echo "Available options are:"
@[[ -f ${HOME}/.config/update.conf ]] || cp update.conf ${HOME}/.config/ @echo "help"
@echo "install"
@echo "uninstall"
compile:
@echo "==> Compiling backup"
go build .
install: compile
@echo "==> Copying the hooks into /etc/pacman.d/hooks"
[[ -d /etc/pacman.d/hooks ]] || sudo mkdir /etc/pacman.d/hooks
sudo cp pre_backup.hook post_backup.hook /etc/pacman.d/hooks
@echo "==> Copying backup into /usr/local/bin"
sudo install -Dm755 backup /usr/local/bin/backup
@echo "==> Copying the config into /etc"
[[ -f /etc/update.toml ]] || sudo cp update.toml /etc
@echo "==> Finished." @echo "==> Finished."
uninstall: uninstall:
@echo "==> Uninstalling update from /usr/local/bin" @echo "==> Removing the hooks from /etc/pacman.d/hooks"
@sudo rm /usr/local/bin/update ${HOME}/.config/update.conf sudo rm /etc/pacman.d/hooks/pre_backup.hook /etc/pacman.d/hooks/post_backup.hook
@echo "==> Removing backup into /usr/local/bin"
sudo rm /usr/local/bin/backup
@echo "==> /etc/update.toml will remain"
@echo "==> Finished." @echo "==> Finished."

View File

@ -2,8 +2,8 @@
Operation = Install Operation = Install
Operation = Upgrade Operation = Upgrade
Operation = Remove Operation = Remove
Type = Path Type = Package
Target = /usr/local/bin/backup Target = *
[Action] [Action]
Description = Backing up the pacman db... Description = Backing up the pacman db...

View File

@ -2,8 +2,8 @@
Operation = Install Operation = Install
Operation = Upgrade Operation = Upgrade
Operation = Remove Operation = Remove
Type = Path Type = Package
Target = /usr/local/bin/backup Target = *
[Action] [Action]
Description = Backing up the pacman db... Description = Backing up the pacman db...

4
update.toml Normal file
View File

@ -0,0 +1,4 @@
# Config for update
[backup]
locations = ['/opt'] # All locations need to be an absolute path