Compare commits
2 Commits
0cf266dd87
...
f89e7112a4
Author | SHA1 | Date | |
---|---|---|---|
f89e7112a4 | |||
b28009f83b |
184
backup.go
184
backup.go
@ -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
4
go.mod
@ -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
2
go.sum
Normal 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=
|
30
makefile
30
makefile
@ -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."
|
||||||
|
@ -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...
|
||||||
|
@ -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
4
update.toml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Config for update
|
||||||
|
|
||||||
|
[backup]
|
||||||
|
locations = ['/opt'] # All locations need to be an absolute path
|
Loading…
Reference in New Issue
Block a user