package binfmt_misc import ( "strings" "sync" "github.com/containerd/containerd/platforms" specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" ) var mu sync.Mutex var arr []string func SupportedPlatforms(noCache bool) []string { mu.Lock() defer mu.Unlock() if !noCache && arr != nil { return arr } def := defaultPlatform() arr = append([]string{}, def) if p := "linux/amd64"; def != p && amd64Supported() == nil { arr = append(arr, p) } if p := "linux/arm64"; def != p && arm64Supported() == nil { arr = append(arr, p) } if p := "linux/riscv64"; def != p && riscv64Supported() == nil { arr = append(arr, p) } if p := "linux/ppc64le"; def != p && ppc64leSupported() == nil { arr = append(arr, p) } if p := "linux/s390x"; def != p && s390xSupported() == nil { arr = append(arr, p) } if p := "linux/386"; def != p && i386Supported() == nil { arr = append(arr, p) } 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 } func Check(pp specs.Platform) bool { p := platforms.Format(pp) if p == "linux/amd64" && amd64Supported() == nil { return true } if p == "linux/arm64" && arm64Supported() == nil { return true } if p == "linux/riscv64" && riscv64Supported() == nil { return true } if p == "linux/ppc64le" && ppc64leSupported() == nil { return true } if p == "linux/s390x" && s390xSupported() == nil { return true } if p == "linux/386" && i386Supported() == nil { return true } if !strings.HasPrefix(p, "linux/arm/") && armSupported() == nil { return true } return false } //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 := defaultPlatform() 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 p == "linux/riscv64" { if err := riscv64Supported(); err != nil { printPlatfromWarning(p, err) } } if p == "linux/ppc64le" { if err := ppc64leSupported(); err != nil { printPlatfromWarning(p, err) } } if p == "linux/s390x" { if err := s390xSupported(); err != nil { printPlatfromWarning(p, err) } } if p == "linux/386" { if err := i386Supported(); 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 defaultPlatform() string { return platforms.Format(platforms.Normalize(platforms.DefaultSpec())) } 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()) } }