Skip to content

CSPL-3354: REBASED Add Lifecycle Hooks and Configurable Termination Grace Period to Splunk Operator #1450

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions api/v4/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ type Spec struct {

// TopologySpreadConstraint https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/
TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`

TerminationGracePeriodSeconds int64 `json:"terminationGracePeriodSeconds"`
}

// Phase is used to represent the current phase of a custom resource
Expand Down
3 changes: 3 additions & 0 deletions config/crd/bases/enterprise.splunk.com_clustermanagers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2132,6 +2132,9 @@ spec:
format: int32
type: integer
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
tolerations:
description: Pod's tolerations for Kubernetes node's taint
items:
Expand Down
3 changes: 3 additions & 0 deletions config/crd/bases/enterprise.splunk.com_clustermasters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2128,6 +2128,9 @@ spec:
format: int32
type: integer
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
tolerations:
description: Pod's tolerations for Kubernetes node's taint
items:
Expand Down
6 changes: 6 additions & 0 deletions config/crd/bases/enterprise.splunk.com_indexerclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,9 @@ spec:
format: int32
type: integer
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
tolerations:
description: Pod's tolerations for Kubernetes node's taint
items:
Expand Down Expand Up @@ -5643,6 +5646,9 @@ spec:
format: int32
type: integer
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
tolerations:
description: Pod's tolerations for Kubernetes node's taint
items:
Expand Down
3 changes: 3 additions & 0 deletions config/crd/bases/enterprise.splunk.com_licensemanagers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2005,6 +2005,9 @@ spec:
format: int32
type: integer
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
tolerations:
description: Pod's tolerations for Kubernetes node's taint
items:
Expand Down
3 changes: 3 additions & 0 deletions config/crd/bases/enterprise.splunk.com_licensemasters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2000,6 +2000,9 @@ spec:
format: int32
type: integer
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
tolerations:
description: Pod's tolerations for Kubernetes node's taint
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2007,6 +2007,9 @@ spec:
format: int32
type: integer
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
tolerations:
description: Pod's tolerations for Kubernetes node's taint
items:
Expand Down Expand Up @@ -6127,6 +6130,9 @@ spec:
format: int32
type: integer
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
tolerations:
description: Pod's tolerations for Kubernetes node's taint
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2018,6 +2018,9 @@ spec:
format: int32
type: integer
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
tolerations:
description: Pod's tolerations for Kubernetes node's taint
items:
Expand Down Expand Up @@ -6466,6 +6469,9 @@ spec:
format: int32
type: integer
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
tolerations:
description: Pod's tolerations for Kubernetes node's taint
items:
Expand Down
6 changes: 6 additions & 0 deletions config/crd/bases/enterprise.splunk.com_standalones.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2129,6 +2129,9 @@ spec:
format: int32
type: integer
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
tolerations:
description: Pod's tolerations for Kubernetes node's taint
items:
Expand Down Expand Up @@ -6493,6 +6496,9 @@ spec:
format: int32
type: integer
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
tolerations:
description: Pod's tolerations for Kubernetes node's taint
items:
Expand Down
54 changes: 54 additions & 0 deletions pkg/splunk/controller/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,18 @@ func MergePodSpecUpdates(ctx context.Context, current *corev1.PodSpec, revised *
}
}

if (current.TerminationGracePeriodSeconds == nil && revised.TerminationGracePeriodSeconds != nil) ||
(current.TerminationGracePeriodSeconds != nil && revised.TerminationGracePeriodSeconds == nil) ||
(current.TerminationGracePeriodSeconds != nil && revised.TerminationGracePeriodSeconds != nil &&
*current.TerminationGracePeriodSeconds != *revised.TerminationGracePeriodSeconds) {

scopedLog.Info("Pod TerminationGracePeriodSeconds differs",
"current", current.TerminationGracePeriodSeconds,
"revised", revised.TerminationGracePeriodSeconds)
current.TerminationGracePeriodSeconds = revised.TerminationGracePeriodSeconds
result = true
}

// check for changes in container images; assume that the ordering is same for pods with > 1 container
if len(current.Containers) != len(revised.Containers) {
scopedLog.Info("Pod Container counts differ",
Expand Down Expand Up @@ -244,12 +256,54 @@ func MergePodSpecUpdates(ctx context.Context, current *corev1.PodSpec, revised *
current.Containers[idx].StartupProbe = revised.Containers[idx].StartupProbe
result = true
}

// check PreStop Lifecycle
if hasPreStopChanged(current.Containers[idx].Lifecycle, revised.Containers[idx].Lifecycle) {
scopedLog.Info("Pod Container PreStop Lifecycle differ",
"current", current.Containers[idx].Lifecycle,
"revised", revised.Containers[idx].Lifecycle)
setPreStopLifecycleHandler(current, idx)
result = true
}
}
}

return result
}

// Function to check if PreStop Lifecycle has changed
func hasPreStopChanged(current, revised *corev1.Lifecycle) bool {
// If both are nil, there's no change
if current == nil && revised == nil {
return false
}

// If one is nil and the other isn't, there's a change
if (current == nil || current.PreStop == nil || current.PreStop.Exec == nil) &&
(revised != nil && revised.PreStop != nil && revised.PreStop.Exec != nil) {
return true
}

if (revised == nil || revised.PreStop == nil || revised.PreStop.Exec == nil) &&
(current != nil && current.PreStop != nil && current.PreStop.Exec != nil) {
return true
}

// If both are non-nil, compare the command
return !reflect.DeepEqual(current.PreStop.Exec.Command, revised.PreStop.Exec.Command)
}

// Set the PreStop lifecycle handler for the specified container index
func setPreStopLifecycleHandler(podSpec *corev1.PodSpec, idx int) {
podSpec.Containers[idx].Lifecycle = &corev1.Lifecycle{
PreStop: &corev1.LifecycleHandler{
Exec: &corev1.ExecAction{
Command: []string{"/bin/sh", "-c", "/opt/splunk/bin/splunk offline && /opt/splunk/bin/splunk stop"},
},
},
}
}

// SortStatefulSetSlices sorts required slices in a statefulSet
func SortStatefulSetSlices(ctx context.Context, current *corev1.PodSpec, name string) error {
reqLogger := log.FromContext(ctx)
Expand Down
43 changes: 40 additions & 3 deletions pkg/splunk/controller/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ func TestMergePodUpdates(t *testing.T) {
matcher = func() bool { return reflect.DeepEqual(current.Spec.InitContainers, revised.Spec.InitContainers) }
podUpdateTester("InitContainer image changed")

// check Termination Grace Period updated
terminationGracePeriodSeconds := int64(60)
revised.Spec.TerminationGracePeriodSeconds = &terminationGracePeriodSeconds
matcher = func() bool {
if current.Spec.TerminationGracePeriodSeconds == nil {
return true
}
if current.Spec.TerminationGracePeriodSeconds == revised.Spec.TerminationGracePeriodSeconds {
return true
}
return false
}
podUpdateTester("TerminationGracePeriod updated")

// check new container added
revised.Spec.Containers = []corev1.Container{{Image: "splunk/splunk"}}
matcher = func() bool { return reflect.DeepEqual(current.Spec.Containers, revised.Spec.Containers) }
Expand All @@ -108,12 +122,16 @@ func TestMergePodUpdates(t *testing.T) {
// check container different Ports
revised.Spec.Containers = []corev1.Container{{Image: "splunk/splunk"}}
revised.Spec.Containers[0].Ports = []corev1.ContainerPort{{ContainerPort: 8000}}
matcher = func() bool { return reflect.DeepEqual(current.Spec.Containers, revised.Spec.Containers) }
matcher = func() bool {
return current.Spec.Containers[0].Ports[0].ContainerPort == revised.Spec.Containers[0].Ports[0].ContainerPort
}
podUpdateTester("Container Ports")

// check container different VolumeMounts
revised.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{{Name: "mnt-splunk"}}
matcher = func() bool { return reflect.DeepEqual(current.Spec.Containers, revised.Spec.Containers) }
matcher = func() bool {
return revised.Spec.Containers[0].VolumeMounts[0].Name == current.Spec.Containers[0].VolumeMounts[0].Name
}
podUpdateTester("Container VolumeMounts")

// check container different Resources
Expand All @@ -127,7 +145,20 @@ func TestMergePodUpdates(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("512Mi"),
},
}
matcher = func() bool { return reflect.DeepEqual(current.Spec.Containers, revised.Spec.Containers) }
matcher = func() bool {
if len(current.Spec.Containers) != len(revised.Spec.Containers) {
return false
}

for i := range current.Spec.Containers {
if !reflect.DeepEqual(current.Spec.Containers[i].Resources.Requests, revised.Spec.Containers[i].Resources.Requests) ||
!reflect.DeepEqual(current.Spec.Containers[i].Resources.Limits, revised.Spec.Containers[i].Resources.Limits) {
return false
}
}

return true
}
podUpdateTester("Container Resources")

// check pod env update
Expand Down Expand Up @@ -206,6 +237,12 @@ func TestMergePodUpdates(t *testing.T) {
}
podUpdateTester("Pod TopologySpreadConstraints changed")

// check Pre Stop Lifecycle Handler updated
idx := 0
setPreStopLifecycleHandler(&revised.Spec, idx)
matcher = func() bool { return reflect.DeepEqual(current.Spec.Containers, revised.Spec.Containers) }
podUpdateTester("PreStopLifecycleHandler updated")

// check container removed
revised.Spec.Containers = []corev1.Container{}
matcher = func() bool { return reflect.DeepEqual(current.Spec.Containers, revised.Spec.Containers) }
Expand Down
Loading
Loading