Skip to content

Commit

Permalink
fixup! Copy io.buildpacks.base.* labels on rebase
Browse files Browse the repository at this point in the history
Signed-off-by: Jesse Brown <[email protected]>
  • Loading branch information
jabrown85 committed Mar 30, 2023
1 parent 68655c8 commit f4092ea
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 59 deletions.
30 changes: 30 additions & 0 deletions platform/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package platform

import (
"encoding/json"
"fmt"
"os"

"github.com/BurntSushi/toml"
Expand Down Expand Up @@ -102,6 +103,35 @@ func (t *TargetMetadata) IsSatisfiedBy(o *buildpack.TargetMetadata) bool {
return true
}

// IsValidRebaseTargetFor treats optional fields (ArchVariant and Distribution fields) as wildcards if empty, returns true if all populated fields match
func (t *TargetMetadata) IsValidRebaseTargetFor(appTargetMetadata *TargetMetadata) bool {
if t.Arch != appTargetMetadata.Arch || t.OS != appTargetMetadata.OS {
return false
}
if t.ArchVariant != "" && appTargetMetadata.ArchVariant != "" && t.ArchVariant != appTargetMetadata.ArchVariant {
return false
}

if t.Distribution != nil && appTargetMetadata.Distribution != nil {
if t.Distribution.Name != appTargetMetadata.Distribution.Name {
return false
}
if t.Distribution.Version != appTargetMetadata.Distribution.Version {
return false
}
}
return true
}

func (t *TargetMetadata) String() string {
var distName, distVersion string
if t.Distribution != nil {
distName = t.Distribution.Name
distVersion = t.Distribution.Version
}
return fmt.Sprintf("OS: %s, Arch: %s, ArchVariant: %s, Distribution: (Name: %s, Version: %s)", t.OS, t.Arch, t.ArchVariant, distName, distVersion)
}

func ReadAnalyzed(analyzedPath string, logger log.Logger) (AnalyzedMetadata, error) {
var analyzedMD AnalyzedMetadata
if _, err := toml.DecodeFile(analyzedPath, &analyzedMD); err != nil {
Expand Down
59 changes: 6 additions & 53 deletions rebaser.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,65 +146,18 @@ func (r *Rebaser) validateRebaseable(appImg imgutil.Image, newBaseImg imgutil.Im
// 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 {
appOS, err := appImg.OS()
appTarget, err := platform.GetTargetFromImage(appImg)
if err != nil {
return errors.Wrap(err, "get app image os")
}
newBaseOS, err := newBaseImg.OS()
if err != nil {
return errors.Wrap(err, "get new base image os")
}
if appOS != newBaseOS {
return fmt.Errorf("incompatible os: '%s' is not compatible with '%s'", newBaseOS, appOS)
}

appArch, err := appImg.Architecture()
if err != nil {
return errors.Wrap(err, "get app image architecture")
}
newBaseArch, err := newBaseImg.Architecture()
if err != nil {
return errors.Wrap(err, "get new base image architecture")
}
if appArch != newBaseArch {
return fmt.Errorf("incompatible architecture: '%s' is not compatible with '%s'", newBaseArch, appArch)
}

appVariant, err := appImg.Variant()
if err != nil {
return errors.Wrap(err, "get app image variant")
}
newBaseVariant, err := newBaseImg.Variant()
if err != nil {
return errors.Wrap(err, "get new base image variant")
}
if appVariant != newBaseVariant {
return fmt.Errorf("incompatible variant: '%s' is not compatible with '%s'", newBaseVariant, appVariant)
return errors.Wrap(err, "get app image target")
}

// check optional labels OSDistributionName and OSDistributionVersion
distroName, err := appImg.Label(platform.OSDistributionNameLabel)
if err != nil {
return errors.Wrap(err, "get app image os distribution name")
}
newBaseDistroName, err := newBaseImg.Label(platform.OSDistributionNameLabel)
newBaseTarget, err := platform.GetTargetFromImage(newBaseImg)
if err != nil {
return errors.Wrap(err, "get new base image os distribution name")
}
if distroName != newBaseDistroName {
return fmt.Errorf("incompatible io.buildpacks.distribution.name: '%s' is not compatible with '%s'", newBaseDistroName, distroName)
return errors.Wrap(err, "get new base image target")
}

distroVersion, err := appImg.Label(platform.OSDistributionVersionLabel)
if err != nil {
return errors.Wrap(err, "get app image os distribution version")
}
newBaseDistroVersion, err := newBaseImg.Label(platform.OSDistributionVersionLabel)
if err != nil {
return errors.Wrap(err, "get new base image os distribution version")
}
if distroVersion != newBaseDistroVersion {
return fmt.Errorf("incompatible io.buildpacks.distribution.version: '%s' is not compatible with '%s'", newBaseDistroVersion, distroVersion)
if !newBaseTarget.IsValidRebaseTargetFor(appTarget) {
return fmt.Errorf("invalid base image target: '%s' is not equal to '%s'", newBaseTarget, appTarget)
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions rebaser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,39 +436,39 @@ func testRebaser(t *testing.T, when spec.G, it spec.S) {
h.AssertNil(t, fakeNewBaseImage.SetOS("notlinux"))

_, err := rebaser.Rebase(fakeAppImage, fakeNewBaseImage, fakeAppImage.Name(), additionalNames)
h.AssertError(t, err, "incompatible os: 'notlinux' is not compatible with 'linux'")
h.AssertError(t, err, "invalid base image target: 'OS: notlinux, Arch: amd64, ArchVariant: , Distribution: (Name: , Version: )' is not equal to 'OS: linux, Arch: amd64, ArchVariant: , Distribution: (Name: , Version: )'")
})

it("returns an error and prevents the rebase from taking place when the architecture are different", func() {
h.AssertNil(t, fakeAppImage.SetArchitecture("amd64"))
h.AssertNil(t, fakeNewBaseImage.SetArchitecture("arm64"))

_, err := rebaser.Rebase(fakeAppImage, fakeNewBaseImage, fakeAppImage.Name(), additionalNames)
h.AssertError(t, err, "incompatible architecture: 'arm64' is not compatible with 'amd64'")
h.AssertError(t, err, "invalid base image target: 'OS: linux, Arch: arm64, ArchVariant: , Distribution: (Name: , Version: )' is not equal to 'OS: linux, Arch: amd64, ArchVariant: , Distribution: (Name: , Version: )'")
})

it("returns an error and prevents the rebase from taking place when the architecture are different", func() {
it("returns an error and prevents the rebase from taking place when the architecture variant are different", func() {
h.AssertNil(t, fakeAppImage.SetVariant("variant1"))
h.AssertNil(t, fakeNewBaseImage.SetVariant("variant2"))

_, err := rebaser.Rebase(fakeAppImage, fakeNewBaseImage, fakeAppImage.Name(), additionalNames)
h.AssertError(t, err, "incompatible variant: 'variant2' is not compatible with 'variant1'")
h.AssertError(t, err, "invalid base image target: 'OS: linux, Arch: amd64, ArchVariant: variant2, Distribution: (Name: , Version: )' is not equal to 'OS: linux, Arch: amd64, ArchVariant: variant1, Distribution: (Name: , Version: )'")
})

it("returns an error and prevents the rebase from taking place when the io.buildpacks.distribution.name are different", func() {
h.AssertNil(t, fakeAppImage.SetLabel("io.buildpacks.distribution.name", "distro1"))
h.AssertNil(t, fakeNewBaseImage.SetLabel("io.buildpacks.distribution.name", "distro2"))

_, err := rebaser.Rebase(fakeAppImage, fakeNewBaseImage, fakeAppImage.Name(), additionalNames)
h.AssertError(t, err, "incompatible io.buildpacks.distribution.name: 'distro2' is not compatible with 'distro1'")
h.AssertError(t, err, "invalid base image target: 'OS: linux, Arch: amd64, ArchVariant: , Distribution: (Name: distro2, Version: )' is not equal to 'OS: linux, Arch: amd64, ArchVariant: , Distribution: (Name: distro1, Version: )'")
})

it("returns an error and prevents the rebase from taking place when the io.buildpacks.distribution.version are different", func() {
h.AssertNil(t, fakeAppImage.SetLabel("io.buildpacks.distribution.version", "version1"))
h.AssertNil(t, fakeNewBaseImage.SetLabel("io.buildpacks.distribution.version", "version2"))

_, err := rebaser.Rebase(fakeAppImage, fakeNewBaseImage, fakeAppImage.Name(), additionalNames)
h.AssertError(t, err, "incompatible io.buildpacks.distribution.version: 'version2' is not compatible with 'version1'")
h.AssertError(t, err, "invalid base image target: 'OS: linux, Arch: amd64, ArchVariant: , Distribution: (Name: , Version: version2)' is not equal to 'OS: linux, Arch: amd64, ArchVariant: , Distribution: (Name: , Version: version1)'")
})
})

Expand Down

0 comments on commit f4092ea

Please sign in to comment.