pkg/resources/statefulset/podspec_util.go (59 lines of code) (raw):

// Copyright (c) 2022, 2024, Oracle and/or its affiliates. // // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ package statefulset import ( v1 "github.com/mysql/ndb-operator/pkg/apis/ndbcontroller/v1" corev1 "k8s.io/api/core/v1" ) func addResourcesToContainer(container *corev1.Container, resources *corev1.ResourceRequirements) { if container.Resources.Limits == nil { container.Resources.Limits = make(corev1.ResourceList) } if container.Resources.Requests == nil { container.Resources.Requests = make(corev1.ResourceList) } // Copy individual limits and requests separately to ensure that we overwrite // the defaults only if the ndbPodSpec has specified a ResourceName explicitly. for key, value := range resources.Limits { container.Resources.Limits[key] = value } for key, value := range resources.Requests { container.Resources.Requests[key] = value } } // Copy values from ndbPodSpec into podSpec func CopyPodSpecFromNdbPodSpec(podSpec *corev1.PodSpec, ndbPodSpec *v1.NdbClusterPodSpec) { if ndbPodSpec == nil { // Nothing to do return } if podSpec == nil { panic("nil podSpec sent to CopyPodSpecFromNdbPodSpec") } // Copy the Resource requests/limits if ndbPodSpec.Resources != nil { resources := ndbPodSpec.Resources // Set the Resources request via the pod's container if len(podSpec.Containers) == 0 { panic("CopyPodSpecFromNdbPodSpec should be called only after the containers are set") } // Add resources to main containers addResourcesToContainer(&podSpec.Containers[0], resources) // Add resources to init containers // Kubernetes identifies the highest value for each resource among all init containers, then compares // it with the sum of resource values across the containers and selects the highest value // to determine node scheduling for this pod. So, setting the resource field of all init // containers same as the main container does not impact the node scheduling process. But, this hack // is essential because OpenShift raises warnings when a container lacks a resource field. for i := range podSpec.InitContainers { addResourcesToContainer(&podSpec.InitContainers[i], resources) } } // Copy the NodeSelector completely as the operator won't be setting any default values on it if len(ndbPodSpec.NodeSelector) != 0 { podSpec.NodeSelector = make(map[string]string) for key, value := range ndbPodSpec.NodeSelector { podSpec.NodeSelector[key] = value } } // Copy Affinities one by one and preserve any default values // if that particular Affinity has not been set in ndbPodSpec if ndbPodSpec.Affinity != nil { if podSpec.Affinity == nil { podSpec.Affinity = new(corev1.Affinity) } // Handle NodeAffinity if ndbPodSpec.Affinity.NodeAffinity != nil { podSpec.Affinity.NodeAffinity = ndbPodSpec.Affinity.NodeAffinity.DeepCopy() } // Handle PodAffinity if ndbPodSpec.Affinity.PodAffinity != nil { podSpec.Affinity.PodAffinity = ndbPodSpec.Affinity.PodAffinity.DeepCopy() } // Handle PodAntiAffinity if ndbPodSpec.Affinity.PodAntiAffinity != nil { podSpec.Affinity.PodAntiAffinity = ndbPodSpec.Affinity.PodAntiAffinity.DeepCopy() } } // Copy the scheduler name as it is podSpec.SchedulerName = ndbPodSpec.SchedulerName // Copy all the Tolerations podSpec.Tolerations = append(podSpec.Tolerations, ndbPodSpec.Tolerations...) }