Skip to content

Commit

Permalink
Merge pull request #20458 from smarterclayton/fix_references
Browse files Browse the repository at this point in the history
An image represents a manifest (and is a blob) and also references a config
  • Loading branch information
openshift-merge-robot authored Jul 30, 2018
2 parents 91bbfec + 7141132 commit 31f6201
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
6 changes: 5 additions & 1 deletion pkg/image/registry/imagestream/etcd/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (r *LayersREST) Get(ctx context.Context, name string, options *metav1.GetOp
isl.Blobs[layer.Name] = imageapi.ImageLayerData{LayerSize: &layer.LayerSize, MediaType: layer.MediaType}
}
}
if blob := entry.Manifest; blob != nil {
if blob := entry.Config; blob != nil {
reference.Manifest = &blob.Name
if _, ok := isl.Blobs[blob.Name]; !ok {
if blob.LayerSize == 0 {
Expand All @@ -203,6 +203,10 @@ func (r *LayersREST) Get(ctx context.Context, name string, options *metav1.GetOp
}
}
}
// the image manifest is always a blob - schema2 images also have a config blob referenced from the manifest
if _, ok := isl.Blobs[item.Image]; !ok {
isl.Blobs[item.Image] = imageapi.ImageLayerData{MediaType: entry.MediaType}
}
isl.Images[item.Image] = reference
}
}
Expand Down
30 changes: 19 additions & 11 deletions pkg/image/registry/imagestream/etcd/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,10 @@ func NewImageLayerIndex(lw ImageListWatch) ImageLayerIndex {
return imageLayerIndex{informer: informer}
}

// manifestFromImage attempts to find a manifest blob description from
// an image. Images older than schema2 in Docker do not have a manifest blob.
func manifestFromImage(image *imagev1.Image) *imagev1.ImageLayer {
// configFromImage attempts to find a config blob description from
// an image. Images older than schema2 in Docker do not have a config blob - the manifest
// has that data embedded.
func configFromImage(image *imagev1.Image) *imagev1.ImageLayer {
if image.DockerImageManifestMediaType != "application/vnd.docker.distribution.manifest.v2+json" {
return nil
}
Expand All @@ -134,7 +135,7 @@ func manifestFromImage(image *imagev1.Image) *imagev1.ImageLayer {
}
return &imagev1.ImageLayer{
Name: meta.ID,
MediaType: image.DockerImageManifestMediaType,
MediaType: "application/vnd.docker.container.image.v1+json",
}
}

Expand All @@ -145,16 +146,22 @@ func manifestFromImage(image *imagev1.Image) *imagev1.ImageLayer {
type ImageLayers struct {
Name string
ResourceVersion string
Manifest *imagev1.ImageLayer
MediaType string
Config *imagev1.ImageLayer
Layers []imagev1.ImageLayer
}

func imageLayersForImage(image *imagev1.Image) *ImageLayers {
mediaType := image.DockerImageManifestMediaType
if len(mediaType) == 0 {
mediaType = "application/vnd.docker.distribution.manifest.v2+json"
}
return &ImageLayers{
Name: image.Name,
ResourceVersion: image.ResourceVersion,
MediaType: mediaType,
Config: configFromImage(image),
Layers: image.DockerImageLayers,
Manifest: manifestFromImage(image),
}
}

Expand All @@ -170,15 +177,16 @@ func (l *ImageLayers) DeepCopyObject() runtime.Object {
layers = make([]imagev1.ImageLayer, len(l.Layers))
copy(layers, l.Layers)
}
var manifest *imagev1.ImageLayer
if l.Manifest != nil {
copied := *l.Manifest
manifest = &copied
var config *imagev1.ImageLayer
if l.Config != nil {
copied := *l.Config
config = &copied
}
return &ImageLayers{
Name: l.Name,
ResourceVersion: l.ResourceVersion,
Manifest: manifest,
MediaType: l.MediaType,
Config: config,
Layers: layers,
}
}
Expand Down
4 changes: 4 additions & 0 deletions test/extended/images/layers.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,14 @@ var _ = g.Describe("[Feature:ImageLayers] Image layer subresource", func() {
o.Expect(ok).To(o.BeTrue())
o.Expect(len(l.Layers)).To(o.BeNumerically(">", 0))
o.Expect(l.Manifest).ToNot(o.BeNil())
o.Expect(layers.Blobs[*l.Manifest]).ToNot(o.BeNil())
o.Expect(layers.Blobs[*l.Manifest].MediaType).To(o.Equal("application/vnd.docker.container.image.v1+json"))
for _, layerID := range l.Layers {
o.Expect(layers.Blobs).To(o.HaveKey(layerID))
o.Expect(layers.Blobs[layerID].MediaType).NotTo(o.BeEmpty())
}
o.Expect(layers.Blobs).To(o.HaveKey(image.Image.Name))
o.Expect(layers.Blobs[image.Image.Name].MediaType).To(o.Equal("application/vnd.docker.distribution.manifest.v2+json"))
if i == 0 {
busyboxLayers = l.Layers
}
Expand Down

0 comments on commit 31f6201

Please sign in to comment.