@@ -13,6 +13,7 @@ import (
13
13
"github.com/docker/docker/api/types/container"
14
14
"github.com/docker/docker/api/types/network"
15
15
"github.com/docker/docker/api/types/versions"
16
+ "github.com/docker/docker/client"
16
17
ctr "github.com/docker/docker/integration/internal/container"
17
18
"github.com/docker/docker/internal/test/request"
18
19
"github.com/docker/docker/oci"
@@ -225,6 +226,131 @@ func TestCreateWithCustomMaskedPaths(t *testing.T) {
225
226
}
226
227
}
227
228
229
+ func TestCreateWithCapabilities (t * testing.T ) {
230
+ skip .If (t , testEnv .DaemonInfo .OSType == "windows" , "FIXME: test should be able to run on LCOW" )
231
+ skip .If (t , versions .LessThan (testEnv .DaemonAPIVersion (), "1.40" ), "Capabilities was added in API v1.40" )
232
+
233
+ defer setupTest (t )()
234
+ ctx := context .Background ()
235
+ clientNew := request .NewAPIClient (t )
236
+ clientOld := request .NewAPIClient (t , client .WithVersion ("1.39" ))
237
+
238
+ testCases := []struct {
239
+ doc string
240
+ hostConfig container.HostConfig
241
+ expected []string
242
+ expectedError string
243
+ oldClient bool
244
+ }{
245
+ {
246
+ doc : "no capabilities" ,
247
+ hostConfig : container.HostConfig {},
248
+ },
249
+ {
250
+ doc : "empty capabilities" ,
251
+ hostConfig : container.HostConfig {
252
+ Capabilities : []string {},
253
+ },
254
+ expected : []string {},
255
+ },
256
+ {
257
+ doc : "valid capabilities" ,
258
+ hostConfig : container.HostConfig {
259
+ Capabilities : []string {"CAP_NET_RAW" , "CAP_SYS_CHROOT" },
260
+ },
261
+ expected : []string {"CAP_NET_RAW" , "CAP_SYS_CHROOT" },
262
+ },
263
+ {
264
+ doc : "invalid capabilities" ,
265
+ hostConfig : container.HostConfig {
266
+ Capabilities : []string {"NET_RAW" },
267
+ },
268
+ expectedError : `invalid Capabilities: unknown capability: "NET_RAW"` ,
269
+ },
270
+ {
271
+ doc : "duplicate capabilities" ,
272
+ hostConfig : container.HostConfig {
273
+ Capabilities : []string {"CAP_SYS_NICE" , "CAP_SYS_NICE" },
274
+ },
275
+ expected : []string {"CAP_SYS_NICE" , "CAP_SYS_NICE" },
276
+ },
277
+ {
278
+ doc : "capabilities API v1.39" ,
279
+ hostConfig : container.HostConfig {
280
+ Capabilities : []string {"CAP_NET_RAW" , "CAP_SYS_CHROOT" },
281
+ },
282
+ expected : nil ,
283
+ oldClient : true ,
284
+ },
285
+ {
286
+ doc : "empty capadd" ,
287
+ hostConfig : container.HostConfig {
288
+ Capabilities : []string {"CAP_NET_ADMIN" },
289
+ CapAdd : []string {},
290
+ },
291
+ expected : []string {"CAP_NET_ADMIN" },
292
+ },
293
+ {
294
+ doc : "empty capdrop" ,
295
+ hostConfig : container.HostConfig {
296
+ Capabilities : []string {"CAP_NET_ADMIN" },
297
+ CapDrop : []string {},
298
+ },
299
+ expected : []string {"CAP_NET_ADMIN" },
300
+ },
301
+ {
302
+ doc : "capadd capdrop" ,
303
+ hostConfig : container.HostConfig {
304
+ CapAdd : []string {"SYS_NICE" , "CAP_SYS_NICE" },
305
+ CapDrop : []string {"SYS_NICE" , "CAP_SYS_NICE" },
306
+ },
307
+ },
308
+ {
309
+ doc : "conflict with capadd" ,
310
+ hostConfig : container.HostConfig {
311
+ Capabilities : []string {"CAP_NET_ADMIN" },
312
+ CapAdd : []string {"SYS_NICE" },
313
+ },
314
+ expectedError : `conflicting options: Capabilities and CapAdd` ,
315
+ },
316
+ {
317
+ doc : "conflict with capdrop" ,
318
+ hostConfig : container.HostConfig {
319
+ Capabilities : []string {"CAP_NET_ADMIN" },
320
+ CapDrop : []string {"NET_RAW" },
321
+ },
322
+ expectedError : `conflicting options: Capabilities and CapDrop` ,
323
+ },
324
+ }
325
+
326
+ for _ , tc := range testCases {
327
+ tc := tc
328
+ t .Run (tc .doc , func (t * testing.T ) {
329
+ t .Parallel ()
330
+ client := clientNew
331
+ if tc .oldClient {
332
+ client = clientOld
333
+ }
334
+
335
+ c , err := client .ContainerCreate (context .Background (),
336
+ & container.Config {Image : "busybox" },
337
+ & tc .hostConfig ,
338
+ & network.NetworkingConfig {},
339
+ "" ,
340
+ )
341
+ if tc .expectedError == "" {
342
+ assert .NilError (t , err )
343
+ ci , err := client .ContainerInspect (ctx , c .ID )
344
+ assert .NilError (t , err )
345
+ assert .Check (t , ci .HostConfig != nil )
346
+ assert .DeepEqual (t , tc .expected , ci .HostConfig .Capabilities )
347
+ } else {
348
+ assert .ErrorContains (t , err , tc .expectedError )
349
+ }
350
+ })
351
+ }
352
+ }
353
+
228
354
func TestCreateWithCustomReadonlyPaths (t * testing.T ) {
229
355
skip .If (t , testEnv .DaemonInfo .OSType != "linux" )
230
356
0 commit comments