Skip to content

Commit

Permalink
exporter: support source-date-epoch for tar exporter
Browse files Browse the repository at this point in the history
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
  • Loading branch information
tonistiigi committed Jun 21, 2022
1 parent 5368827 commit 3e881bb
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 7 deletions.
58 changes: 57 additions & 1 deletion client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ func TestIntegration(t *testing.T) {
testSourceDateEpochClamp,
testSourceDateEpochReset,
testSourceDateEpochLocalExporter,
testSourceDateEpochTarExporter,
)
tests = append(tests, diffOpTestCases()...)
integration.Run(t, tests, mirrors)
Expand Down Expand Up @@ -2333,7 +2334,6 @@ func testSourceDateEpochReset(t *testing.T, sb integration.Sandbox) {
}

func testSourceDateEpochLocalExporter(t *testing.T, sb integration.Sandbox) {
integration.SkipIfDockerd(t, sb, "oci exporter")
requiresLinux(t)
c, err := New(sb.Context(), sb.Address())
require.NoError(t, err)
Expand Down Expand Up @@ -2382,6 +2382,62 @@ func testSourceDateEpochLocalExporter(t *testing.T, sb integration.Sandbox) {
checkAllReleasable(t, c, sb, true)
}

func testSourceDateEpochTarExporter(t *testing.T, sb integration.Sandbox) {
requiresLinux(t)
c, err := New(sb.Context(), sb.Address())
require.NoError(t, err)
defer c.Close()

busybox := llb.Image("busybox:latest")
st := llb.Scratch()

run := func(cmd string) {
st = busybox.Run(llb.Shlex(cmd), llb.Dir("/wd")).AddMount("/wd", st)
}

run(`sh -c "echo -n first > foo"`)
run(`sh -c "echo -n second > bar"`)

def, err := st.Marshal(sb.Context())
require.NoError(t, err)

destDir, err := os.MkdirTemp("", "buildkit")
require.NoError(t, err)
defer os.RemoveAll(destDir)

out := filepath.Join(destDir, "out.tar")
outW, err := os.Create(out)
require.NoError(t, err)

tm := time.Date(2015, time.October, 21, 7, 28, 0, 0, time.UTC)

_, err = c.Solve(sb.Context(), def, SolveOpt{
FrontendAttrs: map[string]string{
"build-arg:SOURCE_DATE_EPOCH": fmt.Sprintf("%d", tm.Unix()),
},
Exports: []ExportEntry{
{
Type: ExporterTar,
Output: fixedWriteCloser(outW),
},
},
}, nil)
require.NoError(t, err)

dt, err := os.ReadFile(out)
require.NoError(t, err)

m, err := testutil.ReadTarToMap(dt, false)
require.NoError(t, err)

require.Equal(t, len(m), 2)

require.Equal(t, tm.Format(time.RFC3339), m["foo"].Header.ModTime.Format(time.RFC3339))
require.Equal(t, tm.Format(time.RFC3339), m["bar"].Header.ModTime.Format(time.RFC3339))

checkAllReleasable(t, c, sb, true)
}

func testFrontendMetadataReturn(t *testing.T, sb integration.Sandbox) {
requiresLinux(t)
c, err := New(sb.Context(), sb.Address())
Expand Down
45 changes: 39 additions & 6 deletions exporter/tar/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/docker/docker/pkg/idtools"
"github.com/moby/buildkit/cache"
"github.com/moby/buildkit/exporter"
"github.com/moby/buildkit/exporter/util/epoch"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/filesync"
"github.com/moby/buildkit/snapshot"
Expand Down Expand Up @@ -43,6 +44,12 @@ func New(opt Opt) (exporter.Exporter, error) {
func (e *localExporter) Resolve(ctx context.Context, opt map[string]string) (exporter.ExporterInstance, error) {
li := &localExporterInstance{localExporter: e}

tm, _, err := epoch.ParseAttr(opt)
if err != nil {
return nil, err
}
li.epoch = tm

v, ok := opt[preferNondistLayersKey]
if ok {
b, err := strconv.ParseBool(v)
Expand All @@ -58,6 +65,7 @@ func (e *localExporter) Resolve(ctx context.Context, opt map[string]string) (exp
type localExporterInstance struct {
*localExporter
preferNonDist bool
epoch *time.Time
}

func (e *localExporterInstance) Name() string {
Expand All @@ -77,6 +85,14 @@ func (e *localExporterInstance) Export(ctx context.Context, inp exporter.Source,
}
}()

if e.epoch == nil {
if tm, ok, err := epoch.ParseSource(inp); err != nil {
return nil, err
} else if ok {
e.epoch = tm
}
}

getDir := func(ctx context.Context, k string, ref cache.ImmutableRef) (*fsutil.Dir, error) {
var src string
var err error
Expand Down Expand Up @@ -106,9 +122,10 @@ func (e *localExporterInstance) Export(ctx context.Context, inp exporter.Source,
}

walkOpt := &fsutil.WalkOpt{}
var idMapFunc func(p string, st *fstypes.Stat) fsutil.MapResult

if idmap != nil {
walkOpt.Map = func(p string, st *fstypes.Stat) fsutil.MapResult {
idMapFunc = func(p string, st *fstypes.Stat) fsutil.MapResult {
uid, gid, err := idmap.ToContainer(idtools.Identity{
UID: int(st.Uid),
GID: int(st.Gid),
Expand All @@ -122,12 +139,28 @@ func (e *localExporterInstance) Export(ctx context.Context, inp exporter.Source,
}
}

walkOpt.Map = func(p string, st *fstypes.Stat) fsutil.MapResult {
res := fsutil.MapResultKeep
if idMapFunc != nil {
res = idMapFunc(p, st)
}
if e.epoch != nil {
st.ModTime = e.epoch.UnixNano()
}
return res
}

st := fstypes.Stat{
Mode: uint32(os.ModeDir | 0755),
Path: strings.Replace(k, "/", "_", -1),
}
if e.epoch != nil {
st.ModTime = e.epoch.UnixNano()
}

return &fsutil.Dir{
FS: fsutil.NewFS(src, walkOpt),
Stat: fstypes.Stat{
Mode: uint32(os.ModeDir | 0755),
Path: strings.Replace(k, "/", "_", -1),
},
FS: fsutil.NewFS(src, walkOpt),
Stat: st,
}, nil
}

Expand Down

0 comments on commit 3e881bb

Please sign in to comment.