Skip to content

Commit

Permalink
Merge pull request #23249 from giuseppe/play-kube-userns-fixes
Browse files Browse the repository at this point in the history
kube generate/play restores the user namespace configuration
  • Loading branch information
openshift-merge-bot[bot] authored Jul 24, 2024
2 parents cceb1a0 + d9c2806 commit 1da89dd
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 23 deletions.
48 changes: 26 additions & 22 deletions libpod/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,32 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po
sort.Slice(containers, func(i, j int) bool { return containers[i].CreatedTime().Before(containers[j].CreatedTime()) })

for _, ctr := range containers {
if !ctr.IsInfra() {
if ctr.IsInfra() {
// If there is an user namespace for the infra container, then register it for the entire pod.
if v, found := ctr.config.Spec.Annotations[define.UserNsAnnotation]; found {
podAnnotations[define.UserNsAnnotation] = v
}
_, _, infraDNS, _, err := containerToV1Container(ctx, ctr, getService)
if err != nil {
return nil, err
}
if infraDNS != nil {
if servers := infraDNS.Nameservers; len(servers) > 0 {
dnsInfo.Nameservers = servers
}
if searches := infraDNS.Searches; len(searches) > 0 {
dnsInfo.Searches = searches
}
if options := infraDNS.Options; len(options) > 0 {
dnsInfo.Options = options
}
}
// If the infraName is not the podID-infra, that means the user set another infra name using
// --infra-name during pod creation
if infraName != "" && infraName != p.ID()[:12]+"-infra" {
podAnnotations[define.InfraNameAnnotation] = infraName
}
} else {
for k, v := range ctr.config.Spec.Annotations {
if !podmanOnly && (define.IsReservedAnnotation(k)) {
continue
Expand Down Expand Up @@ -574,27 +599,6 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po
vol := vol
deDupPodVolumes[vol.Name] = &vol
}
} else {
_, _, infraDNS, _, err := containerToV1Container(ctx, ctr, getService)
if err != nil {
return nil, err
}
if infraDNS != nil {
if servers := infraDNS.Nameservers; len(servers) > 0 {
dnsInfo.Nameservers = servers
}
if searches := infraDNS.Searches; len(searches) > 0 {
dnsInfo.Searches = searches
}
if options := infraDNS.Options; len(options) > 0 {
dnsInfo.Options = options
}
}
// If the infraName is not the podID-infra, that means the user set another infra name using
// --infra-name during pod creation
if infraName != "" && infraName != p.ID()[:12]+"-infra" {
podAnnotations[define.InfraNameAnnotation] = infraName
}
}
}
podVolumes := []v1.Volume{}
Expand Down
3 changes: 3 additions & 0 deletions pkg/api/handlers/libpod/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ func PodCreate(w http.ResponseWriter, r *http.Request) {
infraOptions.Net = &entities.NetOptions{}
infraOptions.Devices = psg.Devices
infraOptions.SecurityOpt = psg.SecurityOpt
if !psg.Userns.IsDefault() {
infraOptions.UserNS = psg.Userns.String()
}
if psg.ShareParent == nil {
t := true
psg.ShareParent = &t
Expand Down
7 changes: 6 additions & 1 deletion pkg/domain/infra/abi/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -603,10 +603,15 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
if options.Userns == "" {
if v, ok := annotations[define.UserNsAnnotation]; ok {
options.Userns = v
} else if v, ok := annotations[define.UserNsAnnotation+"/"+podName]; ok {
options.Userns = v
} else if podYAML.Spec.HostUsers != nil && !*podYAML.Spec.HostUsers {
options.Userns = "auto"
} else {
options.Userns = "host"
}
if podYAML.Spec.HostUsers != nil && !*podYAML.Spec.HostUsers {
// FIXME: how to deal with explicit mappings?
if options.Userns == "private" {
options.Userns = "auto"
}
} else if podYAML.Spec.HostUsers != nil {
Expand Down
4 changes: 4 additions & 0 deletions pkg/specgenutil/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,10 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
if len(s.Annotations) == 0 {
s.Annotations = annotations
}
// Add the user namespace configuration to the annotations
if c.UserNS != "" {
s.Annotations[define.UserNsAnnotation] = c.UserNS
}

if len(c.StorageOpts) > 0 {
opts := make(map[string]string, len(c.StorageOpts))
Expand Down
14 changes: 14 additions & 0 deletions pkg/specgenutil/specgenutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"

"github.com/containers/common/pkg/machine"
"github.com/containers/podman/v5/libpod/define"
"github.com/containers/podman/v5/pkg/domain/entities"
"github.com/containers/podman/v5/pkg/specgen"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -216,3 +217,16 @@ func TestGenRlimits(t *testing.T) {
_, err = GenRlimits([]string{"nofile=bar:buzz"})
assert.Error(t, err, "err is not nil")
}

func TestFillOutSpecGenRecorsUserNs(t *testing.T) {
sg := specgen.NewSpecGenerator("nothing", false)
err := FillOutSpecGen(sg, &entities.ContainerCreateOptions{
ImageVolume: "ignore",
UserNS: "keep-id",
}, []string{})
assert.NoError(t, err)

v, ok := sg.Annotations[define.UserNsAnnotation]
assert.True(t, ok, "UserNsAnnotation is set")
assert.Equal(t, "keep-id", v, "UserNsAnnotation is keep-id")
}
30 changes: 30 additions & 0 deletions test/system/700-play.bats
Original file line number Diff line number Diff line change
Expand Up @@ -1037,3 +1037,33 @@ spec:
run_podman kube down $fname
run_podman rmi $imgname
}

@test "podman kube restore user namespace" {
if ! is_rootless; then
grep -E -q "^containers:" /etc/subuid || skip "no IDs allocated for user 'containers'"
fi

run_podman pod create --userns auto --name usernspod
run_podman create --pod usernspod $IMAGE true

run_podman pod inspect --format {{.InfraContainerID}} usernspod
infraID="$output"

run_podman inspect --format '{{index .Config.Annotations "io.podman.annotations.userns"}}' $infraID
assert "$output" == "auto" "user namespace should be kept"

YAML=$PODMAN_TMPDIR/test.yml

# Make sure the same setting is restored if the pod is recreated from the yaml
run_podman kube generate usernspod -f $YAML
cat $YAML
run_podman kube play --replace $YAML

run_podman pod inspect --format {{.InfraContainerID}} usernspod
infraID="$output"

run_podman inspect --format '{{index .Config.Annotations "io.podman.annotations.userns"}}' $infraID
assert "$output" == "auto" "user namespace should be kept"

run_podman pod rm -f usernspod
}

0 comments on commit 1da89dd

Please sign in to comment.