Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions api/v1alpha1/worker_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,17 @@ type TemporalWorkerDeploymentStatus struct {
// so it's generally not a good idea to read from the status of the root object.
// Instead, you should reconstruct it every run.

// Replicas is the total number of non-terminated pods targeted by this TemporalWorkerDeployment.
// This is used by the /scale subresource to report current replica count to HPA/KEDA.
// +optional
Replicas int32 `json:"replicas,omitempty"`

// Selector is the label selector for pods managed by this TemporalWorkerDeployment.
// This is used by the /scale subresource to allow HPA/KEDA to discover pods.
// Format: "app.kubernetes.io/name=<name>"
// +optional
Selector string `json:"selector,omitempty"`

// TargetVersion is the desired next version. If TargetVersion.Deployment is nil,
// then the controller should create it. If not nil, the controller should
// wait for it to become healthy and then move it to the CurrentVersion.
Expand Down Expand Up @@ -348,7 +359,9 @@ type ManualRolloutStrategy struct{}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.selector
// +kubebuilder:resource:shortName=twd;twdeployment;tworkerdeployment
//+kubebuilder:printcolumn:name="Replicas",type="integer",JSONPath=".status.replicas",description="Current replicas"
//+kubebuilder:printcolumn:name="Current",type="string",JSONPath=".status.currentVersion.buildID",description="Current build ID"
//+kubebuilder:printcolumn:name="Target",type="string",JSONPath=".status.targetVersion.buildID",description="Target build ID"
//+kubebuilder:printcolumn:name="Ramp %",type="number",JSONPath=".status.targetVersion.rampPercentage",description="Ramp percentage"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ spec:
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Current replicas
jsonPath: .status.replicas
name: Replicas
type: integer
- description: Current build ID
jsonPath: .status.currentVersion.buildID
name: Current
Expand Down Expand Up @@ -64,7 +68,6 @@ spec:
gate:
properties:
input:
type: object
x-kubernetes-preserve-unknown-fields: true
inputFrom:
properties:
Expand All @@ -73,25 +76,27 @@ spec:
key:
type: string
name:
default: ""
type: string
optional:
type: boolean
required:
- key
- name
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
properties:
key:
type: string
name:
default: ""
type: string
optional:
type: boolean
required:
- key
- name
type: object
x-kubernetes-map-type: atomic
type: object
workflowType:
type: string
Expand Down Expand Up @@ -4057,6 +4062,11 @@ spec:
type: array
lastModifierIdentity:
type: string
replicas:
format: int32
type: integer
selector:
type: string
targetVersion:
properties:
buildID:
Expand Down Expand Up @@ -4141,4 +4151,8 @@ spec:
served: true
storage: true
subresources:
scale:
labelSelectorPath: .status.selector
specReplicasPath: .spec.replicas
statusReplicasPath: .status.replicas
status: {}
21 changes: 21 additions & 0 deletions internal/controller/state_mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
package controller

import (
"strings"

"github.com/temporalio/temporal-worker-controller/api/v1alpha1"
"github.com/temporalio/temporal-worker-controller/internal/k8s"
"github.com/temporalio/temporal-worker-controller/internal/temporal"
Expand Down Expand Up @@ -35,6 +37,25 @@ func (m *stateMapper) mapToStatus(targetBuildID string) *v1alpha1.TemporalWorker

status.LastModifierIdentity = m.temporalState.LastModifierIdentity

// Compute total replicas from all managed deployments for /scale subresource
// This allows HPA/KEDA to query the current replica count
var totalReplicas int32
for _, deployment := range m.k8sState.Deployments {
if deployment.Status.Replicas > 0 {
totalReplicas += deployment.Status.Replicas
}
}
status.Replicas = totalReplicas

// Set label selector for /scale subresource - allows HPA/KEDA to discover pods
// Uses app.kubernetes.io/name label since all managed pods share this label
// Note: workerDeploymentName is namespace/name, but we only want the name part for labels
name := m.workerDeploymentName
if idx := strings.LastIndex(name, "/"); idx >= 0 {
name = name[idx+1:]
}
status.Selector = "app.kubernetes.io/name=" + name

// Get build IDs directly from temporal state
currentBuildID := m.temporalState.CurrentBuildID
rampingBuildID := m.temporalState.RampingBuildID
Expand Down