| package archutil |
| |
| 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 { |
| printPlatformWarning(p, err) |
| } |
| } |
| if p == "linux/arm64" { |
| if err := arm64Supported(); err != nil { |
| printPlatformWarning(p, err) |
| } |
| } |
| if p == "linux/riscv64" { |
| if err := riscv64Supported(); err != nil { |
| printPlatformWarning(p, err) |
| } |
| } |
| if p == "linux/ppc64le" { |
| if err := ppc64leSupported(); err != nil { |
| printPlatformWarning(p, err) |
| } |
| } |
| if p == "linux/s390x" { |
| if err := s390xSupported(); err != nil { |
| printPlatformWarning(p, err) |
| } |
| } |
| if p == "linux/386" { |
| if err := i386Supported(); err != nil { |
| printPlatformWarning(p, err) |
| } |
| } |
| if strings.HasPrefix(p, "linux/arm/v6") || strings.HasPrefix(p, "linux/arm/v7") { |
| if err := armSupported(); err != nil { |
| printPlatformWarning(p, err) |
| } |
| } |
| } |
| } |
| } |
| |
| func defaultPlatform() string { |
| return platforms.Format(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()) |
| } |
| } |