1
0
mirror of https://github.com/ko-build/ko.git synced 2025-02-07 19:30:23 +02:00

Set GOARM based on platform.variant (#239)

This relies on some hard-coded knowledge of the go compiler, which is
unfortunate, so we will have to update this if things change.
This commit is contained in:
jonjohnsonjr 2020-11-04 12:44:08 -08:00 committed by GitHub
parent 79beb3b015
commit 1f17ce95d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 109 additions and 7 deletions

View File

@ -30,6 +30,7 @@ import (
"os/exec"
"path"
"path/filepath"
"strconv"
"strings"
v1 "github.com/google/go-containerregistry/pkg/v1"
@ -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 {
@ -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
@ -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
}
@ -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)
}
@ -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
}

View File

@ -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)
}
}
}