Skip to content

Commit 3bc5f43

Browse files
Merge pull request #5206 from rhatdan/capabilities
Allow devs to set labels in container images for default capabilities.
2 parents 34baea8 + f678b3f commit 3bc5f43

File tree

11 files changed

+230
-262
lines changed

11 files changed

+230
-262
lines changed

docs/source/markdown/podman-build.1.md

+10
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,16 @@ BUILDAH\_ISOLATION environment variable. `export BUILDAH_ISOLATION=oci`
279279

280280
Add an image *label* (e.g. label=*value*) to the image metadata. Can be used multiple times.
281281

282+
Users can set a special LABEL **io.containers.capabilities=CAP1,CAP2,CAP3** in
283+
a Containerfile that specified the list of Linux capabilities required for the
284+
container to run properly. This label specified in a container image tells
285+
Podman to run the container with just these capabilties. Podman launches the
286+
container with just the specified capabilties, as long as this list of
287+
capabilities is a subset of the default list.
288+
289+
If the specified capabilities are not in the default set, Podman will
290+
print an error message and will run the container with the default capabilities.
291+
282292
**--layers**
283293

284294
Cache intermediate images during the build process (Default is `true`).

docs/source/markdown/podman-commit.1.md

+16-4
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ Suppress output
6060

6161
## EXAMPLES
6262

63+
### Create image from container with entrypoint and label
6364
```
64-
$ podman commit --change CMD=/bin/bash --change ENTRYPOINT=/bin/sh --change LABEL=blue=image reverent_golick image-committed
65+
$ podman commit --change CMD=/bin/bash --change ENTRYPOINT=/bin/sh --change "LABEL blue=image" reverent_golick image-committed
6566
Getting image source signatures
6667
Copying blob sha256:b41deda5a2feb1f03a5c1bb38c598cbc12c9ccd675f438edc6acd815f7585b86
6768
25.80 MB / 25.80 MB [======================================================] 0s
@@ -72,26 +73,37 @@ Storing signatures
7273
e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8
7374
```
7475

