utils

package
v0.1.0-alpha.12-rc1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const InitialScheduleGrace = 5 * time.Second

InitialScheduleGrace is the small window after PodClique / PodCliqueScalingGroup creation in which a flipped Status of a status condition is treated as the first-time-set rather than a transition from a different state. WasPCLQEverScheduled / WasPCSGEverHealthy use it to absorb the gap between the apiserver setting CreationTimestamp and the first reconcile that mutates the relevant condition.

Variables

View Source
var (
	// ErrTopologyNameMissing indicates that a constrained level has no effective topologyName after inheritance is applied.
	ErrTopologyNameMissing = errors.New("topology constraints require an explicit or inherited topologyName")
	// ErrPackDomainMissing indicates that a topologyConstraint exists but does not specify any pack domain.
	ErrPackDomainMissing = errors.New("topology constraints require at least one pack domain")
	// ErrMultipleTopologyNamesUnsupported indicates that topology constraints within a single PCS reference different topology names.
	ErrMultipleTopologyNamesUnsupported = errors.New("multiple topology names within a single PodCliqueSet are not supported")
)

Functions

func AddEnvVarsToContainers

func AddEnvVarsToContainers(containers []corev1.Container, envVars []corev1.EnvVar)

AddEnvVarsToContainers adds the given environment variables to the Pod containers.

func ComputePCLQPodTemplateHash

func ComputePCLQPodTemplateHash(pclqTemplateSpec *grovecorev1alpha1.PodCliqueTemplateSpec, priorityClassName string) string

ComputePCLQPodTemplateHash computes the pod template hash for the PCLQ pod spec.

func FindExplicitTopologyNameForPodCliqueSet

func FindExplicitTopologyNameForPodCliqueSet(pcs *grovecorev1alpha1.PodCliqueSet) (string, error)

FindExplicitTopologyNameForPodCliqueSet returns one explicit topologyName from the PCS. It is intended for callers operating on already-validated PCS objects where all explicit topologyName values are expected to match. Callers that need to distinguish "no topology constraints at all" from missing explicit topologyName values must first call HasAnyTopologyConstraint.

func FindPodCliqueTemplateSpecByName

func FindPodCliqueTemplateSpecByName(pcs *grovecorev1alpha1.PodCliqueSet, pclqName string) *grovecorev1alpha1.PodCliqueTemplateSpec

FindPodCliqueTemplateSpecByName retrieves the PodCliqueTemplateSpec from the PodCliqueSet by its name. If there is no matching PodCliqueTemplateSpec, it returns nil.

func FindScalingGroupConfigForClique

func FindScalingGroupConfigForClique(scalingGroupConfigs []grovecorev1alpha1.PodCliqueScalingGroupConfig, cliqueName string) *grovecorev1alpha1.PodCliqueScalingGroupConfig

FindScalingGroupConfigForClique searches through the scaling group configurations to find the one that contains the specified clique name in its CliqueNames list.

Returns the matching PodCliqueScalingGroupConfig and true if found, or an empty config and false if not found.

func GenerateDependencyNamesForBasePodGang

func GenerateDependencyNamesForBasePodGang(pcs *grovecorev1alpha1.PodCliqueSet, pcsReplicaIndex int, parentCliqueName string) []string

GenerateDependencyNamesForBasePodGang generates the FQNs of all PodCliques that would qualify as a dependency.

func GetExistingPodGangs

func GetExistingPodGangs(ctx context.Context, cl client.Client, pcsObjectMeta metav1.ObjectMeta, namespace string) ([]groveschedulerv1alpha1.PodGang, error)

GetExistingPodGangs fetches all existing PodGangs that are managed by Grove in the given namespace.

func GetExpectedPCLQNamesGroupByOwner

func GetExpectedPCLQNamesGroupByOwner(pcs *grovecorev1alpha1.PodCliqueSet) (expectedPCLQNamesForPCS []string, expectedPCLQNamesForPCSG []string)

GetExpectedPCLQNamesGroupByOwner returns the expected unqualified PodClique names which are either owned by PodCliqueSet or PodCliqueScalingGroup.

func GetExpectedPCLQPodTemplateHash

