From 41631fb9fc7690d42ab3c915323332f1e7e63d36 Mon Sep 17 00:00:00 2001 From: Jon Johnson Date: Thu, 19 Sep 2024 11:27:15 -0700 Subject: [PATCH] Restore SourceDateEpoch in tarball for melange (#1310) We don't use this (and we don't want it) but melange uses the tarball package, so let's avoid breaking that for now until we can migrate stuff off of this tangled web of weird fs.FS implementations. Signed-off-by: Jon Johnson --- pkg/apk/tarball/tarball.go | 28 +++++++++++++++++----------- pkg/apk/tarball/write.go | 11 +++++++++-- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/pkg/apk/tarball/tarball.go b/pkg/apk/tarball/tarball.go index f2bdb27d8..2c71dade8 100644 --- a/pkg/apk/tarball/tarball.go +++ b/pkg/apk/tarball/tarball.go @@ -20,17 +20,19 @@ import ( ) type Context struct { - SourceDateEpoch time.Time - OverrideUIDGID bool - UID int - GID int - OverrideUname string - OverrideGname string - SkipClose bool - UseChecksums bool - remapUIDs map[int]int - remapGIDs map[int]int - overridePerms map[string]tar.Header + SourceDateEpoch time.Time + useSourceDateEpoch bool + + OverrideUIDGID bool + UID int + GID int + OverrideUname string + OverrideGname string + SkipClose bool + UseChecksums bool + remapUIDs map[int]int + remapGIDs map[int]int + overridePerms map[string]tar.Header } type Option func(*Context) error @@ -52,6 +54,10 @@ func NewContext(opts ...Option) (*Context, error) { func WithSourceDateEpoch(t time.Time) Option { return func(ctx *Context) error { ctx.SourceDateEpoch = t + + // to distinguish between unset and zero value + ctx.useSourceDateEpoch = true + return nil } } diff --git a/pkg/apk/tarball/write.go b/pkg/apk/tarball/write.go index cf358bdb9..6a89632d6 100644 --- a/pkg/apk/tarball/write.go +++ b/pkg/apk/tarball/write.go @@ -148,8 +148,15 @@ func (c *Context) writeTar(ctx context.Context, tw *tar.Writer, fsys fs.FS, user // work around some weirdness, without this we wind up with just the basename header.Name = path - // zero out timestamps for reproducibility - header.ModTime = info.ModTime() + // if SourceDateEpoch is set explicitly, overwrite the timestamps, otherwise propagate modtime + // (this option is unused in apko but melange uses this, so we support it for now) + if c.useSourceDateEpoch { + header.AccessTime = c.SourceDateEpoch + header.ModTime = c.SourceDateEpoch + header.ChangeTime = c.SourceDateEpoch + } else { + header.ModTime = info.ModTime() + } if uid, ok := c.remapUIDs[header.Uid]; ok { header.Uid = uid