From aa31ff073fb10a21ddbe0b422ebdb630e78e5a48 Mon Sep 17 00:00:00 2001 From: Dave Chen Date: Tue, 5 Mar 2019 00:21:06 -0800 Subject: [PATCH] Check the validity of the platforms platforms can still be added but some warning message will be emitted if the platform cannot pass the validity check. Signed-off-by: Dave Chen --- cmd/buildkitd/main.go | 4 ++- util/binfmt_misc/amd64_check.go | 4 +-- util/binfmt_misc/amd64_check_amd64.go | 4 +-- util/binfmt_misc/arm64_check.go | 4 +-- util/binfmt_misc/arm64_check_arm64.go | 4 +-- util/binfmt_misc/arm_check.go | 4 +-- util/binfmt_misc/arm_check_arm.go | 4 +-- util/binfmt_misc/check.go | 8 ++++- util/binfmt_misc/detect.go | 45 ++++++++++++++++++++++++--- 9 files changed, 62 insertions(+), 19 deletions(-) diff --git a/cmd/buildkitd/main.go b/cmd/buildkitd/main.go index 507f7091..93b5954a 100644 --- a/cmd/buildkitd/main.go +++ b/cmd/buildkitd/main.go @@ -558,7 +558,9 @@ func newWorkerController(c *cli.Context, wiOpt workerInitializerOpt) (*worker.Co return nil, err } for _, w := range ws { - logrus.Infof("found worker %q, labels=%v, platforms=%v", w.ID(), w.Labels(), formatPlatforms(w.Platforms())) + p := formatPlatforms(w.Platforms()) + logrus.Infof("found worker %q, labels=%v, platforms=%v", w.ID(), w.Labels(), p) + binfmt_misc.WarnIfUnsupported(p) if err = wc.Add(w); err != nil { return nil, err } diff --git a/util/binfmt_misc/amd64_check.go b/util/binfmt_misc/amd64_check.go index 0844b74c..61913389 100644 --- a/util/binfmt_misc/amd64_check.go +++ b/util/binfmt_misc/amd64_check.go @@ -2,6 +2,6 @@ package binfmt_misc -func amd64Supported() bool { - return check(Binaryamd64) == nil +func amd64Supported() error { + return check(Binaryamd64) } diff --git a/util/binfmt_misc/amd64_check_amd64.go b/util/binfmt_misc/amd64_check_amd64.go index a44a7e54..e437dfef 100644 --- a/util/binfmt_misc/amd64_check_amd64.go +++ b/util/binfmt_misc/amd64_check_amd64.go @@ -2,6 +2,6 @@ package binfmt_misc -func amd64Supported() bool { - return true +func amd64Supported() error { + return nil } diff --git a/util/binfmt_misc/arm64_check.go b/util/binfmt_misc/arm64_check.go index 53fec633..334d3142 100644 --- a/util/binfmt_misc/arm64_check.go +++ b/util/binfmt_misc/arm64_check.go @@ -2,6 +2,6 @@ package binfmt_misc -func arm64Supported() bool { - return check(Binaryarm64) == nil +func arm64Supported() error { + return check(Binaryarm64) } diff --git a/util/binfmt_misc/arm64_check_arm64.go b/util/binfmt_misc/arm64_check_arm64.go index 4923badb..a5fc6dc6 100644 --- a/util/binfmt_misc/arm64_check_arm64.go +++ b/util/binfmt_misc/arm64_check_arm64.go @@ -2,6 +2,6 @@ package binfmt_misc -func arm64Supported() bool { - return true +func arm64Supported() error { + return nil } diff --git a/util/binfmt_misc/arm_check.go b/util/binfmt_misc/arm_check.go index 840f69a2..3a10daaf 100644 --- a/util/binfmt_misc/arm_check.go +++ b/util/binfmt_misc/arm_check.go @@ -2,6 +2,6 @@ package binfmt_misc -func armSupported() bool { - return check(Binaryarm) == nil +func armSupported() error { + return check(Binaryarm) } diff --git a/util/binfmt_misc/arm_check_arm.go b/util/binfmt_misc/arm_check_arm.go index 03d0c527..11cfe616 100644 --- a/util/binfmt_misc/arm_check_arm.go +++ b/util/binfmt_misc/arm_check_arm.go @@ -2,6 +2,6 @@ package binfmt_misc -func armSupported() bool { - return true +func armSupported() error { + return nil } diff --git a/util/binfmt_misc/check.go b/util/binfmt_misc/check.go index 49356283..2f2352c8 100644 --- a/util/binfmt_misc/check.go +++ b/util/binfmt_misc/check.go @@ -8,6 +8,7 @@ import ( "os" "os/exec" "path/filepath" + "syscall" ) func check(bin string) error { @@ -35,5 +36,10 @@ func check(bin string) error { } f.Close() - return exec.Command(pp).Run() + cmd := exec.Command("/check") + cmd.SysProcAttr = &syscall.SysProcAttr{ + Chroot: tmpdir, + } + err = cmd.Run() + return err } diff --git a/util/binfmt_misc/detect.go b/util/binfmt_misc/detect.go index 719fe134..3aedbf7f 100644 --- a/util/binfmt_misc/detect.go +++ b/util/binfmt_misc/detect.go @@ -5,6 +5,7 @@ import ( "sync" "github.com/containerd/containerd/platforms" + "github.com/sirupsen/logrus" ) var once sync.Once @@ -14,19 +15,53 @@ func SupportedPlatforms() []string { once.Do(func() { def := platforms.DefaultString() arr = append(arr, def) - - if p := "linux/amd64"; def != p && amd64Supported() { + if p := "linux/amd64"; def != p && amd64Supported() == nil { arr = append(arr, p) } - if p := "linux/arm64"; def != p && arm64Supported() { + if p := "linux/arm64"; def != p && arm64Supported() == nil { arr = append(arr, p) } - if !strings.HasPrefix(def, "linux/arm/") && armSupported() { + if !strings.HasPrefix(def, "linux/arm/") && armSupported() == nil { arr = append(arr, "linux/arm/v7", "linux/arm/v6") } else if def == "linux/arm/v7" { arr = append(arr, "linux/arm/v6") } }) - return arr } + +//WarnIfUnsupported validates the platforms and show warning message if there is, +//the end user could fix the issue based on those warning, and thus no need to drop +//the platform from the candidates. +func WarnIfUnsupported(pfs []string) { + def := platforms.DefaultString() + for _, p := range pfs { + if p != def { + if p == "linux/amd64" { + if err := amd64Supported(); err != nil { + printPlatfromWarning(p, err) + } + } + if p == "linux/arm64" { + if err := arm64Supported(); err != nil { + printPlatfromWarning(p, err) + } + } + if strings.HasPrefix(p, "linux/arm/v6") || strings.HasPrefix(p, "linux/arm/v7") { + if err := armSupported(); err != nil { + printPlatfromWarning(p, err) + } + } + } + } +} + +func printPlatfromWarning(p string, err error) { + if strings.Contains(err.Error(), "exec format error") { + logrus.Warnf("platform %s cannot pass the validation, kernel support for miscellaneous binary may have not enabled.", p) + } else if strings.Contains(err.Error(), "no such file or directory") { + logrus.Warnf("platforms %s cannot pass the validation, '-F' flag might have not set for 'binfmt_misc'.", p) + } else { + logrus.Warnf("platforms %s cannot pass the validation: %s", p, err.Error()) + } +}