From f67c57795658ada0abdbd341233a2ba1d551c80c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20Georg=20Gisn=C3=A5s=20Gleditsch?= Date: Thu, 2 Oct 2025 13:10:27 +0200 Subject: [PATCH] fix: Use PAX tar format for accurate timestamps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Go's `archive/tar` package rounds archive member file timestamps to the closest second unless the POSIX.1-2001 "PAX" tar format is used (see https://pkg.go.dev/archive/tar#Format). This results in noise in processes where the helm charts are immediately extracted by (at least) GNU tar for repackaging/modification/inspection, where tar complains (if the original creation time ended up being rounded up) that `time stamp 2025-10-02 12:06:47 is 0.469095762 s in the future` or similar. This behavior is unlikely to be changed in the the `archive/tar` package; ref comments in golang/go#48275. An alternative fix is to truncate the file mtimes to the nearest second in the past using `ModTime: time.Now().Truncate(time.Second)`, as also suggested in the golang issue referenced above. Signed-off-by: Arne Georg Gisnås Gleditsch --- internal/chart/v3/util/save.go | 1 + internal/chart/v3/util/save_test.go | 5 +---- pkg/chart/v2/util/save.go | 1 + pkg/chart/v2/util/save_test.go | 5 +---- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/internal/chart/v3/util/save.go b/internal/chart/v3/util/save.go index 49d93bf40..606e0b6b0 100644 --- a/internal/chart/v3/util/save.go +++ b/internal/chart/v3/util/save.go @@ -233,6 +233,7 @@ func writeToTar(out *tar.Writer, name string, body []byte) error { Mode: 0644, Size: int64(len(body)), ModTime: time.Now(), + Format: tar.FormatPAX, } if err := out.WriteHeader(h); err != nil { return err diff --git a/internal/chart/v3/util/save_test.go b/internal/chart/v3/util/save_test.go index 9b1b14a4c..91a7ac7dc 100644 --- a/internal/chart/v3/util/save_test.go +++ b/internal/chart/v3/util/save_test.go @@ -137,10 +137,7 @@ func Indent(n int, text string) string { } func TestSavePreservesTimestamps(t *testing.T) { - // Test executes so quickly that if we don't subtract a second, the - // check will fail because `initialCreateTime` will be identical to the - // written timestamp for the files. - initialCreateTime := time.Now().Add(-1 * time.Second) + initialCreateTime := time.Now() tmp := t.TempDir() diff --git a/pkg/chart/v2/util/save.go b/pkg/chart/v2/util/save.go index 69a98924c..ca363279f 100644 --- a/pkg/chart/v2/util/save.go +++ b/pkg/chart/v2/util/save.go @@ -245,6 +245,7 @@ func writeToTar(out *tar.Writer, name string, body []byte) error { Mode: 0644, Size: int64(len(body)), ModTime: time.Now(), + Format: tar.FormatPAX, } if err := out.WriteHeader(h); err != nil { return err diff --git a/pkg/chart/v2/util/save_test.go b/pkg/chart/v2/util/save_test.go index ef822a82a..c88741972 100644 --- a/pkg/chart/v2/util/save_test.go +++ b/pkg/chart/v2/util/save_test.go @@ -140,10 +140,7 @@ func Indent(n int, text string) string { } func TestSavePreservesTimestamps(t *testing.T) { - // Test executes so quickly that if we don't subtract a second, the - // check will fail because `initialCreateTime` will be identical to the - // written timestamp for the files. - initialCreateTime := time.Now().Add(-1 * time.Second) + initialCreateTime := time.Now() tmp := t.TempDir()