165 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package main
 | |
| 
 | |
| import (
 | |
| 	"archive/zip"
 | |
| 	"bufio"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"os"
 | |
| 	"os/exec"
 | |
| 	"path/filepath"
 | |
| 	"strings"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/pelletier/go-toml"
 | |
| )
 | |
| 
 | |
| var backup_locations []string
 | |
| 
 | |
| func parsePacmanConf() (string, error) {
 | |
| 	var err error
 | |
| 	var path string
 | |
| 
 | |
| 	file, err := os.Open("/etc/pacman.conf")
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 
 | |
| 	scanner := bufio.NewScanner(file)
 | |
| 	for scanner.Scan() {
 | |
| 		line := scanner.Text()
 | |
| 		if !strings.Contains(line, "DBPath") {
 | |
| 			continue
 | |
| 		}
 | |
| 		path = strings.TrimSpace(strings.Split(line, "=")[1])
 | |
| 		break
 | |
| 	}
 | |
| 
 | |
| 	err = file.Close()
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 
 | |
| 	return fmt.Sprint(path, "local"), nil
 | |
| }
 | |
| 
 | |
| func zipIt(pathToZip string, pathToFiles string) error {
 | |
| 	var err error
 | |
| 
 | |
| 	zipFile, err := os.Create(pathToZip)
 | |
| 	if err != nil {
 | |
| 		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)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	defer func() {
 | |
| 		os.RemoveAll("/tmp/update")
 | |
| 	}()
 | |
| 
 | |
| 	output, err := exec.Command("pacman",  "--verbose", "--query").Output()
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	err = os.WriteFile(fmt.Sprint(tmpPath, fmt.Sprint(when, "_pacman.txt")), output, 0644)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	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() {
 | |
| 	os.RemoveAll("/tmp/update")
 | |
| 
 | |
| 	tree, err := toml.LoadFile("/etc/update.toml")
 | |
| 	if err != nil {
 | |
| 		fmt.Println("backup failed for the following reason: ", err)
 | |
| 		os.Exit(1)
 | |
| 	}
 | |
| 
 | |
| 	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)
 | |
| 	}
 | |
| }
 |