diff --git a/pkg/kudoctl/packages/writer/writer_tar.go b/pkg/kudoctl/packages/writer/writer_tar.go index 46c1b1509..26fef76e2 100644 --- a/pkg/kudoctl/packages/writer/writer_tar.go +++ b/pkg/kudoctl/packages/writer/writer_tar.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "strings" + "time" "github.com/kudobuilder/kudo/pkg/kudoctl/files" "github.com/kudobuilder/kudo/pkg/kudoctl/packages" @@ -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 diff --git a/pkg/kudoctl/packages/writer/writer_test.go b/pkg/kudoctl/packages/writer/writer_test.go index 7feb5ac0d..59aa817b4 100644 --- a/pkg/kudoctl/packages/writer/writer_test.go +++ b/pkg/kudoctl/packages/writer/writer_test.go @@ -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") @@ -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) }