Merge pull request #23249 from giuseppe/play-kube-userns-fixes

kube generate/play restores the user namespace configuration
This commit is contained in:
openshift-merge-bot[bot]
2024-07-24 17:34:59 +00:00
committed by GitHub
6 changed files with 83 additions and 23 deletions

View File

@ -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
@ -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{}

View File

@ -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

View File

@ -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 {

View File

@ -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))

View File

@ -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"
@ -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")
}

View File

@ -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
}