Skip to content

Commit

Permalink
When downloading buildpacks or extensions for pack build or `pack b…
Browse files Browse the repository at this point in the history
…uilder create`,

ensure the os/arch matches the builder

Signed-off-by: Natalie Arellano <[email protected]>
  • Loading branch information
natalieparellano committed Oct 12, 2023
1 parent 5728158 commit 83e9457
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 19 deletions.
15 changes: 13 additions & 2 deletions pkg/buildpack/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ type DownloadOptions struct {
// The OS of the builder image
ImageOS string

// The OS/Architecture to download
Platform string

// Deprecated: the older alternative to buildpack URI
ImageName string

Expand Down Expand Up @@ -102,7 +105,11 @@ func (c *buildpackDownloader) Download(ctx context.Context, moduleURI string, op
case PackageLocator:
imageName := ParsePackageLocator(moduleURI)
c.logger.Debugf("Downloading %s from image: %s", kind, style.Symbol(imageName))
mainBP, depBPs, err = extractPackaged(ctx, kind, imageName, c.imageFetcher, image.FetchOptions{Daemon: opts.Daemon, PullPolicy: opts.PullPolicy})
mainBP, depBPs, err = extractPackaged(ctx, kind, imageName, c.imageFetcher, image.FetchOptions{
Daemon: opts.Daemon,
PullPolicy: opts.PullPolicy,
Platform: opts.Platform,
})
if err != nil {
return nil, nil, errors.Wrapf(err, "extracting from registry %s", style.Symbol(moduleURI))
}
Expand All @@ -113,7 +120,11 @@ func (c *buildpackDownloader) Download(ctx context.Context, moduleURI string, op
return nil, nil, errors.Wrapf(err, "locating in registry: %s", style.Symbol(moduleURI))
}

mainBP, depBPs, err = extractPackaged(ctx, kind, address, c.imageFetcher, image.FetchOptions{Daemon: opts.Daemon, PullPolicy: opts.PullPolicy})
mainBP, depBPs, err = extractPackaged(ctx, kind, address, c.imageFetcher, image.FetchOptions{
Daemon: opts.Daemon,
PullPolicy: opts.PullPolicy,
Platform: opts.Platform,
})
if err != nil {
return nil, nil, errors.Wrapf(err, "extracting from registry %s", style.Symbol(moduleURI))
}
Expand Down
24 changes: 15 additions & 9 deletions pkg/buildpack/downloader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,12 @@ func testBuildpackDownloader(t *testing.T, when spec.G, it spec.S) {
downloadOptions = buildpack.DownloadOptions{ImageOS: "linux"}
)

shouldFetchPackageImageWith := func(demon bool, pull image.PullPolicy) {
mockImageFetcher.EXPECT().Fetch(gomock.Any(), packageImage.Name(), image.FetchOptions{Daemon: demon, PullPolicy: pull}).Return(packageImage, nil)
shouldFetchPackageImageWith := func(demon bool, pull image.PullPolicy, platform string) {
mockImageFetcher.EXPECT().Fetch(gomock.Any(), packageImage.Name(), image.FetchOptions{
Daemon: demon,
PullPolicy: pull,
Platform: platform,
}).Return(packageImage, nil)
}

when("package image lives in cnb registry", func() {
Expand All @@ -141,11 +145,12 @@ func testBuildpackDownloader(t *testing.T, when spec.G, it spec.S) {
downloadOptions = buildpack.DownloadOptions{
RegistryName: "some-registry",
ImageOS: "linux",
Platform: "linux/amd64",
Daemon: true,
PullPolicy: image.PullAlways,
}

shouldFetchPackageImageWith(true, image.PullAlways)
shouldFetchPackageImageWith(true, image.PullAlways, "linux/amd64")
mainBP, _, err := buildpackDownloader.Download(context.TODO(), "urn:cnb:registry:example/[email protected]", downloadOptions)
h.AssertNil(t, err)
h.AssertEq(t, mainBP.Descriptor().Info().ID, "example/foo")
Expand All @@ -161,7 +166,7 @@ func testBuildpackDownloader(t *testing.T, when spec.G, it spec.S) {
PullPolicy: image.PullAlways,
}

shouldFetchPackageImageWith(true, image.PullAlways)
shouldFetchPackageImageWith(true, image.PullAlways, "")
mainBP, _, err := buildpackDownloader.Download(context.TODO(), "example/[email protected]", downloadOptions)
h.AssertNil(t, err)
h.AssertEq(t, mainBP.Descriptor().Info().ID, "example/foo")
Expand All @@ -185,10 +190,11 @@ func testBuildpackDownloader(t *testing.T, when spec.G, it spec.S) {
Daemon: true,
PullPolicy: image.PullAlways,
ImageOS: "linux",
Platform: "linux/amd64",
ImageName: "some/package:tag",
}

shouldFetchPackageImageWith(true, image.PullAlways)
shouldFetchPackageImageWith(true, image.PullAlways, "linux/amd64")
mainBP, _, err := buildpackDownloader.Download(context.TODO(), "", downloadOptions)
h.AssertNil(t, err)
h.AssertEq(t, mainBP.Descriptor().Info().ID, "example/foo")
Expand All @@ -204,7 +210,7 @@ func testBuildpackDownloader(t *testing.T, when spec.G, it spec.S) {
PullPolicy: image.PullAlways,
}

shouldFetchPackageImageWith(true, image.PullAlways)
shouldFetchPackageImageWith(true, image.PullAlways, "")
mainBP, _, err := buildpackDownloader.Download(context.TODO(), "", downloadOptions)
h.AssertNil(t, err)
h.AssertEq(t, mainBP.Descriptor().Info().ID, "example/foo")
Expand All @@ -220,7 +226,7 @@ func testBuildpackDownloader(t *testing.T, when spec.G, it spec.S) {
PullPolicy: image.PullAlways,
}

shouldFetchPackageImageWith(false, image.PullAlways)
shouldFetchPackageImageWith(false, image.PullAlways, "")
mainBP, _, err := buildpackDownloader.Download(context.TODO(), "", downloadOptions)
h.AssertNil(t, err)
h.AssertEq(t, mainBP.Descriptor().Info().ID, "example/foo")
Expand All @@ -234,7 +240,7 @@ func testBuildpackDownloader(t *testing.T, when spec.G, it spec.S) {
Daemon: false,
PullPolicy: image.PullAlways,
}
shouldFetchPackageImageWith(false, image.PullAlways)
shouldFetchPackageImageWith(false, image.PullAlways, "")
mainBP, _, err := buildpackDownloader.Download(context.TODO(), packageImage.Name(), downloadOptions)
h.AssertNil(t, err)
h.AssertEq(t, mainBP.Descriptor().Info().ID, "example/foo")
Expand All @@ -250,7 +256,7 @@ func testBuildpackDownloader(t *testing.T, when spec.G, it spec.S) {
PullPolicy: image.PullNever,
}

shouldFetchPackageImageWith(false, image.PullNever)
shouldFetchPackageImageWith(false, image.PullNever, "")
mainBP, _, err := buildpackDownloader.Download(context.TODO(), "", downloadOptions)
h.AssertNil(t, err)
h.AssertEq(t, mainBP.Descriptor().Info().ID, "example/foo")
Expand Down
13 changes: 10 additions & 3 deletions pkg/client/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -1032,13 +1032,19 @@ func (c *Client) fetchBuildpack(ctx context.Context, bp string, relativeBaseDir
Version: version,
}
default:
imageOS, err := builderImage.OS()
builderOS, err := builderImage.OS()
if err != nil {
return nil, nil, errors.Wrapf(err, "getting OS from %s", style.Symbol(builderImage.Name()))
return nil, nil, errors.Wrapf(err, "getting builder OS")
}

builderArch, err := builderImage.Architecture()
if err != nil {
return nil, nil, errors.Wrapf(err, "getting builder architecture")
}
downloadOptions := buildpack.DownloadOptions{
RegistryName: registry,
ImageOS: imageOS,
ImageOS: builderOS,
Platform: fmt.Sprintf("%s/%s", builderOS, builderArch),
RelativeBaseDir: relativeBaseDir,
Daemon: !publish,
PullPolicy: pullPolicy,
Expand Down Expand Up @@ -1076,6 +1082,7 @@ func (c *Client) fetchBuildpackDependencies(ctx context.Context, bp string, pack
mainBP, deps, err := c.buildpackDownloader.Download(ctx, dep.URI, buildpack.DownloadOptions{
RegistryName: downloadOptions.RegistryName,
ImageOS: downloadOptions.ImageOS,
Platform: downloadOptions.Platform,
Daemon: downloadOptions.Daemon,
PullPolicy: downloadOptions.PullPolicy,
RelativeBaseDir: filepath.Join(bp, packageCfg.Buildpack.URI),
Expand Down
2 changes: 2 additions & 0 deletions pkg/client/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,8 @@ api = "0.2"
Version: "child.buildpack.version",
},
})
args := fakeImageFetcher.FetchCalls[fakePackage.Name()]
h.AssertEq(t, args.Platform, "linux/amd64")
})

it("fails when no metadata label on package", func() {
Expand Down
12 changes: 9 additions & 3 deletions pkg/client/create_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,20 @@ func (c *Client) addExtensionsToBuilder(ctx context.Context, opts CreateBuilderO
func (c *Client) addConfig(ctx context.Context, kind string, config pubbldr.ModuleConfig, opts CreateBuilderOptions, bldr *builder.Builder) error {
c.logger.Debugf("Looking up %s %s", kind, style.Symbol(config.DisplayString()))

imageOS, err := bldr.Image().OS()
builderOS, err := bldr.Image().OS()
if err != nil {
return errors.Wrapf(err, "getting OS from %s", style.Symbol(bldr.Image().Name()))
return errors.Wrapf(err, "getting builder OS")
}
builderArch, err := bldr.Image().Architecture()
if err != nil {
return errors.Wrapf(err, "getting builder architecture")
}

mainBP, depBPs, err := c.buildpackDownloader.Download(ctx, config.URI, buildpack.DownloadOptions{
Daemon: !opts.Publish,
ImageName: config.ImageName,
ImageOS: imageOS,
ImageOS: builderOS,
Platform: fmt.Sprintf("%s/%s", builderOS, builderArch),
ModuleKind: kind,
PullPolicy: opts.PullPolicy,
RegistryName: opts.Registry,
Expand Down
14 changes: 12 additions & 2 deletions pkg/client/create_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -843,12 +843,22 @@ func testCreateBuilder(t *testing.T, when spec.G, it spec.S) {
buildpackBlob := blob.NewBlob(filepath.Join("testdata", "buildpack-api-0.4"))
bp, err := buildpack.FromBuildpackRootBlob(buildpackBlob, archive.DefaultTarWriterFactory())
h.AssertNil(t, err)
mockBuildpackDownloader.EXPECT().Download(gomock.Any(), "https://example.fake/bp-one-with-api-4.tgz", gomock.Any()).Return(bp, bpDependencies, nil)
mockBuildpackDownloader.EXPECT().Download(gomock.Any(), "https://example.fake/bp-one-with-api-4.tgz", gomock.Any()).DoAndReturn(
func(ctx context.Context, buildpackURI string, opts buildpack.DownloadOptions) (buildpack.BuildModule, []buildpack.BuildModule, error) {
// test options
h.AssertEq(t, opts.Platform, "linux/amd64")
return bp, bpDependencies, nil
})

extensionBlob := blob.NewBlob(filepath.Join("testdata", "extension-api-0.9"))
extension, err := buildpack.FromExtensionRootBlob(extensionBlob, archive.DefaultTarWriterFactory())
h.AssertNil(t, err)
mockBuildpackDownloader.EXPECT().Download(gomock.Any(), "https://example.fake/ext-one-with-api-9.tgz", gomock.Any()).Return(extension, nil, nil)
mockBuildpackDownloader.EXPECT().Download(gomock.Any(), "https://example.fake/ext-one-with-api-9.tgz", gomock.Any()).DoAndReturn(
func(ctx context.Context, buildpackURI string, opts buildpack.DownloadOptions) (buildpack.BuildModule, []buildpack.BuildModule, error) {
// test options
h.AssertEq(t, opts.Platform, "linux/amd64")
return extension, nil, nil
})

successfullyCreateDeterministicBuilder()

Expand Down

0 comments on commit 83e9457

Please sign in to comment.