@@ -440,3 +440,79 @@ func TestCreateServiceSysctls(t *testing.T) {
440440 )
441441 }
442442}
443+
444+ // TestServiceCreateCapabilities tests that a service created with capabilities options in
445+ // the ContainerSpec correctly applies those options.
446+ //
447+ // To test this, we're going to create a service with the capabilities option
448+ //
449+ // []string{"CAP_NET_RAW", "CAP_SYS_CHROOT"}
450+ //
451+ // We'll get the service's tasks to get the container ID, and then we'll
452+ // inspect the container. If the output of the container inspect contains the
453+ // capabilities option with the correct value, we can assume that the capabilities has been
454+ // plumbed correctly.
455+ func TestCreateServiceCapabilities (t * testing.T ) {
456+ skip .If (
457+ t , versions .LessThan (testEnv .DaemonAPIVersion (), "1.41" ),
458+ "setting service capabilities is unsupported before api v1.41" ,
459+ )
460+
461+ defer setupTest (t )()
462+ d := swarm .NewSwarm (t , testEnv )
463+ defer d .Stop (t )
464+ client := d .NewClientT (t )
465+ defer client .Close ()
466+
467+ ctx := context .Background ()
468+
469+ // store the map we're going to be using everywhere.
470+ expectedCapabilities := []string {"CAP_NET_RAW" , "CAP_SYS_CHROOT" }
471+
472+ // Create the service with the capabilities options
473+ var instances uint64 = 1
474+ serviceID := swarm .CreateService (t , d ,
475+ swarm .ServiceWithCapabilities (expectedCapabilities ),
476+ )
477+
478+ // wait for the service to converge to 1 running task as expected
479+ poll .WaitOn (t , swarm .RunningTasksCount (client , serviceID , instances ))
480+
481+ // we're going to check 3 things:
482+ //
483+ // 1. Does the container, when inspected, have the capabilities option set?
484+ // 2. Does the task have the capabilities in the spec?
485+ // 3. Does the service have the capabilities in the spec?
486+ //
487+ // if all 3 of these things are true, we know that the capabilities has been
488+ // plumbed correctly through the engine.
489+ //
490+ // We don't actually have to get inside the container and check its
491+ // logs or anything. If we see the capabilities set on the container inspect,
492+ // we know that the capabilities is plumbed correctly. everything below that
493+ // level has been tested elsewhere.
494+
495+ // get all of the tasks of the service, so we can get the container
496+ filter := filters .NewArgs ()
497+ filter .Add ("service" , serviceID )
498+ tasks , err := client .TaskList (ctx , types.TaskListOptions {
499+ Filters : filter ,
500+ })
501+ assert .NilError (t , err )
502+ assert .Check (t , is .Equal (len (tasks ), 1 ))
503+
504+ // verify that the container has the capabilities option set
505+ ctnr , err := client .ContainerInspect (ctx , tasks [0 ].Status .ContainerStatus .ContainerID )
506+ assert .NilError (t , err )
507+ assert .DeepEqual (t , ctnr .HostConfig .Capabilities , expectedCapabilities )
508+
509+ // verify that the task has the capabilities option set in the task object
510+ assert .DeepEqual (t , tasks [0 ].Spec .ContainerSpec .Capabilities , expectedCapabilities )
511+
512+ // verify that the service also has the capabilities set in the spec.
513+ service , _ , err := client .ServiceInspectWithRaw (ctx , serviceID , types.ServiceInspectOptions {})
514+ assert .NilError (t , err )
515+ assert .DeepEqual (t ,
516+ service .Spec .TaskTemplate .ContainerSpec .Capabilities , expectedCapabilities ,
517+ )
518+ }
0 commit comments