Skip to content

Commit 8446a5c

Browse files
Merge pull request #20514 from soltysh/cmds_external
Update commands with resource builders to use external versions
2 parents 4554bd9 + 74c37b8 commit 8446a5c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1733
-1287
lines changed

contrib/completions/bash/oc

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contrib/completions/zsh/oc

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

hack/import-restrictions.json

+2
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,9 @@
476476
"github.com/openshift/origin/pkg/authorization/generated",
477477
"github.com/openshift/origin/pkg/build/apis/build/v1",
478478
"github.com/openshift/origin/pkg/build/generated",
479+
"github.com/openshift/origin/pkg/image/apis/image/v1",
479480
"github.com/openshift/origin/pkg/image/generated",
481+
"github.com/openshift/origin/pkg/image/util",
480482
"github.com/openshift/origin/pkg/network/generated",
481483
"github.com/openshift/origin/pkg/oauth/generated",
482484
"github.com/openshift/origin/pkg/project/generated",

pkg/image/util/helpers.go

+125-78
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,20 @@ import (
1111
"github.com/golang/glog"
1212
godigest "github.com/opencontainers/go-digest"
1313

14+
imagev1 "github.com/openshift/api/image/v1"
1415
imageapi "github.com/openshift/origin/pkg/image/apis/image"
1516
"github.com/openshift/origin/pkg/image/apis/image/docker10"
1617
)
1718