func GetExpectedPCLQPodTemplateHash(pcs *grovecorev1alpha1.PodCliqueSet, pclqObjectMeta metav1.ObjectMeta) (string, error)

GetExpectedPCLQPodTemplateHash finds the matching PodCliqueTemplateSpec from the PodCliqueSet and computes the pod template hash for the PCLQ pod spec.

func GetExpectedPCSGFQNsForPCS

func GetExpectedPCSGFQNsForPCS(pcs *grovecorev1alpha1.PodCliqueSet) []string

GetExpectedPCSGFQNsForPCS computes the FQNs for all PodCliqueScalingGroups defined in PCS for the given replica.

func GetExpectedPCSGFQNsPerPCSReplica

func GetExpectedPCSGFQNsPerPCSReplica(pcs *grovecorev1alpha1.PodCliqueSet) map[int][]string

GetExpectedPCSGFQNsPerPCSReplica computes the FQNs for all PodCliqueScalingGroups defined in PCS for each replica.

func GetExpectedStandAlonePCLQFQNsPerPCSReplica

func GetExpectedStandAlonePCLQFQNsPerPCSReplica(pcs *grovecorev1alpha1.PodCliqueSet) map[int][]string

GetExpectedStandAlonePCLQFQNsPerPCSReplica computes the FQNs for all standalone PodCliques defined in PCS for each replica.

func GetMinAvailableBreachedPCLQInfo

func GetMinAvailableBreachedPCLQInfo(pclqs []grovecorev1alpha1.PodClique, terminationDelay time.Duration, since time.Time) ([]string, time.Duration)

GetMinAvailableBreachedPCLQInfo filters PodCliques that have grovecorev1alpha1.ConditionTypeMinAvailableBreached set to true. For each such PodClique it returns the name of the PodClique a duration to wait for before terminationDelay is breached.

PodCliques that have never been scheduled (per WasPCLQEverScheduled) are excluded — the MinAvailableBreached condition is still True on them (operators can observe the state) but gang-termination would only churn-loop Pending pods against a cluster that already cannot schedule them. Recycling makes sense only after a workload has been healthy and then regressed.

func GetPCLQPods

func GetPCLQPods(ctx context.Context, cl client.Client, _ string, pclq *grovecorev1alpha1.PodClique) ([]*corev1.Pod, error)

GetPCLQPods lists all Pods controlled by the given PodClique. It queries the podControllerUIDIndexField field index (registered by RegisterPodControllerUIDIndex) keyed on the PodClique UID. That key is the controller owner-reference UID, exactly the ownership relation metav1.IsControlledBy used to verify in-memory, so no post-filter is needed.

When ctx carries a cache from WithPCLQPodsCache, the first call populates the cache and subsequent calls in the same reconcile return the cached slice without hitting the informer.

func GetPCLQTemplateHashes

GetPCLQTemplateHashes generates the Pod template hash for all PCLQs in a PCSG. Returns a map of [PCLQ Name : PodTemplateHas]

func GetPCLQsByOwner

func GetPCLQsByOwner(ctx context.Context, cl client.Client, ownerKind string, ownerObjectKey client.ObjectKey, selectorLabels map[string]string) ([]grovecorev1alpha1.PodClique, error)

GetPCLQsByOwner retrieves PodClique objects that are owned by the specified owner kind and object key, and match the provided selector labels.

func GetPCLQsByOwnerReplicaIndex

func GetPCLQsByOwnerReplicaIndex(ctx context.Context, cl client.Client, ownerKind string, ownerObjectKey client.ObjectKey, selectorLabels map[string]string) (map[string][]grovecorev1alpha1.PodClique, error)

GetPCLQsByOwnerReplicaIndex retrieves PodClique objects per replica of the owner resource matching provided selector labels.

func GetPCLQsInPCSGPendingUpdate

func GetPCLQsInPCSGPendingUpdate(pcs *grovecorev1alpha1.PodCliqueSet, pcsg *grovecorev1alpha1.PodCliqueScalingGroup, existingPCLQs []grovecorev1alpha1.PodClique) []string

