Update containers/image and containers/storage
Bump containers/image to 3d0304a02154dddc8f97cc833aa0861cea5e9ade, and containers/storage to 0d32dfce498e06c132c60dac945081bf44c22464. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
parent
2fa1f3f74a
commit
0651d3a8de
64 changed files with 4121 additions and 1636 deletions
103
vendor/github.com/containers/storage/images.go
generated
vendored
103
vendor/github.com/containers/storage/images.go
generated
vendored
|
@ -14,12 +14,22 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// ImageDigestBigDataKey is the name of the big data item whose
|
||||
// contents we consider useful for computing a "digest" of the
|
||||
// image, by which we can locate the image later.
|
||||
ImageDigestBigDataKey = "manifest"
|
||||
)
|
||||
|
||||
// An Image is a reference to a layer and an associated metadata string.
|
||||
type Image struct {
|
||||
// ID is either one which was specified at create-time, or a random
|
||||
// value which was generated by the library.
|
||||
ID string `json:"id"`
|
||||
|
||||
// Digest is a digest value that we can use to locate the image.
|
||||
Digest digest.Digest `json:"digest,omitempty"`
|
||||
|
||||
// Names is an optional set of user-defined convenience values. The
|
||||
// image can be referred to by its ID or any of its names. Names are
|
||||
// unique among images.
|
||||
|
@ -28,7 +38,7 @@ type Image struct {
|
|||
// TopLayer is the ID of the topmost layer of the image itself, if the
|
||||
// image contains one or more layers. Multiple images can refer to the
|
||||
// same top layer.
|
||||
TopLayer string `json:"layer"`
|
||||
TopLayer string `json:"layer,omitempty"`
|
||||
|
||||
// Metadata is data we keep for the convenience of the caller. It is not
|
||||
// expected to be large, since it is kept in memory.
|
||||
|
@ -74,6 +84,10 @@ type ROImageStore interface {
|
|||
|
||||
// Images returns a slice enumerating the known images.
|
||||
Images() ([]Image, error)
|
||||
|
||||
// Images returns a slice enumerating the images which have a big data
|
||||
// item with the name ImageDigestBigDataKey and the specified digest.
|
||||
ByDigest(d digest.Digest) ([]*Image, error)
|
||||
}
|
||||
|
||||
// ImageStore provides bookkeeping for information about Images.
|
||||
|
@ -87,7 +101,7 @@ type ImageStore interface {
|
|||
// Create creates an image that has a specified ID (or a random one) and
|
||||
// optional names, using the specified layer as its topmost (hopefully
|
||||
// read-only) layer. That layer can be referenced by multiple images.
|
||||
Create(id string, names []string, layer, metadata string, created time.Time) (*Image, error)
|
||||
Create(id string, names []string, layer, metadata string, created time.Time, searchableDigest digest.Digest) (*Image, error)
|
||||
|
||||
// SetNames replaces the list of names associated with an image with the
|
||||
// supplied values.
|
||||
|
@ -107,6 +121,7 @@ type imageStore struct {
|
|||
idindex *truncindex.TruncIndex
|
||||
byid map[string]*Image
|
||||
byname map[string]*Image
|
||||
bydigest map[digest.Digest][]*Image
|
||||
}
|
||||
|
||||
func (r *imageStore) Images() ([]Image, error) {
|
||||
|
@ -140,6 +155,7 @@ func (r *imageStore) Load() error {
|
|||
idlist := []string{}
|
||||
ids := make(map[string]*Image)
|
||||
names := make(map[string]*Image)
|
||||
digests := make(map[digest.Digest][]*Image)
|
||||
if err = json.Unmarshal(data, &images); len(data) == 0 || err == nil {
|
||||
idlist = make([]string, 0, len(images))
|
||||
for n, image := range images {
|
||||
|
@ -152,6 +168,16 @@ func (r *imageStore) Load() error {
|
|||
}
|
||||
names[name] = images[n]
|
||||
}
|
||||
// Implicit digest
|
||||
if digest, ok := image.BigDataDigests[ImageDigestBigDataKey]; ok {
|
||||
digests[digest] = append(digests[digest], images[n])
|
||||
}
|
||||
// Explicit digest
|
||||
if image.Digest == "" {
|
||||
image.Digest = image.BigDataDigests[ImageDigestBigDataKey]
|
||||
} else if image.Digest != image.BigDataDigests[ImageDigestBigDataKey] {
|
||||
digests[image.Digest] = append(digests[image.Digest], images[n])
|
||||
}
|
||||
}
|
||||
}
|
||||
if shouldSave && !r.IsReadWrite() {
|
||||
|
@ -161,6 +187,7 @@ func (r *imageStore) Load() error {
|
|||
r.idindex = truncindex.NewTruncIndex(idlist)
|
||||
r.byid = ids
|
||||
r.byname = names
|
||||
r.bydigest = digests
|
||||
if shouldSave {
|
||||
return r.Save()
|
||||
}
|
||||
|
@ -199,6 +226,7 @@ func newImageStore(dir string) (ImageStore, error) {
|
|||
images: []*Image{},
|
||||
byid: make(map[string]*Image),
|
||||
byname: make(map[string]*Image),
|
||||
bydigest: make(map[digest.Digest][]*Image),
|
||||
}
|
||||
if err := istore.Load(); err != nil {
|
||||
return nil, err
|
||||
|
@ -219,6 +247,7 @@ func newROImageStore(dir string) (ROImageStore, error) {
|
|||
images: []*Image{},
|
||||
byid: make(map[string]*Image),
|
||||
byname: make(map[string]*Image),
|
||||
bydigest: make(map[digest.Digest][]*Image),
|
||||
}
|
||||
if err := istore.Load(); err != nil {
|
||||
return nil, err
|
||||
|
@ -265,7 +294,7 @@ func (r *imageStore) SetFlag(id string, flag string, value interface{}) error {
|
|||
return r.Save()
|
||||
}
|
||||
|
||||
func (r *imageStore) Create(id string, names []string, layer, metadata string, created time.Time) (image *Image, err error) {
|
||||
func (r *imageStore) Create(id string, names []string, layer, metadata string, created time.Time, searchableDigest digest.Digest) (image *Image, err error) {
|
||||
if !r.IsReadWrite() {
|
||||
return nil, errors.Wrapf(ErrStoreIsReadOnly, "not allowed to create new images at %q", r.imagespath())
|
||||
}
|
||||
|
@ -292,6 +321,7 @@ func (r *imageStore) Create(id string, names []string, layer, metadata string, c
|
|||
if err == nil {
|
||||
image = &Image{
|
||||
ID: id,
|
||||
Digest: searchableDigest,
|
||||
Names: names,
|
||||
TopLayer: layer,
|
||||
Metadata: metadata,
|
||||
|
@ -304,6 +334,10 @@ func (r *imageStore) Create(id string, names []string, layer, metadata string, c
|
|||
r.images = append(r.images, image)
|
||||
r.idindex.Add(id)
|
||||
r.byid[id] = image
|
||||
if searchableDigest != "" {
|
||||
list := r.bydigest[searchableDigest]
|
||||
r.bydigest[searchableDigest] = append(list, image)
|
||||
}
|
||||
for _, name := range names {
|
||||
r.byname[name] = image
|
||||
}
|
||||
|
@ -383,6 +417,28 @@ func (r *imageStore) Delete(id string) error {
|
|||
r.images = append(r.images[:toDeleteIndex], r.images[toDeleteIndex+1:]...)
|
||||
}
|
||||
}
|
||||
if digest, ok := image.BigDataDigests[ImageDigestBigDataKey]; ok {
|
||||
// remove the image from the digest-based index
|
||||
if list, ok := r.bydigest[digest]; ok {
|
||||
prunedList := imageSliceWithoutValue(list, image)
|
||||
if len(prunedList) == 0 {
|
||||
delete(r.bydigest, digest)
|
||||
} else {
|
||||
r.bydigest[digest] = prunedList
|
||||
}
|
||||
}
|
||||
}
|
||||
if image.Digest != "" {
|
||||
// remove the image's hard-coded digest from the digest-based index
|
||||
if list, ok := r.bydigest[image.Digest]; ok {
|
||||
prunedList := imageSliceWithoutValue(list, image)
|
||||
if len(prunedList) == 0 {
|
||||
delete(r.bydigest, image.Digest)
|
||||
} else {
|
||||
r.bydigest[image.Digest] = prunedList
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := r.Save(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -411,6 +467,13 @@ func (r *imageStore) Exists(id string) bool {
|
|||
return ok
|
||||
}
|
||||
|
||||
func (r *imageStore) ByDigest(d digest.Digest) ([]*Image, error) {
|
||||
if images, ok := r.bydigest[d]; ok {
|
||||
return images, nil
|
||||
}
|
||||
return nil, ErrImageUnknown
|
||||
}
|
||||
|
||||
func (r *imageStore) BigData(id, key string) ([]byte, error) {
|
||||
if key == "" {
|
||||
return nil, errors.Wrapf(ErrInvalidBigDataName, "can't retrieve image big data value for empty name")
|
||||
|
@ -486,6 +549,17 @@ func (r *imageStore) BigDataNames(id string) ([]string, error) {
|
|||
return image.BigDataNames, nil
|
||||
}
|
||||
|
||||
func imageSliceWithoutValue(slice []*Image, value *Image) []*Image {
|
||||
modified := make([]*Image, 0, len(slice))
|
||||
for _, v := range slice {
|
||||
if v == value {
|
||||
continue
|
||||
}
|
||||
modified = append(modified, v)
|
||||
}
|
||||
return modified
|
||||
}
|
||||
|
||||
func (r *imageStore) SetBigData(id, key string, data []byte) error {
|
||||
if key == "" {
|
||||
return errors.Wrapf(ErrInvalidBigDataName, "can't set empty name for image big data item")
|
||||
|
@ -528,6 +602,29 @@ func (r *imageStore) SetBigData(id, key string, data []byte) error {
|
|||
image.BigDataNames = append(image.BigDataNames, key)
|
||||
save = true
|
||||
}
|
||||
if key == ImageDigestBigDataKey {
|
||||
if oldDigest != "" && oldDigest != newDigest && oldDigest != image.Digest {
|
||||
// remove the image from the list of images in the digest-based
|
||||
// index which corresponds to the old digest for this item, unless
|
||||
// it's also the hard-coded digest
|
||||
if list, ok := r.bydigest[oldDigest]; ok {
|
||||
prunedList := imageSliceWithoutValue(list, image)
|
||||
if len(prunedList) == 0 {
|
||||
delete(r.bydigest, oldDigest)
|
||||
} else {
|
||||
r.bydigest[oldDigest] = prunedList
|
||||
}
|
||||
}
|
||||
}
|
||||
// add the image to the list of images in the digest-based index which
|
||||
// corresponds to the new digest for this item, unless it's already there
|
||||
list := r.bydigest[newDigest]
|
||||
if len(list) == len(imageSliceWithoutValue(list, image)) {
|
||||
// the list isn't shortened by trying to prune this image from it,
|
||||
// so it's not in there yet
|
||||
r.bydigest[newDigest] = append(list, image)
|
||||
}
|
||||
}
|
||||
if save {
|
||||
err = r.Save()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue