Skip to content

Commit

Permalink
An image represents a manifest (and is a blob) and also references a …
Browse files Browse the repository at this point in the history
…config

Our external API and internal structure is wrong. All images are manifests, and all manifests are blobs.
In addition, a v2 schema 2 manifest references a blob that is a "config", not a "manifest".

Corrected the internal code so that the image/manifest digest now shows up in blobs, renamed the internal
field "config", and set the correct mime types and fixed tests.
  • Loading branch information
smarterclayton committed Jul 28, 2018
1 parent 7e5415c commit 7141132
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 7141132

Please sign in to comment.