diff --git a/pkg/domain/infra/abi/generate.go b/pkg/domain/infra/abi/generate.go index 3e1de33097..06e818b9ad 100644 --- a/pkg/domain/infra/abi/generate.go +++ b/pkg/domain/infra/abi/generate.go @@ -9,10 +9,12 @@ import ( "fmt" "strings" + "github.com/opencontainers/selinux/go-selinux" "go.podman.io/podman/v6/libpod" "go.podman.io/podman/v6/libpod/define" "go.podman.io/podman/v6/pkg/domain/entities" k8sAPI "go.podman.io/podman/v6/pkg/k8s.io/api/core/v1" + "go.podman.io/podman/v6/pkg/rootless" "go.podman.io/podman/v6/pkg/specgen" generateUtils "go.podman.io/podman/v6/pkg/specgen/generate" "go.podman.io/podman/v6/pkg/systemd/generate" @@ -218,7 +220,7 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string, if err != nil { return nil, err } - if len(po.Spec.Volumes) != 0 { + if len(po.Spec.Volumes) != 0 && selinux.GetEnabled() && rootless.IsRootless() { warning := ` # NOTE: If you generated this yaml from an unprivileged and rootless podman container on an SELinux # enabled system, check the podman generate kube man page for steps to follow to ensure that your pod/container diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go index 89a4cfade4..55245d28c9 100644 --- a/test/e2e/generate_kube_test.go +++ b/test/e2e/generate_kube_test.go @@ -14,6 +14,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/opencontainers/selinux/go-selinux" v1 "go.podman.io/podman/v6/pkg/k8s.io/api/core/v1" "go.podman.io/podman/v6/pkg/util" . "go.podman.io/podman/v6/test/utils" @@ -61,6 +62,37 @@ var _ = Describe("Podman kube generate", func() { Expect(numContainers).To(Equal(1)) }) + It("on container with volume emits SELinux note only when rootless and SELinux enabled", func() { + vol1 := filepath.Join(podmanTest.TempDir, "vol-selinux-note") + err := os.MkdirAll(vol1, 0o755) + Expect(err).ToNot(HaveOccurred()) + + ctrName := "test-selinux-note-ctr" + session := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "-v", vol1 + ":/volume/:z", CITEST_IMAGE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(ExitCleanly()) + + outputFile := filepath.Join(podmanTest.RunRoot, "ctr.yaml") + kube := podmanTest.Podman([]string{"kube", "generate", ctrName, "-f", outputFile}) + kube.WaitWithDefaultTimeout() + Expect(kube).Should(ExitCleanly()) + + b, err := os.ReadFile(outputFile) + Expect(err).ShouldNot(HaveOccurred()) + + // The SELinux volume-permissions NOTE only applies to unprivileged, + // rootless containers on an SELinux-enabled host. + if isRootless() && selinux.GetEnabled() { + Expect(string(b)).To(ContainSubstring("check the podman generate kube man page")) + } else { + Expect(string(b)).NotTo(ContainSubstring("check the podman generate kube man page")) + } + + rm := podmanTest.Podman([]string{"rm", "-t", "0", "-f", ctrName}) + rm.WaitWithDefaultTimeout() + Expect(rm).Should(ExitCleanly()) + }) + It("service on container with --security-opt level", func() { session := podmanTest.Podman([]string{"create", "--name", "test", "--security-opt", "label=level:s0:c100,c200", CITEST_IMAGE}) session.WaitWithDefaultTimeout()