Skip to content

Commit

Permalink
Merge pull request #105 from cert-manager/self-upgrade
Browse files Browse the repository at this point in the history
[CI] Merge self-upgrade into main
  • Loading branch information
cert-manager-prow[bot] authored Apr 18, 2024
2 parents 01ab93c + dbf3841 commit ec495f9
Show file tree
Hide file tree
Showing 11 changed files with 428 additions and 292 deletions.
24 changes: 12 additions & 12 deletions klone.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,60 +9,60 @@ targets:
- folder_name: api-docs
repo_url: https://github.com/cert-manager/makefile-modules.git
repo_ref: main
repo_hash: ceafef61921de400cb6ce75c5e5e40c63a3ca719
repo_hash: fa9c9274d1d852de501461b9442f7206aaf74007
repo_path: modules/api-docs
- folder_name: boilerplate
repo_url: https://github.com/cert-manager/makefile-modules.git
repo_ref: main
repo_hash: ceafef61921de400cb6ce75c5e5e40c63a3ca719
repo_hash: fa9c9274d1d852de501461b9442f7206aaf74007
repo_path: modules/boilerplate
- folder_name: cert-manager
repo_url: https://github.com/cert-manager/makefile-modules.git
repo_ref: main
repo_hash: ceafef61921de400cb6ce75c5e5e40c63a3ca719
repo_hash: fa9c9274d1d852de501461b9442f7206aaf74007
repo_path: modules/cert-manager
- folder_name: controller-gen
repo_url: https://github.com/cert-manager/makefile-modules.git
repo_ref: main
repo_hash: ceafef61921de400cb6ce75c5e5e40c63a3ca719
repo_hash: fa9c9274d1d852de501461b9442f7206aaf74007
repo_path: modules/controller-gen
- folder_name: generate-verify
repo_url: https://github.com/cert-manager/makefile-modules.git
repo_ref: main
repo_hash: ceafef61921de400cb6ce75c5e5e40c63a3ca719
repo_hash: fa9c9274d1d852de501461b9442f7206aaf74007
repo_path: modules/generate-verify
- folder_name: go
repo_url: https://github.com/cert-manager/makefile-modules.git
repo_ref: main
repo_hash: ceafef61921de400cb6ce75c5e5e40c63a3ca719
repo_hash: fa9c9274d1d852de501461b9442f7206aaf74007
repo_path: modules/go
- folder_name: help
repo_url: https://github.com/cert-manager/makefile-modules.git
repo_ref: main
repo_hash: ceafef61921de400cb6ce75c5e5e40c63a3ca719
repo_hash: fa9c9274d1d852de501461b9442f7206aaf74007
repo_path: modules/help
- folder_name: kind
repo_url: https://github.com/cert-manager/makefile-modules.git
repo_ref: main
repo_hash: ceafef61921de400cb6ce75c5e5e40c63a3ca719
repo_hash: fa9c9274d1d852de501461b9442f7206aaf74007
repo_path: modules/kind
- folder_name: klone
repo_url: https://github.com/cert-manager/makefile-modules.git
repo_ref: main
repo_hash: ceafef61921de400cb6ce75c5e5e40c63a3ca719
repo_hash: fa9c9274d1d852de501461b9442f7206aaf74007
repo_path: modules/klone
- folder_name: oci-build
repo_url: https://github.com/cert-manager/makefile-modules.git
repo_ref: main
repo_hash: ceafef61921de400cb6ce75c5e5e40c63a3ca719
repo_hash: fa9c9274d1d852de501461b9442f7206aaf74007
repo_path: modules/oci-build
- folder_name: repository-base
repo_url: https://github.com/cert-manager/makefile-modules.git
repo_ref: main
repo_hash: ceafef61921de400cb6ce75c5e5e40c63a3ca719
repo_hash: fa9c9274d1d852de501461b9442f7206aaf74007
repo_path: modules/repository-base
- folder_name: tools
repo_url: https://github.com/cert-manager/makefile-modules.git
repo_ref: main
repo_hash: ceafef61921de400cb6ce75c5e5e40c63a3ca719
repo_hash: fa9c9274d1d852de501461b9442f7206aaf74007
repo_path: modules/tools
8 changes: 1 addition & 7 deletions make/_shared/go/01_mod.mk
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,14 @@ verify-govulncheck: | $(NEEDS_GOVULNCHECK)

ifdef golangci_lint_config

