Skip to content

Commit

Permalink
Merge pull request #1969 from buildpacks/bugfix/jjbustamante/issue-1968
Browse files Browse the repository at this point in the history
Retrying logic when pulling an image and platform doesn't match
  • Loading branch information
jjbustamante authored Nov 14, 2023
2 parents b12c9b3 + 63cf11a commit b14250b
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 1 deletion.
39 changes: 39 additions & 0 deletions acceptance/acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1551,6 +1551,45 @@ func testAcceptance(
assertBuildpackOutput := assertions.NewTestBuildpackOutputAssertionManager(t, output)
assertBuildpackOutput.ReportsBuildStep("Simple Layers Buildpack")
})

when("buildpackage is in a registry", func() {
it("adds the buildpacks to the builder and runs them", func() {
h.SkipIf(t, !pack.SupportsFeature(invoke.PlatformRetries), "")
packageImageName = registryConfig.RepoName("buildpack-" + h.RandString(8))

packageTomlPath := generatePackageTomlWithOS(t, assert, pack, tmpDir, "package_for_build_cmd.toml", imageManager.HostOS())
packageImage := buildpacks.NewPackageImage(
t,
pack,
packageImageName,
packageTomlPath,
buildpacks.WithRequiredBuildpacks(
buildpacks.BpFolderSimpleLayersParent,
buildpacks.BpFolderSimpleLayers,
),
buildpacks.WithPublish(),
)

buildpackManager.PrepareBuildModules(tmpDir, packageImage)

output := pack.RunSuccessfully(
"build", repoName,
"-p", filepath.Join("testdata", "mock_app"),
"--buildpack", packageImageName,
)

assertOutput := assertions.NewOutputAssertionManager(t, output)
assertOutput.ReportsAddingBuildpack(
"simple/layers/parent",
"simple-layers-parent-version",
)
assertOutput.ReportsAddingBuildpack("simple/layers", "simple-layers-version")
assertOutput.ReportsSuccessfulImageBuild(repoName)

assertBuildpackOutput := assertions.NewTestBuildpackOutputAssertionManager(t, output)
assertBuildpackOutput.ReportsBuildStep("Simple Layers Buildpack")
})
})
})

when("the argument is a buildpackage file", func() {
Expand Down
4 changes: 4 additions & 0 deletions acceptance/invoke/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ const (
ForceRebase
BuildpackFlatten
MetaBuildpackFolder
PlatformRetries
)

var featureTests = map[Feature]func(i *PackInvoker) bool{
Expand Down Expand Up @@ -262,6 +263,9 @@ var featureTests = map[Feature]func(i *PackInvoker) bool{
MetaBuildpackFolder: func(i *PackInvoker) bool {
return i.atLeast("v0.30.0")
},
PlatformRetries: func(i *PackInvoker) bool {
return i.atLeast("v0.32.1")
},
}

func (i *PackInvoker) SupportsFeature(f Feature) bool {
Expand Down
8 changes: 7 additions & 1 deletion pkg/image/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,13 @@ func (f *Fetcher) Fetch(ctx context.Context, name string, options FetchOptions)
}

f.logger.Debugf("Pulling image %s", style.Symbol(name))
err = f.pullImage(ctx, name, options.Platform)
if err = f.pullImage(ctx, name, options.Platform); err != nil {
// sample error from docker engine:
// image with reference <image> was found but does not match the specified platform: wanted linux/amd64, actual: linux
if strings.Contains(err.Error(), "does not match the specified platform") {
err = f.pullImage(ctx, name, "")
}
}
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
Expand Down
21 changes: 21 additions & 0 deletions pkg/image/fetcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"testing"

"github.com/buildpacks/imgutil"

"github.com/buildpacks/imgutil/local"
"github.com/buildpacks/imgutil/remote"
"github.com/docker/docker/client"
Expand Down Expand Up @@ -48,12 +51,17 @@ func testFetcher(t *testing.T, when spec.G, it spec.S) {
repoName string
repo string
outBuf bytes.Buffer
osType string
)

it.Before(func() {
repo = "some-org/" + h.RandString(10)
repoName = registryConfig.RepoName(repo)
imageFetcher = image.NewFetcher(logging.NewLogWithWriters(&outBuf, &outBuf), docker)

info, err := docker.Info(context.TODO())
h.AssertNil(t, err)
osType = info.OSType
})

when("#Fetch", func() {
Expand Down Expand Up @@ -213,6 +221,19 @@ func testFetcher(t *testing.T, when spec.G, it spec.S) {
_, err := imageFetcher.Fetch(context.TODO(), repoName, image.FetchOptions{Daemon: true, PullPolicy: image.PullAlways, Platform: "some-unsupported-platform"})
h.AssertError(t, err, "unknown operating system or architecture")
})

when("remote platform does not match", func() {
it.Before(func() {
img, err := remote.NewImage(repoName, authn.DefaultKeychain, remote.WithDefaultPlatform(imgutil.Platform{OS: osType, Architecture: ""}))
h.AssertNil(t, err)
h.AssertNil(t, img.Save())
})

it("retry without setting platform", func() {
_, err := imageFetcher.Fetch(context.TODO(), repoName, image.FetchOptions{Daemon: true, PullPolicy: image.PullAlways, Platform: fmt.Sprintf("%s/%s", osType, runtime.GOARCH)})
h.AssertNil(t, err)
})
})
})
})

Expand Down

0 comments on commit b14250b

Please sign in to comment.