@@ -14,6 +14,7 @@ import (
1414 "github.com/docker/docker/api/types/swarm"
1515 "github.com/docker/docker/api/types/versions"
1616 "github.com/docker/docker/client"
17+ "github.com/docker/docker/oci/caps"
1718 "github.com/docker/swarmkit/api"
1819 "github.com/docker/swarmkit/api/defaults"
1920 gogotypes "github.com/gogo/protobuf/types"
@@ -490,6 +491,7 @@ type serviceOptions struct {
490491 hostname string
491492 env opts.ListOpts
492493 envFile opts.ListOpts
494+ capabilities opts.ListOpts
493495 workdir string
494496 user string
495497 groups opts.ListOpts
@@ -539,6 +541,7 @@ func newServiceOptions() *serviceOptions {
539541 containerLabels : opts .NewListOpts (opts .ValidateLabel ),
540542 env : opts .NewListOpts (opts .ValidateEnv ),
541543 envFile : opts .NewListOpts (nil ),
544+ capabilities : opts .NewListOpts (nil ),
542545 groups : opts .NewListOpts (nil ),
543546 logDriver : newLogDriverOptions (),
544547 dns : opts .NewListOpts (opts .ValidateIPAddress ),
@@ -579,6 +582,44 @@ func (options *serviceOptions) ToStopGracePeriod(flags *pflag.FlagSet) *time.Dur
579582 return nil
580583}
581584
585+ func (options * serviceOptions ) ToCapabilities (flags * pflag.FlagSet ) ([]string , error ) {
586+ if flags .Changed (flagCapAdd ) || flags .Changed (flagCapDrop ) || flags .Changed (flagPrivileged ) {
587+ privileged , err := strconv .ParseBool (flags .Lookup (flagPrivileged ).Value .String ())
588+ if err != nil {
589+ return nil , err
590+ }
591+ capAdd := flags .Lookup (flagCapAdd ).Value .(* opts.ListOpts ).GetAll ()
592+ capDrop := flags .Lookup (flagCapDrop ).Value .(* opts.ListOpts ).GetAll ()
593+
594+ defaultCapabilities := []string {
595+ "CAP_CHOWN" ,
596+ "CAP_DAC_OVERRIDE" ,
597+ "CAP_FSETID" ,
598+ "CAP_FOWNER" ,
599+ "CAP_MKNOD" ,
600+ "CAP_NET_RAW" ,
601+ "CAP_SETGID" ,
602+ "CAP_SETUID" ,
603+ "CAP_SETFCAP" ,
604+ "CAP_SETPCAP" ,
605+ "CAP_NET_BIND_SERVICE" ,
606+ "CAP_SYS_CHROOT" ,
607+ "CAP_KILL" ,
608+ "CAP_AUDIT_WRITE" ,
609+ }
610+ capabilities := []string {}
611+ if privileged || len (capAdd ) > 0 || len (capDrop ) > 0 {
612+ capabilities , err := caps .TweakCapabilities (defaultCapabilities , capAdd , capDrop , nil , privileged )
613+ if err != nil {
614+ return nil , err
615+ }
616+ return capabilities , nil
617+ }
618+ return capabilities , nil
619+ }
620+ return nil , nil
621+ }
622+
582623func (options * serviceOptions ) ToService (ctx context.Context , apiClient client.NetworkAPIClient , flags * pflag.FlagSet ) (swarm.ServiceSpec , error ) {
583624 var service swarm.ServiceSpec
584625
@@ -628,6 +669,11 @@ func (options *serviceOptions) ToService(ctx context.Context, apiClient client.N
628669 return service , err
629670 }
630671
672+ capabilities , err := options .ToCapabilities (flags )
673+ if err != nil {
674+ return service , err
675+ }
676+
631677 service = swarm.ServiceSpec {
632678 Annotations : swarm.Annotations {
633679 Name : options .name ,
@@ -659,6 +705,7 @@ func (options *serviceOptions) ToService(ctx context.Context, apiClient client.N
659705 Healthcheck : healthConfig ,
660706 Isolation : container .Isolation (options .isolation ),
661707 Sysctls : opts .ConvertKVStringsToMap (options .sysctls .GetAll ()),
708+ Capabilities : capabilities ,
662709 },
663710 Networks : networks ,
664711 Resources : resources ,
@@ -841,6 +888,8 @@ const (
841888 flagPlacementPref = "placement-pref"
842889 flagPlacementPrefAdd = "placement-pref-add"
843890 flagPlacementPrefRemove = "placement-pref-rm"
891+ flagCapAdd = "cap-add"
892+ flagCapDrop = "cap-drop"
844893 flagConstraint = "constraint"
845894 flagConstraintRemove = "constraint-rm"
846895 flagConstraintAdd = "constraint-add"
@@ -886,6 +935,7 @@ const (
886935 flagNetwork = "network"
887936 flagNetworkAdd = "network-add"
888937 flagNetworkRemove = "network-rm"
938+ flagPrivileged = "privileged"
889939 flagPublish = "publish"
890940 flagPublishRemove = "publish-rm"
891941 flagPublishAdd = "publish-add"
0 commit comments