GetPCLQsInPCSGPendingUpdate collects the PodClique FQNs that are pending updates. It identifies PCLQ pending update by comparing the current PodTemplateHash label on an existing PCLQ with that of a computed PodTemplateHash from the latest PodCliqueSet resource.

func GetPCLQsMatchingLabels

func GetPCLQsMatchingLabels(ctx context.Context, cl client.Client, namespace string, selectorLabels map[string]string) ([]grovecorev1alpha1.PodClique, error)

GetPCLQsMatchingLabels gets all the PodClique's in a given namespace matching selectorLabels.

func GetPCSGsByPCSReplicaIndex

func GetPCSGsByPCSReplicaIndex(ctx context.Context, cl client.Client, pcsObjKey client.ObjectKey) (map[string][]grovecorev1alpha1.PodCliqueScalingGroup, error)

GetPCSGsByPCSReplicaIndex groups the PodCliqueScalingGroups per PodCliqueSet replica index and returns a map with the key being the PodCliqueSet replica index and the value being the slice of PodCliqueScalingGroup objects.

func GetPCSGsForPCS

GetPCSGsForPCS fetches all PodCliqueScalingGroups for a PodCliqueSet.

func GetPodCliqueFQNsForPCSG

func GetPodCliqueFQNsForPCSG(pcsg *grovecorev1alpha1.PodCliqueScalingGroup) []string

GetPodCliqueFQNsForPCSG generates the PodClique FQNs for all PodCliques that are owned by a PodCliqueScalingGroup.

func GetPodCliqueFQNsForPCSNotInPCSG

func GetPodCliqueFQNsForPCSNotInPCSG(pcs *grovecorev1alpha1.PodCliqueSet) []string

GetPodCliqueFQNsForPCSNotInPCSG computes the FQNs for all PodCliques for all PCS replicas which are not part of any PCSG.

func GetPodCliqueFQNsForPCSReplicaNotInPCSG

func GetPodCliqueFQNsForPCSReplicaNotInPCSG(pcs *grovecorev1alpha1.PodCliqueSet, pcsReplicaIndex int) []string

GetPodCliqueFQNsForPCSReplicaNotInPCSG computes the FQNs for all PodCliques for a PCS replica which are not part of any PCSG.

func GetPodCliqueSet

func GetPodCliqueSet(ctx context.Context, cl client.Client, objectMeta metav1.ObjectMeta) (*grovecorev1alpha1.PodCliqueSet, error)

GetPodCliqueSet gets the owner PodCliqueSet object. When the context carries a cache from WithPodCliqueSetCache, the first lookup populates it and subsequent calls skip the Get. The returned pointer is the cached instance — callers must not mutate it in place.

func GetPodCliqueSetName

func GetPodCliqueSetName(objectMeta metav1.ObjectMeta) string

GetPodCliqueSetName retrieves the PodCliqueSet name from the labels of the given ObjectMeta. NOTE: It is assumed that all managed objects like PCSG, PCLQ and Pods will always have PCS name as value for grovecorev1alpha1.LabelPartOfKey label. It should be ensured that labels that are set by the operator are never removed.

func GetPodCliquesWithParentPCS

func GetPodCliquesWithParentPCS(ctx context.Context, cl client.Client, pcsObjKey client.ObjectKey) ([]grovecorev1alpha1.PodClique, error)

GetPodCliquesWithParentPCS retrieves PodClique objects that are not part of any PodCliqueScalingGroup for the given PodCliqueSet.

func GetPodGang

func GetPodGang(ctx context.Context, cl client.Client, podGangName, namespace string) (*groveschedulerv1alpha1.PodGang, error)

GetPodGang fetches a PodGang by name and namespace.

func GetPodGangSelectorLabels

func GetPodGangSelectorLabels(pcsObjMeta metav1.ObjectMeta) map[string]string

GetPodGangSelectorLabels creates the label selector to list all the PodGangs for a PodCliqueSet.

func GetUniqueTopologyDomainsInPodCliqueSet

func GetUniqueTopologyDomainsInPodCliqueSet(pcs *grovecorev1alpha1.PodCliqueSet) []grovecorev1alpha1.TopologyDomain

