1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
package verifier
import (
"context"
"fmt"
"sort"
"strings"
"github.com/containerd/platforms"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/exporter/containerimage/exptypes"
"github.com/moby/buildkit/solver/result"
"github.com/pkg/errors"
)
func CheckInvalidPlatforms[T comparable](ctx context.Context, res *result.Result[T]) ([]client.VertexWarning, error) {
req, err := getRequestOpts(res)
if err != nil {
return nil, err
}
if req.Request != "" {
return nil, nil
}
if _, ok := res.Metadata[exptypes.ExporterPlatformsKey]; len(res.Refs) > 0 && !ok {
return nil, errors.Errorf("build result contains multiple refs without platforms mapping")
}
isMap := len(res.Refs) > 0
ps, err := exptypes.ParsePlatforms(res.Metadata)
if err != nil {
return nil, err
}
warnings := []client.VertexWarning{}
reqMap := map[string]struct{}{}
reqList := []exptypes.Platform{}
for _, v := range req.Platforms {
p, err := platforms.Parse(v)
if err != nil {
warnings = append(warnings, client.VertexWarning{
Short: []byte(fmt.Sprintf("Invalid platform result requested %q: %s", v, err.Error())),
})
}
p = platforms.Normalize(p)
_, ok := reqMap[platforms.Format(p)]
if ok {
warnings = append(warnings, client.VertexWarning{
Short: []byte(fmt.Sprintf("Duplicate platform result requested %q", v)),
})
}
reqMap[platforms.Format(p)] = struct{}{}
reqList = append(reqList, exptypes.Platform{Platform: p})
}
if len(warnings) > 0 {
return warnings, nil
}
if len(reqMap) == 1 && len(ps.Platforms) == 1 {
pp := platforms.Normalize(ps.Platforms[0].Platform)
if _, ok := reqMap[platforms.Format(pp)]; !ok {
return []client.VertexWarning{{
Short: []byte(fmt.Sprintf("Requested platform %q does not match result platform %q", req.Platforms[0], platforms.Format(pp))),
}}, nil
}
return nil, nil
}
if !isMap && len(reqMap) > 1 {
return []client.VertexWarning{{
Short: []byte("Multiple platforms requested but result is not multi-platform"),
}}, nil
}
mismatch := len(reqMap) != len(ps.Platforms)
if !mismatch {
for _, p := range ps.Platforms {
pp := platforms.Normalize(p.Platform)
if _, ok := reqMap[platforms.Format(pp)]; !ok {
mismatch = true
break
}
}
}
if mismatch {
return []client.VertexWarning{{
Short: []byte(fmt.Sprintf("Requested platforms %s do not match result platforms %s", platformsString(reqList), platformsString(ps.Platforms))),
}}, nil
}
return nil, nil
}
func platformsString(ps []exptypes.Platform) string {
var ss []string
for _, p := range ps {
ss = append(ss, platforms.Format(platforms.Normalize(p.Platform)))
}
sort.Strings(ss)
return strings.Join(ss, ",")
}
|