Skip to content

Commit df69a60

Browse files
Merge pull request #3 from cert-manager/library_simplify
Make the logic in pkg/ more easily reusable in other libraries
2 parents d5c252c + 329314d commit df69a60

File tree

7 files changed

+184
-114
lines changed

7 files changed

+184
-114
lines changed

cmd/append_layers.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package cmd
1919
import (
2020
"archive/tar"
2121
"bytes"
22+
"fmt"
2223
"io"
2324
"io/fs"
2425
"os"
@@ -59,13 +60,12 @@ var CommandAppendLayers = cobra.Command{
5960
}
6061

6162
index, err = pkg.MutateOCITree(
62-
index,
63-
func(index v1.ImageIndex) v1.ImageIndex {
64-
return index
65-
},
66-
func(img v1.Image) v1.Image {
63+
index, nil,
64+
func(img v1.Image) (v1.Image, error) {
6765
imgMediaType, err := img.MediaType()
68-
must("could not get image media type", err)
66+
if err != nil {
67+
return nil, fmt.Errorf("could not get image media type: %w", err)
68+
}
6969

7070
layerType := types.DockerLayer
7171
if imgMediaType == types.OCIManifestSchema1 {
@@ -74,17 +74,19 @@ var CommandAppendLayers = cobra.Command{
7474

7575
for _, untypedLayer := range layers {
7676
layer, err := untypedLayer.ToLayer(layerType)
77-
must("could not load image layer", err)
77+
if err != nil {
78+
return nil, fmt.Errorf("could not load image layer: %w", err)
79+
}
7880

7981
img, err = mutate.AppendLayers(img, layer)
80-
must("could not append layer", err)
82+
if err != nil {
83+
return nil, fmt.Errorf("could not append layer: %w", err)
84+
}
8185
}
8286

83-
return img
84-
},
85-
func(descriptor v1.Descriptor) v1.Descriptor {
86-
return descriptor
87+
return img, nil
8788
},
89+
nil,
8890
)
8991
must("could not modify oci tree", err)
9092

cmd/convert_to_docker_tar.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package cmd
1818

1919
import (
20+
"fmt"
2021
"runtime"
2122

2223
"github.com/google/go-containerregistry/pkg/name"
@@ -43,9 +44,34 @@ var CommandConvertToDockerTar = cobra.Command{
4344
index, err := ociLayout.ImageIndex()
4445
must("could not load oci image index", err)
4546

46-
images, err := pkg.FindImagesInOCITree(index, func(desc v1.Descriptor) bool {
47-
return desc.Platform != nil && desc.Platform.Architecture == runtime.GOARCH
48-
})
47+
var images []v1.Image
48+
err = pkg.SearchOCITree(index, nil,
49+
func(descriptors []*v1.Descriptor, image v1.Image) error {
50+
var platform *v1.Platform
51+
52+
for _, desc := range descriptors {
53+
if desc.Platform != nil {
54+
platform = desc.Platform
55+
}
56+
}
57+
58+
{
59+
cfg, err := image.ConfigFile()
60+
if err != nil {
61+
return fmt.Errorf("could not load image config: %w", err)
62+
}
63+
if imgPlatform := cfg.Platform(); imgPlatform != nil {
64+
platform = imgPlatform
65+
}
66+
}
67+
68+
if platform != nil && platform.Architecture == runtime.GOARCH {
69+
images = append(images, image)
70+
}
71+
72+
return nil
73+
},
74+
)
4975
must("could not find images", err)
5076

5177
switch {

cmd/reset_annotations.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package cmd
1818

1919
import (
20+
"fmt"
21+
2022
v1 "github.com/google/go-containerregistry/pkg/v1"
2123
"github.com/google/go-containerregistry/pkg/v1/layout"
2224
"github.com/google/go-containerregistry/pkg/v1/mutate"
@@ -41,21 +43,25 @@ var CommandResetLabelsAndAnnotations = cobra.Command{
4143

4244
index, err = pkg.MutateOCITree(
4345
index,
44-
func(index v1.ImageIndex) v1.ImageIndex {
45-
return pkg.ReplaceImageIndexAnnotations(index, map[string]string{})
46-
}, func(image v1.Image) v1.Image {
46+
func(index v1.ImageIndex) (v1.ImageIndex, error) {
47+
return pkg.ReplaceImageIndexAnnotations(index, map[string]string{}), nil
48+
}, func(image v1.Image) (v1.Image, error) {
4749
configFile, err := image.ConfigFile()
48-
must("could not parse config file", err)
50+
if err != nil {
51+
return nil, fmt.Errorf("could not parse config file: %w", err)
52+
}
4953

5054
configFile.Config.Labels = map[string]string{}
5155

5256
image, err = mutate.ConfigFile(image, configFile)
53-
must("could not replace config file", err)
57+
if err != nil {
58+
return nil, fmt.Errorf("could not replace config file: %w", err)
59+
}
5460

55-
return pkg.ReplaceImageAnnotations(image, map[string]string{})
56-
}, func(descriptor v1.Descriptor) v1.Descriptor {
61+
return pkg.ReplaceImageAnnotations(image, map[string]string{}), nil
62+
}, func(descriptor v1.Descriptor) (v1.Descriptor, error) {
5763
descriptor.Annotations = map[string]string{}
58-
return descriptor
64+
return descriptor, nil
5965
},
6066
)
6167
must("could not modify oci tree", err)

pkg/find_images.go

Lines changed: 0 additions & 77 deletions
This file was deleted.

pkg/mutate_oci.go

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ import (
2424
"github.com/google/go-containerregistry/pkg/v1/mutate"
2525
)
2626

27-
type IndexMutateFn func(index v1.ImageIndex) v1.ImageIndex
28-
type ImageMutateFn func(image v1.Image) v1.Image
29-
type DescriptorMutateFn func(descriptor v1.Descriptor) v1.Descriptor
27+
type IndexMutateFn func(index v1.ImageIndex) (v1.ImageIndex, error)
28+
type ImageMutateFn func(image v1.Image) (v1.Image, error)
29+
type DescriptorMutateFn func(descriptor v1.Descriptor) (v1.Descriptor, error)
3030

3131
func MutateOCITree(
3232
index v1.ImageIndex,
@@ -49,8 +49,12 @@ func MutateOCITree(
4949
return nil, fmt.Errorf("could not load oci image from digest: %w", err)
5050
}
5151

52-
childImg = mutImageFn(childImg)
53-
52+
if mutImageFn != nil {
53+
childImg, err = mutImageFn(childImg)
54+
if err != nil {
55+
return nil, fmt.Errorf("could not mutate oci image: %w", err)
56+
}
57+
}
5458
child = childImg
5559
case descriptor.MediaType.IsIndex():
5660
childIndex, err := index.ImageIndex(descriptor.Digest)
@@ -62,31 +66,43 @@ func MutateOCITree(
6266
if err != nil {
6367
return nil, err
6468
}
65-
6669
child = childIndex
6770
default:
6871
continue
6972
}
7073

71-
digest, err := child.Digest()
74+
oldDigest := descriptor.Digest
75+
newDigest, err := child.Digest()
7276
if err != nil {
7377
return nil, fmt.Errorf("could not get image digest: %w", err)
7478
}
75-
76-
size, err := child.Size()
79+
newSize, err := child.Size()
7780
if err != nil {
7881
return nil, fmt.Errorf("could not get image size: %w", err)
7982
}
8083

84+
descriptor.Digest = newDigest
85+
descriptor.Size = newSize
86+
if mutDescriptorFn != nil {
87+
descriptor, err = mutDescriptorFn(descriptor)
88+
if err != nil {
89+
return nil, fmt.Errorf("could not mutate descriptor: %w", err)
90+
}
91+
}
92+
8193
// Remove descriptor from index and re-add descriptor
82-
index = mutate.RemoveManifests(index, match.Digests(descriptor.Digest))
83-
descriptor.Digest = digest
84-
descriptor.Size = size
94+
index = mutate.RemoveManifests(index, match.Digests(oldDigest))
8595
index = mutate.AppendManifests(index, mutate.IndexAddendum{
8696
Add: child,
87-
Descriptor: mutDescriptorFn(descriptor),
97+
Descriptor: descriptor,
8898
})
8999
}
90100

91-
return mutIndexFn(index), nil
101+
if mutIndexFn != nil {
102+
index, err = mutIndexFn(index)
103+
if err != nil {
104+
return nil, fmt.Errorf("could not mutate index: %w", err)
105+
}
106+
}
107+
return index, nil
92108
}

pkg/search_oci.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
Copyright 2025 The cert-manager Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package pkg
18+
19+
import (
20+
"fmt"
21+
"slices"
22+
23+
v1 "github.com/google/go-containerregistry/pkg/v1"
24+
)
25+
26+
type IndexSearchFn func(descriptors []*v1.Descriptor, index v1.ImageIndex) error
27+
type ImageSearchFn func(descriptors []*v1.Descriptor, image v1.Image) error
28+
29+
func SearchOCITree(
30+
index v1.ImageIndex,
31+
searchIndexFn IndexSearchFn,
32+
searchImageFn ImageSearchFn,
33+
) error {
34+
return searchOCITree(index, nil, searchIndexFn, searchImageFn)
35+
}
36+
37+
func searchOCITree(
38+
index v1.ImageIndex,
39+
descriptors []*v1.Descriptor,
40+
searchIndexFn IndexSearchFn,
41+
searchImageFn ImageSearchFn,
42+
) error {
43+
manifest, err := index.IndexManifest()
44+
if err != nil {
45+
return fmt.Errorf("could not load oci image manifest: %w", err)
46+
}
47+
48+
for _, descriptor := range manifest.Manifests {
49+
childDescriptors := append(slices.Clip(descriptors), &descriptor)
50+
switch {
51+
case descriptor.MediaType.IsImage():
52+
childImg, err := index.Image(descriptor.Digest)
53+
if err != nil {
54+
return fmt.Errorf("could not load oci image from digest: %w", err)
55+
}
56+
57+
if searchImageFn != nil {
58+
if err := searchImageFn(childDescriptors, childImg); err != nil {
59+
return fmt.Errorf("could not mutate oci image: %w", err)
60+
}
61+
}
62+
case descriptor.MediaType.IsIndex():
63+
childIndex, err := index.ImageIndex(descriptor.Digest)
64+
if err != nil {
65+
return fmt.Errorf("could not load oci image index from digest: %w", err)
66+
}
67+
68+
if err := searchOCITree(childIndex, childDescriptors, searchIndexFn, searchImageFn); err != nil {
69+
return err
70+
}
71+
default:
72+
continue
73+
}
74+
}
75+
76+
if searchIndexFn != nil {
77+
if err := searchIndexFn(descriptors, index); err != nil {
78+
return fmt.Errorf("could not mutate index: %w", err)
79+
}
80+
}
81+
82+
return nil
83+
}

0 commit comments

Comments
 (0)