From ef3f098796c7ecc4b67482160ae997b38cf5de75 Mon Sep 17 00:00:00 2001
From: Daniel J Walsh <dwalsh@redhat.com>
Date: Tue, 17 Jan 2023 13:55:24 -0500
Subject: [PATCH] Remove ReservedAnnotations from kube generate specification

Reserved annotations are used internally by Podman and would effect
nothing when run with Kubernetes so we should not be generating these
annotations.

Fixes: https://github.com/containers/podman/issues/17105

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
---
 docs/source/markdown/podman-kube-generate.1.md |  8 --------
 libpod/container_internal_common.go            |  1 -
 libpod/kube.go                                 |  7 +++++++
 pkg/annotations/annotations.go                 | 12 ++++++++++++
 pkg/specgen/generate/container.go              |  1 -
 pkg/specgen/generate/kube/kube.go              |  1 -
 pkg/specgenutil/specgen.go                     |  6 ------
 test/e2e/generate_kube_test.go                 | 14 ++++++++------
 test/system/710-kube.bats                      |  7 +------
 9 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/docs/source/markdown/podman-kube-generate.1.md b/docs/source/markdown/podman-kube-generate.1.md
index 1df6ceff46..583dd2fb17 100644
--- a/docs/source/markdown/podman-kube-generate.1.md
+++ b/docs/source/markdown/podman-kube-generate.1.md
@@ -77,9 +77,7 @@ spec:
     ports:
     - containerPort: 3306
       hostPort: 36533
-    resources: {}
     tty: true
-status: {}
 ```
 
 Create Kubernetes Pod YAML for a container with the directory `/home/user/my-data` on the host bind-mounted in the container to `/volume`.
@@ -102,7 +100,6 @@ spec:
     - /bin/sh
     image: docker.io/library/alpine:latest
     name: test-bind-mount
-    resources: {}
     volumeMounts:
     - mountPath: /volume
       name: home-user-my-data-host
@@ -112,7 +109,6 @@ spec:
       path: /home/user/my-data
       type: Directory
     name: home-user-my-data-host
-status: {}
 ```
 
 Create Kubernetes Pod YAML for a container with the named volume `priceless-data` mounted in the container at `/volume`.
@@ -135,7 +131,6 @@ spec:
     - /bin/sh
     image: docker.io/library/alpine:latest
     name: test-bind-mount
-    resources: {}
     volumeMounts:
     - mountPath: /volume
       name: priceless-data-pvc
@@ -144,7 +139,6 @@ spec:
   - name: priceless-data-pvc
     persistentVolumeClaim:
       claimName: priceless-data
