|
19 | 19 | package platforms |
20 | 20 |
|
21 | 21 | import ( |
| 22 | + "fmt" |
22 | 23 | "runtime" |
| 24 | + "strconv" |
| 25 | + "strings" |
23 | 26 |
|
| 27 | + imagespec "github.com/opencontainers/image-spec/specs-go/v1" |
24 | 28 | specs "github.com/opencontainers/image-spec/specs-go/v1" |
| 29 | + "golang.org/x/sys/windows" |
25 | 30 | ) |
26 | 31 |
|
27 | | -// Default returns the default matcher for the platform. |
| 32 | +type matchComparer struct { |
| 33 | + defaults Matcher |
| 34 | + osVersionPrefix string |
| 35 | +} |
| 36 | + |
| 37 | +// Match matches platform with the same windows major, minor |
| 38 | +// and build version. |
| 39 | +func (m matchComparer) Match(p imagespec.Platform) bool { |
| 40 | + if m.defaults.Match(p) { |
| 41 | + // TODO(windows): Figure out whether OSVersion is deprecated. |
| 42 | + return strings.HasPrefix(p.OSVersion, m.osVersionPrefix) |
| 43 | + } |
| 44 | + return false |
| 45 | +} |
| 46 | + |
| 47 | +// Less sorts matched platforms in front of other platforms. |
| 48 | +// For matched platforms, it puts platforms with larger revision |
| 49 | +// number in front. |
| 50 | +func (m matchComparer) Less(p1, p2 imagespec.Platform) bool { |
| 51 | + m1, m2 := m.Match(p1), m.Match(p2) |
| 52 | + if m1 && m2 { |
| 53 | + r1, r2 := revision(p1.OSVersion), revision(p2.OSVersion) |
| 54 | + return r1 > r2 |
| 55 | + } |
| 56 | + return m1 && !m2 |
| 57 | +} |
| 58 | + |
| 59 | +func revision(v string) int { |
| 60 | + parts := strings.Split(v, ".") |
| 61 | + if len(parts) < 4 { |
| 62 | + return 0 |
| 63 | + } |
| 64 | + r, err := strconv.Atoi(parts[3]) |
| 65 | + if err != nil { |
| 66 | + return 0 |
| 67 | + } |
| 68 | + return r |
| 69 | +} |
| 70 | + |
| 71 | +// Default returns the current platform's default platform specification. |
28 | 72 | func Default() MatchComparer { |
29 | | - return Ordered(DefaultSpec(), specs.Platform{ |
30 | | - OS: "linux", |
31 | | - Architecture: runtime.GOARCH, |
32 | | - }) |
| 73 | + major, minor, build := windows.RtlGetNtVersionNumbers() |
| 74 | + return matchComparer{ |
| 75 | + defaults: Ordered(DefaultSpec(), specs.Platform{ |
| 76 | + OS: "linux", |
| 77 | + Architecture: runtime.GOARCH, |
| 78 | + }), |
| 79 | + osVersionPrefix: fmt.Sprintf("%d.%d.%d", major, minor, build), |
| 80 | + } |
33 | 81 | } |
0 commit comments