Skip to content

Commit bbcf564

Browse files
committed
Add windows image platform comparer
Signed-off-by: Lantao Liu <lantaol@google.com>
1 parent c6cb25c commit bbcf564

File tree

4 files changed

+257
-0
lines changed

4 files changed

+257
-0
lines changed

cri.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040

4141
criconfig "github.com/containerd/cri/pkg/config"
4242
"github.com/containerd/cri/pkg/constants"
43+
criplatforms "github.com/containerd/cri/pkg/containerd/platforms"
4344
"github.com/containerd/cri/pkg/server"
4445
)
4546

@@ -89,6 +90,7 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
8990
client, err := containerd.New(
9091
"",
9192
containerd.WithDefaultNamespace(constants.K8sContainerdNamespace),
93+
containerd.WithDefaultPlatform(criplatforms.Default()),
9294
containerd.WithServices(servicesOpts...),
9395
)
9496
if err != nil {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// +build !windows
2+
3+
/*
4+
Copyright The containerd Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package platforms
20+
21+
import (
22+
"github.com/containerd/containerd/platforms"
23+
)
24+
25+
// Default returns the current platform's default platform specification.
26+
func Default() platforms.MatchComparer {
27+
return platforms.Default()
28+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// +build windows
2+
3+
/*
4+
Copyright The containerd Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package platforms
20+
21+
import (
22+
"fmt"
23+
"strconv"
24+
"strings"
25+
26+
"github.com/containerd/containerd/platforms"
27+
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
28+
"golang.org/x/sys/windows"
29+
)
30+
31+
type matchComparer struct {
32+
defaults platforms.Matcher
33+
osVersionPrefix string
34+
}
35+
36+
// Match matches platform with the same windows major, minor
37+
// and build version.
38+
func (m matchComparer) Match(p imagespec.Platform) bool {
39+
if m.defaults.Match(p) {
40+
// TODO(windows): Figure out whether OSVersion is deprecated.
41+
return strings.HasPrefix(p.OSVersion, m.osVersionPrefix)
42+
}
43+
return false
44+
}
45+
46+
// Less sorts matched platforms in front of other platforms.
47+
// For matched platforms, it puts platforms with larger revision
48+
// number in front.
49+
func (m matchComparer) Less(p1, p2 imagespec.Platform) bool {
50+
m1, m2 := m.Match(p1), m.Match(p2)
51+
if m1 && m2 {
52+
r1, r2 := revision(p1.OSVersion), revision(p2.OSVersion)
53+
return r1 > r2
54+
}
55+
return m1 && !m2
56+
}
57+
58+
func revision(v string) int {
59+
parts := strings.Split(v, ".")
60+
if len(parts) < 4 {
61+
return 0
62+
}
63+
r, err := strconv.Atoi(parts[3])
64+
if err != nil {
65+
return 0
66+
}
67+
return r
68+
}
69+
70+
// Default returns the current platform's default platform specification.
71+
func Default() platforms.MatchComparer {
72+
major, minor, build := windows.RtlGetNtVersionNumbers()
73+
return matchComparer{
74+
defaults: platforms.Only(platforms.DefaultSpec()),
75+
osVersionPrefix: fmt.Sprintf("%d.%d.%d", major, minor, build),
76+
}
77+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// +build windows
2+
3+
/*
4+
Copyright The containerd Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package platforms
20+
21+
import (
22+
"sort"
23+
"testing"
24+
25+
"github.com/containerd/containerd/platforms"
26+
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
27+
"github.com/stretchr/testify/assert"
28+
)
29+
30+
func TestMatchComparerMatch(t *testing.T) {
31+
m := matchComparer{
32+
defaults: platforms.Only(imagespec.Platform{
33+
Architecture: "amd64",
34+
OS: "windows",
35+
}),
36+
osVersionPrefix: "10.0.17763",
37+
}
38+
for _, test := range []struct {
39+
platform imagespec.Platform
40+
match bool
41+
}{
42+
{
43+
platform: imagespec.Platform{
44+
Architecture: "amd64",
45+
OS: "windows",
46+
OSVersion: "10.0.17763.1",
47+
},
48+
match: true,
49+
},
50+
{
51+
platform: imagespec.Platform{
52+
Architecture: "amd64",
53+
OS: "windows",
54+
OSVersion: "10.0.17763.2",
55+
},
56+
match: true,
57+
},
58+
{
59+
platform: imagespec.Platform{
60+
Architecture: "amd64",
61+
OS: "windows",
62+
OSVersion: "10.0.17762.1",
63+
},
64+
match: false,
65+
},
66+
{
67+
platform: imagespec.Platform{
68+
Architecture: "amd64",
69+
OS: "windows",
70+
OSVersion: "10.0.17764.1",
71+
},
72+
match: false,
73+
},
74+
{
75+
platform: imagespec.Platform{
76+
Architecture: "amd64",
77+
OS: "windows",
78+
},
79+
match: false,
80+
},
81+
} {
82+
assert.Equal(t, test.match, m.Match(test.platform))
83+
}
84+
}
85+
86+
func TestMatchComparerLess(t *testing.T) {
87+
m := matchComparer{
88+
defaults: platforms.Only(imagespec.Platform{
89+
Architecture: "amd64",
90+
OS: "windows",
91+
}),
92+
osVersionPrefix: "10.0.17763",
93+
}
94+
platforms := []imagespec.Platform{
95+
{
96+
Architecture: "amd64",
97+
OS: "windows",
98+
OSVersion: "10.0.17764.1",
99+
},
100+
{
101+
Architecture: "amd64",
102+
OS: "windows",
103+
},
104+
{
105+
Architecture: "amd64",
106+
OS: "windows",
107+
OSVersion: "10.0.17763.1",
108+
},
109+
{
110+
Architecture: "amd64",
111+
OS: "windows",
112+
OSVersion: "10.0.17763.2",
113+
},
114+
{
115+
Architecture: "amd64",
116+
OS: "windows",
117+
OSVersion: "10.0.17762.1",
118+
},
119+
}
120+
expected := []imagespec.Platform{
121+
{
122+
Architecture: "amd64",
123+
OS: "windows",
124+
OSVersion: "10.0.17763.2",
125+
},
126+
{
127+
Architecture: "amd64",
128+
OS: "windows",
129+
OSVersion: "10.0.17763.1",
130+
},
131+
{
132+
Architecture: "amd64",
133+
OS: "windows",
134+
OSVersion: "10.0.17764.1",
135+
},
136+
{
137+
Architecture: "amd64",
138+
OS: "windows",
139+
},
140+
{
141+
Architecture: "amd64",
142+
OS: "windows",
143+
OSVersion: "10.0.17762.1",
144+
},
145+
}
146+
sort.SliceStable(platforms, func(i, j int) bool {
147+
return m.Less(platforms[i], platforms[j])
148+
})
149+
assert.Equal(t, expected, platforms)
150+
}

0 commit comments

Comments
 (0)