@@ -26,7 +26,9 @@ var generateFlags = []cli.Flag{
2626 cli.StringSliceFlag {Name : "cap-drop" , Usage : "drop Linux capabilities" },
2727 cli.StringFlag {Name : "cgroups-path" , Usage : "specify the path to the cgroups" },
2828 cli.StringFlag {Name : "cwd" , Value : "/" , Usage : "current working directory for the process" },
29- cli.StringSliceFlag {Name : "device" , Usage : "specifies a device which must be made available in the container" },
29+ cli.StringSliceFlag {Name : "device-add" , Usage : "add a device which must be made available in the container" },
30+ cli.StringSliceFlag {Name : "device-remove" , Usage : "remove a device which must be made available in the container" },
31+ cli.BoolFlag {Name : "device-remove-all" , Usage : "remove all devices which must be made available in the container" },
3032 cli.BoolFlag {Name : "disable-oom-kill" , Usage : "disable OOM Killer" },
3133 cli.StringSliceFlag {Name : "env" , Usage : "add environment variable e.g. key=value" },
3234 cli.StringSliceFlag {Name : "env-file" , Usage : "read in a file of environment variables" },
@@ -502,15 +504,31 @@ func setupSpec(g *generate.Generator, context *cli.Context) error {
502504 g .ClearProcessRlimits ()
503505 }
504506
505- if context .IsSet ("device" ) {
506- devices := context .StringSlice ("device" )
507+ if context .IsSet ("device-add " ) {
508+ devices := context .StringSlice ("device-add " )
507509 for _ , deviceArg := range devices {
508- err := addDevice (deviceArg , g )
510+ dev , err := parseDevice (deviceArg , g )
509511 if err != nil {
510512 return err
511513 }
514+ g .AddDevice (dev )
512515 }
513516 }
517+
518+ if context .IsSet ("device-remove" ) {
519+ devices := context .StringSlice ("device-remove" )
520+ for _ , device := range devices {
521+ err := g .RemoveDevice (device )
522+ if err != nil {
523+ return err
524+ }
525+ }
526+ }
527+
528+ if context .Bool ("device-remove-all" ) {
529+ g .ClearLinuxDevices ()
530+ }
531+
514532 err := addSeccomp (context , g )
515533 return err
516534}
@@ -642,33 +660,33 @@ var deviceType = map[string]bool{
642660 "p" : true , // a FIFO
643661}
644662
645- // addDevice takes the raw string passed with the --device flag, parses it, and add it
646- func addDevice (device string , g * generate.Generator ) error {
663+ // parseDevice takes the raw string passed with the --device- add flag
664+ func parseDevice (device string , g * generate.Generator ) (rspec. LinuxDevice , error ) {
647665 dev := rspec.LinuxDevice {}
648666
649667 // The required part and optional part are separated by ":"
650668 argsParts := strings .Split (device , ":" )
651669 if len (argsParts ) < 4 {
652- return fmt .Errorf ("Incomplete device arguments: %s" , device )
670+ return dev , fmt .Errorf ("Incomplete device arguments: %s" , device )
653671 }
654672 requiredPart := argsParts [0 :4 ]
655673 optionalPart := argsParts [4 :]
656674
657675 // The required part must contain type, major, minor, and path
658676 dev .Type = requiredPart [0 ]
659677 if ! deviceType [dev .Type ] {
660- return fmt .Errorf ("Invalid device type: %s" , dev .Type )
678+ return dev , fmt .Errorf ("Invalid device type: %s" , dev .Type )
661679 }
662680
663681 i , err := strconv .ParseInt (requiredPart [1 ], 10 , 64 )
664682 if err != nil {
665- return err
683+ return dev , err
666684 }
667685 dev .Major = i
668686
669687 i , err = strconv .ParseInt (requiredPart [2 ], 10 , 64 )
670688 if err != nil {
671- return err
689+ return dev , err
672690 }
673691 dev .Minor = i
674692 dev .Path = requiredPart [3 ]
@@ -678,7 +696,7 @@ func addDevice(device string, g *generate.Generator) error {
678696 parts := strings .SplitN (s , "=" , 2 )
679697
680698 if len (parts ) != 2 {
681- return fmt .Errorf ("Incomplete device arguments: %s" , s )
699+ return dev , fmt .Errorf ("Incomplete device arguments: %s" , s )
682700 }
683701
684702 name , value := parts [0 ], parts [1 ]
@@ -687,33 +705,31 @@ func addDevice(device string, g *generate.Generator) error {
687705 case "fileMode" :
688706 i , err := strconv .ParseInt (value , 10 , 32 )
689707 if err != nil {
690- return err
708+ return dev , err
691709 }
692710 mode := os .FileMode (i )
693711 dev .FileMode = & mode
694712 case "uid" :
695713 i , err := strconv .ParseInt (value , 10 , 32 )
696714 if err != nil {
697- return err
715+ return dev , err
698716 }
699717 uid := uint32 (i )
700718 dev .UID = & uid
701719
702720 case "gid" :
703721 i , err := strconv .ParseInt (value , 10 , 32 )
704722 if err != nil {
705- return err
723+ return dev , err
706724 }
707725 gid := uint32 (i )
708726 dev .GID = & gid
709727 default :
710- return fmt .Errorf ("'%s' is not supported by device section" , name )
728+ return dev , fmt .Errorf ("'%s' is not supported by device section" , name )
711729 }
712730 }
713731
714- g .AddDevice (dev .Path , dev .Type , dev .Major , dev .Minor , dev .FileMode , dev .UID , dev .GID )
715-
716- return nil
732+ return dev , nil
717733}
718734
719735func addSeccomp (context * cli.Context , g * generate.Generator ) error {
0 commit comments