Skip to content

Commit 34748fb

Browse files
committed
Correct generate kube on containers userns annotation
The `podman generate kube` command on containers follows a different codepath from pods. Pods store a lot of pod-level configuration - including user namespace information - in annotations, so it can be restored by `play kube`. Generating for a container does not do the same thing, because we don't have a pod. However, per-container generation was still generating a nearly identical user namespace annotation to a pod. Example: In Pod: io.podman.annotations.userns: auto:size=40 Not in Pod: io.podman.annotations.userns/awesomegreider: auto:size=2048 The second annotation seems like it should apply a user namespace config to the generated Kubernetes pod. Instead, it's just adding an annotation to the awesomegreider container, that says said container has a user namespace, when it does not in fact have a user namespace configured because it is now in a pod. After this PR, both containers in and out of pods generate identical annotations (the In Pod version, missing container name) and as such should generate pods with appropriately configured user namespaces. I also added some conflict detection to refuse to generate if you try to generate YAML containing two containers with conflicting user namespace configuration. Fixes #25896 Signed-off-by: Matt Heon <[email protected]>
1 parent b849550 commit 34748fb

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

libpod/kube.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,17 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container, getServic
765765
if !podmanOnly && define.IsReservedAnnotation(k) {
766766
continue
767767
}
768-
kubeAnnotations[fmt.Sprintf("%s/%s", k, removeUnderscores(ctr.Name()))] = v
768+
// Certain annotations should be applied to the whole pod.
769+
// For others, add container name as a suffix.
770+
// For annotations such as this, error if already set.
771+
if k == define.UserNsAnnotation {
772+
if oldV, ok := kubeAnnotations[k]; ok && oldV != v {
773+
return nil, fmt.Errorf("two or more containers have differing user namespace configuration, cannot place in same Kubernetes pod: %w", define.ErrInvalidArg)
774+
}
775+
kubeAnnotations[k] = v
776+
} else {
777+
kubeAnnotations[fmt.Sprintf("%s/%s", k, removeUnderscores(ctr.Name()))] = v
778+
}
769779
}
770780

771781
// Convert auto-update labels into kube annotations

test/e2e/generate_kube_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,27 @@ var _ = Describe("Podman kube generate", func() {
10251025
Expect(kube).Should(ExitCleanly())
10261026
})
10271027

1028+
It("multiple containers with same user namespace configuration", func() {
1029+
name1 := "c1"
1030+
name2 := "c2"
1031+
_ = podmanTest.PodmanExitCleanly("run", "--userns", "auto:size=30", "-dt", "--name", name1, ALPINE, "top")
1032+
_ = podmanTest.PodmanExitCleanly("run", "--userns", "auto:size=30", "-dt", "--name", name2, ALPINE, "top")
1033+
1034+
gen := podmanTest.PodmanExitCleanly("kube", "generate", name1, name2)
1035+
Expect(gen.OutputToString()).To(ContainSubstring("io.podman.annotations.userns: auto:size=10"))
1036+
})
1037+
1038+
It("multiple containers with differing user namespace configuration", func() {
1039+
name1 := "c1"
1040+
name2 := "c2"
1041+
_ = podmanTest.PodmanExitCleanly("run", "--userns", "auto:size=30", "-dt", "--name", name1, ALPINE, "top")
1042+
_ = podmanTest.PodmanExitCleanly("run", "--userns", "auto:size=40", "-dt", "--name", name2, ALPINE, "top")
1043+
1044+
gen := podmanTest.Podman([]string{"kube", "generate", name1, name2})
1045+
gen.WaitWithDefaultTimeout()
1046+
Expect(gen).Should(ExitWithError(125, "two or more containers have differing user namespace configuration, cannot place in same Kubernetes pod: invalid argument"))
1047+
})
1048+
10281049
It("with containers in pods should fail", func() {
10291050
pod1 := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:pod1", "--name", "top1", CITEST_IMAGE, "top"})
10301051
pod1.WaitWithDefaultTimeout()

0 commit comments

Comments
 (0)