diff --git a/cnb_image.go b/cnb_image.go index 564932a2..f272dc5c 100644 --- a/cnb_image.go +++ b/cnb_image.go @@ -310,6 +310,13 @@ func (i *CNBImageCore) AddLayerWithDiffID(path, _ string) error { } func (i *CNBImageCore) AddLayerWithDiffIDAndHistory(path, _ string, history v1.History) error { + // ensure existing history + if err := i.MutateConfigFile(func(c *v1.ConfigFile) { + c.History = NormalizedHistory(c.History, len(c.RootFS.DiffIDs)) + }); err != nil { + return err + } + layer, err := tarball.LayerFromFile(path) if err != nil { return err @@ -437,7 +444,9 @@ func (i *CNBImageCore) ReuseLayerWithHistory(diffID string, history v1.History) if err != nil { return err } - if !i.preserveHistory { + if i.preserveHistory { + history.Created = v1.Time{Time: i.createdAt} + } else { history = emptyHistory } i.Image, err = mutate.Append( @@ -464,6 +473,34 @@ func (i *CNBImageCore) MutateConfigFile(withFunc func(c *v1.ConfigFile)) error { return err } +func (i *CNBImageCore) SetCreatedAtAndHistory() error { + var err error + // set created at + if err = i.MutateConfigFile(func(c *v1.ConfigFile) { + c.Created = v1.Time{Time: i.createdAt} + c.Container = "" + }); err != nil { + return err + } + // set history + if i.preserveHistory { + // set created at for each history + err = i.MutateConfigFile(func(c *v1.ConfigFile) { + for j := range c.History { + c.History[j].Created = v1.Time{Time: i.createdAt} + } + }) + } else { + // zero history + err = i.MutateConfigFile(func(c *v1.ConfigFile) { + for j := range c.History { + c.History[j] = v1.History{Created: v1.Time{Time: i.createdAt}} + } + }) + } + return err +} + func getConfigFile(image v1.Image) (*v1.ConfigFile, error) { configFile, err := image.ConfigFile() if err != nil { diff --git a/layout/layout_test.go b/layout/layout_test.go index d0ee1850..c8e53b67 100644 --- a/layout/layout_test.go +++ b/layout/layout_test.go @@ -502,10 +502,7 @@ func testImage(t *testing.T, when spec.G, it spec.S) { }) }) - when.Pend("#CreatedAt", func() { - // Previously, we only zeroed CreatedAt at the point of save. - // Now, we zero CreatedAt at the point of instantiation. - // If this behavior change is acceptable, we can remove this test. + when("#CreatedAt", func() { it.Before(func() { imagePath = filepath.Join(tmpDir, "new-created-at-image") }) diff --git a/layout/save.go b/layout/save.go index 27932526..bc6bfca8 100644 --- a/layout/save.go +++ b/layout/save.go @@ -12,6 +12,9 @@ func (i *Image) Save(additionalNames ...string) error { // SaveAs ignores the image `Name()` method and saves the image according to name & additional names provided to this method func (i *Image) SaveAs(name string, additionalNames ...string) error { + if err := i.SetCreatedAtAndHistory(); err != nil { + return err + } refName, err := i.GetAnnotateRefName() if err != nil { return err diff --git a/layout/sparse/sparse_test.go b/layout/sparse/sparse_test.go index e5ad871e..a1b73914 100644 --- a/layout/sparse/sparse_test.go +++ b/layout/sparse/sparse_test.go @@ -137,8 +137,7 @@ func testImage(t *testing.T, when spec.G, it spec.S) { }) when("#Digest", func() { - it.Pend("returns the original image digest when there are no modifications", func() { - // TODO: created at + it("returns the original image digest when there are no modifications", func() { image, err := sparse.NewImage(imagePath, testImage) h.AssertNil(t, err) diff --git a/locallayout/image.go b/locallayout/image.go index 1c97219e..e2e294e8 100644 --- a/locallayout/image.go +++ b/locallayout/image.go @@ -104,13 +104,19 @@ func (i *Image) Rebase(baseTopLayerDiffID string, withNewBase imgutil.Image) err } func (i *Image) Save(additionalNames ...string) error { - var err error + err := i.SetCreatedAtAndHistory() + if err != nil { + return err + } i.lastIdentifier, err = i.store.Save(i, i.Name(), additionalNames...) return err } func (i *Image) SaveAs(name string, additionalNames ...string) error { - var err error + err := i.SetCreatedAtAndHistory() + if err != nil { + return err + } i.lastIdentifier, err = i.store.Save(i, name, additionalNames...) return err } diff --git a/locallayout/image_test.go b/locallayout/image_test.go index 0a18293e..61f0d848 100644 --- a/locallayout/image_test.go +++ b/locallayout/image_test.go @@ -709,10 +709,7 @@ func testImage(t *testing.T, when spec.G, it spec.S) { }) }) - when.Pend("#CreatedAt", func() { - // Previously, we only zeroed CreatedAt at the point of save. - // Now, we zero CreatedAt at the point of instantiation. - // If this behavior change is acceptable, we can remove this test. + when("#CreatedAt", func() { it("returns the containers created at time", func() { img, err := local.NewImage(newTestImageName(), dockerClient, local.FromBaseImage(runnableBaseImageName)) h.AssertNil(t, err) diff --git a/new.go b/new.go index 091da8fa..1f53c1e7 100644 --- a/new.go +++ b/new.go @@ -41,13 +41,6 @@ func NewCNBImage(options ImageOptions) (*CNBImageCore, error) { return nil, err } - // ensure existing history - if err = image.MutateConfigFile(func(c *v1.ConfigFile) { - c.History = NormalizedHistory(c.History, len(c.RootFS.DiffIDs)) - }); err != nil { - return nil, err - } - // set config if requested if options.Config != nil { if err = image.MutateConfigFile(func(c *v1.ConfigFile) { @@ -57,33 +50,6 @@ func NewCNBImage(options ImageOptions) (*CNBImageCore, error) { } } - // set created at - if err = image.MutateConfigFile(func(c *v1.ConfigFile) { - c.Created = v1.Time{Time: image.createdAt} - c.Container = "" - }); err != nil { - return nil, err - } - // set history - if options.PreserveHistory { - // set created at for each history - err = image.MutateConfigFile(func(c *v1.ConfigFile) { - for j := range c.History { - c.History[j].Created = v1.Time{Time: image.createdAt} - } - }) - } else { - // zero history - err = image.MutateConfigFile(func(c *v1.ConfigFile) { - for j := range c.History { - c.History[j] = v1.History{Created: v1.Time{Time: image.createdAt}} - } - }) - } - if err != nil { - return nil, err - } - return image, nil }