Skip to content

Commit

Permalink
Merge pull request #19568 from umohnani8/infra-name
Browse files Browse the repository at this point in the history
Add infra-name annotations to kube gen/play
  • Loading branch information
openshift-merge-robot authored Aug 25, 2023
2 parents c3ac109 + 52ed7fc commit 4ff21cf
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 3 deletions.
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-kube-generate.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Once completed, the correct permissions are in place to access the volume when t

Note that the generated Kubernetes YAML file can be used to re-run the deployment via podman-play-kube(1).

Note that if the pod being generated was created with the **--infra-name** flag set, then the generated kube yaml will have the **io.podman.annotations.infra.name** set where the value is the name of the infra container set by the user.

## OPTIONS

#### **--filename**, **-f**=*filename*
Expand Down
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-kube-play.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ Note: The command `podman play kube` is an alias of `podman kube play`, and perf
Note: The command `podman kube down` can be used to stop and remove pods or containers based on the same Kubernetes YAML used
by `podman kube play` to create them.

Note: To customize the name of the infra container created during `podman kube play`, use the **io.podman.annotations.infra.name** annotation in the pod definition. This annotation is automatically set when generating a kube yaml from a pod that was created with the `--infra-name` flag set.

`Kubernetes PersistentVolumeClaims`

A Kubernetes PersistentVolumeClaim represents a Podman named volume. Only the PersistentVolumeClaim name is required by Podman to create a volume. Kubernetes annotations can be used to make use of the available options for Podman volumes.
Expand Down
4 changes: 4 additions & 0 deletions libpod/define/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ const (
// of the init container.
InitContainerType = "io.podman.annotations.init.container.type"

// InfraNameAnnotation is used by generate and play kube when the infra container is set by the user during
// pod creation
InfraNameAnnotation = "io.podman.annotations.infra.name"

// UlimitAnnotation is used by kube play when playing a kube yaml to specify the ulimits
// of the container
UlimitAnnotation = "io.podman.annotations.ulimit"
Expand Down
11 changes: 9 additions & 2 deletions libpod/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func (p *Pod) GenerateForKube(ctx context.Context, getService, useLongAnnotation
extraHost := make([]v1.HostAlias, 0)
hostNetwork := false
hostUsers := true
infraName := ""
if p.HasInfraContainer() {
infraContainer, err := p.getInfraContainer()
if err != nil {
Expand All @@ -90,8 +91,9 @@ func (p *Pod) GenerateForKube(ctx context.Context, getService, useLongAnnotation
}
hostNetwork = infraContainer.NetworkMode() == string(namespaces.NetworkMode(specgen.Host))
hostUsers = infraContainer.IDMappings().HostUIDMapping && infraContainer.IDMappings().HostGIDMapping
infraName = infraContainer.config.Name
}
pod, err := p.podWithContainers(ctx, allContainers, ports, hostNetwork, hostUsers, getService, useLongAnnotations, podmanOnly)
pod, err := p.podWithContainers(ctx, allContainers, ports, hostNetwork, hostUsers, getService, useLongAnnotations, podmanOnly, infraName)
if err != nil {
return nil, servicePorts, err
}
Expand Down Expand Up @@ -426,7 +428,7 @@ func containersToServicePorts(containers []v1.Container) ([]v1.ServicePort, erro
return sps, nil
}

func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, ports []v1.ContainerPort, hostNetwork, hostUsers, getService, useLongAnnotations, podmanOnly bool) (*v1.Pod, error) {
func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, ports []v1.ContainerPort, hostNetwork, hostUsers, getService, useLongAnnotations, podmanOnly bool, infraName string) (*v1.Pod, error) {
deDupPodVolumes := make(map[string]*v1.Volume)
first := true
podContainers := make([]v1.Container, 0, len(containers))
Expand Down Expand Up @@ -512,6 +514,11 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po
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] = truncateKubeAnnotation(infraName, useLongAnnotations)
}
}
}
podVolumes := []v1.Volume{}
Expand Down
2 changes: 1 addition & 1 deletion pkg/bindings/kube/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type PlayOptions struct {
Force *bool
// PublishPorts - configure how to expose ports configured inside the K8S YAML file
PublishPorts []string
// // Wait - indicates whether to return after having created the pods
// Wait - indicates whether to return after having created the pods
Wait *bool
ServiceContainer *bool
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/domain/infra/abi/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,11 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
podSpec.PodSpecGen.InfraContainerSpec = specgen.NewSpecGenerator(infraImage, false)
podSpec.PodSpecGen.InfraContainerSpec.NetworkOptions = p.NetworkOptions
podSpec.PodSpecGen.InfraContainerSpec.SdNotifyMode = define.SdNotifyModeIgnore
// If the infraNameAnnotation is set in the yaml, use that as the infra container name
// If not, fall back to the default infra container name
if v, ok := podYAML.Annotations[define.InfraNameAnnotation]; ok {
podSpec.PodSpecGen.InfraContainerSpec.Name = v
}

err = specgenutil.FillOutSpecGen(podSpec.PodSpecGen.InfraContainerSpec, &infraOptions, []string{})
if err != nil {
Expand Down
42 changes: 42 additions & 0 deletions test/e2e/generate_kube_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1838,4 +1838,46 @@ EXPOSE 2004-2005/tcp`, ALPINE)
Expect(err).ToNot(HaveOccurred())
Expect(pod.Annotations).To(HaveKeyWithValue(define.InspectAnnotationPublishAll+"/"+ctr, define.InspectResponseTrue))
})

It("podman generate kube on pod with --infra-name set", func() {
infraName := "infra-ctr"
podName := "test-pod"
podSession := podmanTest.Podman([]string{"pod", "create", "--infra-name", infraName, podName})
podSession.WaitWithDefaultTimeout()
Expect(podSession).Should(Exit(0))

session := podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

kube := podmanTest.Podman([]string{"generate", "kube", podName})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))

pod := new(v1.Pod)
err := yaml.Unmarshal(kube.Out.Contents(), pod)
Expect(err).ToNot(HaveOccurred())
Expect(pod.Annotations).To(HaveKeyWithValue(define.InfraNameAnnotation, infraName))
})

It("podman generate kube on pod without --infra-name set", func() {
podName := "test-pod"
podSession := podmanTest.Podman([]string{"pod", "create", podName})
podSession.WaitWithDefaultTimeout()
Expect(podSession).Should(Exit(0))

session := podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

kube := podmanTest.Podman([]string{"generate", "kube", podName})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))

// There should be no infra name annotation set if the --infra-name flag wasn't set during pod creation
pod := new(v1.Pod)
err := yaml.Unmarshal(kube.Out.Contents(), pod)
Expect(err).ToNot(HaveOccurred())
Expect(pod.Annotations).To(BeEmpty())
})
})
76 changes: 76 additions & 0 deletions test/e2e/play_kube_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5879,4 +5879,80 @@ EXPOSE 2004-2005/tcp`, ALPINE)
Expect(inspect).Should(Exit(0))
Expect(inspect.OutputToString()).To(Equal(defaultUmask))
})