18-
func fillImageLayers(image *imageapi.Image, manifest docker10.DockerImageManifest) error {
19-
if len(image.DockerImageLayers) != 0 {
20-
// DockerImageLayers is already filled by the registry.
21-
return nil
22-
}
23-
19+
func getImageLayers(manifest docker10.DockerImageManifest) ([]imageapi.ImageLayer, error) {
20+
var imageLayers []imageapi.ImageLayer
2421
switch manifest.SchemaVersion {
2522
case 1:
2623
if len(manifest.History) != len(manifest.FSLayers) {
27-
return fmt.Errorf("the image %s (%s) has mismatched history and fslayer cardinality (%d != %d)", image.Name, image.DockerImageReference, len(manifest.History), len(manifest.FSLayers))
24+
return nil, fmt.Errorf("mismatched history and fslayer cardinality (%d != %d)", len(manifest.History), len(manifest.FSLayers))
2825
}
2926

30-
image.DockerImageLayers = make([]imageapi.ImageLayer, len(manifest.FSLayers))
27+
imageLayers = make([]imageapi.ImageLayer, len(manifest.FSLayers))
3128
for i, obj := range manifest.History {
3229
layer := manifest.FSLayers[i]
3330

@@ -42,29 +39,80 @@ func fillImageLayers(image *imageapi.Image, manifest docker10.DockerImageManifes
4239
// in order from the oldest to the youngest.
4340
revidx := (len(manifest.History) - 1) - i // n-1, n-2, ..., 1, 0
4441

45-
image.DockerImageLayers[revidx].Name = layer.DockerBlobSum
46-
image.DockerImageLayers[revidx].LayerSize = size.Size
47-
image.DockerImageLayers[revidx].MediaType = schema1.MediaTypeManifestLayer
42+
imageLayers[revidx].Name = layer.DockerBlobSum
43+
imageLayers[revidx].LayerSize = size.Size
44+
imageLayers[revidx].MediaType = schema1.MediaTypeManifestLayer
4845
}
4946
case 2:
5047
// The layer list is ordered starting from the base image (opposite order of schema1).
5148
// So, we do not need to change the order of layers.
52-
image.DockerImageLayers = make([]imageapi.ImageLayer, len(manifest.Layers))
49+
imageLayers = make([]imageapi.ImageLayer, len(manifest.Layers))
5350
for i, layer := range manifest.Layers {
54-
image.DockerImageLayers[i].Name = layer.Digest
55-
image.DockerImageLayers[i].LayerSize = layer.Size
56-
image.DockerImageLayers[i].MediaType = layer.MediaType
51+
imageLayers[i].Name = layer.Digest
52+
imageLayers[i].LayerSize = layer.Size
53+
imageLayers[i].MediaType = layer.MediaType
5754
}
5855
default:
59-
return fmt.Errorf("unrecognized Docker image manifest schema %d for %q (%s)", manifest.SchemaVersion, image.Name, image.DockerImageReference)
56+
return nil, fmt.Errorf("unrecognized Docker image manifest schema %d", manifest.SchemaVersion)
6057
}
6158

62-
if image.Annotations == nil {
63-
image.Annotations = map[string]string{}
59+
return imageLayers, nil
60+
}
61+
62+
// reorderImageLayers mutates the given image. It reorders the layers in ascending order.
63+
// Ascending order matches the order of layers in schema 2. Schema 1 has reversed (descending) order of layers.
64+
func reorderImageLayers(imageLayers []imageapi.ImageLayer, layersOrder, imageManifestMediaType string) bool {
65+
if imageLayers == nil || len(imageLayers) == 0 {
66+
return false
6467
}
65-
image.Annotations[imageapi.DockerImageLayersOrderAnnotation] = imageapi.DockerImageLayersOrderAscending
6668

67-
return nil
69+
if layersOrder == "" {
70+
switch imageManifestMediaType {
71+
case schema1.MediaTypeManifest, schema1.MediaTypeSignedManifest:
72+
layersOrder = imageapi.DockerImageLayersOrderAscending
73+
case schema2.MediaTypeManifest:
74+
layersOrder = imageapi.DockerImageLayersOrderDescending
75+
default:
76+
return false
77+
}
78+
}
79+
80+
if layersOrder == imageapi.DockerImageLayersOrderDescending {
81+
// reverse order of the layers (lowest = 0, highest = i)
82+
for i, j := 0, len(imageLayers)-1; i < j; i, j = i+1, j-1 {
83+
imageLayers[i], imageLayers[j] = imageLayers[j], imageLayers[i]
84+
}
85+
}
86+
87+
return true
88+
}
89+
90+
func convertImageLayers(imageLayers []imagev1.ImageLayer) []imageapi.ImageLayer {
91+
if imageLayers == nil {
92+
return nil
93+
}
94+
95+
result := make([]imageapi.ImageLayer, len(imageLayers))
96+
for i := range imageLayers {
97+
result[i].MediaType = imageLayers[i].MediaType
98+
result[i].Name = imageLayers[i].Name
99+
result[i].LayerSize = imageLayers[i].LayerSize
100+
}
101+
return result
102+
}
103+
104+
func GetImageMetadata(image *imagev1.Image) (imageapi.DockerImage, error) {
105+
if len(image.DockerImageManifest) == 0 {
106+
return imageapi.DockerImage{}, nil
107+
}
108+
109+
imageLayers := convertImageLayers(image.DockerImageLayers)
110+
reorderImageLayers(imageLayers, image.Annotations[imageapi.DockerImageLayersOrderAnnotation], image.DockerImageManifestMediaType)
111+
112+
_, imageMetadata, _, _, err := getImageMetadata(image.Name, image.DockerImageReference,
113+
image.DockerImageManifest, image.DockerImageConfig, imageLayers)
114+
return imageMetadata, err
115+
68116
}
69117

70118
// ImageWithMetadata mutates the given image. It parses raw DockerImageManifest data stored in the image and
@@ -74,110 +122,109 @@ func ImageWithMetadata(image *imageapi.Image) error {
74122
return nil
75123
}
76124

77-
ReorderImageLayers(image)
125+
if ok := reorderImageLayers(image.DockerImageLayers,
126+
image.Annotations[imageapi.DockerImageLayersOrderAnnotation], image.DockerImageManifestMediaType); ok {
127+
if image.Annotations == nil {
128+
image.Annotations = map[string]string{}
129+
}
130+
image.Annotations[imageapi.DockerImageLayersOrderAnnotation] = imageapi.DockerImageLayersOrderAscending
131+
}
78132

79133
if len(image.DockerImageLayers) > 0 && image.DockerImageMetadata.Size > 0 && len(image.DockerImageManifestMediaType) > 0 {
80134
glog.V(5).Infof("Image metadata already filled for %s", image.Name)
81135
return nil
82136
}
137+
imageManifestMediaType, imageMetadata, imageLayers, orderAscending, err := getImageMetadata(image.Name, image.DockerImageReference,
138+
image.DockerImageManifest, image.DockerImageConfig, image.DockerImageLayers)
139+
if err != nil {
140+
return err
141+
}
142+
image.DockerImageManifestMediaType = imageManifestMediaType
143+
image.DockerImageMetadata = imageMetadata
144+
image.DockerImageLayers = imageLayers
145+
if orderAscending {
146+
if image.Annotations == nil {
147+
image.Annotations = map[string]string{}
148+
}
149+
image.Annotations[imageapi.DockerImageLayersOrderAnnotation] = imageapi.DockerImageLayersOrderAscending
150+
}
83151

152+
return nil
153+
}
154+
155+
func getImageMetadata(imageName, imageReference, imageManifest, imageConfig string,
156+
imageLayers []imageapi.ImageLayer) (string, imageapi.DockerImage, []imageapi.ImageLayer, bool, error) {
84157
manifest := docker10.DockerImageManifest{}
85-
if err := json.Unmarshal([]byte(image.DockerImageManifest), &manifest); err != nil {
86-
return err
158+
if err := json.Unmarshal([]byte(imageManifest), &manifest); err != nil {
159+
return "", imageapi.DockerImage{}, []imageapi.ImageLayer{}, false, err
87160
}
88161

89-
err := fillImageLayers(image, manifest)
90-
if err != nil {
91-
return err
162+
var err error
163+
var orderAscending bool
164+
if len(imageLayers) == 0 {
165+
imageLayers, err = getImageLayers(manifest)
166+
if err != nil {
167+
return "", imageapi.DockerImage{}, []imageapi.ImageLayer{}, false, fmt.Errorf("the image %s (%s) failed reading layers: %v", imageName, imageReference, err)
168+
}
169+
orderAscending = true
92170
}
93171

172+
var imageManifestMediaType string
173+
var imageMetadata imageapi.DockerImage
94174
switch manifest.SchemaVersion {
95175
case 1:
96-
image.DockerImageManifestMediaType = schema1.MediaTypeManifest
176+
imageManifestMediaType = schema1.MediaTypeManifest
97177

98178
if len(manifest.History) == 0 {
99179
// It should never have an empty history, but just in case.
100-
return fmt.Errorf("the image %s (%s) has a schema 1 manifest, but it doesn't have history", image.Name, image.DockerImageReference)
180+
return "", imageapi.DockerImage{}, []imageapi.ImageLayer{}, false, fmt.Errorf("the image %s (%s) has a schema 1 manifest, but it doesn't have history", imageName, imageReference)
101181
}
102182

103183
v1Metadata := docker10.DockerV1CompatibilityImage{}
104184
if err := json.Unmarshal([]byte(manifest.History[0].DockerV1Compatibility), &v1Metadata); err != nil {
105-
return err
185+
return "", imageapi.DockerImage{}, []imageapi.ImageLayer{}, false, err
106186
}
107187

108-
if err := imageapi.Convert_compatibility_to_api_DockerImage(&v1Metadata, &image.DockerImageMetadata); err != nil {
109-
return err
188+
if err := imageapi.Convert_compatibility_to_api_DockerImage(&v1Metadata, &imageMetadata); err != nil {
189+
return "", imageapi.DockerImage{}, []imageapi.ImageLayer{}, false, err
110190
}
111191
case 2:
112-
image.DockerImageManifestMediaType = schema2.MediaTypeManifest
192+
imageManifestMediaType = schema2.MediaTypeManifest
113193

114-
if len(image.DockerImageConfig) == 0 {
115-
return fmt.Errorf("dockerImageConfig must not be empty for manifest schema 2")
194+
if len(imageConfig) == 0 {
195+
return "", imageapi.DockerImage{}, []imageapi.ImageLayer{}, false, fmt.Errorf("dockerImageConfig must not be empty for manifest schema 2")
116196
}
117197

118198
config := docker10.DockerImageConfig{}
119-
if err := json.Unmarshal([]byte(image.DockerImageConfig), &config); err != nil {
120-
return fmt.Errorf("failed to parse dockerImageConfig: %v", err)
199+
if err := json.Unmarshal([]byte(imageConfig), &config); err != nil {
200+
return "", imageapi.DockerImage{}, []imageapi.ImageLayer{}, false, fmt.Errorf("failed to parse dockerImageConfig: %v", err)
121201
}
122202

123-
if err := imageapi.Convert_imageconfig_to_api_DockerImage(&config, &image.DockerImageMetadata); err != nil {
124-
return err
203+
if err := imageapi.Convert_imageconfig_to_api_DockerImage(&config, &imageMetadata); err != nil {
204+
return "", imageapi.DockerImage{}, []imageapi.ImageLayer{}, false, err
125205
}
126-
image.DockerImageMetadata.ID = manifest.Config.Digest
206+
imageMetadata.ID = manifest.Config.Digest
127207

128208
default:
129-
return fmt.Errorf("unrecognized Docker image manifest schema %d for %q (%s)", manifest.SchemaVersion, image.Name, image.DockerImageReference)
209+
return "", imageapi.DockerImage{}, []imageapi.ImageLayer{}, false, fmt.Errorf("unrecognized Docker image manifest schema %d for %q (%s)", manifest.SchemaVersion, imageName, imageReference)
130210
}
131211

132212
layerSet := sets.NewString()
133213
if manifest.SchemaVersion == 2 {
134214
layerSet.Insert(manifest.Config.Digest)
135-
image.DockerImageMetadata.Size = int64(len(image.DockerImageConfig))
215+
imageMetadata.Size = int64(len(imageConfig))
136216
} else {
137-
image.DockerImageMetadata.Size = 0
217+
imageMetadata.Size = 0
138218
}
139-
for _, layer := range image.DockerImageLayers {
219+
for _, layer := range imageLayers {
140220
if layerSet.Has(layer.Name) {
141221
continue
142222
}
143223
layerSet.Insert(layer.Name)
144-
image.DockerImageMetadata.Size += layer.LayerSize
145-
}
146-
147-
return nil
148-
}
149-
150-
// ReorderImageLayers mutates the given image. It reorders the layers in ascending order.
151-
// Ascending order matches the order of layers in schema 2. Schema 1 has reversed (descending) order of layers.
152-
func ReorderImageLayers(image *imageapi.Image) {
153-
if len(image.DockerImageLayers) == 0 {
154-
return
155-
}
156-
157-
layersOrder, ok := image.Annotations[imageapi.DockerImageLayersOrderAnnotation]
158-
if !ok {
159-
switch image.DockerImageManifestMediaType {
160-
case schema1.MediaTypeManifest, schema1.MediaTypeSignedManifest:
161-
layersOrder = imageapi.DockerImageLayersOrderAscending
162-
case schema2.MediaTypeManifest:
163-
layersOrder = imageapi.DockerImageLayersOrderDescending
164-
default:
165-
return
166-
}
167-
}
168-
169-
if layersOrder == imageapi.DockerImageLayersOrderDescending {
170-
// reverse order of the layers (lowest = 0, highest = i)
171-
for i, j := 0, len(image.DockerImageLayers)-1; i < j; i, j = i+1, j-1 {
172-
image.DockerImageLayers[i], image.DockerImageLayers[j] = image.DockerImageLayers[j], image.DockerImageLayers[i]
173-
}
174-
}
175-
176-
if image.Annotations == nil {
177-
image.Annotations = map[string]string{}
224+
imageMetadata.Size += layer.LayerSize
178225
}
179226

180-
image.Annotations[imageapi.DockerImageLayersOrderAnnotation] = imageapi.DockerImageLayersOrderAscending
227+
return imageManifestMediaType, imageMetadata, imageLayers, orderAscending, nil
181228
}
182229

183230
// ManifestMatchesImage returns true if the provided manifest matches the name of the image.

0 commit comments

Comments
 (0)