From 18197e66b7a264fb468a9fc23b60f13c33314b17 Mon Sep 17 00:00:00 2001 From: DionJones615 Date: Tue, 11 Jun 2024 17:57:48 -0400 Subject: [PATCH] feat: expose jenkins master terminationGracePeriodSeconds (#1012) Co-authored-by: brokenpip3 --- api/v1alpha2/jenkins_types.go | 7 +++++ api/v1alpha2/zz_generated.deepcopy.go | 5 ++++ chart/jenkins-operator/README.md | 1 + chart/jenkins-operator/crds/jenkins-crd.yaml | 4 +++ chart/jenkins-operator/templates/jenkins.yaml | 5 +++- chart/jenkins-operator/values.yaml | 4 +++ config/crd/bases/jenkins.io_jenkins.yaml | 8 ++++++ pkg/configuration/base/resources/pod.go | 26 ++++++++++++------- pkg/constants/constants.go | 2 ++ test/e2e/configuration_test.go | 3 +++ 10 files changed, 54 insertions(+), 11 deletions(-) diff --git a/api/v1alpha2/jenkins_types.go b/api/v1alpha2/jenkins_types.go index 6064dccfd..7ffed5a86 100644 --- a/api/v1alpha2/jenkins_types.go +++ b/api/v1alpha2/jenkins_types.go @@ -386,6 +386,13 @@ type JenkinsMaster struct { // HostAliases for Jenkins master pod and SeedJob agent // +optional HostAliases []corev1.HostAlias `json:"hostAliases,omitempty"` + + // The grace period is the duration in seconds after the processes running in the pod are sent + // a termination signal and the time when the processes are forcibly halted with a kill signal. + // Set this value longer than the expected cleanup time for your process. + // Defaults to 30 seconds. + // +optional + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"` } // Service defines Kubernetes service attributes diff --git a/api/v1alpha2/zz_generated.deepcopy.go b/api/v1alpha2/zz_generated.deepcopy.go index 6caa129b7..ef06493c8 100644 --- a/api/v1alpha2/zz_generated.deepcopy.go +++ b/api/v1alpha2/zz_generated.deepcopy.go @@ -368,6 +368,11 @@ func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.TerminationGracePeriodSeconds != nil { + in, out := &in.TerminationGracePeriodSeconds, &out.TerminationGracePeriodSeconds + *out = new(int64) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsMaster. diff --git a/chart/jenkins-operator/README.md b/chart/jenkins-operator/README.md index ccaaae9c4..4ce0beb71 100644 --- a/chart/jenkins-operator/README.md +++ b/chart/jenkins-operator/README.md @@ -90,6 +90,7 @@ Kubernetes native operator which fully manages Jenkins on Kubernetes | jenkins.seedJobAgentImage | string | `""` | | | jenkins.seedJobs | list | `[]` | | | jenkins.serviceAccount.annotations | object | `{}` | | +| jenkins.terminationGracePeriodSeconds | int | `30` | | | jenkins.tolerations | list | `[]` | | | jenkins.validateSecurityWarnings | bool | `false` | | | jenkins.volumeMounts | list | `[]` | | diff --git a/chart/jenkins-operator/crds/jenkins-crd.yaml b/chart/jenkins-operator/crds/jenkins-crd.yaml index 87d407049..2caa71d2a 100644 --- a/chart/jenkins-operator/crds/jenkins-crd.yaml +++ b/chart/jenkins-operator/crds/jenkins-crd.yaml @@ -1330,6 +1330,10 @@ spec: type: string type: object type: object + terminationGracePeriodSeconds: + description: 'Optional duration in seconds the pod needs to terminate gracefully.' + type: integer + default: 30 tolerations: description: If specified, the pod's tolerations. items: diff --git a/chart/jenkins-operator/templates/jenkins.yaml b/chart/jenkins-operator/templates/jenkins.yaml index 0a918a3d9..72c18c239 100644 --- a/chart/jenkins-operator/templates/jenkins.yaml +++ b/chart/jenkins-operator/templates/jenkins.yaml @@ -115,6 +115,9 @@ spec: {{- with .Values.jenkins.hostAliases }} hostAliases: {{ toYaml . | nindent 4 }} {{- end }} + {{- if .Values.jenkins.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.jenkins.terminationGracePeriodSeconds }} + {{- end }} containers: - name: jenkins-master image: {{ .Values.jenkins.image }} @@ -137,7 +140,7 @@ spec: {{- if .Values.jenkins.backup.enabled }} - name: {{ .Values.jenkins.backup.containerName }} image: {{ .Values.jenkins.backup.image }} - imagePullPolicy: {{ .Values.jenkins.imagePullPolicy }} + imagePullPolicy: {{ .Values.jenkins.imagePullPolicy }} {{- with .Values.jenkins.backup.resources }} resources: {{ toYaml . | nindent 10 }} {{- end }} diff --git a/chart/jenkins-operator/values.yaml b/chart/jenkins-operator/values.yaml index ed1e401d8..f2eba788a 100644 --- a/chart/jenkins-operator/values.yaml +++ b/chart/jenkins-operator/values.yaml @@ -65,6 +65,10 @@ jenkins: # - "foo.remote" # - "bar.remote" + # Optional duration in seconds the pod needs to terminate gracefully. + # Default 30sec + terminationGracePeriodSeconds: 30 + # validateSecurityWarnings enables or disables validating potential security warnings in Jenkins plugins via admission webhooks. validateSecurityWarnings: false diff --git a/config/crd/bases/jenkins.io_jenkins.yaml b/config/crd/bases/jenkins.io_jenkins.yaml index 87d407049..0e3a40e5d 100644 --- a/config/crd/bases/jenkins.io_jenkins.yaml +++ b/config/crd/bases/jenkins.io_jenkins.yaml @@ -1330,6 +1330,14 @@ spec: type: string type: object type: object + terminationGracePeriodSeconds: + description: The grace period is the duration in seconds after + the processes running in the pod are sent a termination signal + and the time when the processes are forcibly halted with a kill + signal. Set this value longer than the expected cleanup time + for your process. Defaults to 30 seconds. + format: int64 + type: integer tolerations: description: If specified, the pod's tolerations. items: diff --git a/pkg/configuration/base/resources/pod.go b/pkg/configuration/base/resources/pod.go index 1a2949714..783ccaa2b 100644 --- a/pkg/configuration/base/resources/pod.go +++ b/pkg/configuration/base/resources/pod.go @@ -369,20 +369,26 @@ func NewJenkinsMasterPod(objectMeta metav1.ObjectMeta, jenkins *v1alpha2.Jenkins objectMeta.Name = GetJenkinsMasterPodName(jenkins) objectMeta.Labels = GetJenkinsMasterPodLabels(*jenkins) + if jenkins.Spec.Master.TerminationGracePeriodSeconds == nil { + defaultGracePeriod := constants.DefaultTerminationGracePeriodSeconds + jenkins.Spec.Master.TerminationGracePeriodSeconds = &defaultGracePeriod + } + return &corev1.Pod{ TypeMeta: buildPodTypeMeta(), ObjectMeta: objectMeta, Spec: corev1.PodSpec{ - ServiceAccountName: serviceAccountName, - RestartPolicy: corev1.RestartPolicyNever, - NodeSelector: jenkins.Spec.Master.NodeSelector, - Containers: newContainers(jenkins), - Volumes: append(GetJenkinsMasterPodBaseVolumes(jenkins), jenkins.Spec.Master.Volumes...), - SecurityContext: jenkins.Spec.Master.SecurityContext, - ImagePullSecrets: jenkins.Spec.Master.ImagePullSecrets, - Tolerations: jenkins.Spec.Master.Tolerations, - PriorityClassName: jenkins.Spec.Master.PriorityClassName, - HostAliases: jenkins.Spec.Master.HostAliases, + ServiceAccountName: serviceAccountName, + RestartPolicy: corev1.RestartPolicyNever, + NodeSelector: jenkins.Spec.Master.NodeSelector, + Containers: newContainers(jenkins), + Volumes: append(GetJenkinsMasterPodBaseVolumes(jenkins), jenkins.Spec.Master.Volumes...), + SecurityContext: jenkins.Spec.Master.SecurityContext, + ImagePullSecrets: jenkins.Spec.Master.ImagePullSecrets, + Tolerations: jenkins.Spec.Master.Tolerations, + PriorityClassName: jenkins.Spec.Master.PriorityClassName, + HostAliases: jenkins.Spec.Master.HostAliases, + TerminationGracePeriodSeconds: jenkins.Spec.Master.TerminationGracePeriodSeconds, }, } } diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 2a2be9e30..7e26f4115 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -15,4 +15,6 @@ const ( DefaultSlavePortInt32 = int32(50000) // JavaOpsVariableName is the name of environment variable which consists Jenkins Java options JavaOpsVariableName = "JAVA_OPTS" + // DefaultTerminationGracePeriodSeconds is the default pod termination period second + DefaultTerminationGracePeriodSeconds = int64(30) ) diff --git a/test/e2e/configuration_test.go b/test/e2e/configuration_test.go index 107f971cc..4bef64e04 100644 --- a/test/e2e/configuration_test.go +++ b/test/e2e/configuration_test.go @@ -111,6 +111,8 @@ func verifyJenkinsMasterPodAttributes(jenkins *v1alpha2.Jenkins) { jenkinsPod := getJenkinsMasterPod(jenkins) jenkins = getJenkins(jenkins.Namespace, jenkins.Name) + defaultGracePeriod := constants.DefaultTerminationGracePeriodSeconds + assertMapContainsElementsFromAnotherMap(jenkins.Spec.Master.Annotations, jenkinsPod.ObjectMeta.Annotations) Expect(jenkinsPod.Spec.NodeSelector).Should(Equal(jenkins.Spec.Master.NodeSelector)) @@ -125,6 +127,7 @@ func verifyJenkinsMasterPodAttributes(jenkins *v1alpha2.Jenkins) { Expect(jenkinsPod.Labels).Should(Equal(resources.GetJenkinsMasterPodLabels(*jenkins))) Expect(jenkinsPod.Spec.PriorityClassName).Should(Equal(jenkins.Spec.Master.PriorityClassName)) + Expect(jenkinsPod.Spec.TerminationGracePeriodSeconds).Should(Equal(&defaultGracePeriod)) for _, actualContainer := range jenkinsPod.Spec.Containers { if actualContainer.Name == resources.JenkinsMasterContainerName {