// podman play with infra name annotation
It("podman play kube test with infra name annotation set", func() {
infraName := "infra-ctr"
podName := "mypod"
outputFile := filepath.Join(podmanTest.TempDir, "pod.yaml")
pod := podmanTest.Podman([]string{"pod", "create", "--infra-name", infraName, podName})
pod.WaitWithDefaultTimeout()
Expect(pod).Should(Exit(0))

ctr := podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"})
ctr.WaitWithDefaultTimeout()
Expect(ctr).Should(Exit(0))

// Generate kube yaml and it should have the infra name annotation set
gen := podmanTest.Podman([]string{"kube", "generate", "-f", outputFile, podName})
gen.WaitWithDefaultTimeout()
Expect(gen).Should(Exit(0))
// Remove the pod so it can be recreated via kube play
rm := podmanTest.Podman([]string{"pod", "rm", "-f", podName})
rm.WaitWithDefaultTimeout()
Expect(rm).Should(Exit(0))

kube := podmanTest.Podman([]string{"kube", "play", outputFile})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))

// Expect the number of containers created to be 2, infra, and regular container
numOfCtrs := podmanTest.NumberOfContainers()
Expect(numOfCtrs).To(Equal(2))

ps := podmanTest.Podman([]string{"ps", "--format", "{{.Names}}"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(Exit(0))
Expect(ps.OutputToString()).To(ContainSubstring(infraName))
})

// podman play with default infra name
It("podman play kube test with default infra name", func() {
podName := "mypod"
outputFile := filepath.Join(podmanTest.TempDir, "pod.yaml")
pod := podmanTest.Podman([]string{"pod", "create", podName})
pod.WaitWithDefaultTimeout()
Expect(pod).Should(Exit(0))

ctr := podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"})
ctr.WaitWithDefaultTimeout()
Expect(ctr).Should(Exit(0))

// Generate kube yaml and it should have the infra name annotation set
gen := podmanTest.Podman([]string{"kube", "generate", "-f", outputFile, podName})
gen.WaitWithDefaultTimeout()
Expect(gen).Should(Exit(0))
// Remove the pod so it can be recreated via kube play
rm := podmanTest.Podman([]string{"pod", "rm", "-f", podName})
rm.WaitWithDefaultTimeout()
Expect(rm).Should(Exit(0))

kube := podmanTest.Podman([]string{"play", "kube", outputFile})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))

// Expect the number of containers created to be 2, infra, and regular container
numOfCtrs := podmanTest.NumberOfContainers()
Expect(numOfCtrs).To(Equal(2))

podPs := podmanTest.Podman([]string{"pod", "ps", "-q"})
podPs.WaitWithDefaultTimeout()
Expect(podPs).Should(Exit(0))
podID := podPs.OutputToString()

ps := podmanTest.Podman([]string{"ps", "--format", "{{.Names}}"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(Exit(0))
Expect(ps.OutputToString()).To(ContainSubstring(podID[:12] + "-infra"))
})
})

0 comments on commit 4ff21cf

Please sign in to comment.