Skip to content

Commit 31f6201

Browse files
Merge pull request #20458 from smarterclayton/fix_references
An image represents a manifest (and is a blob) and also references a config
2 parents 91bbfec + 7141132 commit 31f6201

File tree

3 files changed

+28
-12
lines changed

3 files changed

+28
-12
lines changed

pkg/image/registry/imagestream/etcd/etcd.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ func (r *LayersREST) Get(ctx context.Context, name string, options *metav1.GetOp
192192
isl.Blobs[layer.Name] = imageapi.ImageLayerData{LayerSize: &layer.LayerSize, MediaType: layer.MediaType}
193193
}
194194
}
195-
if blob := entry.Manifest; blob != nil {
195+
if blob := entry.Config; blob != nil {
196196
reference.Manifest = &blob.Name
197197
if _, ok := isl.Blobs[blob.Name]; !ok {
198198
if blob.LayerSize == 0 {
@@ -203,6 +203,10 @@ func (r *LayersREST) Get(ctx context.Context, name string, options *metav1.GetOp
203203
}
204204
}
205205
}
206+
// the image manifest is always a blob - schema2 images also have a config blob referenced from the manifest
207+
if _, ok := isl.Blobs[item.Image]; !ok {
208+
isl.Blobs[item.Image] = imageapi.ImageLayerData{MediaType: entry.MediaType}
209+
}
206210
isl.Images[item.Image] = reference
207211
}
208212
}

pkg/image/registry/imagestream/etcd/image.go

+19-11
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,10 @@ func NewImageLayerIndex(lw ImageListWatch) ImageLayerIndex {
121121
return imageLayerIndex{informer: informer}
122122
}
123123

124-
// manifestFromImage attempts to find a manifest blob description from
125-
// an image. Images older than schema2 in Docker do not have a manifest blob.
126-
func manifestFromImage(image *imagev1.Image) *imagev1.ImageLayer {
124+
// configFromImage attempts to find a config blob description from
125+
// an image. Images older than schema2 in Docker do not have a config blob - the manifest
126+
// has that data embedded.
127+
func configFromImage(image *imagev1.Image) *imagev1.ImageLayer {
127128
if image.DockerImageManifestMediaType != "application/vnd.docker.distribution.manifest.v2+json" {
128129
return nil
129130
}
@@ -134,7 +135,7 @@ func manifestFromImage(image *imagev1.Image) *imagev1.ImageLayer {
134135
}
135136
return &imagev1.ImageLayer{
136137
Name: meta.ID,
137-
MediaType: image.DockerImageManifestMediaType,
138+
MediaType: "application/vnd.docker.container.image.v1+json",
138139
}
139140
}
140141

@@ -145,16 +146,22 @@ func manifestFromImage(image *imagev1.Image) *imagev1.ImageLayer {
145146
type ImageLayers struct {
146147
Name string
147148
ResourceVersion string
148-
Manifest *imagev1.ImageLayer
149+
MediaType string
150+
Config *imagev1.ImageLayer
149151
Layers []imagev1.ImageLayer
150152
}
151153

152154
func imageLayersForImage(image *imagev1.Image) *ImageLayers {
155+
mediaType := image.DockerImageManifestMediaType
156+
if len(mediaType) == 0 {
157+
mediaType = "application/vnd.docker.distribution.manifest.v2+json"
158+
}
153159
return &ImageLayers{
154160
Name: image.Name,
155161
ResourceVersion: image.ResourceVersion,
162+
MediaType: mediaType,
163+
Config: configFromImage(image),
156164
Layers: image.DockerImageLayers,
157-
Manifest: manifestFromImage(image),
158165
}
159166
}
160167

@@ -170,15 +177,16 @@ func (l *ImageLayers) DeepCopyObject() runtime.Object {
170177
layers = make([]imagev1.ImageLayer, len(l.Layers))
171178
copy(layers, l.Layers)
172179
}
173-
var manifest *imagev1.ImageLayer
174-
if l.Manifest != nil {
175-
copied := *l.Manifest
176-
manifest = &copied
180+
var config *imagev1.ImageLayer
181+
if l.Config != nil {
182+
copied := *l.Config
183+
config = &copied
177184
}
178185
return &ImageLayers{
179186
Name: l.Name,
180187
ResourceVersion: l.ResourceVersion,
181-
Manifest: manifest,
188+
MediaType: l.MediaType,
189+
Config: config,
182190
Layers: layers,
183191
}
184192
}

test/extended/images/layers.go

+4
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,14 @@ var _ = g.Describe("[Feature:ImageLayers] Image layer subresource", func() {
7272
o.Expect(ok).To(o.BeTrue())
7373
o.Expect(len(l.Layers)).To(o.BeNumerically(">", 0))
7474
o.Expect(l.Manifest).ToNot(o.BeNil())
75+
o.Expect(layers.Blobs[*l.Manifest]).ToNot(o.BeNil())
76+
o.Expect(layers.Blobs[*l.Manifest].MediaType).To(o.Equal("application/vnd.docker.container.image.v1+json"))
7577
for _, layerID := range l.Layers {
7678
o.Expect(layers.Blobs).To(o.HaveKey(layerID))
7779
o.Expect(layers.Blobs[layerID].MediaType).NotTo(o.BeEmpty())
7880
}
81+
o.Expect(layers.Blobs).To(o.HaveKey(image.Image.Name))
82+
o.Expect(layers.Blobs[image.Image.Name].MediaType).To(o.Equal("application/vnd.docker.distribution.manifest.v2+json"))
7983
if i == 0 {
8084
busyboxLayers = l.Layers
8185
}

0 commit comments

Comments
 (0)