GetUniqueTopologyDomainsInPodCliqueSet returns all unique, non-empty pack domains referenced by the PCS.

func GroupPCLQsByPCSGReplicaIndex

func GroupPCLQsByPCSGReplicaIndex(pclqs []grovecorev1alpha1.PodClique) map[string][]grovecorev1alpha1.PodClique

GroupPCLQsByPCSGReplicaIndex filters PCLQs that have a PodCliqueScalingGroupReplicaIndex label and groups them by the PCSG replica.

func GroupPCLQsByPCSReplicaIndex

func GroupPCLQsByPCSReplicaIndex(pclqs []grovecorev1alpha1.PodClique) map[string][]grovecorev1alpha1.PodClique

GroupPCLQsByPCSReplicaIndex filters PCLQs that have a PodCliqueSetReplicaIndex label and groups them by the PCS replica.

func GroupPCLQsByPodGangName

func GroupPCLQsByPodGangName(pclqs []grovecorev1alpha1.PodClique) map[string][]grovecorev1alpha1.PodClique

GroupPCLQsByPodGangName filters PCLQs that have a PodGang label and groups them by the PodGang name.

func GroupPCSGsByPCSReplicaIndex

GroupPCSGsByPCSReplicaIndex filters PCSGs that have a PodCliqueSetReplicaIndex label and groups them by the PCS replica.

func HasAnyTopologyConstraint

func HasAnyTopologyConstraint(pcs *grovecorev1alpha1.PodCliqueSet) bool

HasAnyTopologyConstraint reports whether the PCS contains a topology constraint at any supported level.

func IsAutoUpdateStrategy

func IsAutoUpdateStrategy(pcs *grovecorev1alpha1.PodCliqueSet) bool

IsAutoUpdateStrategy returns true when PodCliqueSet update strategy is automatically orchestrated by Grove. Only the OnDelete update strategy is not an auto update strategy.

func IsLastPCLQUpdateCompleted

func IsLastPCLQUpdateCompleted(pclq *grovecorev1alpha1.PodClique) bool

IsLastPCLQUpdateCompleted checks if the last update of PodClique is completed. For auto update strategies, it returns if all Pods of the PodClique have been updated with the new specification. For the OnDelete strategy, it returns whether the PodClique controller has processed the update by refreshing all hash fields in the PodCliqueStatus, based on which PodCliqueStatus.UpdatedReplicas are calculated.

func IsPCLQAutoUpdateInProgress

func IsPCLQAutoUpdateInProgress(pclq *grovecorev1alpha1.PodClique) bool

IsPCLQAutoUpdateInProgress checks if PodClique is under an auto-orchestrated update.

func IsPCSGUpdateComplete

func IsPCSGUpdateComplete(pcsg *grovecorev1alpha1.PodCliqueScalingGroup, pcsGenerationHash string) bool

IsPCSGUpdateComplete returns whether the rolling update of the PodCliqueScalingGroup is complete.

func IsPCSGUpdateInProgress

func IsPCSGUpdateInProgress(pcsg *grovecorev1alpha1.PodCliqueScalingGroup) bool

IsPCSGUpdateInProgress checks if PCSG is under rolling update.

func PCSGByName

PCSGByName builds a name-keyed map for O(1) PodCliqueScalingGroup lookups.

func PodCliqueByName

func PodCliqueByName(pclqs []grovecorev1alpha1.PodClique) map[string]grovecorev1alpha1.PodClique

PodCliqueByName builds a name-keyed map for O(1) PodClique lookups.

func PodGangByName

PodGangByName builds a name-keyed map for O(1) PodGang lookups.

func PodsToObjectNames

func PodsToObjectNames(pods []*corev1.Pod) []string

PodsToObjectNames converts a slice of Pods to a slice of string representations in "namespace/name" format.

func RegisterPodControllerUIDIndex

func RegisterPodControllerUIDIndex(ctx context.Context, fieldIndexer client.FieldIndexer) error

RegisterPodControllerUIDIndex registers the Pod field index that GetPCLQPods queries via client.MatchingFields. Call it exactly once during controller setup (RegisterControllers) so the single shared manager cache carries the index before any reconcile lists Pods.

