From 2becdcee3bf92146b762f716f20d6f73b118cfef Mon Sep 17 00:00:00 2001 From: Khurram Baig Date: Fri, 4 Oct 2024 14:23:11 +0530 Subject: [PATCH] Compressing archive to save storage costs Enable compressing to save storage costs. Archive is compressed by gzip. If in future zstd is supported natively by Go, we can move to that. --- internal/tar/file-utils.go | 26 ++++++++++-- internal/tar/file_utils_test.go | 71 +++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 internal/tar/file_utils_test.go diff --git a/internal/tar/file-utils.go b/internal/tar/file-utils.go index f3ecd62f6..c2c5aeb47 100644 --- a/internal/tar/file-utils.go +++ b/internal/tar/file-utils.go @@ -2,8 +2,11 @@ package tar import ( "archive/tar" + "bytes" + "compress/gzip" "context" "io" + "log" "os" "path/filepath" "strings" @@ -12,16 +15,19 @@ import ( ) func Tarit(source, target string) error { + var buf bytes.Buffer + + // write the .tar.gzip tarfile, err := os.Create(target) if err != nil { return err } defer tarfile.Close() - tarball := tar.NewWriter(tarfile) - defer tarball.Close() + gz := gzip.NewWriter(&buf) + tarball := tar.NewWriter(gz) - return filepath.Walk(source, + err = filepath.Walk(source, func(path string, info os.FileInfo, err error) error { if err != nil { return err @@ -49,6 +55,18 @@ func Tarit(source, target string) error { _, err = io.Copy(tarball, file) return err }) + if err != nil { + return err + } + + gz.Close() + tarball.Close() + + if _, err := io.Copy(tarfile, &buf); err != nil { + log.Println("error copying tarfile", err) + return err + } + return nil } func Untar(ctx context.Context, file *os.File, target string) error { @@ -57,5 +75,5 @@ func Untar(ctx context.Context, file *os.File, target string) error { return err } defer f.Close() - return extract.Archive(ctx, f, target, nil) + return extract.Gz(ctx, f, target, nil) } diff --git a/internal/tar/file_utils_test.go b/internal/tar/file_utils_test.go new file mode 100644 index 000000000..866c0679f --- /dev/null +++ b/internal/tar/file_utils_test.go @@ -0,0 +1,71 @@ +package tar + +import ( + "context" + "os" + "path/filepath" + "testing" +) + +func TestTaritAndUntar(t *testing.T) { + // Create a temporary directory for testing + tempDir, err := os.MkdirTemp("", "tarit_test") + if err != nil { + t.Fatalf("Failed to create temp directory: %v", err) + } + defer os.RemoveAll(tempDir) + + // Create a test file structure + testDir := filepath.Join(tempDir, "foo-archive") + err = os.Mkdir(testDir, 0755) + if err != nil { + t.Fatalf("Failed to create test directory: %v", err) + } + + testFile := filepath.Join(testDir, "test_file.txt") + err = os.WriteFile(testFile, []byte("Test content"), 0644) + if err != nil { + t.Fatalf("Failed to create test file: %v", err) + } + + // Test Tarit + tarFile := filepath.Join(tempDir, "test.tar.gz") + err = Tarit(testDir, tarFile) + if err != nil { + t.Fatalf("Tarit failed: %v", err) + } + + // Check if the tar file was created + if _, err := os.Stat(tarFile); os.IsNotExist(err) { + t.Fatalf("Tar file was not created") + } + + // Test Untar + extractDir := filepath.Join(tempDir, "bar-archive-extracted") + err = os.Mkdir(extractDir, 0755) + if err != nil { + t.Fatalf("Failed to create extraction directory: %v", err) + } + + tarFileHandle, err := os.Open(tarFile) + if err != nil { + t.Fatalf("Failed to open tar file: %v", err) + } + defer tarFileHandle.Close() + + err = Untar(context.Background(), tarFileHandle, extractDir) + if err != nil { + t.Fatalf("Untar failed: %v", err) + } + + // Check if the extracted file exists and has the correct content + extractedFile := filepath.Join(extractDir, "test_file.txt") + content, err := os.ReadFile(extractedFile) + if err != nil { + t.Fatalf("Failed to read extracted file: %v", err) + } + + if string(content) != "Test content" { + t.Errorf("Extracted file content mismatch. Expected 'Test content', got '%s'", string(content)) + } +}