Skip to content

Commit

Permalink
Set GOARM based on platform.variant (ko-build#239)
Browse files Browse the repository at this point in the history
This relies on some hard-coded knowledge of the go compiler, which is
unfortunate, so we will have to update this if things change.
  • Loading branch information
jonjohnsonjr authored Nov 4, 2020
1 parent 79beb3b commit 1f17ce9
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 7 deletions.
49 changes: 42 additions & 7 deletions pkg/build/gobuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"os/exec"
"path"
"path/filepath"
"strconv"
"strings"

v1 "github.com/google/go-containerregistry/pkg/v1"
Expand Down Expand Up @@ -210,6 +211,26 @@ func (g *gobuild) importPackage(ref reference) (*gb.Package, error) {
return nil, fmt.Errorf("unmatched importPackage %q with gomodules", ref.String())
}

func getGoarm(platform v1.Platform) (string, error) {
if !strings.HasPrefix(platform.Variant, "v") {
return "", fmt.Errorf("strange arm variant: %v", platform.Variant)
}

vs := strings.TrimPrefix(platform.Variant, "v")
variant, err := strconv.Atoi(vs)
if err != nil {
return "", fmt.Errorf("cannot parse arm variant %q: %v", platform.Variant, err)
}
if variant >= 5 {
// TODO(golang/go#29373): Allow for 8 in later go versions if this is fixed.
if variant > 7 {
vs = "7"
}
return vs, nil
}
return "", nil
}

func build(ctx context.Context, ip string, platform v1.Platform, disableOptimizations bool) (string, error) {
tmpDir, err := ioutil.TempDir("", "ko")
if err != nil {
Expand All @@ -234,6 +255,17 @@ func build(ctx context.Context, ip string, platform v1.Platform, disableOptimiza
"GOOS=" + platform.OS,
"GOARCH=" + platform.Architecture,
}

if strings.HasPrefix(platform.Architecture, "arm") && platform.Variant != "" {
goarm, err := getGoarm(platform)
if err != nil {
return "", fmt.Errorf("goarm failure for %s: %v", ip, err)
}
if goarm != "" {
defaultEnv = append(defaultEnv, "GOARM="+goarm)
}
}

cmd.Env = append(defaultEnv, os.Environ()...)

var output bytes.Buffer
Expand Down Expand Up @@ -428,20 +460,23 @@ func (g *gobuild) tarKoData(ref reference) (*bytes.Buffer, error) {
return buf, walkRecursive(tw, root, kodataRoot)
}

func (g *gobuild) buildOne(ctx context.Context, s string, base v1.Image) (v1.Image, error) {
func (g *gobuild) buildOne(ctx context.Context, s string, base v1.Image, platform *v1.Platform) (v1.Image, error) {
ref := newRef(s)

cf, err := base.ConfigFile()
if err != nil {
return nil, err
}
platform := v1.Platform{
OS: cf.OS,
Architecture: cf.Architecture,
if platform == nil {
platform = &v1.Platform{
OS: cf.OS,
Architecture: cf.Architecture,
OSVersion: cf.OSVersion,
}
}

// Do the build into a temporary file.
file, err := g.build(ctx, ref.Path(), platform, g.disableOptimizations)
file, err := g.build(ctx, ref.Path(), *platform, g.disableOptimizations)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -570,7 +605,7 @@ func (g *gobuild) Build(ctx context.Context, s string) (Result, error) {
if !ok {
return nil, fmt.Errorf("failed to interpret base as image: %v", base)
}
return g.buildOne(ctx, s, base)
return g.buildOne(ctx, s, base, nil)
default:
return nil, fmt.Errorf("base image media type: %s", mt)
}
Expand All @@ -595,7 +630,7 @@ func (g *gobuild) buildAll(ctx context.Context, s string, base v1.ImageIndex) (v
if err != nil {
return nil, err
}
img, err := g.buildOne(ctx, s, base)
img, err := g.buildOne(ctx, s, base, desc.Platform)
if err != nil {
return nil, err
}
Expand Down
67 changes: 67 additions & 0 deletions pkg/build/gobuild_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,3 +540,70 @@ func TestNestedIndex(t *testing.T) {
t.Errorf("Build() expected unexpected mediaType error, got: %s", err)
}
}

func TestGoarm(t *testing.T) {
// From golang@sha256:1ba0da74b20aad52b091877b0e0ece503c563f39e37aa6b0e46777c4d820a2ae
// and made up invalid cases.
for _, tc := range []struct {
platform v1.Platform
variant string
err bool
}{{
platform: v1.Platform{
Architecture: "arm",
OS: "linux",
Variant: "vnot-a-number",
},
err: true,
}, {
platform: v1.Platform{
Architecture: "arm",
OS: "linux",
Variant: "wrong-prefix",
},
err: true,
}, {
platform: v1.Platform{
Architecture: "arm64",
OS: "linux",
Variant: "v3",
},
variant: "",
}, {
platform: v1.Platform{
Architecture: "arm",
OS: "linux",
Variant: "v5",
},
variant: "5",
}, {
platform: v1.Platform{
Architecture: "arm",
OS: "linux",
Variant: "v7",
},
variant: "7",
}, {
platform: v1.Platform{
Architecture: "arm64",
OS: "linux",
Variant: "v8",
},
variant: "7",
},
} {
variant, err := getGoarm(tc.platform)
if tc.err {
if err == nil {
t.Errorf("getGoarm(%v) expected err", tc.platform)
}
continue
}
if err != nil {
t.Fatalf("getGoarm failed for %v: %v", tc.platform, err)
}
if got, want := variant, tc.variant; got != want {
t.Errorf("wrong variant for %v: want %q got %q", tc.platform, want, got)
}
}
}

0 comments on commit 1f17ce9

Please sign in to comment.