mirror of
https://github.com/agent-substrate/substrate.git
synced 2026-10-02 03:24:42 +08:00
Add pod selector to the WorkerPool scale subresource (#547)
WorkerPool already served /scale, so `kubectl scale` worked, but a HPA pointed at one did not: the subresource declared no labelSelectorPath, and HPA needs a selector to find the pods whose metrics it is averaging or to compute ambiguous selectors. https://github.com/agent-substrate/substrate/issues/198 - [x] Tests pass - [x] Appropriate changes to documentation are included in the PR
This commit is contained in:
@@ -21,6 +21,7 @@ import (
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
k8errors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
@@ -98,7 +99,15 @@ func (r *WorkerPoolReconciler) applyDeployment(ctx context.Context, wp *atev1alp
|
||||
}
|
||||
|
||||
func (r *WorkerPoolReconciler) syncStatus(ctx context.Context, wp *atev1alpha1.WorkerPool, dep *appsv1.Deployment) error {
|
||||
want := atev1alpha1.WorkerPoolStatus{Replicas: dep.Status.Replicas}
|
||||
selector, err := metav1.LabelSelectorAsSelector(dep.Spec.Selector)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to convert Deployment selector: %w", err)
|
||||
}
|
||||
|
||||
want := atev1alpha1.WorkerPoolStatus{
|
||||
Replicas: dep.Status.Replicas,
|
||||
Selector: selector.String(),
|
||||
}
|
||||
if equality.Semantic.DeepEqual(wp.Status, want) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -297,7 +297,8 @@ func TestDeletedDeploymentRecreated(t *testing.T) {
|
||||
}
|
||||
|
||||
// TestStatusReplicasPropagation verifies that the controller syncs the
|
||||
// Deployment's status.replicas into WorkerPool.status.replicas.
|
||||
// Deployment's status.replicas into WorkerPool.status.replicas, and publishes
|
||||
// the Deployment's pod selector as WorkerPool.status.selector.
|
||||
func TestStatusReplicasPropagation(t *testing.T) {
|
||||
wp := makeWorkerPool("test-status", "default", 3, "ateom:v1")
|
||||
if err := k8sClient.Create(testCtx, wp); err != nil {
|
||||
@@ -320,6 +321,9 @@ func TestStatusReplicasPropagation(t *testing.T) {
|
||||
if err := k8sClient.Get(ctx, types.NamespacedName{Name: wp.Name, Namespace: wp.Namespace}, current); err != nil {
|
||||
return false, nil
|
||||
}
|
||||
if current.Status.Selector != "ate.dev/worker-pool="+wp.Name {
|
||||
return false, nil
|
||||
}
|
||||
return current.Status.Replicas == 3, nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -78,6 +78,13 @@ spec:
|
||||
memory: 2Gi
|
||||
```
|
||||
|
||||
### Status (`WorkerPoolStatus`)
|
||||
|
||||
| Field | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `replicas` | `int32` | Total number of worker pods, mirrored from the managed Deployment. |
|
||||
| `selector` | `string` | Label selector for the worker pods. |
|
||||
|
||||
---
|
||||
|
||||
## 2. ActorTemplate: The Workload Blueprint
|
||||
|
||||
@@ -424,6 +424,9 @@ spec:
|
||||
format: int32
|
||||
minimum: 0
|
||||
type: integer
|
||||
selector:
|
||||
description: Selector is the label selector for the worker pods.
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
@@ -432,6 +435,7 @@ spec:
|
||||
storage: true
|
||||
subresources:
|
||||
scale:
|
||||
labelSelectorPath: .status.selector
|
||||
specReplicasPath: .spec.replicas
|
||||
statusReplicasPath: .status.replicas
|
||||
status: {}
|
||||
|
||||
@@ -93,6 +93,10 @@ type WorkerPoolStatus struct {
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
// +optional
|
||||
Replicas int32 `json:"replicas"`
|
||||
|
||||
// Selector is the label selector for the worker pods.
|
||||
// +optional
|
||||
Selector string `json:"selector,omitempty"`
|
||||
}
|
||||
|
||||
// WorkerPool is the Schema for the workerpools API
|
||||
@@ -101,7 +105,7 @@ type WorkerPoolStatus struct {
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:scope=Namespaced,shortName=workerpool
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas
|
||||
// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.selector
|
||||
// +kubebuilder:printcolumn:name="Desired",type=integer,JSONPath=`.spec.replicas`
|
||||
// +kubebuilder:printcolumn:name="Replicas",type=integer,JSONPath=`.status.replicas`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
|
||||
Reference in New Issue
Block a user