dockerfile: ensure metadata commands have created time

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-19.03
Tonis Tiigi 2019-01-09 11:28:13 -08:00
parent 3cba03783c
commit db3db1033d
2 changed files with 48 additions and 9 deletions

View File

@ -409,6 +409,37 @@ func normalizeLayersAndHistory(diffs []blobs.DiffPair, history []ocispec.History
history[i] = h history[i] = h
} }
// Find the first new layer time. Otherwise, the history item for a first
// metadata command would be the creation time of a base image layer.
// If there is no such then the last layer with timestamp.
var created *time.Time
var noCreatedTime bool
for _, h := range history {
if h.Created != nil {
created = h.Created
if noCreatedTime {
break
}
} else {
noCreatedTime = true
}
}
// Fill in created times for all history items to be either the first new
// layer time or the previous layer.
noCreatedTime = false
for i, h := range history {
if h.Created != nil {
if noCreatedTime {
created = h.Created
}
} else {
noCreatedTime = true
h.Created = created
}
history[i] = h
}
return diffs, history return diffs, history
} }

View File

@ -1569,6 +1569,7 @@ FROM busybox AS base
ENV foo=bar ENV foo=bar
COPY foo /foo2 COPY foo /foo2
FROM busybox FROM busybox
LABEL lbl=val
COPY --from=base foo2 foo3 COPY --from=base foo2 foo3
WORKDIR / WORKDIR /
RUN echo bar > foo4 RUN echo bar > foo4
@ -1623,15 +1624,22 @@ RUN ["ls"]
// this depends on busybox. should be ok after freezing images // this depends on busybox. should be ok after freezing images
require.Equal(t, 3, len(ociimg.RootFS.DiffIDs)) require.Equal(t, 3, len(ociimg.RootFS.DiffIDs))
require.Equal(t, 6, len(ociimg.History)) require.Equal(t, 7, len(ociimg.History))
require.Contains(t, ociimg.History[2].CreatedBy, "COPY foo2 foo3") require.Contains(t, ociimg.History[2].CreatedBy, "lbl=val")
require.Equal(t, false, ociimg.History[2].EmptyLayer) require.Equal(t, true, ociimg.History[2].EmptyLayer)
require.Contains(t, ociimg.History[3].CreatedBy, "WORKDIR /") require.NotNil(t, ociimg.History[2].Created)
require.Equal(t, true, ociimg.History[3].EmptyLayer) require.Contains(t, ociimg.History[3].CreatedBy, "COPY foo2 foo3")
require.Contains(t, ociimg.History[4].CreatedBy, "echo bar > foo4") require.Equal(t, false, ociimg.History[3].EmptyLayer)
require.Equal(t, false, ociimg.History[4].EmptyLayer) require.NotNil(t, ociimg.History[3].Created)
require.Contains(t, ociimg.History[5].CreatedBy, "RUN ls") require.Contains(t, ociimg.History[4].CreatedBy, "WORKDIR /")
require.Equal(t, true, ociimg.History[5].EmptyLayer) require.Equal(t, true, ociimg.History[4].EmptyLayer)
require.NotNil(t, ociimg.History[4].Created)
require.Contains(t, ociimg.History[5].CreatedBy, "echo bar > foo4")
require.Equal(t, false, ociimg.History[5].EmptyLayer)
require.NotNil(t, ociimg.History[5].Created)
require.Contains(t, ociimg.History[6].CreatedBy, "RUN ls")
require.Equal(t, true, ociimg.History[6].EmptyLayer)
require.NotNil(t, ociimg.History[6].Created)
} }
func testUser(t *testing.T, sb integration.Sandbox) { func testUser(t *testing.T, sb integration.Sandbox) {