Skip to content

Commit

Permalink
Fix rebase run-image resolution (#1305)
Browse files Browse the repository at this point in the history
* Fix rebase run-image resolution

Currently, if `-run-image` is not set, `io.buildpacks.lifecycle.metdata[runImage.reference]` is used. This does not follow the [Run Image Resolution spec](https://github.com/buildpacks/spec/blob/main/platform.md#run-image-resolution), which specifies using `io.buildpacks.lifecycle.metdata[runImage.image]` and optionally `io.buildpacks.lifecycle.metdata[runImage.mirrors]`. Because of this, it ends up making `lifecycle rebase` without the `-run-image` flag a no-op because the run image is pinned to the same version instead of getting the latest.

This change simplfies and unifies the behavior for before and after Platform Version 0.12 so that they both read the same run-image data type (just from different locations), and then validate and resolve mirrors the same.

Signed-off-by: Ryan Brainard <966764+ryanbrainard@users.noreply.github.com>

* Rewrite if-else-if-else as switch for go-critic

This is to make go-critic happy. See go-critic/go-critic#453.

Signed-off-by: Ryan Brainard <966764+ryanbrainard@users.noreply.github.com>

* Extract and test platform.GetRunImageFromMetadata

Signed-off-by: Ryan Brainard <966764+ryanbrainard@users.noreply.github.com>

---------

Signed-off-by: Ryan Brainard <966764+ryanbrainard@users.noreply.github.com>
  • Loading branch information
ryanbrainard authored Mar 1, 2024
1 parent f885774 commit 73af3c1
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 12 deletions.
16 changes: 4 additions & 12 deletions cmd/lifecycle/rebaser.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,21 +191,13 @@ func (r *rebaseCmd) setAppImage() error {
}

if r.RunImageRef == "" {
if r.PlatformAPI.AtLeast("0.12") {
r.RunImageRef = md.RunImage.Reference
if r.RunImageRef != "" {
return nil
}
}

// for backwards compatibility, we need to fallback to the stack metadata
// fail if there is no run image metadata available from either location
if md.Stack == nil || md.Stack.RunImage.Image == "" {
runImage, err := platform.GetRunImageFromMetadata(*r.LifecycleInputs, md)
if err != nil {
return cmd.FailErrCode(errors.New("-run-image is required when there is no run image metadata available"), cmd.CodeForInvalidArgs, "parse arguments")
}

// for older platforms, we find the best mirror for the run image as this point
r.RunImageRef, err = platform.BestRunImageMirrorFor(registry, md.Stack.RunImage, r.LifecycleInputs.AccessChecker())
// we find the best mirror for the run image as this point
r.RunImageRef, err = platform.BestRunImageMirrorFor(registry, runImage, r.LifecycleInputs.AccessChecker())
if err != nil {
return err
}
Expand Down
14 changes: 14 additions & 0 deletions platform/run_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,17 @@ func GetRunImageForExport(inputs LifecycleInputs) (files.RunImageForExport, erro
}
return runMD.Images[0], nil
}

// GetRunImageFromMetadata extracts the run image from the image metadata
func GetRunImageFromMetadata(inputs LifecycleInputs, md files.LayersMetadata) (files.RunImageForExport, error) {
switch {
case inputs.PlatformAPI.AtLeast("0.12") && md.RunImage.RunImageForExport.Image != "":
return md.RunImage.RunImageForExport, nil
case md.Stack != nil && md.Stack.RunImage.Image != "":
// for backwards compatibility, we need to fallback to the stack metadata
// fail if there is no run image metadata available from either location
return md.Stack.RunImage, nil
default:
return files.RunImageForExport{}, errors.New("no run image metadata available")
}
}
54 changes: 54 additions & 0 deletions platform/run_image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,60 @@ func testRunImage(t *testing.T, when spec.G, it spec.S) {
})
})

when(".GetRunImageFromMetadata", func() {
var inputs = platform.LifecycleInputs{
PlatformAPI: api.Platform.Latest(),
}

var md = files.LayersMetadata{}

when("run image not set in metadata", func() {
it("errors", func() {
result, err := platform.GetRunImageFromMetadata(inputs, md)
h.AssertNotNil(t, err)
h.AssertEq(t, result.Image, "")
})
})

when("run image set in runImage metadata", func() {
md.RunImage.RunImageForExport.Image = "run-image-in-metadata"

it("returns the run image from runImage metadata", func() {
result, err := platform.GetRunImageFromMetadata(inputs, md)
h.AssertNil(t, err)
h.AssertEq(t, result, files.RunImageForExport{Image: "run-image-in-metadata"})
})
})

when("run image set in stack metadata", func() {
md.Stack = &files.Stack{
RunImage: files.RunImageForExport{
Image: "run-image-in-stack-metadata",
},
}

it("returns the run image from stack metadata", func() {
result, err := platform.GetRunImageFromMetadata(inputs, md)
h.AssertNil(t, err)
h.AssertEq(t, result, files.RunImageForExport{Image: "run-image-in-stack-metadata"})
})
})

when("platform api < 0.12", func() {
inputs.PlatformAPI = api.MustParse("0.11")

when("run image set in runImage metadata", func() {
md.RunImage.RunImageForExport.Image = "run-image-in-metadata"

it("fails to return at this platform version", func() {
result, err := platform.GetRunImageFromMetadata(inputs, md)
h.AssertNotNil(t, err)
h.AssertEq(t, result.Image, "")
})
})
})
})

when(".EnvVarsFor", func() {
it("returns the right thing", func() {
tm := files.TargetMetadata{Arch: "pentium", ArchVariant: "mmx", ID: "my-id", OS: "linux", Distro: &files.OSDistro{Name: "nix", Version: "22.11"}}
Expand Down

0 comments on commit 73af3c1

Please sign in to comment.