Skip to content

Commit

Permalink
util: add binfmt_misc binary detection
Browse files Browse the repository at this point in the history
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
  • Loading branch information
tonistiigi committed Feb 27, 2019
1 parent 2bd8e6c commit 7d41a90
Show file tree
Hide file tree
Showing 18 changed files with 273 additions and 0 deletions.
4 changes: 4 additions & 0 deletions cmd/buildkitd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/moby/buildkit/util/apicaps"
"github.com/moby/buildkit/util/appcontext"
"github.com/moby/buildkit/util/appdefaults"
"github.com/moby/buildkit/util/binfmt_misc"
"github.com/moby/buildkit/util/profiler"
"github.com/moby/buildkit/util/resolver"
"github.com/moby/buildkit/version"
Expand Down Expand Up @@ -307,6 +308,9 @@ func setDefaultConfig(cfg *config.Config) {
cfg.GRPC.Address = []string{appdefaults.Address}
}

cfg.Workers.OCI.Platforms = binfmt_misc.SupportedPlatforms()
cfg.Workers.Containerd.Platforms = binfmt_misc.SupportedPlatforms()

if system.RunningInUserNS() {
// if buildkitd is being executed as the mapped-root (not only EUID==0 but also $USER==root)
// in a user namespace, we need to enable the rootless mode but
Expand Down
32 changes: 32 additions & 0 deletions util/binfmt_misc/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
FROM debian:buster-slim AS base
RUN apt-get update && apt-get install -y --no-install-recommends \
binutils-arm-linux-gnueabihf \
binutils-aarch64-linux-gnu \
binutils-x86-64-linux-gnu
WORKDIR /src


FROM base AS exit-amd64
COPY fixtures/exit.amd64.s .
RUN x86_64-linux-gnu-as -o exit.o exit.amd64.s && x86_64-linux-gnu-ld -o exit exit.o

FROM base AS exit-arm64
COPY fixtures/exit.arm64.s .
RUN aarch64-linux-gnu-as -o exit.o exit.arm64.s && aarch64-linux-gnu-ld -o exit exit.o

FROM base AS exit-arm
COPY fixtures/exit.arm.s .
RUN arm-linux-gnueabihf-as -o exit.o exit.arm.s && arm-linux-gnueabihf-ld -o exit exit.o

FROM golang:1.11-alpine AS generate
WORKDIR /src
COPY --from=exit-amd64 /src/exit amd64
COPY --from=exit-arm64 /src/exit arm64
COPY --from=exit-arm /src/exit arm
COPY generate.go .

RUN go run generate.go amd64 arm64 arm && ls -l


FROM scratch
COPY --from=generate /src/*_binary.go /
4 changes: 4 additions & 0 deletions util/binfmt_misc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
generate:
buildctl build --frontend dockerfile.v0 --local context=. --local dockerfile=. --exporter=local --exporter-opt output=.

.PHONY: generate
4 changes: 4 additions & 0 deletions util/binfmt_misc/amd64_binary.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// +build !amd64
package binfmt_misc

const Binaryamd64 = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\xec\x98\xbd\x4a\xfc\x40\x14\xc5\x4f\x3e\xff\xf9\x83\x62\x16\x2c\x14\x9b\x7d\x82\x01\xc1\xc2\x42\x24\x8d\x1f\x85\xd8\x59\x87\x2c\x1b\xb4\x31\xbb\x24\x23\xb8\x95\xaf\xe3\x23\x58\x6e\x67\xed\x5b\xec\x5b\x28\x99\xbd\x77\x77\x32\x1a\xd2\x58\xc9\xfd\xc1\x72\xf6\x1e\xee\xcd\x1d\xa6\x9b\xf3\x72\x71\x73\xe9\x7b\x1e\x18\x1f\xe7\x30\x55\x9a\x99\x3a\x23\x3f\x19\x6d\x5a\x90\xe1\x14\x01\x32\xc4\x88\x4c\x6f\x08\x9b\xac\xa3\x09\x7d\x9a\x15\xe9\x5a\xda\x32\xb2\x6a\xde\xc7\xba\x43\x36\x2b\xf7\x85\xf4\x5b\x91\xbd\xa2\x3d\xac\x63\xf2\x59\x13\x6c\xe7\x52\xda\x79\x75\x7b\xd7\xee\x5f\x86\x74\x0e\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\xf8\xeb\x5c\xbf\x2f\xcf\x5a\x39\xfe\xdc\x8b\x86\x7a\x03\x78\x9b\x77\x76\xd7\xf7\xb7\xef\x77\x22\x36\xef\xed\xef\xbe\xc7\xfe\xb8\xeb\xef\xf6\xf8\xfb\x3d\x3e\xf2\x7c\xd2\x34\x79\xa3\x8b\x5a\x23\x2f\xa7\x85\x2e\x90\x97\xd5\x14\x50\xcd\xe2\x51\x17\x13\xa8\x46\xd7\x6b\x7d\xe0\x7f\xd5\x4c\x97\xea\xbe\x7a\x52\xf3\x7a\x36\x2f\x6b\xbd\x80\xd2\xe5\xb3\xfe\x8d\x7b\x3c\x02\xf0\xcf\xe4\x27\x6e\x2e\xd1\xcd\x23\xe0\xe4\x12\x8c\xa2\xbb\x89\xe1\xe6\x21\x4e\x0e\x62\xdd\xa3\x5b\xfb\x3f\x9c\x2b\xa5\xf9\x57\x2b\x07\x09\xac\xfd\x07\xa4\xff\xc9\x77\x79\xa3\xf9\xc3\x81\xfd\xa3\x9e\xf9\x0f\x9a\x3f\x19\x98\xff\x0a\x00\x00\xff\xff\x8e\x72\x8d\xdd\x88\x12\x00\x00"
7 changes: 7 additions & 0 deletions util/binfmt_misc/amd64_check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build !amd64

package binfmt_misc

func amd64Supported() bool {
return check(Binaryamd64) == nil
}
7 changes: 7 additions & 0 deletions util/binfmt_misc/amd64_check_amd64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build amd64

package binfmt_misc

func amd64Supported() bool {
return true
}
4 changes: 4 additions & 0 deletions util/binfmt_misc/arm64_binary.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// +build !arm64
package binfmt_misc

const Binaryarm64 = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\xa4\x92\x3d\x4e\x03\x31\x10\x85\xdf\x2c\x1b\x14\x14\x0a\xe8\xf8\x69\x40\x82\x86\x62\x25\x3a\xe8\x4c\x11\x2a\xee\x60\x6d\x14\x4b\x50\x00\x52\x3c\x85\xa9\x48\xb1\x45\x8e\x92\x1b\x70\x8f\x88\x6b\x50\x70\x02\xd0\x3a\x63\x6b\x63\xb0\xb6\xc8\x6b\xc6\xef\xcd\x37\xf6\xfe\xf8\x7d\xfc\x70\x5f\x10\x21\xa8\xc0\x07\x5a\xe7\xa0\xbc\x57\x92\x1f\x14\x11\x81\xc2\x0d\x08\x0a\x03\x94\x9e\x1d\xa0\x2b\xb5\x51\x1b\x71\x4d\xec\x87\xb3\xe6\xab\xe5\x68\xbe\x22\xe0\x13\x3d\xda\x01\xc5\xe7\xe9\xee\x52\xe2\xfb\x27\x65\x87\xd2\x4d\xf9\x93\xf6\x1d\x40\x68\x70\xb7\x91\x8f\x32\xf9\x71\x26\xbf\x92\x3c\xdd\xff\x32\xc3\x5f\x4b\xbe\x48\xf2\xdb\x0c\xaf\x32\x3c\x8c\x7b\xe2\xea\x15\x17\x0e\x5a\x4f\xac\xd5\x96\xeb\x19\x6b\x2d\xce\xbc\x4c\xe3\xda\x77\xa0\x43\x66\xa6\x35\xd7\x68\x1d\x50\xd9\xb7\x67\xae\x27\xa8\x2c\xcf\xd6\xf5\x31\xac\xd8\x38\xc6\xf6\x3a\x95\x7f\xb3\x2b\x3e\x7c\x27\x27\x7e\x3f\xe1\xcb\xc4\x93\xbf\x83\x7f\xb5\x90\x7a\x46\xe1\x4e\xac\x67\x87\x92\x1f\x49\xdd\x93\x5e\xaa\xa5\xcc\x8d\xff\x39\xaf\xab\xc3\xcc\xfc\x97\x80\xe7\x3d\xf3\xbf\x01\x00\x00\xff\xff\xc6\x12\x32\x6a\x50\x03\x00\x00"
7 changes: 7 additions & 0 deletions util/binfmt_misc/arm64_check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build !arm64

package binfmt_misc

func arm64Supported() bool {
return check(Binaryarm64) == nil
}
7 changes: 7 additions & 0 deletions util/binfmt_misc/arm64_check_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build arm64

package binfmt_misc

func arm64Supported() bool {
return true
}
4 changes: 4 additions & 0 deletions util/binfmt_misc/arm_binary.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// +build !arm
package binfmt_misc

const Binaryarm = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\x8c\x91\xb1\x4a\x33\x41\x14\x85\xbf\xbb\xf9\x37\x7f\x44\x8b\xc4\x4e\x6d\x14\x14\x82\xc5\x82\x90\xc6\xce\x80\xb1\xd2\x46\xd2\xaf\xb3\x64\xc1\x14\x6a\xc8\x5c\x21\x56\xd6\xbe\x45\x1e\xc4\x87\xf0\x1d\xf2\x00\xe2\x13\x28\x3b\x99\xdd\xec\x0e\x16\x1e\x58\xee\x7c\x67\xce\xdc\x61\xe7\xbe\x8e\xae\xaf\x44\x84\x52\x11\x7d\x0a\x1a\x23\x0c\x80\x77\x71\x66\x3c\xe0\x10\xa1\x4f\x9b\x98\x4d\x5a\xdc\x77\x07\xee\x8b\x2b\x6f\xb9\x92\xd9\x72\x05\x7c\x0e\x7b\x80\xc9\x4d\x36\x45\xfe\x03\x9d\xcd\xe1\x86\xc6\xbe\x6b\x8b\x66\xa0\x45\xd4\x70\xfe\xf1\xf5\xdd\xa9\xe5\x8b\xfb\xf6\xdd\xfd\x91\xa3\x2e\xc2\x76\xc0\x7b\x01\x9f\xd6\xce\x17\x7c\x12\xec\x9f\x05\x7c\x1e\xf0\x45\xc0\xe4\x8b\xa9\x26\x4f\x1c\x1b\xd2\x34\xb3\x36\xb5\x6a\xe6\x9a\xa6\x9e\xf2\xc7\x49\xb5\x76\x3b\xa4\xa5\x97\x4f\x8c\x1a\x0a\x82\xc4\xbe\x3c\xa8\xc9\x48\xac\xce\xd7\xf5\xbe\x5c\x69\xbe\x50\x92\xe1\xed\x4d\x62\x54\xe7\xd3\xec\x59\x73\xcb\xdf\x75\xe0\xa7\xd2\xf6\xff\x3d\x06\x76\x1a\x6f\xba\xd6\x91\x7b\x6f\x66\xa5\x5f\xcc\x74\xb7\x96\x93\x5a\x8d\x6a\xbe\x02\x1f\xbe\x4f\xec\x6b\x17\xd8\x5a\xf7\xab\x74\x29\x30\xfa\xa5\x5f\x2f\xc8\xbd\x09\x6e\x06\x61\xee\x27\x00\x00\xff\xff\x29\x78\x7d\xe8\xac\x02\x00\x00"
7 changes: 7 additions & 0 deletions util/binfmt_misc/arm_check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build !arm

package binfmt_misc

func armSupported() bool {
return check(Binaryarm) == nil
}
7 changes: 7 additions & 0 deletions util/binfmt_misc/arm_check_arm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build arm

package binfmt_misc

func armSupported() bool {
return true
}
39 changes: 39 additions & 0 deletions util/binfmt_misc/check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package binfmt_misc

import (
"bytes"
"compress/gzip"
"io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
)

func check(bin string) error {
tmpdir, err := ioutil.TempDir("", "qemu-check")
if err != nil {
return err
}
defer os.RemoveAll(tmpdir)
pp := filepath.Join(tmpdir, "check")

r, err := gzip.NewReader(bytes.NewReader([]byte(bin)))
if err != nil {
return err
}
defer r.Close()

f, err := os.OpenFile(pp, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0700)
if err != nil {
return err
}

if _, err := io.Copy(f, r); err != nil {
f.Close()
return err
}
f.Close()

return exec.Command(pp).Run()
}
32 changes: 32 additions & 0 deletions util/binfmt_misc/detect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package binfmt_misc

import (
"strings"
"sync"

"github.com/containerd/containerd/platforms"
)

var once sync.Once
var arr []string

func SupportedPlatforms() []string {
once.Do(func() {
def := platforms.DefaultString()
arr = append(arr, def)

if p := "linux/amd64"; def != p && amd64Supported() {
arr = append(arr, p)
}
if p := "linux/arm64"; def != p && arm64Supported() {
arr = append(arr, p)
}
if !strings.HasPrefix(def, "linux/arm/") && armSupported() {
arr = append(arr, "linux/arm/v7", "linux/arm/v6")
} else if def == "linux/arm/v7" {
arr = append(arr, "linux/arm/v6")
}
})

return arr
}
6 changes: 6 additions & 0 deletions util/binfmt_misc/fixtures/exit.amd64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.global _start
.text
_start:
mov $60, %rax
xor %rdi, %rdi
syscall
6 changes: 6 additions & 0 deletions util/binfmt_misc/fixtures/exit.arm.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.global _start
.text
_start:
mov %r0, $0x0
mov %r7, $0x01
swi 0x0
6 changes: 6 additions & 0 deletions util/binfmt_misc/fixtures/exit.arm64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.global _start
.text
_start:
mov x0, #0
mov x8, #93
svc #0
90 changes: 90 additions & 0 deletions util/binfmt_misc/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// +build ignore

package main

import (
"bytes"
"compress/gzip"
"flag"
"fmt"
"html/template"
"io"
"os"
"path/filepath"
)

// saves baseimage binaries statically into go code
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
panic(fmt.Errorf("arch is required"))
}

for _, arch := range flag.Args() {
wd, err := os.Getwd()
if err != nil {
panic(err)
}
f, err := os.Open(filepath.Join(wd, arch))
if err != nil {
panic(err)
}
defer f.Close()
buf := &bytes.Buffer{}

gz, err := gzip.NewWriterLevel(newHexStringWriter(buf), gzip.BestCompression)
if err != nil {
panic(err)
}
if _, err = io.Copy(gz, f); err != nil {
panic(err)
}
if err := gz.Close(); err != nil {
panic(err)
}

fn := filepath.Join(wd, arch+"_binary.go")
dest, err := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
panic(err)
}
if err := tmpl.Execute(dest, struct{ Arch, Package, Data string }{Arch: arch, Package: "binfmt_misc", Data: buf.String()}); err != nil {
panic(err)
}
dest.Close()
}

}

type hexStringWriter struct {
w io.Writer
}

func newHexStringWriter(w io.Writer) io.Writer {
return &hexStringWriter{w: w}
}

func (w *hexStringWriter) Write(d []byte) (int, error) {
const hextable = "0123456789abcdef"
b := make([]byte, len(d)*4)
for i, v := range d {
b[i*4] = '\\'
b[i*4+1] = 'x'
b[i*4+2] = hextable[v>>4]
b[i*4+3] = hextable[v&0x0f]
}
for {
n, err := w.w.Write(b)
if err == io.ErrShortWrite {
b = b[n:]
continue
}
return len(d), err
}
}

var tmpl = template.Must(template.New("pause").Parse(`// +build !{{.Arch}}
package {{.Package}}
const Binary{{.Arch}} = "{{.Data}}"
`))

0 comments on commit 7d41a90

Please sign in to comment.