Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for ARM64 support in DependencyResolver #296

Merged
merged 2 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions buildpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ package libpak

import (
"fmt"
"net/url"
"os"
"reflect"
"runtime"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -506,6 +508,15 @@ func (d *DependencyResolver) Resolve(id string, version string) (BuildpackDepend
return BuildpackDependency{}, fmt.Errorf("unable to parse version %s\n%w", c.Version, err)
}

// filter out deps that do not match the current running architecture
arch, err := archFromPURL(c.PURL)
if err != nil {
return BuildpackDependency{}, fmt.Errorf("unable to compare arch\n%w", err)
}
if arch != archFromSystem() {
continue
}

if c.ID == id && vc.Check(v) && d.contains(c.Stacks, d.StackID) {
candidates = append(candidates, c)
}
Expand Down Expand Up @@ -534,6 +545,33 @@ func (d *DependencyResolver) Resolve(id string, version string) (BuildpackDepend
return candidate, nil
}

func archFromPURL(rawPURL string) (string, error) {
if len(strings.TrimSpace(rawPURL)) == 0 {
return "amd64", nil
}

purl, err := url.Parse(rawPURL)
if err != nil {
return "", fmt.Errorf("unable to parse PURL\n%w", err)
}

queryParams := purl.Query()
if arch, ok := queryParams["arch"]; ok {
return arch[0], nil
}

return archFromSystem(), nil
}

func archFromSystem() string {
archFromEnv, ok := os.LookupEnv("BP_ARCH")
anthonydahanne marked this conversation as resolved.
Show resolved Hide resolved
if !ok {
archFromEnv = runtime.GOARCH
}

return archFromEnv
}

func (DependencyResolver) contains(candidates []string, value string) bool {
if len(candidates) == 0 {
return true
Expand Down
67 changes: 67 additions & 0 deletions buildpack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,10 @@ func testBuildpack(t *testing.T, context spec.G, it spec.S) {
resolver libpak.DependencyResolver
)

it.Before(func() {
t.Setenv("BP_ARCH", "amd64") // force for test consistency
})

context("Resolve", func() {

it("filters by id", func() {
Expand Down Expand Up @@ -315,6 +319,69 @@ func testBuildpack(t *testing.T, context spec.G, it spec.S) {
}))
})

it("filters by arch", func() {
resolver.Dependencies = []libpak.BuildpackDependency{
{
ID: "test-id-1",
Name: "test-name",
Version: "1.0",
URI: "test-uri-amd64",
SHA256: "test-sha256",
Stacks: []string{"test-stack-1", "test-stack-2"},
PURL: "pkg:generic/[email protected]?arch=amd64",
},
{
ID: "test-id-1",
Name: "test-name",
Version: "1.0",
URI: "test-uri-arm64",
SHA256: "test-sha256",
Stacks: []string{"test-stack-1", "test-stack-2"},
PURL: "pkg:generic/[email protected]?arch=arm64",
},
}
resolver.StackID = "test-stack-1"

t.Setenv("BP_ARCH", "arm64")

Expect(resolver.Resolve("test-id-1", "1.0")).To(Equal(libpak.BuildpackDependency{
ID: "test-id-1",
Name: "test-name",
Version: "1.0",
URI: "test-uri-arm64",
SHA256: "test-sha256",
Stacks: []string{"test-stack-1", "test-stack-2"},
PURL: "pkg:generic/[email protected]?arch=arm64",
}))
})

it("filters by arch where arch should match any", func() {
resolver.Dependencies = []libpak.BuildpackDependency{
{
ID: "test-id-1",
Name: "test-name",
Version: "1.0",
URI: "test-uri",
SHA256: "test-sha256",
Stacks: []string{"test-stack-1", "test-stack-2"},
PURL: "pkg:generic/[email protected]",
},
}
resolver.StackID = "test-stack-1"

t.Setenv("BP_ARCH", "arm64")

Expect(resolver.Resolve("test-id-1", "1.0")).To(Equal(libpak.BuildpackDependency{
ID: "test-id-1",
Name: "test-name",
Version: "1.0",
URI: "test-uri",
SHA256: "test-sha256",
Stacks: []string{"test-stack-1", "test-stack-2"},
PURL: "pkg:generic/[email protected]",
}))
})

it("filters by version constraint", func() {
resolver.Dependencies = []libpak.BuildpackDependency{
{
Expand Down
4 changes: 2 additions & 2 deletions carton/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (p Package) Create(options ...Option) {
config.exitHandler.Error(fmt.Errorf("unable to decode buildpack %s\n%w", file, err))
return
}
logger.Debug("Buildpack: %+v", buildpack)
logger.Debugf("Buildpack: %+v", buildpack)

metadata, err := libpak.NewBuildpackMetadata(buildpack.Metadata)
if err != nil {
Expand All @@ -102,7 +102,7 @@ func (p Package) Create(options ...Option) {
for _, i := range metadata.IncludeFiles {
entries[i] = filepath.Join(p.Source, i)
}
logger.Debug("Include files: %+v", entries)
logger.Debugf("Include files: %+v", entries)

if p.Version != "" {
buildpack.Info.Version = p.Version
Expand Down