Merge pull request #8778 from kiashok/stableABI_WindowsMatcher

Invoke stable ABI compliant platform check in windows matcher
This commit is contained in:
Fu Wei 2023-08-16 19:14:22 +08:00 committed by GitHub
commit a3c68d161f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 153 additions and 3 deletions

View File

@ -164,7 +164,7 @@ func ReceiveStream(ctx context.Context, stream streaming.Stream) io.Reader {
} }
anyType, err := stream.Recv() anyType, err := stream.Recv()
if err != nil { if err != nil {
if errors.Is(err, io.EOF) { if errors.Is(err, io.EOF) || errors.Is(err, context.Canceled) {
err = nil err = nil
} else { } else {
err = fmt.Errorf("received failed: %w", err) err = fmt.Errorf("received failed: %w", err)

View File

@ -22,6 +22,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/Microsoft/hcsshim/osversion"
specs "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/image-spec/specs-go/v1"
"golang.org/x/sys/windows" "golang.org/x/sys/windows"
) )
@ -50,15 +51,36 @@ func (m windowsmatcher) Match(p specs.Platform) bool {
match := m.defaultMatcher.Match(p) match := m.defaultMatcher.Match(p)
if match && m.OS == "windows" { if match && m.OS == "windows" {
if strings.HasPrefix(p.OSVersion, m.osVersionPrefix) { // HPC containers do not have OS version filled
if p.OSVersion == "" {
return true return true
} }
return p.OSVersion == ""
hostOsVersion := GetOsVersion(m.osVersionPrefix)
ctrOsVersion := GetOsVersion(p.OSVersion)
return osversion.CheckHostAndContainerCompat(hostOsVersion, ctrOsVersion)
} }
return match return match
} }
func GetOsVersion(osVersionPrefix string) osversion.OSVersion {
parts := strings.Split(osVersionPrefix, ".")
if len(parts) < 3 {
return osversion.OSVersion{}
}
majorVersion, _ := strconv.Atoi(parts[0])
minorVersion, _ := strconv.Atoi(parts[1])
buildNumber, _ := strconv.Atoi(parts[2])
return osversion.OSVersion{
MajorVersion: uint8(majorVersion),
MinorVersion: uint8(minorVersion),
Build: uint16(buildNumber),
}
}
// Less sorts matched platforms in front of other platforms. // Less sorts matched platforms in front of other platforms.
// For matched platforms, it puts platforms with larger revision // For matched platforms, it puts platforms with larger revision
// number in front. // number in front.

View File

@ -142,6 +142,110 @@ func TestMatchComparerMatch_WCOW(t *testing.T) {
} }
} }
// TestMatchComparerMatch_ABICheckWCOW checks windows platform matcher
// behavior for stable ABI and non-stable ABI compliant versions
func TestMatchComparerMatch_ABICheckWCOW(t *testing.T) {
platformWS2019 := imagespec.Platform{
Architecture: "amd64",
OS: "windows",
OSVersion: "10.0.17763",
}
platformWS2022 := imagespec.Platform{
Architecture: "amd64",
OS: "windows",
OSVersion: "10.0.20348",
}
platformWindows11 := imagespec.Platform{
Architecture: "amd64",
OS: "windows",
OSVersion: "10.0.22621",
}
matcherWS2019 := windowsmatcher{
Platform: platformWS2019,
osVersionPrefix: platformWS2019.OSVersion,
defaultMatcher: &matcher{
Platform: Normalize(platformWS2019),
},
}
matcherWS2022 := windowsmatcher{
Platform: platformWS2022,
osVersionPrefix: platformWS2022.OSVersion,
defaultMatcher: &matcher{
Platform: Normalize(platformWS2022),
},
}
matcherWindows11 := windowsmatcher{
Platform: platformWindows11,
osVersionPrefix: platformWindows11.OSVersion,
defaultMatcher: &matcher{
Platform: Normalize(platformWindows11),
},
}
for _, test := range []struct {
hostPlatformMatcher windowsmatcher
testPlatform imagespec.Platform
match bool
}{
{
hostPlatformMatcher: matcherWS2019,
testPlatform: imagespec.Platform{
Architecture: "amd64",
OS: "windows",
OSVersion: "10.0.17763",
},
match: true,
},
{
hostPlatformMatcher: matcherWS2019,
testPlatform: imagespec.Platform{
Architecture: "amd64",
OS: "windows",
OSVersion: "10.0.20348",
},
match: false,
},
{
hostPlatformMatcher: matcherWS2022,
testPlatform: imagespec.Platform{
Architecture: "amd64",
OS: "windows",
OSVersion: "10.0.17763",
},
match: false,
},
{
hostPlatformMatcher: matcherWS2022,
testPlatform: imagespec.Platform{
Architecture: "amd64",
OS: "windows",
OSVersion: "10.0.20348",
},
match: true,
},
{
hostPlatformMatcher: matcherWindows11,
testPlatform: imagespec.Platform{
Architecture: "amd64",
OS: "windows",
OSVersion: "10.0.17763",
},
match: false,
},
{
hostPlatformMatcher: matcherWindows11,
testPlatform: imagespec.Platform{
Architecture: "amd64",
OS: "windows",
OSVersion: "10.0.20348",
},
match: true,
},
} {
assert.Equal(t, test.match, test.hostPlatformMatcher.Match(test.testPlatform), "should match: %t, %s to %s", test.match, test.hostPlatformMatcher.Platform, test.testPlatform)
}
}
func TestMatchComparerMatch_LCOW(t *testing.T) { func TestMatchComparerMatch_LCOW(t *testing.T) {
major, minor, build := windows.RtlGetNtVersionNumbers() major, minor, build := windows.RtlGetNtVersionNumbers()
buildStr := fmt.Sprintf("%d.%d.%d", major, minor, build) buildStr := fmt.Sprintf("%d.%d.%d", major, minor, build)

View File

@ -213,6 +213,10 @@ func Parse(specifier string) (specs.Platform, error) {
p.Variant = cpuVariant() p.Variant = cpuVariant()
} }
if p.OS == "windows" {
p.OSVersion = GetWindowsOsVersion()
}
return p, nil return p, nil
} }
@ -235,6 +239,10 @@ func Parse(specifier string) (specs.Platform, error) {
p.Variant = "" p.Variant = ""
} }
if p.OS == "windows" {
p.OSVersion = GetWindowsOsVersion()
}
return p, nil return p, nil
case 3: case 3:
// we have a fully specified variant, this is rare // we have a fully specified variant, this is rare
@ -244,6 +252,10 @@ func Parse(specifier string) (specs.Platform, error) {
p.Variant = "v8" p.Variant = "v8"
} }
if p.OS == "windows" {
p.OSVersion = GetWindowsOsVersion()
}
return p, nil return p, nil
} }

View File

@ -28,3 +28,7 @@ func newDefaultMatcher(platform specs.Platform) Matcher {
Platform: Normalize(platform), Platform: Normalize(platform),
} }
} }
func GetWindowsOsVersion() string {
return ""
}

View File

@ -17,7 +17,10 @@
package platforms package platforms
import ( import (
"fmt"
specs "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/image-spec/specs-go/v1"
"golang.org/x/sys/windows"
) )
// NewMatcher returns a Windows matcher that will match on osVersionPrefix if // NewMatcher returns a Windows matcher that will match on osVersionPrefix if
@ -32,3 +35,8 @@ func newDefaultMatcher(platform specs.Platform) Matcher {
}, },
} }
} }
func GetWindowsOsVersion() string {
major, minor, build := windows.RtlGetNtVersionNumbers()
return fmt.Sprintf("%d.%d.%d", major, minor, build)
}