# see https://stackoverflow.com/a/53408233
sed_inplace := sed -i''
ifeq ($(HOST_OS),darwin)
sed_inplace := sed -i ''
endif

.PHONY: generate-golangci-lint-config
## Generate a golangci-lint configuration file
## @category [shared] Generate/ Verify
generate-golangci-lint-config: | $(NEEDS_YQ) $(bin_dir)/scratch
cp $(golangci_lint_config) $(bin_dir)/scratch/golangci-lint.yaml.tmp
$(YQ) -i 'del(.linters.enable)' $(bin_dir)/scratch/golangci-lint.yaml.tmp
$(YQ) eval-all -i '. as $$item ireduce ({}; . * $$item)' $(bin_dir)/scratch/golangci-lint.yaml.tmp $(golangci_lint_override)
$(sed_inplace) 's|{{REPO-NAME}}|$(repo_name)|g' $(bin_dir)/scratch/golangci-lint.yaml.tmp
$(YQ) -i '(.. | select(tag == "!!str")) |= sub("{{REPO-NAME}}", "$(repo_name)")' $(bin_dir)/scratch/golangci-lint.yaml.tmp
mv $(bin_dir)/scratch/golangci-lint.yaml.tmp $(golangci_lint_config)

shared_generate_targets += generate-golangci-lint-config
Expand Down
1 change: 1 addition & 0 deletions make/_shared/oci-build/00_mod.mk
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ GOEXPERIMENT ?= # empty by default
define default_per_build_variables
cgo_enabled_$1 ?= $(CGO_ENABLED)
goexperiment_$1 ?= $(GOEXPERIMENT)
oci_additional_layers_$1 ?=
endef

$(foreach build_name,$(build_names),$(eval $(call default_per_build_variables,$(build_name))))
Expand Down
4 changes: 4 additions & 0 deletions make/_shared/oci-build/01_mod.mk
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ $(oci_build_targets): oci-build-%: ko-config-% | $(NEEDS_KO) $(NEEDS_GO) $(NEEDS
--push=false \
--bare

$(IMAGE_TOOL) append-layers \
$(CURDIR)/$(oci_layout_path_$*) \
$(oci_additional_layers_$*)

$(IMAGE_TOOL) list-digests \
$(CURDIR)/$(oci_layout_path_$*) \
> $(oci_digest_path_$*)
Expand Down
180 changes: 180 additions & 0 deletions make/_shared/oci-build/image_tool/append_layers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*
Copyright 2023 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"archive/tar"
"bytes"
"io"
"io/fs"
"log/slog"
"os"
"path/filepath"

v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/layout"
"github.com/google/go-containerregistry/pkg/v1/match"
"github.com/google/go-containerregistry/pkg/v1/mutate"
"github.com/google/go-containerregistry/pkg/v1/tarball"
"github.com/spf13/cobra"
)

var CommandAppendLayers = cobra.Command{
Use: "append-layers oci-path [path-to-tarball...]",
Short: "Appends a tarball or directory to every image in an OCI index.",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
oci := args[0]
extra := args[1:]

if len(extra) == 0 {
return
}

layers := []v1.Layer{}
for _, path := range extra {
layers = append(layers, loadLayerFromDirOrTarball(path))
}

appendLayersToAllImages(oci, layers...)
},
}

func loadLayerFromDirOrTarball(path string) v1.Layer {
stat, err := os.Stat(path)
must("could not open directory or tarball", err)

var layer v1.Layer
if stat.IsDir() {
var buf bytes.Buffer

tw := tar.NewWriter(&buf)

filepath.Walk(path, func(target string, info fs.FileInfo, err error) error {
must("walk error", err)

header, err := tar.FileInfoHeader(info, info.Name())
must("could not create tar header", err)

name, err := filepath.Rel(path, target)
must("could not build relative path", err)

// Write simplified header, this removes all fields that would cause
// the build to be non-reproducible (like modtime for example)
err = tw.WriteHeader(&tar.Header{
Typeflag: header.Typeflag,
Name: name,
Mode: header.Mode,
Linkname: header.Linkname,
Size: header.Size,
})

must("could not write tar header", err)

if !info.IsDir() {
file, err := os.Open(target)
must("could not write tar contents", err)

defer file.Close()

_, err = io.Copy(tw, file)
must("could not write tar contents", err)
}

return nil
})

tw.Close()

byts := buf.Bytes()

layer, err = tarball.LayerFromOpener(func() (io.ReadCloser, error) {
return io.NopCloser(bytes.NewReader(byts)), nil
})

} else {
layer, err = tarball.LayerFromFile(path)
}

must("could not open directory or tarball", err)
return layer
}

