Skip to content

Commit a01ec79

Browse files
feat: Backport changes from KubeFleet (09/16/2025) (#1194)
2 parents 8b17072 + 7e430ed commit a01ec79

File tree

15 files changed

+1368
-270
lines changed

15 files changed

+1368
-270
lines changed

.github/workflows/codespell.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
runs-on: ubuntu-latest
1313
steps:
1414
- name: Harden Runner
15-
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
15+
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
1616
with:
1717
egress-policy: audit
1818

cmd/memberagent/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ var (
102102
workApplierRequeueRateLimiterExponentialBaseForFastBackoff = flag.Float64("work-applier-requeue-rate-limiter-exponential-base-for-fast-backoff", 1.5, "If set, the work applier will start to back off fast at this factor after it completes the slow backoff stage, until it reaches the fast backoff delay cap. Its value should be larger than the base value for the slow backoff stage.")
103103
workApplierRequeueRateLimiterMaxFastBackoffDelaySeconds = flag.Float64("work-applier-requeue-rate-limiter-max-fast-backoff-delay-seconds", 900, "If set, the work applier will not back off longer than this value in seconds when it is in the fast backoff stage.")
104104
workApplierRequeueRateLimiterSkipToFastBackoffForAvailableOrDiffReportedWorkObjs = flag.Bool("work-applier-requeue-rate-limiter-skip-to-fast-backoff-for-available-or-diff-reported-work-objs", true, "If set, the rate limiter will skip the slow backoff stage and start fast backoff immediately for work objects that are available or have diff reported.")
105+
// Azure property provider feature gates.
106+
isAzProviderCostPropertiesEnabled = flag.Bool("use-cost-properties-in-azure-provider", true, "If set, the Azure property provider will expose cost properties in the member cluster.")
107+
isAzProviderAvailableResPropertiesEnabled = flag.Bool("use-available-res-properties-in-azure-provider", true, "If set, the Azure property provider will expose available resources properties in the member cluster.")
105108
)
106109

107110
func init() {
@@ -461,7 +464,7 @@ func Start(ctx context.Context, hubCfg, memberConfig *rest.Config, hubOpts, memb
461464
// the specific instance wins the leader election.
462465
klog.V(1).InfoS("Property Provider is azure, loading cloud config", "cloudConfigFile", *cloudConfigFile)
463466
// TODO (britaniar): load cloud config for Azure property provider.
464-
pp = azure.New(region)
467+
pp = azure.New(region, *isAzProviderCostPropertiesEnabled, *isAzProviderAvailableResPropertiesEnabled)
465468
default:
466469
// Fall back to not using any property provider if the provided type is none or
467470
// not recognizable.

pkg/controllers/placement/resource_selector.go

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -41,44 +41,52 @@ import (
4141
)
4242

4343
var (
44-
// ApplyOrder is the order in which resources should be applied.
45-
// Those occurring earlier in the list get applied before those occurring later in the list.
46-
// Source: https://github.com/helm/helm/blob/31e22b9866af91e1a0ea2ad381798f6c5eec7f4f/pkg/release/util/kind_sorter.go#L31.
47-
applyOrder = []string{
48-
"PriorityClass",
49-
"Namespace",
50-
"NetworkPolicy",
51-
"ResourceQuota",
52-
"LimitRange",
53-
"PodDisruptionBudget",
54-
"ServiceAccount",
55-
"Secret",
56-
"ConfigMap",
57-
"StorageClass",
58-
"PersistentVolume",
59-
"PersistentVolumeClaim",
60-
"CustomResourceDefinition",
61-
"ClusterRole",
62-
"ClusterRoleBinding",
63-
"Role",
64-
"RoleBinding",
65-
"Service",
66-
"DaemonSet",
67-
"Pod",
68-
"ReplicationController",
69-
"ReplicaSet",
70-
"Deployment",
71-
"HorizontalPodAutoscaler",
72-
"StatefulSet",
73-
"Job",
74-
"CronJob",
75-
"IngressClass",
76-
"Ingress",
77-
"APIService",
78-
"MutatingWebhookConfiguration",
79-
"ValidatingWebhookConfiguration",
80-
}
81-
applyOrderMap = buildApplyOrderMap()
44+
// resourceSortOrder is the order in which resources are sorted when KubeFleet
45+
// organizes the resources in a resource snapshot.
46+
//
47+
// Note (chenyu1): the sort order here does not affect the order in which resources
48+
// are applied on a selected member cluster (the work applier will handle the resources
49+
// in batch with its own grouping logic). KubeFleet sorts resources here solely
50+
// for consistency (deterministic processing) reasons (i.e., if the set of the
51+
// resources remain the same, no new snapshots are generated).
52+
//
53+
// Important (chenyu1): changing the sort order here may induce side effects in
54+
// existing KubeFleet deployments, as a new snapshot might be prepared and rolled out.
55+
// Do not update the sort order unless absolutely necessary.
56+
resourceSortOrder = map[string]int{
57+
"PriorityClass": 0,
58+
"Namespace": 1,
59+
"NetworkPolicy": 2,
60+
"ResourceQuota": 3,
61+
"LimitRange": 4,
62+
"PodDisruptionBudget": 5,
63+
"ServiceAccount": 6,
64+
"Secret": 7,
65+
"ConfigMap": 8,
66+
"StorageClass": 9,
67+
"PersistentVolume": 10,
68+
"PersistentVolumeClaim": 11,
69+
"CustomResourceDefinition": 12,
70+
"ClusterRole": 13,
71+
"ClusterRoleBinding": 14,
72+
"Role": 15,
73+
"RoleBinding": 16,
74+
"Service": 17,
75+
"DaemonSet": 18,
76+
"Pod": 19,
77+
"ReplicationController": 20,
78+
"ReplicaSet": 21,
79+
"Deployment": 22,
80+
"HorizontalPodAutoscaler": 23,
81+
"StatefulSet": 24,
82+
"Job": 25,
83+
"CronJob": 26,
84+
"IngressClass": 27,
85+
"Ingress": 28,
86+
"APIService": 29,
87+
"MutatingWebhookConfiguration": 30,
88+
"ValidatingWebhookConfiguration": 31,
89+
}
8290
)
8391

8492
// selectResources selects the resources according to the placement resourceSelectors.
@@ -185,8 +193,8 @@ func sortResources(resources []*unstructured.Unstructured) {
185193
k1 := obj1.GetObjectKind().GroupVersionKind().Kind
186194
k2 := obj2.GetObjectKind().GroupVersionKind().Kind
187195

188-
first, aok := applyOrderMap[k1]
189-
second, bok := applyOrderMap[k2]
196+
first, aok := resourceSortOrder[k1]
197+
second, bok := resourceSortOrder[k2]
190198
switch {
191199
// if both kinds are unknown.
192200
case !aok && !bok:
@@ -222,14 +230,6 @@ func lessByGVK(obj1, obj2 *unstructured.Unstructured, ignoreKind bool) bool {
222230
return comp < 0
223231
}
224232

225-
func buildApplyOrderMap() map[string]int {
226-
ordering := make(map[string]int, len(applyOrder))
227-
for v, k := range applyOrder {
228-
ordering[k] = v
229-
}
230-
return ordering
231-
}
232-
233233
// fetchResources retrieves the objects based on the selector.
234234
func (r *Reconciler) fetchResources(selector fleetv1beta1.ResourceSelectorTerm, placementKey types.NamespacedName) ([]runtime.Object, error) {
235235
klog.V(2).InfoS("Start to fetch resources by the selector", "selector", selector, "placement", placementKey)

pkg/controllers/workgenerator/envelope.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@ func extractManifestsFromEnvelopeCR(envelopeReader fleetv1beta1.EnvelopeReader)
147147
}
148148

149149
// Do a stable sort of the extracted manifests to ensure consistent, deterministic ordering.
150+
//
151+
// Note (chenyu1): the sort order here does not affect the order in which resources
152+
// are applied on a selected member cluster (the work applier will handle the resources
153+
// in batch with its own grouping logic). KubeFleet sorts resources here solely
154+
// for consistency (deterministic processing) reasons (i.e., if the set of the
155+
// resources remain the same, work objects will not be updated).
156+
//
157+
// Important (chenyu1): changing the sort order here may induce side effects in
158+
// existing KubeFleet deployments, as it might trigger update ops on work objects.
159+
// Do not update the sort order unless absolutely necessary.
150160
sort.Slice(manifests, func(i, j int) bool {
151161
obj1 := manifests[i].Raw
152162
obj2 := manifests[j].Raw

pkg/propertyprovider/azure/controllers/node.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ func (r *NodeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
8989
return ctrl.Result{}, nil
9090
}
9191

92-
func (r *NodeReconciler) SetupWithManager(mgr ctrl.Manager) error {
92+
func (r *NodeReconciler) SetupWithManager(mgr ctrl.Manager, controllerName string) error {
9393
// Reconcile any node changes (create, update, delete).
9494
return ctrl.NewControllerManagedBy(mgr).
95+
Named(controllerName).
9596
For(&corev1.Node{}).
9697
Complete(r)
9798
}

pkg/propertyprovider/azure/controllers/pod.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,10 @@ func (p *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
108108
return ctrl.Result{}, nil
109109
}
110110

111-
func (p *PodReconciler) SetupWithManager(mgr ctrl.Manager) error {
111+
func (p *PodReconciler) SetupWithManager(mgr ctrl.Manager, controllerName string) error {
112112
// Reconcile any pod changes (create, update, delete).
113113
return ctrl.NewControllerManagedBy(mgr).
114+
Named(controllerName).
114115
For(&corev1.Pod{}).
115116
Complete(p)
116117
}

0 commit comments

Comments
 (0)