@@ -27,6 +27,8 @@ import (
27
27
"gotest.tools/v3/assert"
28
28
29
29
"github.com/containerd/containerd/v2/core/mount"
30
+ "github.com/containerd/nerdctl/mod/tigron/expect"
31
+ "github.com/containerd/nerdctl/mod/tigron/test"
30
32
31
33
"github.com/containerd/nerdctl/v2/cmd/nerdctl/helpers"
32
34
"github.com/containerd/nerdctl/v2/pkg/rootlessutil"
@@ -304,68 +306,103 @@ func TestRunBindMountTmpfs(t *testing.T) {
304
306
base .Cmd ("run" , "--rm" , "--mount" , "type=tmpfs,target=/tmp,tmpfs-size=64m" , testutil .AlpineImage , "grep" , "/tmp" , "/proc/mounts" ).AssertOutWithFunc (f ([]string {"rw" , "nosuid" , "nodev" , "size=65536k" }))
305
307
}
306
308
307
- func TestRunBindMountBind (t * testing.T ) {
308
- t .Parallel ()
309
- base := testutil .NewBase (t )
310
- tID := testutil .Identifier (t )
311
- rwDir , err := os .MkdirTemp (t .TempDir (), "rw" )
312
- if err != nil {
313
- t .Fatal (err )
314
- }
315
- roDir , err := os .MkdirTemp (t .TempDir (), "ro" )
316
- if err != nil {
317
- t .Fatal (err )
318
- }
309
+ func mountExistsWithOpt (mountPoint , mountOpt string ) test.Comparator {
310
+ return func (stdout , info string , t * testing.T ) {
311
+ lines := strings .Split (strings .TrimSpace (stdout ), "\n " )
312
+ mountOutput := []string {}
313
+ for _ , line := range lines {
314
+ if strings .Contains (line , mountPoint ) {
315
+ mountOutput = strings .Split (line , " " )
316
+ break
317
+ }
318
+ }
319
319
320
- containerName := tID
321
- defer base .Cmd ("rm" , "-f" , containerName ).AssertOK ()
322
- base .Cmd ("run" ,
323
- "-d" ,
324
- "--name" , containerName ,
325
- "--mount" , fmt .Sprintf ("type=bind,src=%s,target=/mnt1" , rwDir ),
326
- "--mount" , fmt .Sprintf ("type=bind,src=%s,target=/mnt2,ro" , roDir ),
327
- testutil .AlpineImage ,
328
- "top" ,
329
- ).AssertOK ()
330
- base .Cmd ("exec" , containerName , "sh" , "-exc" , "echo -n str1 > /mnt1/file1" ).AssertOK ()
331
- base .Cmd ("exec" , containerName , "sh" , "-exc" , "echo -n str2 > /mnt2/file2" ).AssertFail ()
320
+ assert .Assert (t , len (mountOutput ) > 0 , "we should have found the mount point in /proc/mounts" )
321
+ assert .Assert (t , len (mountOutput ) >= 4 , "invalid format for mount line" )
332
322
333
- base .Cmd ("run" ,
334
- "--rm" ,
335
- "--mount" , fmt .Sprintf ("type=bind,src=%s,target=/mnt1" , rwDir ),
336
- testutil .AlpineImage ,
337
- "cat" , "/mnt1/file1" ,
338
- ).AssertOutExactly ("str1" )
323
+ options := strings .Split (mountOutput [3 ], "," )
339
324
340
- // check `bind-propagation`
341
- f := func (allow string ) func (stdout string ) error {
342
- return func (stdout string ) error {
343
- lines := strings .Split (strings .TrimSpace (stdout ), "\n " )
344
- if len (lines ) != 1 {
345
- return fmt .Errorf ("expected 1 lines, got %q" , stdout )
346
- }
347
- fields := strings .Split (lines [0 ], " " )
348
- if len (fields ) < 4 {
349
- return fmt .Errorf ("invalid /proc/mounts format %q" , stdout )
325
+ found := false
326
+ for _ , opt := range options {
327
+ if mountOpt == opt {
328
+ found = true
329
+ break
350
330
}
331
+ }
332
+
333
+ assert .Assert (t , found , "mount option %s not found" , mountOpt )
334
+ }
335
+ }
351
336
352
- options := strings .Split (fields [3 ], "," )
337
+ func TestRunBindMountBind (t * testing.T ) {
338
+ testCase := nerdtest .Setup ()
339
+
340
+ testCase .Setup = func (data test.Data , helpers test.Helpers ) {
341
+ // Run a container with bind mount directories, one rw, the other ro
342
+ rwDir := data .Temp ().Dir ("rw" )
343
+ roDir := data .Temp ().Dir ("ro" )
344
+
345
+ helpers .Ensure (
346
+ "run" ,
347
+ "-d" ,
348
+ "--name" , data .Identifier ("container" ),
349
+ "--mount" , fmt .Sprintf ("type=bind,src=%s,target=/mntrw" , rwDir ),
350
+ "--mount" , fmt .Sprintf ("type=bind,src=%s,target=/mntro,ro" , roDir ),
351
+ testutil .AlpineImage ,
352
+ "top" ,
353
+ )
354
+
355
+ // Save host rwDir location and container id for subtests
356
+ data .Labels ().Set ("container" , data .Identifier ("container" ))
357
+ data .Labels ().Set ("rwDir" , rwDir )
358
+ }
353
359
354
- found := false
355
- for _ , s := range options {
356
- if allow == s {
357
- found = true
358
- break
360
+ testCase .SubTests = []* test.Case {
361
+ {
362
+ Description : "ensure we cannot write to ro mount" ,
363
+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
364
+ return helpers .Command ("exec" , data .Labels ().Get ("container" ), "sh" , "-exc" , "echo -n failure > /mntro/file" )
365
+ },
366
+ Expected : test .Expects (expect .ExitCodeGenericFail , nil , nil ),
367
+ },
368
+ {
369
+ Description : "ensure we can write to rw, and read it back from another container mounting the same target" ,
370
+ Setup : func (data test.Data , helpers test.Helpers ) {
371
+ helpers .Ensure ("exec" , data .Labels ().Get ("container" ), "sh" , "-exc" , "echo -n success > /mntrw/file" )
372
+ },
373
+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
374
+ return helpers .Command (
375
+ "run" ,
376
+ "--rm" ,
377
+ "--mount" , fmt .Sprintf ("type=bind,src=%s,target=/mntrw" , data .Labels ().Get ("rwDir" )),
378
+ testutil .AlpineImage ,
379
+ "cat" , "/mntrw/file" ,
380
+ )
381
+ },
382
+ Expected : test .Expects (expect .ExitCodeSuccess , nil , expect .Equals ("success" )),
383
+ },
384
+ {
385
+ Description : "Check that mntrw is seen in /proc/mounts" ,
386
+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
387
+ return helpers .Command ("exec" , data .Labels ().Get ("container" ), "cat" , "/proc/mounts" )
388
+ },
389
+ Expected : func (data test.Data , helpers test.Helpers ) * test.Expected {
390
+ return & test.Expected {
391
+ Output : expect .All (
392
+ // Ensure we have mntrw in the mount list
393
+ mountExistsWithOpt ("/mntrw" , "rw" ),
394
+ mountExistsWithOpt ("/mntro" , "ro" ),
395
+ ),
359
396
}
360
- }
361
- if ! found {
362
- return fmt .Errorf ("expected stdout to contain %q, got %+v" , allow , options )
363
- }
364
- return nil
365
- }
397
+ },
398
+ },
366
399
}
367
- base .Cmd ("exec" , containerName , "grep" , "/mnt1" , "/proc/mounts" ).AssertOutWithFunc (f ("rw" ))
368
- base .Cmd ("exec" , containerName , "grep" , "/mnt2" , "/proc/mounts" ).AssertOutWithFunc (f ("ro" ))
400
+
401
+ testCase .Cleanup = func (data test.Data , helpers test.Helpers ) {
402
+ helpers .Anyhow ("rm" , "-f" , data .Identifier ("container" ))
403
+ }
404
+
405
+ testCase .Run (t )
369
406
}
370
407
371
408
func TestRunMountBindMode (t * testing.T ) {
0 commit comments