func appendLayersToAllImages(oci string, layers ...v1.Layer) {
path, err := layout.FromPath(oci)
must("could not load oci directory", err)

index, err := path.ImageIndex()
must("could not load oci image index", err)

index = appendLayersToImageIndex(index, layers)

_, err = layout.Write(oci, index)
must("could not write image", err)
}

func appendLayersToImageIndex(index v1.ImageIndex, layers []v1.Layer) v1.ImageIndex {
manifest, err := index.IndexManifest()
must("could not load oci image manifest", err)

for _, descriptor := range manifest.Manifests {
switch {
case descriptor.MediaType.IsImage():
slog.Info("found image", "digest", descriptor.Digest, "platform", descriptor.Platform)

img, err := index.Image(descriptor.Digest)
must("could not load oci image with digest", err)

img, err = mutate.AppendLayers(img, layers...)
must("could not load append layer to image", err)

digest, err := img.Digest()
must("could not get image digest", err)

slog.Info("appended layers to image", "old_digest", descriptor.Digest, "digest", digest, "platform", descriptor.Platform)

index = mutate.RemoveManifests(index, match.Digests(descriptor.Digest))

descriptor.Digest = digest
index = mutate.AppendManifests(index, mutate.IndexAddendum{
Add: img,
Descriptor: descriptor,
})

case descriptor.MediaType.IsIndex():
slog.Info("found image index", "digest", descriptor.Digest)

child, err := index.ImageIndex(descriptor.Digest)
must("could not load oci image manifest", err)

child = appendLayersToImageIndex(child, layers)

digest, err := child.Digest()
must("could not get image digest", err)

index = mutate.RemoveManifests(index, match.Digests(descriptor.Digest))

descriptor.Digest = digest
index = mutate.AppendManifests(index, mutate.IndexAddendum{
Add: child,
Descriptor: descriptor,
})
}
}

return index
}
97 changes: 97 additions & 0 deletions make/_shared/oci-build/image_tool/convert_to_docker_tar.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
Copyright 2023 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"runtime"

"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/layout"
"github.com/google/go-containerregistry/pkg/v1/match"
"github.com/google/go-containerregistry/pkg/v1/tarball"
"github.com/spf13/cobra"
)

var CommandConvertToDockerTar = cobra.Command{
Use: "convert-to-docker-tar oci-path output image-name",
Short: "Reads the OCI directory and outputs a tarball that is compatible with \"docker load\"",
Args: cobra.ExactArgs(3),
Run: func(cmd *cobra.Command, args []string) {
path := args[0]
output := args[1]
imageName := args[2]

ociLayout, err := layout.FromPath(path)
must("could not load oci directory", err)

index, err := ociLayout.ImageIndex()
must("could not load oci image index", err)

images := getImagesFromIndex(index, func(desc v1.Descriptor) bool {
return desc.Platform != nil && desc.Platform.Architecture == runtime.GOARCH
})

switch {
case len(images) == 0:
fail("no matching images found")
case len(images) > 1:
fail("multiple matching images found")
}

ref, err := name.ParseReference(imageName)
must("invalid image name", err)

err = tarball.WriteToFile(output, ref, images[0])
must("could not write tarball", err)
},
}

func getImagesFromIndex(index v1.ImageIndex, matcher match.Matcher) (images []v1.Image) {
manifest, err := index.IndexManifest()
must("could not load oci index manifest", err)

for _, descriptor := range manifest.Manifests {
switch {
case descriptor.MediaType.IsImage():
// If the platform is not part of the index manifest, attempt to
// load it from the image config
if descriptor.Platform == nil {
img, err := index.Image(descriptor.Digest)
must("could not load image", err)

cfg, err := img.ConfigFile()
must("could not load image config", err)

descriptor.Platform = cfg.Platform()
}

if matcher(descriptor) {
img, err := index.Image(descriptor.Digest)
must("could not load image", err)
images = append(images, img)
}

case descriptor.MediaType.IsIndex():
idx, err := index.ImageIndex(descriptor.Digest)
must("could not load image index", err)
images = append(images, getImagesFromIndex(idx, matcher)...)
}
}

return
}
Loading

0 comments on commit ec495f9

Please sign in to comment.