Skip to content

Commit

Permalink
Service cap-add/cap-drop: add special "RESET" value
Browse files Browse the repository at this point in the history
This implements a special "RESET" value that can be used to reset the
list of capabilities to add/drop when updating a service.

Given the following service;

| CapDrop        | CapAdd        |
| -------------- | ------------- |
| CAP_SOME_CAP   |               |

When updating the service, and applying `--cap-drop RESET`, the "drop" list
is reset to its default:

| CapDrop        | CapAdd        |
| -------------- | ------------- |
|                |               |

When updating the service, and applying `--cap-drop RESET`, combined with
`--cap-add CAP_SOME_CAP` and `--cap-drop CAP_SOME_OTHER_CAP`:

| CapDrop        | CapAdd        |
| -------------- | ------------- |
| CAP_FOO_CAP    | CAP_SOME_CAP  |

Signed-off-by: Sebastiaan van Stijn <[email protected]>
  • Loading branch information
thaJeztah committed Aug 27, 2020
1 parent e926f01 commit 10b529e
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 deletions.
8 changes: 8 additions & 0 deletions cli/command/service/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -1411,9 +1411,17 @@ func updateCapabilities(flags *pflag.FlagSet, containerSpec *swarm.ContainerSpec
)
if flags.Changed(flagCapAdd) {
toAdd = opts.CapabilitiesMap(flags.Lookup(flagCapAdd).Value.(*opts.ListOpts).GetAll())
if toAdd[opts.ResetCapabilities] {
capAdd = make(map[string]bool)
delete(toAdd, opts.ResetCapabilities)
}
}
if flags.Changed(flagCapDrop) {
toDrop = opts.CapabilitiesMap(flags.Lookup(flagCapDrop).Value.(*opts.ListOpts).GetAll())
if toDrop[opts.ResetCapabilities] {
capDrop = make(map[string]bool)
delete(toDrop, opts.ResetCapabilities)
}
}

// First remove the capabilities to "drop" from the service's exiting
Expand Down
20 changes: 20 additions & 0 deletions cli/command/service/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1469,6 +1469,26 @@ func TestUpdateCaps(t *testing.T) {
expectedAdd: []string{"CAP_AAA", "CAP_BBB", "CAP_CCC", "CAP_DDD"},
expectedDrop: []string{"CAP_WWW", "CAP_XXX", "CAP_YYY", "CAP_ZZZ"},
},
{
name: "Reset capabilities",
flagAdd: []string{"RESET"},
flagDrop: []string{"RESET"},
spec: &swarm.ContainerSpec{
CapabilityAdd: []string{"CAP_AAA", "CAP_BBB", "CAP_CCC", "CAP_DDD"},
CapabilityDrop: []string{"CAP_WWW", "CAP_XXX", "CAP_YYY", "CAP_ZZZ"},
},
},
{
name: "Reset capabilities, and update after",
flagAdd: []string{"RESET", "CAP_ADD_ONE", "CAP_FOO"},
flagDrop: []string{"RESET", "CAP_DROP_ONE", "CAP_FOO"},
spec: &swarm.ContainerSpec{
CapabilityAdd: []string{"CAP_AAA", "CAP_BBB", "CAP_CCC", "CAP_DDD"},
CapabilityDrop: []string{"CAP_WWW", "CAP_XXX", "CAP_YYY", "CAP_ZZZ"},
},
expectedAdd: []string{"CAP_ADD_ONE", "CAP_FOO"},
expectedDrop: []string{"CAP_DROP_ONE"},
},
}

for _, tc := range tests {
Expand Down
2 changes: 2 additions & 0 deletions contrib/completion/bash/docker
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,7 @@ __docker_complete_capabilities_addable() {
MAC_OVERRIDE
NET_ADMIN
NET_BROADCAST
RESET
SYS_ADMIN
SYS_BOOT
SYSLOG
Expand Down Expand Up @@ -874,6 +875,7 @@ __docker_complete_capabilities_droppable() {
MKNOD
NET_BIND_SERVICE
NET_RAW
RESET
SETFCAP
SETGID
SETPCAP
Expand Down
17 changes: 14 additions & 3 deletions opts/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import (
const (
// AllCapabilities is a special value to add or drop all capabilities
AllCapabilities = "ALL"

// ResetCapabilities is a special value to reset capabilities when updating.
// This value should only be used when updating, not used on "create".
ResetCapabilities = "RESET"
)

// NormalizeCapability normalizes a capability by upper-casing, trimming white space
Expand All @@ -19,7 +23,7 @@ const (
// handled by the daemon.
func NormalizeCapability(cap string) string {
cap = strings.ToUpper(strings.TrimSpace(cap))
if cap == AllCapabilities {
if cap == AllCapabilities || cap == ResetCapabilities {
return cap
}
if !strings.HasPrefix(cap, "CAP_") {
Expand All @@ -44,6 +48,9 @@ func CapabilitiesMap(caps []string) map[string]bool {
// lists are removed from the list of capabilities to drop. The special "ALL"
// capability is also taken into account.
//
// Note that the special "RESET" value is only used when updating an existing
// service, and will be ignored.
//
// Duplicates are removed, and the resulting lists are sorted.
func EffectiveCapAddCapDrop(add, drop []string) (capAdd, capDrop []string) {
var (
Expand All @@ -64,11 +71,15 @@ func EffectiveCapAddCapDrop(add, drop []string) (capAdd, capDrop []string) {
// Adding a capability takes precedence, so skip dropping
continue
}
capDrop = append(capDrop, c)
if c != ResetCapabilities {
capDrop = append(capDrop, c)
}
}

for c := range addCaps {
capAdd = append(capAdd, c)
if c != ResetCapabilities {
capAdd = append(capAdd, c)
}
}

sort.Strings(capAdd)
Expand Down

0 comments on commit 10b529e

Please sign in to comment.