76+
### Create image from container with commit message
7577
```
76-
$ podman commit -q --message "committing container to image" reverent_golick image-committed
77-
e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8
78+
$ podman commit -q --message "committing container to image"
79+
reverent_golick image-committed
80+
e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8 ```
7881
```
7982

83+
### Create image from container with author
8084
```
8185
$ podman commit -q --author "firstName lastName" reverent_golick image-committed
8286
e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8
8387
```
8488

89+
### Pause a running container while creating the image
8590
```
86-
$ podman commit -q --pause=false containerID image-committed
91+
$ podman commit -q --pause=true containerID image-committed
8792
e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8
8893
```
8994

95+
### Create an image from a container with a default image tag
9096
```
9197
$ podman commit containerID
9298
e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8
9399
```
94100

101+
### Create an image from container with default required capabilities are SETUID and SETGID
102+
```
103+
$ podman commit -q --change LABEL=io.containers.capabilities=setuid,setgid epic_nobel privimage
104+
400d31a3f36dca751435e80a0e16da4859beb51ff84670ce6bdc5edb30b94066
105+
```
106+
95107
## SEE ALSO
96108
podman(1), podman-run(1), podman-create(1)
97109

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require (
99
github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784
1010
github.com/containernetworking/plugins v0.8.5
1111
github.com/containers/buildah v1.14.1-0.20200227103754-f0c3fd7c3d34
12-
github.com/containers/common v0.4.2 // indirect
12+
github.com/containers/common v0.4.2
1313
github.com/containers/conmon v2.0.10+incompatible
1414
github.com/containers/image/v5 v5.2.1
1515
github.com/containers/psgo v1.4.0

go.sum

-115
Large diffs are not rendered by default.

libpod/container_api.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import (
99
"os"
1010
"time"
1111

12+
"github.com/containers/common/pkg/capabilities"
1213
"github.com/containers/libpod/libpod/define"
1314
"github.com/containers/libpod/libpod/events"
14-
"github.com/containers/libpod/pkg/capabilities"
1515
"github.com/containers/storage/pkg/stringid"
1616
"github.com/opentracing/opentracing-go"
1717
"github.com/pkg/errors"

pkg/capabilities/capabilities.go

-129
This file was deleted.

pkg/spec/createconfig.go

+1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ type NetworkConfig struct {
112112
type SecurityConfig struct {
113113
CapAdd []string // cap-add
114114
CapDrop []string // cap-drop
115+
CapRequired []string // cap-required
115116
LabelOpts []string //SecurityOpts
116117
NoNewPrivs bool //SecurityOpts
117118
ApparmorProfile string //SecurityOpts

pkg/spec/security.go

+34-11
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import (
44
"fmt"
55
"strings"
66

7+
"github.com/containers/common/pkg/capabilities"
78
"github.com/containers/libpod/libpod"
8-
"github.com/containers/libpod/pkg/capabilities"
9+
"github.com/containers/libpod/pkg/util"
910
"github.com/opencontainers/runtime-tools/generate"
1011
"github.com/opencontainers/selinux/go-selinux/label"
1112
"github.com/pkg/errors"
13+
"github.com/sirupsen/logrus"
1214
)
1315

1416
// ToCreateOptions convert the SecurityConfig to a slice of container create
@@ -113,28 +115,49 @@ func (c *SecurityConfig) ConfigureGenerator(g *generate.Generator, user *UserCon
113115

114116
configSpec := g.Config
115117
var err error
116-
var caplist []string
118+
var defaultCaplist []string
117119
bounding := configSpec.Process.Capabilities.Bounding
118120
if useNotRoot(user.User) {
119-
configSpec.Process.Capabilities.Bounding = caplist
121+
configSpec.Process.Capabilities.Bounding = defaultCaplist
120122
}
121-
caplist, err = capabilities.MergeCapabilities(configSpec.Process.Capabilities.Bounding, c.CapAdd, c.CapDrop)
123+
defaultCaplist, err = capabilities.MergeCapabilities(configSpec.Process.Capabilities.Bounding, c.CapAdd, c.CapDrop)
122124
if err != nil {
123125
return err
124126
}
125127

126-
configSpec.Process.Capabilities.Bounding = caplist
127-
configSpec.Process.Capabilities.Permitted = caplist
128-
configSpec.Process.Capabilities.Inheritable = caplist
129-
configSpec.Process.Capabilities.Effective = caplist
130-
configSpec.Process.Capabilities.Ambient = caplist
128+
privCapRequired := []string{}
129+
130+
if !c.Privileged && len(c.CapRequired) > 0 {
131+
// Pass CapRequired in CapAdd field to normalize capabilties names
132+
capRequired, err := capabilities.MergeCapabilities(nil, c.CapRequired, nil)
133+
if err != nil {
134+
logrus.Errorf("capabilties requested by user or image are not valid: %q", strings.Join(c.CapRequired, ","))
135+
} else {
136+
// Verify all capRequiered are in the defaultCapList
137+
for _, cap := range capRequired {
138+
if !util.StringInSlice(cap, defaultCaplist) {
139+
privCapRequired = append(privCapRequired, cap)
140+
}
141+
}
142+
}
143+
if len(privCapRequired) == 0 {
144+
defaultCaplist = capRequired
145+
} else {
146+
logrus.Errorf("capabilties requested by user or image are not allowed by default: %q", strings.Join(privCapRequired, ","))
147+
}
148+
}
149+
configSpec.Process.Capabilities.Bounding = defaultCaplist
150+
configSpec.Process.Capabilities.Permitted = defaultCaplist
151+
configSpec.Process.Capabilities.Inheritable = defaultCaplist
152+
configSpec.Process.Capabilities.Effective = defaultCaplist
153+
configSpec.Process.Capabilities.Ambient = defaultCaplist
131154
if useNotRoot(user.User) {
132-
caplist, err = capabilities.MergeCapabilities(bounding, c.CapAdd, c.CapDrop)
155+
defaultCaplist, err = capabilities.MergeCapabilities(bounding, c.CapAdd, c.CapDrop)
133156
if err != nil {
134157
return err
135158
}
136159
}
137-
configSpec.Process.Capabilities.Bounding = caplist
160+
configSpec.Process.Capabilities.Bounding = defaultCaplist
138161

139162
// HANDLE SECCOMP
140163
if c.SeccompProfilePath != "unconfined" {

pkg/spec/spec.go

+14
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ package createconfig
33
import (
44
"strings"
55

6+
"github.com/containers/common/pkg/capabilities"
67
"github.com/containers/libpod/libpod"
78
libpodconfig "github.com/containers/libpod/libpod/config"
89
"github.com/containers/libpod/libpod/define"
910
"github.com/containers/libpod/pkg/cgroups"
1011
"github.com/containers/libpod/pkg/env"
1112
"github.com/containers/libpod/pkg/rootless"
1213
"github.com/containers/libpod/pkg/sysinfo"
14+
"github.com/containers/libpod/pkg/util"
1315
"github.com/docker/go-units"
1416
"github.com/opencontainers/runc/libcontainer/user"
1517
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -330,6 +332,18 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
330332
}
331333
configSpec := g.Config
332334

335+
// If the container image specifies an label with a
336+
// capabilities.ContainerImageLabel then split the comma separated list
337+
// of capabilities and record them. This list indicates the only
338+
// capabilities, required to run the container.
339+
var capRequired []string
340+
for key, val := range config.Labels {
341+
if util.StringInSlice(key, capabilities.ContainerImageLabels) {
342+
capRequired = strings.Split(val, ",")
343+
}
344+
}
345+
config.Security.CapRequired = capRequired
346+
333347
if err := config.Security.ConfigureGenerator(&g, &config.User); err != nil {
334348
return nil, err
335349
}

pkg/specgen/namespaces.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ package specgen
33
import (
44
"os"
55

6+
"github.com/containers/common/pkg/capabilities"
67
"github.com/containers/libpod/libpod"
78
"github.com/containers/libpod/libpod/image"
8-
"github.com/containers/libpod/pkg/capabilities"
99
"github.com/cri-o/ocicni/pkg/ocicni"
1010
spec "github.com/opencontainers/runtime-spec/specs-go"
1111
"github.com/opencontainers/runtime-tools/generate"

0 commit comments

Comments
 (0)