Skip to content

Commit

Permalink
Skip validation if the image was built < 0.12
Browse files Browse the repository at this point in the history
If the target image was built prior to 0.12, do not run the additional validation. This is because the validation is not backwards compatible with older images. Older images may not have the required fields and we don't want to force platforms to use the `--force` flag.

Signed-off-by: Jesse Brown <[email protected]>
  • Loading branch information
jabrown85 committed Apr 10, 2023
1 parent f4092ea commit f0a88f5
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 21 deletions.
55 changes: 34 additions & 21 deletions rebaser.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,31 +134,44 @@ func validateMixins(appImg, newBaseImg imgutil.Image) error {
}

func (r *Rebaser) validateRebaseable(appImg imgutil.Image, newBaseImg imgutil.Image) error {
if r.PlatformAPI.AtLeast("0.12") {
rebaseable, err := appImg.Label(platform.RebaseableLabel)
if r.PlatformAPI.LessThan("0.12") {
return nil
}

// skip validation if the previous image was built before 0.12
appPlatformAPI, err := appImg.Env(platform.EnvPlatformAPI)
if err != nil {
return errors.Wrap(err, "get app image platform API")
}

// if the image doesn't have the platform API set, treat it as if it was built before 0.12 and skip additional validation
if appPlatformAPI == "" || api.MustParse(appPlatformAPI).LessThan("0.12") {
return nil
}

rebaseable, err := appImg.Label(platform.RebaseableLabel)
if err != nil {
return errors.Wrap(err, "get app image rebaseable label")
}
if !r.Force && rebaseable == "false" {
return fmt.Errorf("app image is not marked as rebaseable")
}

// check the OS, architecture, and variant values
// if they are not the same, the image cannot be rebased unless the force flag is set
if !r.Force {
appTarget, err := platform.GetTargetFromImage(appImg)
if err != nil {
return errors.Wrap(err, "get app image rebaseable label")
return errors.Wrap(err, "get app image target")
}
if !r.Force && rebaseable == "false" {
return fmt.Errorf("app image is not marked as rebaseable")

newBaseTarget, err := platform.GetTargetFromImage(newBaseImg)
if err != nil {
return errors.Wrap(err, "get new base image target")
}

// check the OS, architecture, and variant values
// if they are not the same, the image cannot be rebased unless the force flag is set
if !r.Force {
appTarget, err := platform.GetTargetFromImage(appImg)
if err != nil {
return errors.Wrap(err, "get app image target")
}

newBaseTarget, err := platform.GetTargetFromImage(newBaseImg)
if err != nil {
return errors.Wrap(err, "get new base image target")
}

if !newBaseTarget.IsValidRebaseTargetFor(appTarget) {
return fmt.Errorf("invalid base image target: '%s' is not equal to '%s'", newBaseTarget, appTarget)
}
if !newBaseTarget.IsValidRebaseTargetFor(appTarget) {
return fmt.Errorf("invalid base image target: '%s' is not equal to '%s'", newBaseTarget, appTarget)
}
}
return nil
Expand Down
46 changes: 46 additions & 0 deletions rebaser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ func testRebaser(t *testing.T, when spec.G, it spec.S) {
)
h.AssertNil(t, fakePreviousImage.SetLabel(platform.StackIDLabel, "io.buildpacks.stacks.bionic"))

h.AssertNil(t, fakeAppImage.SetEnv(platform.EnvPlatformAPI, api.Platform.Latest().String()))

additionalNames = []string{"some-repo/app-image:foo", "some-repo/app-image:bar"}

rebaser = &lifecycle.Rebaser{
Expand Down Expand Up @@ -431,6 +433,50 @@ func testRebaser(t *testing.T, when spec.G, it spec.S) {
rebaser.PlatformAPI = api.MustParse("0.12")
})

when("previous image was built on unknown platform API", func() {
it.Before(func() {
h.AssertNil(t, fakeAppImage.SetEnv(platform.EnvPlatformAPI, ""))
})

it("allows rebase with missing labels", func() {
h.AssertNil(t, fakeAppImage.SetOS(""))
h.AssertNil(t, fakeNewBaseImage.SetOS("linux"))
_, err := rebaser.Rebase(fakeAppImage, fakeNewBaseImage, fakeAppImage.Name(), additionalNames)
h.AssertNil(t, err)
h.AssertEq(t, fakeAppImage.Base(), "some-repo/new-base-image")
})

it("allows rebase with mismatched variants", func() {
h.AssertNil(t, fakeAppImage.SetVariant("variant1"))
h.AssertNil(t, fakeNewBaseImage.SetVariant("variant2"))
_, err := rebaser.Rebase(fakeAppImage, fakeNewBaseImage, fakeAppImage.Name(), additionalNames)
h.AssertNil(t, err)
h.AssertEq(t, fakeAppImage.Base(), "some-repo/new-base-image")
})
})

when("previous image was built on older platform API", func() {
it.Before(func() {
h.AssertNil(t, fakeAppImage.SetEnv(platform.EnvPlatformAPI, "0.11"))
})

it("allows rebase with missing labels", func() {
h.AssertNil(t, fakeAppImage.SetOS(""))
h.AssertNil(t, fakeNewBaseImage.SetOS("linux"))
_, err := rebaser.Rebase(fakeAppImage, fakeNewBaseImage, fakeAppImage.Name(), additionalNames)
h.AssertNil(t, err)
h.AssertEq(t, fakeAppImage.Base(), "some-repo/new-base-image")
})

it("allows rebase with mismatched variants", func() {
h.AssertNil(t, fakeAppImage.SetVariant("variant1"))
h.AssertNil(t, fakeNewBaseImage.SetVariant("variant2"))
_, err := rebaser.Rebase(fakeAppImage, fakeNewBaseImage, fakeAppImage.Name(), additionalNames)
h.AssertNil(t, err)
h.AssertEq(t, fakeAppImage.Base(), "some-repo/new-base-image")
})
})

it("returns an error and prevents the rebase from taking place when the os are different", func() {
h.AssertNil(t, fakeAppImage.SetOS("linux"))
h.AssertNil(t, fakeNewBaseImage.SetOS("notlinux"))
Expand Down

0 comments on commit f0a88f5

Please sign in to comment.