Skip to content

Commit

Permalink
Merge pull request #19914 from umohnani8/term
Browse files Browse the repository at this point in the history
Add support for kube TerminationGracePeriodSeconds
  • Loading branch information
openshift-merge-robot authored Sep 11, 2023
2 parents fd886d6 + d9a8546 commit 325736f
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docs/kubernetes_support.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Note: **N/A** means that the option cannot be supported in a single-node Podman
| topologySpreadConstraints\.labelSelector | N/A |
| topologySpreadConstraints\.minDomains | N/A |
| restartPolicy ||
| terminationGracePeriod | no |
| terminationGracePeriodSeconds | |
| activeDeadlineSeconds | no |
| readinessGates\.conditionType | no |
| hostname ||
Expand Down
36 changes: 30 additions & 6 deletions libpod/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,10 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po
podInitCtrs := []v1.Container{}
podAnnotations := make(map[string]string)
dnsInfo := v1.PodDNSConfig{}
var hostname string
var (
hostname string
stopTimeout *uint
)

// Let's sort the containers in order of created time
// This will ensure that the init containers are defined in the correct order in the kube yaml
Expand Down Expand Up @@ -463,6 +466,12 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po
}
}

// Pick the first container that has a stop-timeout set and use that value
// Ignore podman's default
if ctr.config.StopTimeout != util.DefaultContainerConfig().Engine.StopTimeout && stopTimeout == nil {
stopTimeout = &ctr.config.StopTimeout
}

ctr, volumes, _, annotations, err := containerToV1Container(ctx, ctr, getService)
if err != nil {
return nil, err
Expand Down Expand Up @@ -536,10 +545,11 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po
&dnsInfo,
hostNetwork,
hostUsers,
hostname), nil
hostname,
stopTimeout), nil
}

func newPodObject(podName string, annotations map[string]string, initCtrs, containers []v1.Container, volumes []v1.Volume, dnsOptions *v1.PodDNSConfig, hostNetwork, hostUsers bool, hostname string) *v1.Pod {
func newPodObject(podName string, annotations map[string]string, initCtrs, containers []v1.Container, volumes []v1.Volume, dnsOptions *v1.PodDNSConfig, hostNetwork, hostUsers bool, hostname string, stopTimeout *uint) *v1.Pod {
tm := v12.TypeMeta{
Kind: "Pod",
APIVersion: "v1",
Expand Down Expand Up @@ -571,6 +581,10 @@ func newPodObject(podName string, annotations map[string]string, initCtrs, conta
if dnsOptions != nil && (len(dnsOptions.Nameservers)+len(dnsOptions.Searches)+len(dnsOptions.Options) > 0) {
ps.DNSConfig = dnsOptions
}
if stopTimeout != nil {
terminationGracePeriod := int64(*stopTimeout)
ps.TerminationGracePeriodSeconds = &terminationGracePeriod
}
p := v1.Pod{
TypeMeta: tm,
ObjectMeta: om,
Expand All @@ -590,8 +604,11 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container, getServic
podDNS := v1.PodDNSConfig{}
kubeAnnotations := make(map[string]string)
ctrNames := make([]string, 0, len(ctrs))
var hostname string
var restartPolicy *string
var (
hostname string
restartPolicy *string
stopTimeout *uint
)
for _, ctr := range ctrs {
ctrNames = append(ctrNames, removeUnderscores(ctr.Name()))
for k, v := range ctr.config.Spec.Annotations {
Expand All @@ -616,6 +633,12 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container, getServic
}
}

// Pick the first container that has a stop-timeout set and use that value
// Ignore podman's default
if ctr.config.StopTimeout != util.DefaultContainerConfig().Engine.StopTimeout && stopTimeout == nil {
stopTimeout = &ctr.config.StopTimeout
}

// Use the restart policy of the first non-init container
if !isInit && restartPolicy == nil {
restartPolicy = &ctr.config.RestartPolicy
Expand Down Expand Up @@ -707,7 +730,8 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container, getServic
&podDNS,
hostNetwork,
hostUsers,
hostname)
hostname,
stopTimeout)

// Set the pod's restart policy
policy := ""
Expand Down
4 changes: 4 additions & 0 deletions pkg/domain/infra/abi/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,10 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
Volumes: volumes,
}

if podYAML.Spec.TerminationGracePeriodSeconds != nil {
specgenOpts.TerminationGracePeriodSeconds = podYAML.Spec.TerminationGracePeriodSeconds
}

specGen, err := kube.ToSpecGen(ctx, &specgenOpts)
if err != nil {
return nil, nil, err
Expand Down
8 changes: 8 additions & 0 deletions pkg/specgen/generate/kube/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ type CtrSpecGenOptions struct {
InitContainerType string
// PodSecurityContext is the security context specified for the pod
PodSecurityContext *v1.PodSecurityContext
// TerminationGracePeriodSeconds is the grace period given to a container to stop before being forcefully killed
TerminationGracePeriodSeconds *int64
}

func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGenerator, error) {
Expand Down Expand Up @@ -584,6 +586,12 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
s.Labels[systemdDefine.EnvVariable] = unit
}

// Set the stopTimeout if terminationGracePeriodSeconds is set in the kube yaml
if opts.TerminationGracePeriodSeconds != nil {
timeout := uint(*opts.TerminationGracePeriodSeconds)
s.StopTimeout = &timeout
}

return s, nil
}

Expand Down
22 changes: 22 additions & 0 deletions test/e2e/generate_kube_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ var _ = Describe("Podman kube generate", 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.Spec.TerminationGracePeriodSeconds).To(BeNil())

numContainers := 0
for range pod.Spec.Containers {
Expand Down Expand Up @@ -1880,4 +1881,25 @@ EXPOSE 2004-2005/tcp`, ALPINE)
Expect(err).ToNot(HaveOccurred())
Expect(pod.Annotations).To(BeEmpty())
})

It("podman generate kube on pod with --stop-timeout set for ctr", 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, "--stop-timeout", "20", ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

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

// TerminationGracePeriodSeconds should be set to 20
pod := new(v1.Pod)
err := yaml.Unmarshal(kube.Out.Contents(), pod)
Expect(err).ToNot(HaveOccurred())
Expect(int(*pod.Spec.TerminationGracePeriodSeconds)).To(Equal(20))
})
})
23 changes: 23 additions & 0 deletions test/e2e/play_kube_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5991,4 +5991,27 @@ EXPOSE 2004-2005/tcp`, ALPINE)
Expect(inspect).Should(Exit(0))
Expect(inspect.OutputToString()).To(ContainSubstring(`FOO=bar`))
})

It("podman kube play with TerminationGracePeriodSeconds set", func() {
ctrName := "ctr"
ctrNameInPod := "ctr-pod-ctr"
outputFile := filepath.Join(podmanTest.TempDir, "pod.yaml")

create := podmanTest.Podman([]string{"create", "--restart", "never", "--stop-timeout", "20", "--name", ctrName, ALPINE})
create.WaitWithDefaultTimeout()
Expect(create).Should(Exit(0))

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

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

inspect := podmanTest.Podman([]string{"inspect", ctrNameInPod, "-f", "{{ .Config.StopTimeout }}"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(Exit(0))
Expect(inspect.OutputToString()).To(Equal("20"))
})
})

0 comments on commit 325736f

Please sign in to comment.