Skip to content

Commit e834426

Browse files
authored
Introduce workload.PatchStatus function to commonize workload status updates (#8063)
* Introduce workload.PatchStatus function to commonize workload status updates. * Split patchStatus to applyPatchStatus and patchStatus. * Optimize unit tests * Revert "Split patchStatus to applyPatchStatus and patchStatus." This reverts commit 0511918.
1 parent 98c941f commit e834426

File tree

2 files changed

+451
-81
lines changed

2 files changed

+451
-81
lines changed

pkg/workload/workload.go

Lines changed: 67 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -594,28 +594,9 @@ func SetConditionAndUpdate(ctx context.Context,
594594
Reason: reason,
595595
Message: api.TruncateConditionMessage(message),
596596
}
597-
598-
var (
599-
wlCopy *kueue.Workload
600-
err error
601-
)
602-
603-
if features.Enabled(features.WorkloadRequestUseMergePatch) {
604-
wlCopy = wl.DeepCopy()
605-
err = clientutil.PatchStatus(ctx, c, wlCopy, func() (bool, error) {
606-
return apimeta.SetStatusCondition(&wlCopy.Status.Conditions, condition), nil
607-
})
608-
} else {
609-
wlCopy = BaseSSAWorkload(wl, true)
610-
wlCopy.Status.Conditions = []metav1.Condition{condition}
611-
err = c.Status().Patch(ctx, wlCopy, client.Apply, client.FieldOwner(managerPrefix+"-"+condition.Type))
612-
}
613-
if err != nil {
614-
return err
615-
}
616-
617-
wlCopy.DeepCopyInto(wl)
618-
return nil
597+
return PatchStatus(ctx, c, wl, client.FieldOwner(managerPrefix+"-"+condition.Type), func(wl *kueue.Workload) (bool, error) {
598+
return apimeta.SetStatusCondition(&wl.Status.Conditions, condition), nil
599+
})
619600
}
620601

621602
// UnsetQuotaReservationWithCondition sets the QuotaReserved condition to false, clears
@@ -965,12 +946,14 @@ func PrepareWorkloadPatch(w *kueue.Workload, strict bool, clk clock.Clock) *kueu
965946
return wlCopy
966947
}
967948

968-
// PatchAdmissionStatusOption defines a functional option for customizing PatchAdmissionStatusOptions.
949+
type UpdateFunc func(*kueue.Workload) (bool, error)
950+
951+
// PatchStatusOption defines a functional option for customizing PatchStatusOptions.
969952
// It follows the functional options pattern, allowing callers to configure
970-
// patch behavior at call sites without directly manipulating PatchAdmissionStatusOptions.
971-
type PatchAdmissionStatusOption func(*PatchAdmissionStatusOptions)
953+
// patch behavior at call sites without directly manipulating PatchStatusOptions.
954+
type PatchStatusOption func(*PatchStatusOptions)
972955

