@@ -325,33 +325,24 @@ func (r *ShardReconciler) updateStatus(
325325 ctx context.Context ,
326326 shard * multigresv1alpha1.Shard ,
327327) error {
328- var totalPods , readyPods int32
328+ cellsSet := make ( map [multigresv1alpha1. CellName ] bool )
329329
330- // Aggregate status from all pool StatefulSets
331- for poolName := range shard .Spec .Pools {
332- stsName := buildPoolName (shard .Name , poolName )
333- sts := & appsv1.StatefulSet {}
334- err := r .Get (
335- ctx ,
336- client.ObjectKey {Namespace : shard .Namespace , Name : stsName },
337- sts ,
338- )
339- if err != nil {
340- if errors .IsNotFound (err ) {
341- // StatefulSet not created yet, skip
342- continue
343- }
344- return fmt .Errorf ("failed to get pool StatefulSet for status: %w" , err )
345- }
330+ // Update pools status
331+ totalPods , readyPods , err := r .updatePoolsStatus (ctx , shard , cellsSet )
332+ if err != nil {
333+ return err
334+ }
346335
347- totalPods += sts .Status .Replicas
348- readyPods += sts .Status .ReadyReplicas
336+ // Update MultiOrch status
337+ if err := r .updateMultiOrchStatus (ctx , shard , cellsSet ); err != nil {
338+ return err
349339 }
350340
351- // Update status fields
341+ // Update cells list from all observed cells
342+ shard .Status .Cells = cellSetToSlice (cellsSet )
343+
344+ // Update aggregate status fields
352345 shard .Status .PoolsReady = (totalPods > 0 && totalPods == readyPods )
353- // TODO: Add OrchReady status check when MultiOrch deployment is implemented
354- // shard.Status.OrchReady = ...
355346
356347 // Update conditions
357348 shard .Status .Conditions = r .buildConditions (shard , totalPods , readyPods )
@@ -363,6 +354,96 @@ func (r *ShardReconciler) updateStatus(
363354 return nil
364355}
365356
357+ // updatePoolsStatus aggregates status from all pool StatefulSets.
358+ // Returns total pods, ready pods, and tracks cells in the cellsSet.
359+ func (r * ShardReconciler ) updatePoolsStatus (
360+ ctx context.Context ,
361+ shard * multigresv1alpha1.Shard ,
362+ cellsSet map [multigresv1alpha1.CellName ]bool ,
363+ ) (int32 , int32 , error ) {
364+ var totalPods , readyPods int32
365+
366+ for poolName , poolSpec := range shard .Spec .Pools {
367+ // TODO(#91): Pool.Cells may contain duplicates - add +listType=set validation at API level
368+ for _ , cell := range poolSpec .Cells {
369+ cellName := string (cell )
370+ cellsSet [cell ] = true
371+
372+ stsName := buildPoolNameWithCell (shard .Name , poolName , cellName )
373+ sts := & appsv1.StatefulSet {}
374+ err := r .Get (
375+ ctx ,
376+ client.ObjectKey {Namespace : shard .Namespace , Name : stsName },
377+ sts ,
378+ )
379+ if err != nil {
380+ if errors .IsNotFound (err ) {
381+ continue
382+ }
383+ return 0 , 0 , fmt .Errorf ("failed to get pool StatefulSet for status: %w" , err )
384+ }
385+
386+ totalPods += sts .Status .Replicas
387+ readyPods += sts .Status .ReadyReplicas
388+ }
389+ }
390+
391+ return totalPods , readyPods , nil
392+ }
393+
394+ // updateMultiOrchStatus checks MultiOrch Deployments and sets OrchReady status.
395+ // Also tracks cells in the cellsSet.
396+ func (r * ShardReconciler ) updateMultiOrchStatus (
397+ ctx context.Context ,
398+ shard * multigresv1alpha1.Shard ,
399+ cellsSet map [multigresv1alpha1.CellName ]bool ,
400+ ) error {
401+ multiOrchCells , err := getMultiOrchCells (shard )
402+ if err != nil {
403+ shard .Status .OrchReady = false
404+ return nil
405+ }
406+
407+ orchReady := true
408+ for _ , cell := range multiOrchCells {
409+ cellName := string (cell )
410+ cellsSet [cell ] = true
411+
412+ deployName := buildMultiOrchNameWithCell (shard .Name , cellName )
413+ deploy := & appsv1.Deployment {}
414+ err := r .Get (
415+ ctx ,
416+ client.ObjectKey {Namespace : shard .Namespace , Name : deployName },
417+ deploy ,
418+ )
419+ if err != nil {
420+ if errors .IsNotFound (err ) {
421+ orchReady = false
422+ break
423+ }
424+ return fmt .Errorf ("failed to get MultiOrch Deployment for status: %w" , err )
425+ }
426+
427+ // Check if deployment is ready
428+ if deploy .Spec .Replicas == nil || deploy .Status .ReadyReplicas != * deploy .Spec .Replicas {
429+ orchReady = false
430+ break
431+ }
432+ }
433+
434+ shard .Status .OrchReady = orchReady
435+ return nil
436+ }
437+
438+ // cellSetToSlice converts a cell set (map) to a slice.
439+ func cellSetToSlice (cellsSet map [multigresv1alpha1.CellName ]bool ) []multigresv1alpha1.CellName {
440+ cells := make ([]multigresv1alpha1.CellName , 0 , len (cellsSet ))
441+ for cell := range cellsSet {
442+ cells = append (cells , cell )
443+ }
444+ return cells
445+ }
446+
366447// buildConditions creates status conditions based on observed state.
367448func (r * ShardReconciler ) buildConditions (
368449 shard * multigresv1alpha1.Shard ,
0 commit comments