diff --git a/daemon/images/image_builder.go b/daemon/images/image_builder.go index 52cd3d88ee..79894332e3 100644 --- a/daemon/images/image_builder.go +++ b/daemon/images/image_builder.go @@ -250,6 +250,9 @@ func (i *ImageService) CreateImage(config []byte, parent string) (builder.Image, return nil, errors.Wrapf(err, "failed to set parent %s", parent) } } + if err := i.imageStore.SetBuiltLocally(id); err != nil { + return nil, errors.Wrapf(err, "failed to mark image %s as built locally", id) + } return i.imageStore.Get(id) } diff --git a/daemon/images/image_commit.go b/daemon/images/image_commit.go index dcde88adc4..54435ac011 100644 --- a/daemon/images/image_commit.go +++ b/daemon/images/image_commit.go @@ -57,6 +57,9 @@ func (i *ImageService) CommitImage(c backend.CommitConfig) (image.ID, error) { if err != nil { return "", err } + if err := i.imageStore.SetBuiltLocally(id); err != nil { + return "", err + } if c.ParentImageID != "" { if err := i.imageStore.SetParent(id, image.ID(c.ParentImageID)); err != nil { diff --git a/image/store.go b/image/store.go index 291150c607..3d945405ce 100644 --- a/image/store.go +++ b/image/store.go @@ -2,6 +2,7 @@ package image // import "github.com/docker/docker/image" import ( "fmt" + "os" "sync" "time" @@ -24,6 +25,8 @@ type Store interface { GetParent(id ID) (ID, error) SetLastUpdated(id ID) error GetLastUpdated(id ID) (time.Time, error) + SetBuiltLocally(id ID) error + IsBuiltLocally(id ID) (bool, error) Children(id ID) []ID Map() map[ID]*Image Heads() map[ID]*Image @@ -291,6 +294,23 @@ func (is *store) GetLastUpdated(id ID) (time.Time, error) { return time.Parse(time.RFC3339Nano, string(bytes)) } +// SetBuiltLocally sets whether image can be used as a builder cache +func (is *store) SetBuiltLocally(id ID) error { + return is.fs.SetMetadata(id.Digest(), "builtLocally", []byte{1}) +} + +// IsBuiltLocally returns whether image can be used as a builder cache +func (is *store) IsBuiltLocally(id ID) (bool, error) { + bytes, err := is.fs.GetMetadata(id.Digest(), "builtLocally") + if err != nil || len(bytes) == 0 { + if errors.Is(err, os.ErrNotExist) { + err = nil + } + return false, err + } + return bytes[0] == 1, nil +} + func (is *store) Children(id ID) []ID { is.RLock() defer is.RUnlock()