973-
// PatchAdmissionStatusOptions contains configuration parameters that control how patches
956+
// PatchStatusOptions contains configuration parameters that control how patches
974957
// are generated and applied.
975958
//
976959
// Fields:
@@ -983,28 +966,28 @@ type PatchAdmissionStatusOption func(*PatchAdmissionStatusOptions)
983966
// patch. Defaults to true. Setting StrictPatch=false preserves the current
984967
// ResourceVersion.
985968
//
986-
// Typically, PatchAdmissionStatusOptions are constructed via DefaultPatchAdmissionStatusOptions and
987-
// modified using PatchAdmissionStatusOption functions (e.g., WithLoose).
988-
type PatchAdmissionStatusOptions struct {
969+
// Typically, PatchStatusOptions are constructed via DefaultPatchStatusOptions and
970+
// modified using PatchStatusOption functions (e.g., WithLoose).
971+
type PatchStatusOptions struct {
989972
StrictPatch bool
990973
StrictApply bool
991974
RetryOnConflictForPatch bool
992975
}
993976

994-
// DefaultPatchAdmissionStatusOptions returns a new PatchAdmissionStatusOptions instance configured with
977+
// DefaultPatchStatusOptions returns a new PatchStatusOptions instance configured with
995978
// default settings.
996979
//
997980
// By default, StrictPatch and StrictApply is set to true, meaning ResourceVersion is cleared
998981
// from the original object so it will always be included in the generated
999982
// patch. This ensures stricter version handling during patch application.
1000-
func DefaultPatchAdmissionStatusOptions() *PatchAdmissionStatusOptions {
1001-
return &PatchAdmissionStatusOptions{
983+
func DefaultPatchStatusOptions() *PatchStatusOptions {
984+
return &PatchStatusOptions{
1002985
StrictPatch: true, // default is strict
1003986
StrictApply: true, // default is strict
1004987
}
1005988
}
1006989

1007-
// WithLooseOnApply returns a PatchAdmissionStatusOption that resets the StrictApply field on PatchAdmissionStatusOptions.
990+
// WithLooseOnApply returns a PatchStatusOption that resets the StrictApply field on PatchStatusOptions.
1008991
//
1009992
// When using Patch Apply, setting StrictApply to false enforces looser
1010993
// version handling only for Patch Apply.
@@ -1016,52 +999,83 @@ func DefaultPatchAdmissionStatusOptions() *PatchAdmissionStatusOptions {
1016999
// return updateFn(obj), nil
10171000
// }, WithLooseOnApply()) // disables strict mode for Patch Apply
10181001

1019-
func WithLooseOnApply() PatchAdmissionStatusOption {
1020-
return func(o *PatchAdmissionStatusOptions) {
1002+
func WithLooseOnApply() PatchStatusOption {
1003+
return func(o *PatchStatusOptions) {
10211004
o.StrictApply = false
10221005
}
10231006
}
10241007

1025-
// WithRetryOnConflictForPatch configures PatchAdmissionStatusOptions to enable retry logic on conflicts.
1008+
// WithRetryOnConflictForPatch configures PatchStatusOptions to enable retry logic on conflicts.
10261009
// Note: This only works with merge patches.
1027-
func WithRetryOnConflictForPatch() PatchAdmissionStatusOption {
1028-
return func(o *PatchAdmissionStatusOptions) {
1010+
func WithRetryOnConflictForPatch() PatchStatusOption {
1011+
return func(o *PatchStatusOptions) {
10291012
o.RetryOnConflictForPatch = true
10301013
}
10311014
}
10321015

1033-
// PatchAdmissionStatus updates the admission status of a workload.
1034-
// If the WorkloadRequestUseMergePatch feature is enabled, it uses a Merge Patch with update function.
1035-
// Otherwise, it runs the update function and, if updated, applies the SSA Patch status.
1036-
func PatchAdmissionStatus(ctx context.Context, c client.Client, w *kueue.Workload, clk clock.Clock, update func(*kueue.Workload) (bool, error), options ...PatchAdmissionStatusOption) error {
1037-
opts := DefaultPatchAdmissionStatusOptions()
1016+
func patchStatusOptions(options []PatchStatusOption) *PatchStatusOptions {
1017+
opts := DefaultPatchStatusOptions()
10381018
for _, opt := range options {
10391019
opt(opts)
10401020
}
1041-
var err error
1042-
wlCopy := w.DeepCopy()
1021+
return opts
1022+
}
1023+
1024+
// patchStatus updates the status of a workload.
1025+
// If the WorkloadRequestUseMergePatch feature is enabled, it uses a Merge Patch with update function.
1026+
// Otherwise, it runs the update function and, if updated, applies the SSA Patch status.
1027+
func patchStatus(ctx context.Context, c client.Client, wl *kueue.Workload, owner client.FieldOwner, update UpdateFunc, opts *PatchStatusOptions) error {
1028+
wlCopy := wl.DeepCopy()
10431029
if features.Enabled(features.WorkloadRequestUseMergePatch) {
1044-
var patchOptions []clientutil.PatchOption
1030+
patchOptions := make([]clientutil.PatchOption, 0, 2)
10451031
if !opts.StrictPatch {
10461032
patchOptions = append(patchOptions, clientutil.WithLoose())
10471033
}
10481034
if opts.RetryOnConflictForPatch {
10491035
patchOptions = append(patchOptions, clientutil.WithRetryOnConflict())
10501036
}
1051-
err = clientutil.PatchStatus(ctx, c, wlCopy, func() (bool, error) {
1037+
err := clientutil.PatchStatus(ctx, c, wlCopy, func() (bool, error) {
10521038
return update(wlCopy)
10531039
}, patchOptions...)
1040+
if err != nil {
1041+
return err
1042+
}
10541043
} else {
10551044
if updated, err := update(wlCopy); err != nil || !updated {
10561045
return err
10571046
}
1058-
wlCopy = PrepareWorkloadPatch(wlCopy, opts.StrictApply, clk)
1059-
err = c.Status().Patch(ctx, wlCopy, client.Apply, client.FieldOwner(constants.AdmissionName), client.ForceOwnership)
1060-
}
1061-
if err == nil {
1062-
wlCopy.DeepCopyInto(w)
1047+
err := c.Status().Patch(ctx, wlCopy, client.Apply, owner, client.ForceOwnership)
1048+
if err != nil {
1049+
return err
1050+
}
10631051
}
1064-
return err
1052+
wlCopy.DeepCopyInto(wl)
1053+
return nil
1054+
}
1055+
1056+
func PatchStatus(ctx context.Context, c client.Client, wl *kueue.Workload, owner client.FieldOwner, update UpdateFunc, options ...PatchStatusOption) error {
1057+
opts := patchStatusOptions(options)
1058+
return patchStatus(ctx, c, wl, owner, func(wl *kueue.Workload) (bool, error) {
1059+
if !features.Enabled(features.WorkloadRequestUseMergePatch) {
1060+
wlPatch := BaseSSAWorkload(wl, opts.StrictApply)
1061+
wlPatch.DeepCopyInto(wl)
1062+
}
1063+
return update(wl)
1064+
}, opts)
1065+
}
1066+
1067+
func PatchAdmissionStatus(ctx context.Context, c client.Client, wl *kueue.Workload, clk clock.Clock, update UpdateFunc, options ...PatchStatusOption) error {
1068+
opts := patchStatusOptions(options)
1069+
return patchStatus(ctx, c, wl, constants.AdmissionName, func(wl *kueue.Workload) (bool, error) {
1070+
if updated, err := update(wl); err != nil || !updated {
1071+
return updated, err
1072+
}
1073+
if !features.Enabled(features.WorkloadRequestUseMergePatch) {
1074+
wlPatch := PrepareWorkloadPatch(wl, opts.StrictApply, clk)
1075+
wlPatch.DeepCopyInto(wl)
1076+
}
1077+
return true, nil
1078+
}, opts)
10651079
}
10661080

10671081
type Ordering struct {

0 commit comments

Comments
 (0)