-status: {}
 ```
 
 Create Kubernetes Pod YAML for a pod called `demoweb` and include a service.
@@ -168,10 +162,8 @@ spec:
     - /root/code/graph.py
     image: quay.io/baude/demoweb:latest
     name: practicalarchimedes
-    resources: {}
     tty: true
     workingDir: /root/code
-status: {}
 ---
 apiVersion: v1
 kind: Service
diff --git a/libpod/container_internal_common.go b/libpod/container_internal_common.go
index 0a97bd055d..05a36e49b8 100644
--- a/libpod/container_internal_common.go
+++ b/libpod/container_internal_common.go
@@ -499,7 +499,6 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
 	}
 
 	g.SetRootPath(c.state.Mountpoint)
-	g.AddAnnotation(annotations.Created, c.config.CreatedTime.Format(time.RFC3339Nano))
 	g.AddAnnotation("org.opencontainers.image.stopSignal", fmt.Sprintf("%d", c.config.StopSignal))
 
 	if _, exists := g.Config.Annotations[annotations.ContainerManager]; !exists {
diff --git a/libpod/kube.go b/libpod/kube.go
index cf73851525..07f3deeeef 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -17,6 +17,7 @@ import (
 	"github.com/containers/common/pkg/config"
 	cutil "github.com/containers/common/pkg/util"
 	"github.com/containers/podman/v4/libpod/define"
+	"github.com/containers/podman/v4/pkg/annotations"
 	"github.com/containers/podman/v4/pkg/env"
 	v1 "github.com/containers/podman/v4/pkg/k8s.io/api/core/v1"
 	"github.com/containers/podman/v4/pkg/k8s.io/apimachinery/pkg/api/resource"
@@ -365,6 +366,9 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po
 	for _, ctr := range containers {
 		if !ctr.IsInfra() {
 			for k, v := range ctr.config.Spec.Annotations {
+				if define.IsReservedAnnotation(k) || annotations.IsReservedAnnotation(k) {
+					continue
+				}
 				podAnnotations[fmt.Sprintf("%s/%s", k, removeUnderscores(ctr.Name()))] = TruncateKubeAnnotation(v)
 			}
 			// Convert auto-update labels into kube annotations
@@ -506,6 +510,9 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod,
 	for _, ctr := range ctrs {
 		ctrNames = append(ctrNames, removeUnderscores(ctr.Name()))
 		for k, v := range ctr.config.Spec.Annotations {
+			if define.IsReservedAnnotation(k) || annotations.IsReservedAnnotation(k) {
+				continue
+			}
 			kubeAnnotations[fmt.Sprintf("%s/%s", k, removeUnderscores(ctr.Name()))] = TruncateKubeAnnotation(v)
 		}
 
diff --git a/pkg/annotations/annotations.go b/pkg/annotations/annotations.go
index a22222f104..5d3cb992ac 100644
--- a/pkg/annotations/annotations.go
+++ b/pkg/annotations/annotations.go
@@ -120,3 +120,15 @@ const (
 // ContainerManagerLibpod indicates that libpod created and manages the
 // container.
 const ContainerManagerLibpod = "libpod"
+
+// IsReservedAnnotation returns true if the specified value corresponds to an
+// already reserved annotation that Podman sets during container creation.
+func IsReservedAnnotation(value string) bool {
+	switch value {
+	case Annotations, ContainerID, ContainerName, ContainerType, Created, HostName, CgroupParent, IP, NamespaceOptions, SeccompProfilePath, Image, ImageName, ImageRef, KubeName, PortMappings, Labels, LogPath, Metadata, Name, Namespace, PrivilegedRuntime, ResolvPath, HostnamePath, SandboxID, SandboxName, ShmPath, MountPoint, RuntimeHandler, TTY, Stdin, StdinOnce, Volumes, HostNetwork, CNIResult, ContainerManager:
+		return true
+
+	default:
+		return false
+	}
+}
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 834345f4c8..54d96d3285 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -213,7 +213,6 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
 			sandboxID = infra.ID()
 		}
 		annotations[ann.SandboxID] = sandboxID
-		annotations[ann.ContainerType] = ann.ContainerTypeContainer
 		// Check if this is an init-ctr and if so, check if
 		// the pod is running.  we do not want to add init-ctrs to
 		// a running pod because it creates confusion for us.
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index 46a5a1a22a..2b416e450c 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -324,7 +324,6 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
 	}
 	if opts.PodInfraID != "" {
 		annotations[ann.SandboxID] = opts.PodInfraID
-		annotations[ann.ContainerType] = ann.ContainerTypeContainer
 	}
 	s.Annotations = annotations
 
diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go
index 695018f6fc..8e2a490b28 100644
--- a/pkg/specgenutil/specgen.go
+++ b/pkg/specgenutil/specgen.go
@@ -13,7 +13,6 @@ import (
 	"github.com/containers/image/v5/manifest"
 	"github.com/containers/podman/v4/cmd/podman/parse"
 	"github.com/containers/podman/v4/libpod/define"
-	ann "github.com/containers/podman/v4/pkg/annotations"
 	"github.com/containers/podman/v4/pkg/domain/entities"
 	envLib "github.com/containers/podman/v4/pkg/env"
 	"github.com/containers/podman/v4/pkg/namespaces"
@@ -433,11 +432,6 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
 	// ANNOTATIONS
 	annotations := make(map[string]string)
 
-	// First, add our default annotations
-	if c.TTY {
-		annotations[ann.TTY] = "true"
-	}
-
 	// Last, add user annotations
 	for _, annotation := range c.Annotation {
 		splitAnnotation := strings.SplitN(annotation, "=", 2)
diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go
index 2429dd4d2f..29932abd6f 100644
--- a/test/e2e/generate_kube_test.go
+++ b/test/e2e/generate_kube_test.go
@@ -18,7 +18,7 @@ import (
 	. "github.com/onsi/gomega/gexec"
 )
 
-var _ = Describe("Podman generate kube", func() {
+var _ = Describe("Podman kube generate", func() {
 	var (
 		tempdir    string
 		err        error
@@ -41,19 +41,19 @@ var _ = Describe("Podman generate kube", func() {
 
 	})
 
-	It("podman generate pod kube on bogus object", func() {
+	It("podman kube generate pod on bogus object", func() {
 		session := podmanTest.Podman([]string{"generate", "kube", "foobar"})
 		session.WaitWithDefaultTimeout()
 		Expect(session).To(ExitWithError())
 	})
 
-	It("podman generate service kube on bogus object", func() {
-		session := podmanTest.Podman([]string{"generate", "kube", "-s", "foobar"})
+	It("podman kube generate service on bogus object", func() {
+		session := podmanTest.Podman([]string{"kube", "generate", "-s", "foobar"})
 		session.WaitWithDefaultTimeout()
 		Expect(session).To(ExitWithError())
 	})
 
-	It("podman generate kube on container", func() {
+	It("podman kube generate on container", func() {
 		session := podmanTest.RunTopContainer("top")
 		session.WaitWithDefaultTimeout()
 		Expect(session).Should(Exit(0))
@@ -72,6 +72,7 @@ var _ = Describe("Podman generate kube", func() {
 		Expect(pod.Spec.Containers[0].SecurityContext).To(BeNil())
 		Expect(pod.Spec.Containers[0].Env).To(BeNil())
 		Expect(pod).To(HaveField("Name", "top-pod"))
+		Expect(pod.Annotations).To(HaveLen(0))
 
 		numContainers := 0
 		for range pod.Spec.Containers {
@@ -80,7 +81,7 @@ var _ = Describe("Podman generate kube", func() {
 		Expect(numContainers).To(Equal(1))
 	})
 
-	It("podman generate service kube on container with --security-opt level", func() {
+	It("podman kube generate service on container with --security-opt level", func() {
 		session := podmanTest.Podman([]string{"create", "--name", "test", "--security-opt", "label=level:s0:c100,c200", "alpine"})
 		session.WaitWithDefaultTimeout()
 		Expect(session).Should(Exit(0))
@@ -166,6 +167,7 @@ var _ = Describe("Podman generate kube", func() {
 		err := yaml.Unmarshal(kube.Out.Contents(), pod)
 		Expect(err).ToNot(HaveOccurred())
 		Expect(pod.Spec).To(HaveField("HostNetwork", false))
+		Expect(pod.Annotations).To(HaveLen(0))
 
 		numContainers := 0
 		for range pod.Spec.Containers {
diff --git a/test/system/710-kube.bats b/test/system/710-kube.bats
index 945d8d735c..350d4cc77f 100644
--- a/test/system/710-kube.bats
+++ b/test/system/710-kube.bats
@@ -33,7 +33,7 @@ json.dump(yaml.safe_load(sys.stdin), sys.stdout)'
     cname=c$(random_string 15)
     run_podman container create --cap-drop fowner --cap-drop setfcap --name $cname $IMAGE top
     run_podman kube generate $cname
-
+    assert "$output" !~ "Kubernetes only allows 63 characters"
     # Convert yaml to json, and dump to stdout (to help in case of errors)
     json=$(yaml2json <<<"$output")
     jq . <<<"$json"
@@ -101,11 +101,6 @@ status                           | =  | null
 apiVersion | =  | v1
 kind       | =  | Pod
 
-metadata.annotations.\"io.kubernetes.cri-o.ContainerType/$cname1\" | =  | container
-metadata.annotations.\"io.kubernetes.cri-o.ContainerType/$cname2\" | =  | container
-metadata.annotations.\"io.kubernetes.cri-o.SandboxID/$cname1\"     | =~ | [0-9a-f]\\{56\\}
-metadata.annotations.\"io.kubernetes.cri-o.SandboxID/$cname2\"     | =~ | [0-9a-f]\\{56\\}
-
 metadata.creationTimestamp | =~ | [0-9T:-]\\+Z
 metadata.labels.app        | =  | ${pname}
 metadata.name              | =  | ${pname}