diff --git a/cmd/buildkitd/main.go b/cmd/buildkitd/main.go index a0fcf729..e5f7d163 100644 --- a/cmd/buildkitd/main.go +++ b/cmd/buildkitd/main.go @@ -407,10 +407,10 @@ func setDefaultConfig(cfg *config.Config) { } if cfg.Workers.OCI.Platforms == nil { - cfg.Workers.OCI.Platforms = archutil.SupportedPlatforms(false) + cfg.Workers.OCI.Platforms = formatPlatforms(archutil.SupportedPlatforms(false)) } if cfg.Workers.Containerd.Platforms == nil { - cfg.Workers.Containerd.Platforms = archutil.SupportedPlatforms(false) + cfg.Workers.Containerd.Platforms = formatPlatforms(archutil.SupportedPlatforms(false)) } cfg.Workers.OCI.NetworkConfig = setDefaultNetworkConfig(cfg.Workers.OCI.NetworkConfig) @@ -700,8 +700,8 @@ func newWorkerController(c *cli.Context, wiOpt workerInitializerOpt) (*worker.Co return nil, err } for _, w := range ws { - p := formatPlatforms(w.Platforms(false)) - logrus.Infof("found worker %q, labels=%v, platforms=%v", w.ID(), w.Labels(), p) + p := w.Platforms(false) + logrus.Infof("found worker %q, labels=%v, platforms=%v", w.ID(), w.Labels(), formatPlatforms(p)) archutil.WarnIfUnsupported(p) if err = wc.Add(w); err != nil { return nil, err diff --git a/solver/llbsolver/ops/exec_binfmt.go b/solver/llbsolver/ops/exec_binfmt.go index 84e44a21..7ac7b922 100644 --- a/solver/llbsolver/ops/exec_binfmt.go +++ b/solver/llbsolver/ops/exec_binfmt.go @@ -91,11 +91,9 @@ func getEmulator(p *pb.Platform, idmap *idtools.IdentityMapping) (*emulator, err Variant: p.Variant, }) - for _, ps := range all { - if p, err := platforms.Parse(ps); err == nil { - if platforms.Only(p).Match(pp) { - return nil, nil - } + for _, p := range all { + if platforms.Only(p).Match(pp) { + return nil, nil } } diff --git a/util/archutil/detect.go b/util/archutil/detect.go index 8b2af3ca..cbc6c408 100644 --- a/util/archutil/detect.go +++ b/util/archutil/detect.go @@ -10,129 +10,105 @@ import ( ) var mu sync.Mutex -var arr []string +var arr []ocispecs.Platform -func SupportedPlatforms(noCache bool) []string { +func SupportedPlatforms(noCache bool) []ocispecs.Platform { 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) + def := nativePlatform() + arr = append([]ocispecs.Platform{}, def) + + if def.OS != "linux" { + return arr } - if p := "linux/arm64"; def != p && arm64Supported() == nil { - arr = append(arr, p) + + if p := "amd64"; def.Architecture != p && amd64Supported() == nil { + arr = append(arr, linux(p)) } - if p := "linux/riscv64"; def != p && riscv64Supported() == nil { - arr = append(arr, p) + if p := "arm64"; def.Architecture != p && arm64Supported() == nil { + arr = append(arr, linux(p)) } - if p := "linux/ppc64le"; def != p && ppc64leSupported() == nil { - arr = append(arr, p) + if p := "riscv64"; def.Architecture != p && riscv64Supported() == nil { + arr = append(arr, linux(p)) } - if p := "linux/s390x"; def != p && s390xSupported() == nil { - arr = append(arr, p) + if p := "ppc64le"; def.Architecture != p && ppc64leSupported() == nil { + arr = append(arr, linux(p)) } - if p := "linux/386"; def != p && i386Supported() == nil { - arr = append(arr, p) + if p := "s390x"; def.Architecture != p && s390xSupported() == nil { + arr = append(arr, linux(p)) } - if p := "linux/mips64le"; def != p && mips64leSupported() == nil { - arr = append(arr, p) + if p := "386"; def.Architecture != p && i386Supported() == nil { + arr = append(arr, linux(p)) } - if p := "linux/mips64"; def != p && mips64Supported() == nil { - arr = append(arr, p) + if p := "mips64le"; def.Architecture != p && mips64leSupported() == nil { + arr = append(arr, linux(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") + if p := "mips64"; def.Architecture != p && mips64Supported() == nil { + arr = append(arr, linux(p)) + } + if p := "arm"; def.Architecture != p && armSupported() == nil { + p := linux("arm") + p.Variant = "v6" + arr = append(arr, linux("arm"), p) + } else if def.Architecture == "arm" && def.Variant == "" { + p := linux("arm") + p.Variant = "v6" + arr = append(arr, p) } return arr } -func Check(pp ocispecs.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 p == "linux/mips64le" && mips64leSupported() == nil { - return true - } - if p == "linux/mips64" && mips64Supported() == 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() +func WarnIfUnsupported(pfs []ocispecs.Platform) { + def := nativePlatform() for _, p := range pfs { - if p != def { - if p == "linux/amd64" { + if p.Architecture != def.Architecture { + if p.Architecture == "amd64" { if err := amd64Supported(); err != nil { printPlatformWarning(p, err) } } - if p == "linux/arm64" { + if p.Architecture == "arm64" { if err := arm64Supported(); err != nil { printPlatformWarning(p, err) } } - if p == "linux/riscv64" { + if p.Architecture == "riscv64" { if err := riscv64Supported(); err != nil { printPlatformWarning(p, err) } } - if p == "linux/ppc64le" { + if p.Architecture == "ppc64le" { if err := ppc64leSupported(); err != nil { printPlatformWarning(p, err) } } - if p == "linux/s390x" { + if p.Architecture == "s390x" { if err := s390xSupported(); err != nil { printPlatformWarning(p, err) } } - if p == "linux/386" { + if p.Architecture == "386" { if err := i386Supported(); err != nil { printPlatformWarning(p, err) } } - if p == "linux/mips64le" { + if p.Architecture == "mips64le" { if err := mips64leSupported(); err != nil { printPlatformWarning(p, err) } } - if p == "linux/mips64" { + if p.Architecture == "mips64" { if err := mips64Supported(); err != nil { printPlatformWarning(p, err) } } - if strings.HasPrefix(p, "linux/arm/v6") || strings.HasPrefix(p, "linux/arm/v7") { + if p.Architecture == "arm" { if err := armSupported(); err != nil { printPlatformWarning(p, err) } @@ -141,16 +117,23 @@ func WarnIfUnsupported(pfs []string) { } } -func defaultPlatform() string { - return platforms.Format(platforms.Normalize(platforms.DefaultSpec())) +func nativePlatform() ocispecs.Platform { + return platforms.Normalize(platforms.DefaultSpec()) } -func printPlatformWarning(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 'archutil'.", p) - } else { - logrus.Warnf("platforms %s cannot pass the validation: %s", p, err.Error()) +func linux(arch string) ocispecs.Platform { + return ocispecs.Platform{ + OS: "linux", + Architecture: arch, + } +} + +func printPlatformWarning(p ocispecs.Platform, 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.", platforms.Format(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 'archutil'.", platforms.Format(p)) + } else { + logrus.Warnf("platforms %s cannot pass the validation: %s", platforms.Format(p), err.Error()) } } diff --git a/worker/base/worker.go b/worker/base/worker.go index 2f2e9d79..6ec311b0 100644 --- a/worker/base/worker.go +++ b/worker/base/worker.go @@ -198,14 +198,16 @@ func (w *Worker) Labels() map[string]string { func (w *Worker) Platforms(noCache bool) []ocispecs.Platform { if noCache { - pm := make(map[string]struct{}, len(w.WorkerOpt.Platforms)) - for _, p := range w.WorkerOpt.Platforms { - pm[platforms.Format(p)] = struct{}{} - } for _, p := range archutil.SupportedPlatforms(noCache) { - if _, ok := pm[p]; !ok { - pp, _ := platforms.Parse(p) - w.WorkerOpt.Platforms = append(w.WorkerOpt.Platforms, pp) + exists := false + for _, pp := range w.WorkerOpt.Platforms { + if platforms.Only(pp).Match(p) { + exists = true + break + } + } + if !exists { + w.WorkerOpt.Platforms = append(w.WorkerOpt.Platforms, p) } } }