From 9eda23e512d29252b778c3cdc9c732eb5add032a Mon Sep 17 00:00:00 2001 From: Frederik Ring Date: Tue, 19 Apr 2022 21:08:53 +0200 Subject: [PATCH] Make header format for created tar archive configurable --- cmd/backup/archive.go | 18 +++++++++++++----- cmd/backup/config.go | 32 +++++++++++++++++++++++++++++++- cmd/backup/script.go | 4 +++- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/cmd/backup/archive.go b/cmd/backup/archive.go index d419eac..a3f7604 100644 --- a/cmd/backup/archive.go +++ b/cmd/backup/archive.go @@ -18,7 +18,7 @@ import ( "strings" ) -func createArchive(inputFilePath, outputFilePath string) error { +func createArchive(inputFilePath, outputFilePath string, options createArchiveOptions) error { inputFilePath = stripTrailingSlashes(inputFilePath) inputFilePath, outputFilePath, err := makeAbsolute(inputFilePath, outputFilePath) if err != nil { @@ -28,7 +28,7 @@ func createArchive(inputFilePath, outputFilePath string) error { return fmt.Errorf("createArchive: error creating output file path: %w", err) } - if err := compress(inputFilePath, outputFilePath, filepath.Dir(inputFilePath)); err != nil { + if err := compress(inputFilePath, outputFilePath, filepath.Dir(inputFilePath), options); err != nil { return fmt.Errorf("createArchive: error creating archive: %w", err) } @@ -52,7 +52,7 @@ func makeAbsolute(inputFilePath, outputFilePath string) (string, string, error) return inputFilePath, outputFilePath, err } -func compress(inPath, outFilePath, subPath string) error { +func compress(inPath, outFilePath, subPath string, options createArchiveOptions) error { file, err := os.Create(outFilePath) if err != nil { return fmt.Errorf("compress: error creating out file: %w", err) @@ -71,7 +71,7 @@ func compress(inPath, outFilePath, subPath string) error { } for _, p := range paths { - if err := writeTarGz(p, tarWriter, prefix); err != nil { + if err := writeTarGz(p, tarWriter, prefix, options.format); err != nil { return fmt.Errorf("compress error writing %s to archive: %w", p, err) } } @@ -94,7 +94,7 @@ func compress(inPath, outFilePath, subPath string) error { return nil } -func writeTarGz(path string, tarWriter *tar.Writer, prefix string) error { +func writeTarGz(path string, tarWriter *tar.Writer, prefix string, format tar.Format) error { fileInfo, err := os.Lstat(path) if err != nil { return fmt.Errorf("writeTarGz: error getting file infor for %s: %w", path, err) @@ -113,6 +113,10 @@ func writeTarGz(path string, tarWriter *tar.Writer, prefix string) error { } header, err := tar.FileInfoHeader(fileInfo, link) + if format >= 0 { + header.Format = format + } + if err != nil { return fmt.Errorf("writeTarGz: error getting file info header: %w", err) } @@ -140,3 +144,7 @@ func writeTarGz(path string, tarWriter *tar.Writer, prefix string) error { return nil } + +type createArchiveOptions struct { + format tar.Format +} diff --git a/cmd/backup/config.go b/cmd/backup/config.go index 06c8c3a..954e1e5 100644 --- a/cmd/backup/config.go +++ b/cmd/backup/config.go @@ -3,7 +3,11 @@ package main -import "time" +import ( + "archive/tar" + "fmt" + "time" +) // Config holds all configuration values that are expected to be set // by users. @@ -42,4 +46,30 @@ type Config struct { ExecLabel string `split_words:"true"` ExecForwardOutput bool `split_words:"true"` LockTimeout time.Duration `split_words:"true" default:"60m"` + TarArchiveHeaderFormat TarFormat `split_words:"true"` +} + +type TarFormat tar.Format + +func (t *TarFormat) Decode(value string) error { + switch value { + case "PAX": + *t = TarFormat(tar.FormatPAX) + return nil + case "USTAR": + *t = TarFormat(tar.FormatUSTAR) + return nil + case "GNU": + *t = TarFormat(tar.FormatGNU) + return nil + case "": + *t = TarFormat(-1) + return nil + default: + return fmt.Errorf("tarFormat: unknown format %s", value) + } +} + +func (t *TarFormat) Format() tar.Format { + return tar.Format(*t) } diff --git a/cmd/backup/script.go b/cmd/backup/script.go index 8bc6074..d7dfdca 100644 --- a/cmd/backup/script.go +++ b/cmd/backup/script.go @@ -388,7 +388,9 @@ func (s *script) takeBackup() error { s.logger.Infof("Removed tar file `%s`.", tarFile) return nil }) - if err := createArchive(backupSources, tarFile); err != nil { + if err := createArchive(backupSources, tarFile, createArchiveOptions{ + format: s.c.TarArchiveHeaderFormat.Format(), + }); err != nil { return fmt.Errorf("takeBackup: error compressing backup folder: %w", err) }