From cfe85b94ce9e2c537d2a61b9f47e76498f167fb4 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 10 Nov 2021 14:36:22 -0500 Subject: [PATCH] Adds flag to update the version Previously, update-buildpack-image-id would only allow you to update the id. In some cases, the id and version need to change in sync. For example of you have buildpack abc v5.4.10, you may want to map that to buildpack xyz v1.0.0. This will now rewrite the metadata such that both the id and the version are updated. The current id and version are pulled from the metadata on the existing buildpack (arg #1) image. Signed-off-by: Daniel Mikusa --- buildpack/images.go | 13 +++++++------ buildpack/rewriteLayer.go | 11 ++++++++--- cmd/update-buildpack-image-id/main.go | 7 ++++++- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/buildpack/images.go b/buildpack/images.go index a542a3d4..df10c199 100644 --- a/buildpack/images.go +++ b/buildpack/images.go @@ -16,7 +16,7 @@ const ( buildpackMetadataLabel = "io.buildpacks.buildpackage.metadata" ) -func Rename(buildpack, tag, newID string) (string, error) { +func Rename(buildpack, tag, newID, newVersion string) (string, error) { reference, err := name.ParseReference(buildpack) if err != nil { return "", fmt.Errorf("unable to parse reference for existing buildpack tag\n%w", err) @@ -39,7 +39,7 @@ func Rename(buildpack, tag, newID string) (string, error) { return "", fmt.Errorf("unable to get buildpack layer metadata\n%w", err) } - newLayersMetedata, layers, err := layerMetadata.metadataAndLayersFor(image, metadata.Id, metadata.Version, newID) + newLayersMetedata, layers, err := layerMetadata.metadataAndLayersFor(image, metadata.Id, metadata.Version, newID, newVersion) if err != nil { return "", fmt.Errorf("unable to generate new metadata\n%w", err) } @@ -55,6 +55,7 @@ func Rename(buildpack, tag, newID string) (string, error) { } metadata.Id = newID + metadata.Version = newVersion newBuildpackage, err = SetLabels(newBuildpackage, map[string]interface{}{ layerMetadataLabel: newLayersMetedata, buildpackMetadataLabel: metadata, @@ -83,7 +84,7 @@ func Rename(buildpack, tag, newID string) (string, error) { return identifer, nil } -func (m BuildpackLayerMetadata) metadataAndLayersFor(sourceImage v1.Image, oldId string, oldVersion string, newId string) (BuildpackLayerMetadata, []v1.Layer, error) { +func (m BuildpackLayerMetadata) metadataAndLayersFor(sourceImage v1.Image, oldId string, oldVersion string, newId string, newVersion string) (BuildpackLayerMetadata, []v1.Layer, error) { newLayerMetdata := BuildpackLayerMetadata{} var layers []v1.Layer @@ -121,9 +122,9 @@ func (m BuildpackLayerMetadata) metadataAndLayersFor(sourceImage v1.Image, oldId return nil, nil, fmt.Errorf("unable to fetch layer by diff id %s for matching layer\n%w", diffId, err) } - layer, err = rewriteLayer(layer, oldId, newId) + layer, err = rewriteLayer(layer, oldId, newId, oldVersion, newVersion) if err != nil { - return nil, nil, fmt.Errorf("unable to rewrite layer, old id: %s, new id: %s\n%w", oldId, newId, err) + return nil, nil, fmt.Errorf("unable to rewrite layer, old id: %s, new id: %s, new version: %s\n%w", oldId, newId, newVersion, err) } diffID, err := layer.DiffID() @@ -133,7 +134,7 @@ func (m BuildpackLayerMetadata) metadataAndLayersFor(sourceImage v1.Image, oldId buildpack.LayerDiffID = diffID.String() - newLayerMetdata[newId][v] = buildpack + newLayerMetdata[newId][newVersion] = buildpack layers = append(layers, layer) } } diff --git a/buildpack/rewriteLayer.go b/buildpack/rewriteLayer.go index 320aa454..e3297d42 100644 --- a/buildpack/rewriteLayer.go +++ b/buildpack/rewriteLayer.go @@ -13,7 +13,7 @@ import ( "github.com/google/go-containerregistry/pkg/v1/tarball" ) -func rewriteLayer(layer v1.Layer, old, new string) (v1.Layer, error) { +func rewriteLayer(layer v1.Layer, oldID, newID, oldVersion, newVersion string) (v1.Layer, error) { b := &bytes.Buffer{} tw := tar.NewWriter(b) @@ -30,8 +30,12 @@ func rewriteLayer(layer v1.Layer, old, new string) (v1.Layer, error) { break } - newName := strings.ReplaceAll(header.Name, escapedID(old), escapedID(new)) + // replace buildpack id and version in folder names + newName := strings.ReplaceAll( + strings.ReplaceAll(header.Name, escapedID(oldID), escapedID(newID)), + oldVersion, newVersion) + // replace buildpack id and version in buildpack.toml if strings.HasSuffix(path.Clean(header.Name), "buildpack.toml") { buf, err := ioutil.ReadAll(tr) if err != nil { @@ -44,7 +48,8 @@ func rewriteLayer(layer v1.Layer, old, new string) (v1.Layer, error) { return nil, fmt.Errorf("unable to decode buildpack.toml\n%w", err) } - bd.Info.ID = new + bd.Info.ID = newID + bd.Info.Version = newVersion updatedBuildpackToml := &bytes.Buffer{} err = toml.NewEncoder(updatedBuildpackToml).Encode(bd) diff --git a/cmd/update-buildpack-image-id/main.go b/cmd/update-buildpack-image-id/main.go index 4cfb4d42..c8b8fce9 100644 --- a/cmd/update-buildpack-image-id/main.go +++ b/cmd/update-buildpack-image-id/main.go @@ -14,6 +14,7 @@ func main() { image := flagSet.String("image", "", "The exisiting buildpack image") newImage := flagSet.String("new-image", "", "The new buildpack image") id := flagSet.String("id", "", "The new id of the buildpack") + version := flagSet.String("version", "", "The new version of the buildpack") if err := flagSet.Parse(os.Args[1:]); err != nil { log.Fatal(fmt.Errorf("unable to parse flags\n%w", err)) @@ -31,7 +32,11 @@ func main() { log.Fatal("--id is required") } - rename, err := buildpack.Rename(*image, *newImage, *id) + if *version == "" { + log.Fatal("--version is required") + } + + rename, err := buildpack.Rename(*image, *newImage, *id, *version) if err != nil { log.Fatal(err) }