Merge pull request #5298 from jsturtevant/issue-5297
Support multi-arch images for Windows via ctr
This commit is contained in:
		@@ -19,59 +19,10 @@
 | 
				
			|||||||
package platforms
 | 
					package platforms
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/containerd/containerd/platforms"
 | 
						"github.com/containerd/containerd/platforms"
 | 
				
			||||||
	imagespec "github.com/opencontainers/image-spec/specs-go/v1"
 | 
					 | 
				
			||||||
	"golang.org/x/sys/windows"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type matchComparer struct {
 | 
					 | 
				
			||||||
	defaults        platforms.Matcher
 | 
					 | 
				
			||||||
	osVersionPrefix string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Match matches platform with the same windows major, minor
 | 
					 | 
				
			||||||
// and build version.
 | 
					 | 
				
			||||||
func (m matchComparer) Match(p imagespec.Platform) bool {
 | 
					 | 
				
			||||||
	if m.defaults.Match(p) {
 | 
					 | 
				
			||||||
		// TODO(windows): Figure out whether OSVersion is deprecated.
 | 
					 | 
				
			||||||
		return strings.HasPrefix(p.OSVersion, m.osVersionPrefix)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Less sorts matched platforms in front of other platforms.
 | 
					 | 
				
			||||||
// For matched platforms, it puts platforms with larger revision
 | 
					 | 
				
			||||||
// number in front.
 | 
					 | 
				
			||||||
func (m matchComparer) Less(p1, p2 imagespec.Platform) bool {
 | 
					 | 
				
			||||||
	m1, m2 := m.Match(p1), m.Match(p2)
 | 
					 | 
				
			||||||
	if m1 && m2 {
 | 
					 | 
				
			||||||
		r1, r2 := revision(p1.OSVersion), revision(p2.OSVersion)
 | 
					 | 
				
			||||||
		return r1 > r2
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return m1 && !m2
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func revision(v string) int {
 | 
					 | 
				
			||||||
	parts := strings.Split(v, ".")
 | 
					 | 
				
			||||||
	if len(parts) < 4 {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	r, err := strconv.Atoi(parts[3])
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return r
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Default returns the current platform's default platform specification.
 | 
					// Default returns the current platform's default platform specification.
 | 
				
			||||||
func Default() platforms.MatchComparer {
 | 
					func Default() platforms.MatchComparer {
 | 
				
			||||||
	major, minor, build := windows.RtlGetNtVersionNumbers()
 | 
						return platforms.Default()
 | 
				
			||||||
	return matchComparer{
 | 
					 | 
				
			||||||
		defaults:        platforms.Only(platforms.DefaultSpec()),
 | 
					 | 
				
			||||||
		osVersionPrefix: fmt.Sprintf("%d.%d.%d", major, minor, build),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,15 +19,63 @@
 | 
				
			|||||||
package platforms
 | 
					package platforms
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						imagespec "github.com/opencontainers/image-spec/specs-go/v1"
 | 
				
			||||||
	specs "github.com/opencontainers/image-spec/specs-go/v1"
 | 
						specs "github.com/opencontainers/image-spec/specs-go/v1"
 | 
				
			||||||
 | 
						"golang.org/x/sys/windows"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Default returns the default matcher for the platform.
 | 
					type matchComparer struct {
 | 
				
			||||||
 | 
						defaults        Matcher
 | 
				
			||||||
 | 
						osVersionPrefix string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Match matches platform with the same windows major, minor
 | 
				
			||||||
 | 
					// and build version.
 | 
				
			||||||
 | 
					func (m matchComparer) Match(p imagespec.Platform) bool {
 | 
				
			||||||
 | 
						if m.defaults.Match(p) {
 | 
				
			||||||
 | 
							// TODO(windows): Figure out whether OSVersion is deprecated.
 | 
				
			||||||
 | 
							return strings.HasPrefix(p.OSVersion, m.osVersionPrefix)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Less sorts matched platforms in front of other platforms.
 | 
				
			||||||
 | 
					// For matched platforms, it puts platforms with larger revision
 | 
				
			||||||
 | 
					// number in front.
 | 
				
			||||||
 | 
					func (m matchComparer) Less(p1, p2 imagespec.Platform) bool {
 | 
				
			||||||
 | 
						m1, m2 := m.Match(p1), m.Match(p2)
 | 
				
			||||||
 | 
						if m1 && m2 {
 | 
				
			||||||
 | 
							r1, r2 := revision(p1.OSVersion), revision(p2.OSVersion)
 | 
				
			||||||
 | 
							return r1 > r2
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return m1 && !m2
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func revision(v string) int {
 | 
				
			||||||
 | 
						parts := strings.Split(v, ".")
 | 
				
			||||||
 | 
						if len(parts) < 4 {
 | 
				
			||||||
 | 
							return 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						r, err := strconv.Atoi(parts[3])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return r
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Default returns the current platform's default platform specification.
 | 
				
			||||||
func Default() MatchComparer {
 | 
					func Default() MatchComparer {
 | 
				
			||||||
	return Ordered(DefaultSpec(), specs.Platform{
 | 
						major, minor, build := windows.RtlGetNtVersionNumbers()
 | 
				
			||||||
 | 
						return matchComparer{
 | 
				
			||||||
 | 
							defaults: Ordered(DefaultSpec(), specs.Platform{
 | 
				
			||||||
			OS:           "linux",
 | 
								OS:           "linux",
 | 
				
			||||||
			Architecture: runtime.GOARCH,
 | 
								Architecture: runtime.GOARCH,
 | 
				
			||||||
	})
 | 
							}),
 | 
				
			||||||
 | 
							osVersionPrefix: fmt.Sprintf("%d.%d.%d", major, minor, build),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,14 +22,13 @@ import (
 | 
				
			|||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/containerd/containerd/platforms"
 | 
					 | 
				
			||||||
	imagespec "github.com/opencontainers/image-spec/specs-go/v1"
 | 
						imagespec "github.com/opencontainers/image-spec/specs-go/v1"
 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestMatchComparerMatch(t *testing.T) {
 | 
					func TestMatchComparerMatch(t *testing.T) {
 | 
				
			||||||
	m := matchComparer{
 | 
						m := matchComparer{
 | 
				
			||||||
		defaults: platforms.Only(imagespec.Platform{
 | 
							defaults: Only(imagespec.Platform{
 | 
				
			||||||
			Architecture: "amd64",
 | 
								Architecture: "amd64",
 | 
				
			||||||
			OS:           "windows",
 | 
								OS:           "windows",
 | 
				
			||||||
		}),
 | 
							}),
 | 
				
			||||||
@@ -85,7 +84,7 @@ func TestMatchComparerMatch(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestMatchComparerLess(t *testing.T) {
 | 
					func TestMatchComparerLess(t *testing.T) {
 | 
				
			||||||
	m := matchComparer{
 | 
						m := matchComparer{
 | 
				
			||||||
		defaults: platforms.Only(imagespec.Platform{
 | 
							defaults: Only(imagespec.Platform{
 | 
				
			||||||
			Architecture: "amd64",
 | 
								Architecture: "amd64",
 | 
				
			||||||
			OS:           "windows",
 | 
								OS:           "windows",
 | 
				
			||||||
		}),
 | 
							}),
 | 
				
			||||||
		Reference in New Issue
	
	Block a user