Skip to content

Commit

Permalink
repro tarballs for components + sboms
Browse files Browse the repository at this point in the history
Signed-off-by: razzle <[email protected]>
  • Loading branch information
Noxsios committed Dec 29, 2023
1 parent 93e80e8 commit 223c671
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/pkg/layout/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (c *Components) Archive(component types.ZarfComponent, cleanupTemp bool) (e
if size > 0 {
tb := fmt.Sprintf("%s.tar", base)
message.Debugf("Archiving %q", name)
if err := archiver.Archive([]string{base}, tb); err != nil {
if err := utils.CreateReproducibleTarballFromDir(base, tb); err != nil {
return err
}
if c.Tarballs == nil {
Expand Down
7 changes: 1 addition & 6 deletions src/pkg/layout/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,9 @@ func (s *SBOMs) Archive() (err error) {
dir := s.Path
tb := filepath.Join(filepath.Dir(dir), SBOMTar)

allSBOMFiles, err := filepath.Glob(filepath.Join(dir, "*"))
if err != nil {
if err := utils.CreateReproducibleTarballFromDir(dir, tb); err != nil {
return err
}

if err = archiver.Archive(allSBOMFiles, tb); err != nil {
return
}
s.Path = tb
return os.RemoveAll(dir)
}
Expand Down
70 changes: 70 additions & 0 deletions src/pkg/utils/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package utils

import (
"archive/tar"
"bufio"
"crypto/sha256"
"fmt"
Expand All @@ -16,6 +17,7 @@ import (
"path/filepath"
"regexp"
"strings"
"time"

"github.com/defenseunicorns/zarf/src/config"
"github.com/defenseunicorns/zarf/src/pkg/message"
Expand Down Expand Up @@ -422,3 +424,71 @@ func SHAsMatch(path, expected string) error {
}
return nil
}

// CreateReproducibleTarballFromDir creates a tarball from a directory with stripped headers
func CreateReproducibleTarballFromDir(dirPath, tarballPath string) error {
// Create a new tarball for the output
outFile, err := os.Create(tarballPath)
if err != nil {
return fmt.Errorf("error creating tarball: %w", err)
}
defer outFile.Close()

tarWriter := tar.NewWriter(outFile)
defer tarWriter.Close()

// Walk through the directory and process each file
err = filepath.Walk(dirPath, func(filePath string, info os.FileInfo, err error) error {
if err != nil {
return err
}

// Create a new header
header, err := tar.FileInfoHeader(info, "")
if err != nil {
return fmt.Errorf("error creating tar header: %w", err)
}

// Strip non-deterministic header data
header.ModTime = time.Time{}
header.AccessTime = time.Time{}
header.ChangeTime = time.Time{}
header.Uid = 0
header.Gid = 0
header.Uname = ""
header.Gname = ""

// Ensure the header's name is correctly set relative to the base directory
relPath, err := filepath.Rel(dirPath, filePath)
if err != nil {
return fmt.Errorf("error getting relative path: %w", err)
}
header.Name = relPath

// Write the header to the tarball
if err := tarWriter.WriteHeader(header); err != nil {
return fmt.Errorf("error writing header: %w", err)
}

// If it's a file, write its content
if !info.IsDir() {
file, err := os.Open(filePath)
if err != nil {
return fmt.Errorf("error opening file: %w", err)
}
defer file.Close()

if _, err := io.Copy(tarWriter, file); err != nil {
return fmt.Errorf("error writing file to tarball: %w", err)
}
}

return nil
})

if err != nil {
return fmt.Errorf("error walking through directory: %w", err)
}

return nil
}

0 comments on commit 223c671

Please sign in to comment.