The index is required, not an optimization: GetPCLQPods selects Pods with a field selector, and controller-runtime's cache returns an error from List when the field index is not registered. A field index is used because the cache cannot index label selectors — the MatchingLabels equivalent would scan every grove-managed Pod in the namespace on each call (O(pods-in-namespace)); the field index serves the same list via ByIndex.

func ResolveEffectiveTopologyNameForConstraint

func ResolveEffectiveTopologyNameForConstraint(explicitTopologyName, inheritedTopologyName string) (string, error)

ResolveEffectiveTopologyNameForConstraint resolves the topologyName for a single constrained level.

func ResolveEffectiveTopologyNameForPodCliqueSet

func ResolveEffectiveTopologyNameForPodCliqueSet(pcs *grovecorev1alpha1.PodCliqueSet) (string, error)

ResolveEffectiveTopologyNameForPodCliqueSet resolves the single effective topologyName for the PCS after inheritance is applied. Callers that need to distinguish "no topology constraints at all" from invalid topology constraints must first call HasAnyTopologyConstraint.

func WasPCLQEverScheduled

func WasPCLQEverScheduled(pclq *grovecorev1alpha1.PodClique) bool

WasPCLQEverScheduled reports whether the PodClique has ever reached the PodCliqueScheduled=True state since creation. The signal is derived from the PodCliqueScheduled condition: either it is currently True, or it is currently False with a LastTransitionTime sufficiently after CreationTimestamp that the condition must have flipped since creation (i.e. through True). Used to gate gang-termination actions so a workload that has never been healthy is left alone — only regressions get recycled.

Limitation: like every status-derived check in the operator, this only sees transitions the operator actually observed and persisted. If the condition flipped while no reconcile ran (e.g. the operator was down), that transition is lost and the PCLQ is treated as never-scheduled. This is a deliberate design trade-off: the gate errs on the side of NOT gang-terminating, and the system stays eventually consistent — once the operator observes a healthy state the gate re-arms and a later regression is recycled normally.

func WasPCSGEverHealthy

func WasPCSGEverHealthy(pcsg *grovecorev1alpha1.PodCliqueScalingGroup) bool

WasPCSGEverHealthy reports whether the PodCliqueScalingGroup has ever reached the MinAvailableBreached=False state since creation. Mirrors WasPCLQEverScheduled but reads the PCSG's own MinAvailableBreached condition (PCSGs have no PodCliqueScheduled equivalent). Used to gate gang-termination so an initial-startup PCSG that has not yet stabilized is left alone — only regressions from a previously-healthy state get recycled. Shares the observed-transitions-only limitation documented on WasPCLQEverScheduled.

func WithPCLQPodsCache

func WithPCLQPodsCache(ctx context.Context) context.Context

WithPCLQPodsCache returns a context that memoizes GetPCLQPods results for the lifetime of one reconcile. Call this once at the top of Reconcile and propagate the returned context.

func WithPodCliqueSetCache

func WithPodCliqueSetCache(ctx context.Context) context.Context

WithPodCliqueSetCache returns a context that memoizes GetPodCliqueSet results for the lifetime of one reconcile. Call this once at the top of Reconcile and propagate the ctx.

Types

type Set

type Set[T comparable] map[T]struct{}

Set represents unique values with O(1) membership checks. Use it where callers only need to test whether an element is present; use a plain map[K]V (built via lo.SliceToMap) where callers also need to retrieve the value associated with the key.

func NewSet

func NewSet[T comparable](values []T) Set[T]

NewSet converts a slice into a set for O(1) membership checks.

func NewSetBy

func NewSetBy[T any, K comparable](values []T, keyFunc func(T) K) Set[K]

NewSetBy converts a slice into a set using keyFunc to derive the key.

func PodCliqueNameSet

func PodCliqueNameSet(pclqs []grovecorev1alpha1.PodClique) Set[string]

PodCliqueNameSet builds a set of PodClique names for O(1) membership checks.

func (Set[T]) Has

func (s Set[T]) Has(value T) bool

Has returns true if the set contains value. The Set type uses a sentinel struct{} value, so callers cannot use the comma-ok idiom directly; this method gives them an equivalent.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL