Skip to content

Commit 135681b

Browse files
scotwellsclaude
andcommitted
feat(cli): add UP-TO-DATE column to compute workloads
Surface rolling-update / restart progress in `datumctl compute workloads` by showing updated/desired replica counts next to ready. UP-TO-DATE counts instances on the latest template revision (status.updatedReplicas), so a roll is visible as the count dips below desired and then recovers. Includes a byte-identical copy of the UpdatedReplicas/ObservedGeneration WorkloadDeployment status fields in api/v1alpha so the plugin can read them. These fields are defined identically on the controller branch (PR #129); the duplicate resolves cleanly once both land on main. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 4cc6f07 commit 135681b

2 files changed

Lines changed: 26 additions & 8 deletions

File tree

api/v1alpha/workloaddeployment_types.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,28 @@ type WorkloadDeploymentStatus struct {
4949
// The number of instances created
5050
Replicas int32 `json:"replicas"`
5151

52-
// The number of instances which have the latest workload settings applied.
52+
// The number of instances which have the latest workload settings applied
53+
// and are programmed (a subset of UpdatedReplicas that are ready to serve).
5354
CurrentReplicas int32 `json:"currentReplicas"`
5455

56+
// The number of instances updated to the latest template revision (their
57+
// observed template hash matches the desired template), regardless of
58+
// readiness. Lags Replicas during a rolling update or restart, then catches
59+
// back up — making an in-progress roll observable.
60+
UpdatedReplicas int32 `json:"updatedReplicas"`
61+
5562
// The desired number of instances
5663
DesiredReplicas int32 `json:"desiredReplicas"`
5764

5865
// The number of instances which are ready.
5966
ReadyReplicas int32 `json:"readyReplicas"`
67+
68+
// The most recent generation observed by the deployment controller. When
69+
// this matches metadata.generation, the controller has reconciled the
70+
// latest spec (e.g. a restart request).
71+
//
72+
// +kubebuilder:validation:Optional
73+
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
6074
}
6175

6276
const (

internal/cmd/compute/workloads/workloads.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ func runList(cmd *cobra.Command, _ []string) error {
118118
health string
119119
healthShort string // first word, for filter comparison
120120
readyStr string
121+
upToDateStr string
121122
placements string
122123
image string
123124
age string
@@ -137,9 +138,10 @@ func runList(cmd *cobra.Command, _ []string) error {
137138
}
138139

139140
deps := deploysByWorkload[wUID]
140-
var totalReady, totalDesired int32
141+
var totalReady, totalUpdated, totalDesired int32
141142
for _, d := range deps {
142143
totalReady += d.Status.ReadyReplicas
144+
totalUpdated += d.Status.UpdatedReplicas
143145
totalDesired += d.Status.DesiredReplicas
144146
}
145147

@@ -169,13 +171,15 @@ func runList(cmd *cobra.Command, _ []string) error {
169171
}
170172

171173
readyStr := fmt.Sprintf("%d/%d", totalReady, totalDesired)
174+
upToDateStr := fmt.Sprintf("%d/%d", totalUpdated, totalDesired)
172175
instType := wl.Spec.Template.Spec.Runtime.Resources.InstanceType
173176

174177
rows = append(rows, workloadRow{
175178
name: wl.Name,
176179
health: health,
177180
healthShort: healthShort,
178181
readyStr: readyStr,
182+
upToDateStr: upToDateStr,
179183
placements: placements,
180184
image: image,
181185
age: util.RelativeAge(wl.CreationTimestamp),
@@ -221,18 +225,18 @@ func runList(cmd *cobra.Command, _ []string) error {
221225
tw := util.NewTabWriter(out)
222226
if !noHeaders {
223227
if wide {
224-
fmt.Fprintf(tw, "NAME\tHEALTH\tREADY\tPLACEMENTS\tIMAGE\tAGE\tINSTANCE TYPE\n")
228+
fmt.Fprintf(tw, "NAME\tHEALTH\tREADY\tUP-TO-DATE\tPLACEMENTS\tIMAGE\tAGE\tINSTANCE TYPE\n")
225229
} else {
226-
fmt.Fprintf(tw, "NAME\tHEALTH\tREADY\tPLACEMENTS\tIMAGE\tAGE\n")
230+
fmt.Fprintf(tw, "NAME\tHEALTH\tREADY\tUP-TO-DATE\tPLACEMENTS\tIMAGE\tAGE\n")
227231
}
228232
}
229233
for _, r := range rows {
230234
if wide {
231-
fmt.Fprintf(tw, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
232-
r.name, r.healthShort, r.readyStr, r.placements, r.image, r.age, r.instType)
235+
fmt.Fprintf(tw, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
236+
r.name, r.healthShort, r.readyStr, r.upToDateStr, r.placements, r.image, r.age, r.instType)
233237
} else {
234-
fmt.Fprintf(tw, "%s\t%s\t%s\t%s\t%s\t%s\n",
235-
r.name, r.healthShort, r.readyStr, r.placements, r.image, r.age)
238+
fmt.Fprintf(tw, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
239+
r.name, r.healthShort, r.readyStr, r.upToDateStr, r.placements, r.image, r.age)
236240
}
237241
}
238242
_ = tw.Flush()

0 commit comments

Comments
 (0)