17
17
package podsandbox
18
18
19
19
import (
20
+ "context"
20
21
"os"
21
22
"path/filepath"
22
23
"strconv"
24
+ "syscall"
23
25
"testing"
24
26
25
27
"github.com/moby/sys/userns"
@@ -32,11 +34,15 @@ import (
32
34
v1 "k8s.io/cri-api/pkg/apis/runtime/v1"
33
35
34
36
"github.com/containerd/containerd/v2/internal/cri/annotations"
37
+ criconfig "github.com/containerd/containerd/v2/internal/cri/config"
35
38
"github.com/containerd/containerd/v2/internal/cri/opts"
39
+ "github.com/containerd/containerd/v2/pkg/netns"
36
40
ostesting "github.com/containerd/containerd/v2/pkg/os/testing"
41
+ "github.com/containerd/containerd/v2/pkg/sys"
42
+ "github.com/containerd/containerd/v2/pkg/testutil"
37
43
)
38
44
39
- func getRunPodSandboxTestData () (* runtime.PodSandboxConfig , * imagespec.ImageConfig , func (* testing.T , string , * runtimespec.Spec )) {
45
+ func getRunPodSandboxTestData (criCfg criconfig. Config ) (* runtime.PodSandboxConfig , * imagespec.ImageConfig , func (* testing.T , string , * runtimespec.Spec )) {
40
46
config := & runtime.PodSandboxConfig {
41
47
Metadata : & runtime.PodSandboxMetadata {
42
48
Name : "test-name" ,
@@ -94,7 +100,7 @@ func getRunPodSandboxTestData() (*runtime.PodSandboxConfig, *imagespec.ImageConf
94
100
}
95
101
96
102
assert .Contains (t , spec .Mounts , runtimespec.Mount {
97
- Source : "/test/root/ sandboxes/test-id/resolv.conf" ,
103
+ Source : filepath . Join ( criCfg . RootDir , " sandboxes/test-id/resolv.conf") ,
98
104
Destination : resolvConfPath ,
99
105
Type : "bind" ,
100
106
Options : []string {"rbind" , "ro" , "nosuid" , "nodev" , "noexec" },
@@ -105,8 +111,10 @@ func getRunPodSandboxTestData() (*runtime.PodSandboxConfig, *imagespec.ImageConf
105
111
}
106
112
107
113
func TestLinuxSandboxContainerSpec (t * testing.T ) {
114
+ testutil .RequiresRoot (t )
115
+
108
116
testID := "test-id"
109
- nsPath := "test-cni"
117
+
110
118
idMap := runtime.IDMapping {
111
119
HostId : 1000 ,
112
120
ContainerId : 1000 ,
@@ -118,15 +126,30 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
118
126
Size : 10 ,
119
127
}
120
128
129
+ netnsBasedir := t .TempDir ()
130
+ t .Cleanup (func () {
131
+ assert .NoError (t , unmountRecursive (context .Background (), netnsBasedir ))
132
+ })
133
+
134
+ var netNs * netns.NetNS
135
+ uerr := sys .UnshareAfterEnterUserns ("1000:1000:10" , "1000:1000:10" , syscall .CLONE_NEWNET , func (pid int ) error {
136
+ var err error
137
+ netNs , err = netns .NewNetNSFromPID (netnsBasedir , uint32 (pid ))
138
+ return err
139
+ })
140
+ require .NoError (t , uerr )
141
+
142
+ nsPath := netNs .GetPath ()
143
+
121
144
for _ , test := range []struct {
122
145
desc string
123
146
configChange func (* runtime.PodSandboxConfig )
124
- specCheck func (* testing.T , * runtimespec.Spec )
147
+ specCheck func (* testing.T , * Controller , * runtimespec.Spec )
125
148
expectErr bool
126
149
}{
127
150
{
128
151
desc : "spec should reflect original config" ,
129
- specCheck : func (t * testing.T , spec * runtimespec.Spec ) {
152
+ specCheck : func (t * testing.T , _ * Controller , spec * runtimespec.Spec ) {
130
153
// runtime spec should have expected namespaces enabled by default.
131
154
require .NotNil (t , spec .Linux )
132
155
assert .Contains (t , spec .Linux .Namespaces , runtimespec.LinuxNamespace {
@@ -162,10 +185,11 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
162
185
},
163
186
}
164
187
},
165
- specCheck : func (t * testing.T , spec * runtimespec.Spec ) {
188
+ specCheck : func (t * testing.T , c * Controller , spec * runtimespec.Spec ) {
166
189
require .NotNil (t , spec .Linux )
167
190
assert .Contains (t , spec .Linux .Namespaces , runtimespec.LinuxNamespace {
168
191
Type : runtimespec .UserNamespace ,
192
+ Path : filepath .Join (c .config .StateDir , "sandboxes" , testID , "pinned-namespaces" , "user" ),
169
193
})
170
194
assert .NotContains (t , spec .Linux .Sysctl ["net.ipv4.ping_group_range" ], "0 2147483647" )
171
195
},
@@ -181,7 +205,7 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
181
205
},
182
206
}
183
207
},
184
- specCheck : func (t * testing.T , spec * runtimespec.Spec ) {
208
+ specCheck : func (t * testing.T , _ * Controller , spec * runtimespec.Spec ) {
185
209
// runtime spec should disable expected namespaces in host mode.
186
210
require .NotNil (t , spec .Linux )
187
211
assert .NotContains (t , spec .Linux .Namespaces , runtimespec.LinuxNamespace {
@@ -213,10 +237,11 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
213
237
},
214
238
}
215
239
},
216
- specCheck : func (t * testing.T , spec * runtimespec.Spec ) {
240
+ specCheck : func (t * testing.T , c * Controller , spec * runtimespec.Spec ) {
217
241
require .NotNil (t , spec .Linux )
218
242
assert .Contains (t , spec .Linux .Namespaces , runtimespec.LinuxNamespace {
219
243
Type : runtimespec .UserNamespace ,
244
+ Path : filepath .Join (c .config .StateDir , "sandboxes" , testID , "pinned-namespaces" , "user" ),
220
245
})
221
246
require .Equal (t , spec .Linux .UIDMappings , []runtimespec.LinuxIDMapping {expIDMap })
222
247
require .Equal (t , spec .Linux .GIDMappings , []runtimespec.LinuxIDMapping {expIDMap })
@@ -314,7 +339,7 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
314
339
SupplementalGroups : []int64 {1111 , 2222 },
315
340
}
316
341
},
317
- specCheck : func (t * testing.T , spec * runtimespec.Spec ) {
342
+ specCheck : func (t * testing.T , _ * Controller , spec * runtimespec.Spec ) {
318
343
require .NotNil (t , spec .Process )
319
344
assert .Contains (t , spec .Process .User .AdditionalGids , uint32 (1111 ))
320
345
assert .Contains (t , spec .Process .User .AdditionalGids , uint32 (2222 ))
@@ -328,7 +353,7 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
328
353
"net.ipv4.ping_group_range" : "1 1000" ,
329
354
}
330
355
},
331
- specCheck : func (t * testing.T , spec * runtimespec.Spec ) {
356
+ specCheck : func (t * testing.T , _ * Controller , spec * runtimespec.Spec ) {
332
357
require .NotNil (t , spec .Process )
333
358
assert .Contains (t , spec .Linux .Sysctl ["net.ipv4.ip_unprivileged_port_start" ], "500" )
334
359
assert .Contains (t , spec .Linux .Sysctl ["net.ipv4.ping_group_range" ], "1 1000" )
@@ -344,7 +369,7 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
344
369
MemoryLimitInBytes : 1024 ,
345
370
}
346
371
},
347
- specCheck : func (t * testing.T , spec * runtimespec.Spec ) {
372
+ specCheck : func (t * testing.T , _ * Controller , spec * runtimespec.Spec ) {
348
373
value , ok := spec .Annotations [annotations .SandboxCPUPeriod ]
349
374
assert .True (t , ok )
350
375
assert .EqualValues (t , strconv .FormatInt (100 , 10 ), value )
@@ -365,7 +390,7 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
365
390
},
366
391
{
367
392
desc : "sandbox sizing annotations should not be set if LinuxContainerResources were not provided" ,
368
- specCheck : func (t * testing.T , spec * runtimespec.Spec ) {
393
+ specCheck : func (t * testing.T , _ * Controller , spec * runtimespec.Spec ) {
369
394
_ , ok := spec .Annotations [annotations .SandboxCPUPeriod ]
370
395
assert .False (t , ok )
371
396
_ , ok = spec .Annotations [annotations .SandboxCPUQuota ]
@@ -381,7 +406,7 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
381
406
configChange : func (c * runtime.PodSandboxConfig ) {
382
407
c .Linux .Resources = & v1.LinuxContainerResources {}
383
408
},
384
- specCheck : func (t * testing.T , spec * runtimespec.Spec ) {
409
+ specCheck : func (t * testing.T , _ * Controller , spec * runtimespec.Spec ) {
385
410
value , ok := spec .Annotations [annotations .SandboxCPUPeriod ]
386
411
assert .True (t , ok )
387
412
assert .EqualValues (t , "0" , value )
@@ -400,9 +425,17 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
400
425
test := test
401
426
t .Run (test .desc , func (t * testing.T ) {
402
427
c := newControllerService ()
428
+ c .config .RootDir = t .TempDir ()
429
+ c .config .StateDir = t .TempDir ()
430
+
431
+ defer func () {
432
+ assert .NoError (t , unmountRecursive (context .Background (), c .config .StateDir ))
433
+ }()
434
+
403
435
c .config .EnableUnprivilegedICMP = true
404
436
c .config .EnableUnprivilegedPorts = true
405
- config , imageConfig , specCheck := getRunPodSandboxTestData ()
437
+
438
+ config , imageConfig , specCheck := getRunPodSandboxTestData (c .config )
406
439
if test .configChange != nil {
407
440
test .configChange (config )
408
441
}
@@ -416,7 +449,7 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
416
449
assert .NotNil (t , spec )
417
450
specCheck (t , testID , spec )
418
451
if test .specCheck != nil {
419
- test .specCheck (t , spec )
452
+ test .specCheck (t , c , spec )
420
453
}
421
454
})
422
455
}
@@ -757,6 +790,3 @@ options timeout:1
757
790
})
758
791
}
759
792
}
760
-
761
- // TODO(random-liu): [P1] Add unit test for different error cases to make sure
762
- // the function cleans up on error properly.
0 commit comments