Skip to content

Commit

Permalink
MountStubsCleaner: preserve timestamps
Browse files Browse the repository at this point in the history
Fix issue 3148

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
  • Loading branch information
AkihiroSuda committed Oct 5, 2022
1 parent 092e977 commit 3827376
Show file tree
Hide file tree
Showing 20 changed files with 415 additions and 1 deletion.
56 changes: 56 additions & 0 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ func TestIntegration(t *testing.T) {
testExportAnnotationsMediaTypes,
testExportAttestations,
testAttestationDefaultSubject,
testMountStubsTimestamp,
)
tests = append(tests, diffOpTestCases()...)
integration.Run(t, tests, mirrors)
Expand Down Expand Up @@ -6769,6 +6770,61 @@ func testAttestationDefaultSubject(t *testing.T, sb integration.Sandbox) {
}
}

// https://github.com/moby/buildkit/issues/3148
func testMountStubsTimestamp(t *testing.T, sb integration.Sandbox) {
c, err := New(sb.Context(), sb.Address())
require.NoError(t, err)
defer c.Close()

const sourceDateEpoch = int64(1234567890) // Fri Feb 13 11:31:30 PM UTC 2009
st := llb.Image("busybox:latest").Run(
llb.Args([]string{"/bin/touch", fmt.Sprintf("--date=@%d", sourceDateEpoch), "/bin", "/etc"}),
)
def, err := st.Marshal(sb.Context())
require.NoError(t, err)

tmpDir := t.TempDir()
tarFile := filepath.Join(tmpDir, "out.tar")
tarFileW, err := os.Create(tarFile)
require.NoError(t, err)
defer tarFileW.Close()

_, err = c.Solve(sb.Context(), def, SolveOpt{
Exports: []ExportEntry{
{
Type: ExporterTar,
Output: fixedWriteCloser(tarFileW),
},
},
}, nil)
require.NoError(t, err)
tarFileW.Close()

tarFileR, err := os.Open(tarFile)
require.NoError(t, err)
defer tarFileR.Close()
tarR := tar.NewReader(tarFileR)
touched := map[string]*tar.Header{
"bin/": nil,
"etc/": nil,
}
for {
hd, err := tarR.Next()
if errors.Is(err, io.EOF) {
break
}
require.NoError(t, err)
if x, ok := touched[hd.Name]; ok && x == nil {
touched[hd.Name] = hd
}
}
for name, hd := range touched {
t.Logf("Verifying %q (%+v)", name, hd)
require.NotNil(t, hd, name)
require.Equal(t, sourceDateEpoch, hd.ModTime.Unix(), name)
}
}

func makeSSHAgentSock(t *testing.T, agent agent.Agent) (p string, err error) {
tmpDir, err := integration.Tmpdir(t)
if err != nil {
Expand Down
23 changes: 22 additions & 1 deletion executor/stubs.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"syscall"

"github.com/containerd/continuity/fs"
"github.com/djherbis/atime"
"github.com/sirupsen/logrus"
)

func MountStubsCleaner(dir string, mounts []Mount) func() {
Expand Down Expand Up @@ -43,7 +45,26 @@ func MountStubsCleaner(dir string, mounts []Mount) func() {
if st.Size() != 0 {
continue
}
os.Remove(p)
// Back up the timestamps of the dir for reproducible builds
// https://github.com/moby/buildkit/issues/3148
dir := filepath.Dir(p)
dirSt, err := os.Stat(dir)
if err != nil {
logrus.WithError(err).Warnf("Failed to stat %q (parent of %q)", dir, p)
continue
}
atime := atime.Get(dirSt)
mtime := dirSt.ModTime()

if err := os.RemoveAll(p); err != nil {
logrus.WithError(err).Warnf("Failed to remove %q", p)
continue
}

// Revert the timestamps of the dir
if err := os.Chtimes(dir, atime, mtime); err != nil {
logrus.WithError(err).Warnf("Failed to os.Chtimes(%q, %v, %v)", dir, atime, mtime)
}
}
}
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ require (
github.com/containerd/stargz-snapshotter/estargz v0.12.0
github.com/containerd/typeurl v1.0.2
github.com/coreos/go-systemd/v22 v22.3.2
github.com/djherbis/atime v1.1.0
github.com/docker/cli v20.10.17+incompatible
github.com/docker/distribution v2.8.1+incompatible
github.com/docker/docker v20.10.17+incompatible // v22.06.x - see "replace" for the actual version
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
github.com/djherbis/atime v1.1.0 h1:rgwVbP/5by8BvvjBNrbh64Qz33idKT3pSnMSJsxhi0g=
github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c=
github.com/docker/cli v0.0.0-20190925022749-754388324470/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
Expand Down
22 changes: 22 additions & 0 deletions vendor/github.com/djherbis/atime/.travis.yml

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

22 changes: 22 additions & 0 deletions vendor/github.com/djherbis/atime/LICENSE

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

42 changes: 42 additions & 0 deletions vendor/github.com/djherbis/atime/README.md

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

21 changes: 21 additions & 0 deletions vendor/github.com/djherbis/atime/atime_darwin.go

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

21 changes: 21 additions & 0 deletions vendor/github.com/djherbis/atime/atime_dragonfly.go

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

21 changes: 21 additions & 0 deletions vendor/github.com/djherbis/atime/atime_freebsd.go

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

21 changes: 21 additions & 0 deletions vendor/github.com/djherbis/atime/atime_linux.go

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

22 changes: 22 additions & 0 deletions vendor/github.com/djherbis/atime/atime_nacl.go

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

21 changes: 21 additions & 0 deletions vendor/github.com/djherbis/atime/atime_netbsd.go

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

21 changes: 21 additions & 0 deletions vendor/github.com/djherbis/atime/atime_openbsd.go

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

16 changes: 16 additions & 0 deletions vendor/github.com/djherbis/atime/atime_plan9.go

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

Loading

0 comments on commit 3827376

Please sign in to comment.