Skip to content

Commit

Permalink
Merge pull request #8764 from AkihiroSuda/zero-whiteout-timestamp
Browse files Browse the repository at this point in the history
  • Loading branch information
dmcgowan committed Jun 30, 2023
2 parents a542a57 + 5dedb6d commit 5d1ab01
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 19 deletions.
5 changes: 4 additions & 1 deletion api/services/diff/v1/diff.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion api/services/diff/v1/diff.proto
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,11 @@ message DiffRequest {
// on content store commit.
map<string, string> labels = 5;

// SourceDateEpoch specifies the timestamp used for whiteouts to provide control for reproducibility.
// SourceDateEpoch specifies the timestamp used to provide control for reproducibility.
// See also https://reproducible-builds.org/docs/source-date-epoch/ .
//
// Since containerd v2.0, the whiteout timestamps are set to zero (1970-01-01),
// not to the source date epoch.
google.protobuf.Timestamp source_date_epoch = 6;
}

Expand Down
24 changes: 9 additions & 15 deletions archive/tar.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ func WriteDiff(ctx context.Context, w io.Writer, a, b string, opts ...WriteDiffO
func writeDiffNaive(ctx context.Context, w io.Writer, a, b string, o WriteDiffOptions) error {
var opts []ChangeWriterOpt
if o.SourceDateEpoch != nil {
opts = append(opts,
WithModTimeUpperBound(*o.SourceDateEpoch),
WithWhiteoutTime(*o.SourceDateEpoch))
opts = append(opts, WithModTimeUpperBound(*o.SourceDateEpoch))
// Since containerd v2.0, the whiteout timestamps are set to zero (1970-01-01),
// not to the source date epoch
}
cw := NewChangeWriter(w, b, opts...)
err := fs.Changes(ctx, a, b, cw.HandleChange)
Expand Down Expand Up @@ -505,7 +505,6 @@ type ChangeWriter struct {
tw *tar.Writer
source string
modTimeUpperBound *time.Time
whiteoutT time.Time
inodeSrc map[uint64]string
inodeRefs map[uint64][]string
addedDirs map[string]struct{}
Expand All @@ -521,21 +520,13 @@ func WithModTimeUpperBound(tm time.Time) ChangeWriterOpt {
}
}

// WithWhiteoutTime sets the whiteout timestamp.
func WithWhiteoutTime(tm time.Time) ChangeWriterOpt {
return func(cw *ChangeWriter) {
cw.whiteoutT = tm
}
}

// NewChangeWriter returns ChangeWriter that writes tar stream of the source directory
// to the privided writer. Change information (add/modify/delete/unmodified) for each
// file needs to be passed through HandleChange method.
func NewChangeWriter(w io.Writer, source string, opts ...ChangeWriterOpt) *ChangeWriter {
cw := &ChangeWriter{
tw: tar.NewWriter(w),
source: source,
whiteoutT: time.Now(), // can be overridden with WithWhiteoutTime(time.Time) ChangeWriterOpt .
inodeSrc: map[uint64]string{},
inodeRefs: map[uint64][]string{},
addedDirs: map[string]struct{}{},
Expand All @@ -557,13 +548,16 @@ func (cw *ChangeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, e
whiteOutDir := filepath.Dir(p)
whiteOutBase := filepath.Base(p)
whiteOut := filepath.Join(whiteOutDir, whiteoutPrefix+whiteOutBase)
// Since containerd v2.0, the whiteout timestamps are set to zero (1970-01-01),
// not to the source date epoch.
whiteOutT := time.Unix(0, 0).UTC()
hdr := &tar.Header{
Typeflag: tar.TypeReg,
Name: whiteOut[1:],
Size: 0,
ModTime: cw.whiteoutT,
AccessTime: cw.whiteoutT,
ChangeTime: cw.whiteoutT,
ModTime: whiteOutT,
AccessTime: whiteOutT,
ChangeTime: whiteOutT,
}
if err := cw.includeParents(hdr); err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion archive/tar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,7 @@ func TestSourceDateEpoch(t *testing.T) {

opts := []WriteDiffOpt{WithSourceDateEpoch(&sourceDateEpoch)}
validators := []tarEntryValidator{
composeValidators(whiteoutEntry("f1"), requireModTime(sourceDateEpoch)),
composeValidators(whiteoutEntry("f1"), requireModTime(time.Unix(0, 0).UTC())), // not sourceDateEpoch
composeValidators(fileEntry("f2", []byte("content2"), 0644), requireModTime(past)),
composeValidators(fileEntry("f3", []byte("content3"), 0644), requireModTime(sourceDateEpoch)),
}
Expand Down
5 changes: 4 additions & 1 deletion diff/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,11 @@ func WithPayloads(payloads map[string]typeurl.Any) ApplyOpt {
}
}

// WithSourceDateEpoch specifies the timestamp used for whiteouts to provide control for reproducibility.
// WithSourceDateEpoch specifies the timestamp used to provide control for reproducibility.
// See also https://reproducible-builds.org/docs/source-date-epoch/ .
//
// Since containerd v2.0, the whiteout timestamps are set to zero (1970-01-01),
// not to the source date epoch.
func WithSourceDateEpoch(tm *time.Time) Opt {
return func(c *Config) error {
c.SourceDateEpoch = tm
Expand Down

0 comments on commit 5d1ab01

Please sign in to comment.