Compare commits
	
		
			2 Commits
		
	
	
		
			0cf266dd87
			...
			f89e7112a4
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f89e7112a4 | |||
| b28009f83b | 
							
								
								
									
										192
									
								
								backup.go
									
									
									
									
									
								
							
							
						
						
									
										192
									
								
								backup.go
									
									
									
									
									
								
							| @@ -1,42 +1,29 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"archive/zip" | ||||
| 	"bufio" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io/fs" | ||||
| 	"log" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/pelletier/go-toml" | ||||
| ) | ||||
|  | ||||
| func parseEnvironment(key string) 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 | ||||
| } | ||||
| var backup_locations []string | ||||
|  | ||||
| func parsePacmanConf() string { | ||||
| func parsePacmanConf() (string, error) { | ||||
| 	var err error | ||||
| 	var path string | ||||
|  | ||||
| 	file, err := os.Open("/etc/pacman.conf") | ||||
| 	if err != nil { | ||||
| 		log.Panicln(err) | ||||
| 		return "", err | ||||
| 	} | ||||
| 	defer func() { | ||||
| 		if err := file.Close(); err != nil { | ||||
| 			log.Panicln(err) | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	scanner := bufio.NewScanner(file) | ||||
| 	for scanner.Scan() { | ||||
| @@ -48,73 +35,130 @@ func parsePacmanConf() string { | ||||
| 		break | ||||
| 	} | ||||
|  | ||||
| 	if _, err := os.Stat(path); err != nil { | ||||
| 		if errors.Is(err, fs.ErrNotExist) { | ||||
| 			log.Panicln("DBPath in /etc/pacman.conf does not point to a valid path") | ||||
| 		} | ||||
| 		log.Panicf("trying to stat %s produced an unkown error\n", path) | ||||
| 	} | ||||
|  | ||||
| 	return fmt.Sprintf("%s%s", path, "local") | ||||
| } | ||||
|  | ||||
| func preBackup() { | ||||
| 	pacmanDb := parsePacmanConf() | ||||
| 	log.Printf("pacmanDb: %s\n", pacmanDb) | ||||
| 	tmpPath := "/tmp/update/pre_backup" | ||||
|  | ||||
| 	output, err := exec.Command("pacman",  "--verbose", "--query").Output() | ||||
| 	err = file.Close() | ||||
| 	if err != nil { | ||||
| 		log.Panicln(err) | ||||
| 		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) | ||||
|  | ||||
| 	err = os.WriteFile(fmt.Sprintf("%s/%s", tmpPath, "pre_pacman.txt"), output, 0644) | ||||
| 	if err != nil { | ||||
| 		log.Panicln(err) | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	defer func() { | ||||
| 		if r := recover(); r != nil { | ||||
| 			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") | ||||
| 		} | ||||
| 		os.RemoveAll("/tmp/update") | ||||
| 	}() | ||||
|  | ||||
| 	err = CopyDir(pacmanDb, fmt.Sprintf("%s/%s", tmpPath, pacmanDb)) | ||||
| 	output, err := exec.Command("pacman",  "--verbose", "--query").Output() | ||||
| 	if err != nil { | ||||
| 		log.Panicln(err) | ||||
| 		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 | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| func postBackup() { | ||||
| 	/* | ||||
| 	 * basic logic for post: | ||||
| 	 * create new pkg list and delete all lines which are the same as pre | ||||
| 	 */ | ||||
| 	panic("unimplemented") | ||||
| 	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() { | ||||
| 	// backup_dir := parseEnvironment("UPDATE_BACKUP_DIR") | ||||
| 	cmdlineArg := os.Args[1] | ||||
| 	log.Printf("cmdlineArg: %s\n", cmdlineArg) | ||||
| 	os.RemoveAll("/tmp/update") | ||||
|  | ||||
| 	if cmdlineArg == "pre" { | ||||
| 		preBackup() | ||||
| 	} else if cmdlineArg == "post" { | ||||
| 		postBackup() | ||||
| 	} else { | ||||
| 		log.Panicf("invalid cmdline argument. supplied value was: %s\n", cmdlineArg) | ||||
| 	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) | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										4
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							| @@ -1,3 +1,5 @@ | ||||
| module update | ||||
| module backup | ||||
|  | ||||
| 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: | ||||
| 	@echo "==> Installing update into /usr/local/bin" | ||||
| 	@sudo install -Dm755 update /usr/local/bin/update | ||||
| 	@[[ -f ${HOME}/.config/update.conf ]] || cp update.conf ${HOME}/.config/ | ||||
| help: | ||||
| 	@echo "Usage: make [OPTION]" | ||||
| 	@echo "Available options are:" | ||||
| 	@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." | ||||
|  | ||||
| uninstall: | ||||
| 	@echo "==> Uninstalling update from /usr/local/bin" | ||||
| 	@sudo rm /usr/local/bin/update ${HOME}/.config/update.conf | ||||
| 	@echo "==> Removing the hooks from /etc/pacman.d/hooks" | ||||
| 	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." | ||||
|   | ||||
| @@ -2,8 +2,8 @@ | ||||
| Operation = Install | ||||
| Operation = Upgrade | ||||
| Operation = Remove | ||||
| Type = Path | ||||
| Target = /usr/local/bin/backup | ||||
| Type = Package | ||||
| Target = * | ||||
|  | ||||
| [Action] | ||||
| Description = Backing up the pacman db... | ||||
|   | ||||
| @@ -2,8 +2,8 @@ | ||||
| Operation = Install | ||||
| Operation = Upgrade | ||||
| Operation = Remove | ||||
| Type = Path | ||||
| Target = /usr/local/bin/backup | ||||
| Type = Package | ||||
| Target = * | ||||
|  | ||||
| [Action] | ||||
| 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 | ||||
		Reference in New Issue
	
	Block a user