Skip to content

Commit

Permalink
Make package builds reproducible (#1067)
Browse files Browse the repository at this point in the history
For reproducible builder, certain file metadata has to be changed for archives. This is described in https://reproducible-builds.org/docs/archives/. File ordering is guaranteed by afero, file modification times and uid/gid are changed before adding them to the tarball.
  • Loading branch information
Jan Schlicht authored Nov 19, 2019
1 parent fc1ef45 commit 9eaf5e0
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
8 changes: 8 additions & 0 deletions pkg/kudoctl/packages/writer/writer_tar.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os"
"path/filepath"
"strings"
"time"

"github.com/kudobuilder/kudo/pkg/kudoctl/files"
"github.com/kudobuilder/kudo/pkg/kudoctl/packages"
Expand Down Expand Up @@ -74,6 +75,13 @@ func TgzDir(fs afero.Fs, path string, w io.Writer) (err error) {
// update the name to correctly reflect the desired destination when untaring
header.Name = strings.TrimPrefix(strings.Replace(file, path, "", -1), string(filepath.Separator))

// change certain header metadata to make the build reproducible
header.ModTime = time.Time{}
header.Uid = 0
header.Gid = 0
header.Uname = "root"
header.Gname = "root"

// tar_zcvf the header
if err := tw.WriteHeader(header); err != nil {
return err
Expand Down
14 changes: 14 additions & 0 deletions pkg/kudoctl/packages/writer/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"github.com/spf13/afero"
)

const expectedTarballSHA = "ad0b1650b6f50979815acedae884851527b4e721696a7cc1d37fef3970888b19"

func TestRegularFileTarball(t *testing.T) {
var fs = afero.NewMemMapFs()
files.CopyOperatorToFs(fs, "../testdata/zk", "/opt")
Expand All @@ -31,6 +33,18 @@ func TestRegularFileTarball(t *testing.T) {
f, _ = fs.Open("/opt/zk.tgz")
defer f.Close()

actualTarballSHA, err := files.Sha256Sum(f)
if err != nil {
t.Fatal(err)
}

if expectedTarballSHA != actualTarballSHA {
t.Errorf("Expecting the tarball to have a specific (reproducible) hash but it differs: %v, %v", expectedTarballSHA, actualTarballSHA)
}
if _, err := f.Seek(0, io.SeekStart); err != nil {
t.Fatal(err)
}

if err := untar(fs, "/opt/untar", f); err != nil {
t.Fatal(err)
}
Expand Down

0 comments on commit 9eaf5e0

Please sign in to comment.