2020-07-18 16:17:49 +00:00
|
|
|
package archutil
|
2019-02-27 06:55:26 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/containerd/containerd/platforms"
|
2021-07-26 08:53:30 +00:00
|
|
|
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
|
2019-03-05 08:21:06 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
2019-02-27 06:55:26 +00:00
|
|
|
)
|
|
|
|
|
2020-02-25 23:23:34 +00:00
|
|
|
var mu sync.Mutex
|
2019-02-27 06:55:26 +00:00
|
|
|
var arr []string
|
|
|
|
|
2020-02-25 23:23:34 +00:00
|
|
|
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)
|
|
|
|
}
|
2021-02-02 02:54:17 +00:00
|
|
|
if p := "linux/mips64le"; def != p && mips64leSupported() == nil {
|
|
|
|
arr = append(arr, p)
|
|
|
|
}
|
|
|
|
if p := "linux/mips64"; def != p && mips64Supported() == nil {
|
|
|
|
arr = append(arr, p)
|
|
|
|
}
|
2020-02-25 23:23:34 +00:00
|
|
|
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")
|
|
|
|
}
|
2019-02-27 06:55:26 +00:00
|
|
|
return arr
|
|
|
|
}
|
2019-03-05 08:21:06 +00:00
|
|
|
|
2021-07-26 08:53:30 +00:00
|
|
|
func Check(pp ocispecs.Platform) bool {
|
2020-02-25 23:23:34 +00:00
|
|
|
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
|
|
|
|
}
|
2021-02-02 02:54:17 +00:00
|
|
|
if p == "linux/mips64le" && mips64leSupported() == nil {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if p == "linux/mips64" && mips64Supported() == nil {
|
|
|
|
return true
|
|
|
|
}
|
2020-02-25 23:23:34 +00:00
|
|
|
if !strings.HasPrefix(p, "linux/arm/") && armSupported() == nil {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2019-03-05 08:21:06 +00:00
|
|
|
//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) {
|
2019-04-17 23:14:08 +00:00
|
|
|
def := defaultPlatform()
|
2019-03-05 08:21:06 +00:00
|
|
|
for _, p := range pfs {
|
|
|
|
if p != def {
|
|
|
|
if p == "linux/amd64" {
|
|
|
|
if err := amd64Supported(); err != nil {
|
2020-08-17 23:31:02 +00:00
|
|
|
printPlatformWarning(p, err)
|
2019-03-05 08:21:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if p == "linux/arm64" {
|
|
|
|
if err := arm64Supported(); err != nil {
|
2020-08-17 23:31:02 +00:00
|
|
|
printPlatformWarning(p, err)
|
2019-03-05 08:21:06 +00:00
|
|
|
}
|
|
|
|
}
|
2019-06-04 06:21:04 +00:00
|
|
|
if p == "linux/riscv64" {
|
|
|
|
if err := riscv64Supported(); err != nil {
|
2020-08-17 23:31:02 +00:00
|
|
|
printPlatformWarning(p, err)
|
2019-06-04 06:21:04 +00:00
|
|
|
}
|
|
|
|
}
|
2019-07-30 21:55:46 +00:00
|
|
|
if p == "linux/ppc64le" {
|
|
|
|
if err := ppc64leSupported(); err != nil {
|
2020-08-17 23:31:02 +00:00
|
|
|
printPlatformWarning(p, err)
|
2019-07-30 21:55:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if p == "linux/s390x" {
|
|
|
|
if err := s390xSupported(); err != nil {
|
2020-08-17 23:31:02 +00:00
|
|
|
printPlatformWarning(p, err)
|
2019-07-30 21:55:46 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-06 01:03:20 +00:00
|
|
|
if p == "linux/386" {
|
|
|
|
if err := i386Supported(); err != nil {
|
2020-08-17 23:31:02 +00:00
|
|
|
printPlatformWarning(p, err)
|
2019-08-06 01:03:20 +00:00
|
|
|
}
|
|
|
|
}
|
2021-02-02 02:54:17 +00:00
|
|
|
if p == "linux/mips64le" {
|
|
|
|
if err := mips64leSupported(); err != nil {
|
|
|
|
printPlatformWarning(p, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if p == "linux/mips64" {
|
|
|
|
if err := mips64Supported(); err != nil {
|
|
|
|
printPlatformWarning(p, err)
|
|
|
|
}
|
|
|
|
}
|
2019-03-05 08:21:06 +00:00
|
|
|
if strings.HasPrefix(p, "linux/arm/v6") || strings.HasPrefix(p, "linux/arm/v7") {
|
|
|
|
if err := armSupported(); err != nil {
|
2020-08-17 23:31:02 +00:00
|
|
|
printPlatformWarning(p, err)
|
2019-03-05 08:21:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-17 23:14:08 +00:00
|
|
|
func defaultPlatform() string {
|
|
|
|
return platforms.Format(platforms.Normalize(platforms.DefaultSpec()))
|
|
|
|
}
|
|
|
|
|
2020-08-17 23:31:02 +00:00
|
|
|
func printPlatformWarning(p string, err error) {
|
2019-03-05 08:21:06 +00:00
|
|
|
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") {
|
2020-07-18 16:17:49 +00:00
|
|
|
logrus.Warnf("platforms %s cannot pass the validation, '-F' flag might have not set for 'archutil'.", p)
|
2019-03-05 08:21:06 +00:00
|
|
|
} else {
|
|
|
|
logrus.Warnf("platforms %s cannot pass the validation: %s", p, err.Error())
|
|
|
|
}
|
|
|
|
}
|