@@ -177,8 +177,11 @@ func trackCluster(ctx context.Context, config *rest.Config, c client.Client, age
177177 }
178178
179179 if alreadyTracked {
180- if shardMap [oldShard ].Has (cluster ) &&
181- shardMap [oldShard ].Len () == 1 {
180+ // shardMap[oldShard] may be nil when a previous reconcile failed after
181+ // updating clusterMap but before updating shardMap. Guard every access.
182+ oldClusterPerShard := shardMap [oldShard ]
183+ if oldClusterPerShard != nil && oldClusterPerShard .Has (cluster ) &&
184+ oldClusterPerShard .Len () == 1 {
182185 // By removing cluster, no more clusters will match oldShard.
183186 // Remove controllers first
184187 logger .V (logs .LogInfo ).Info (fmt .Sprintf ("no more clusters for shard %s" , oldShard ))
@@ -187,18 +190,14 @@ func trackCluster(ctx context.Context, config *rest.Config, c client.Client, age
187190 }
188191 }
189192
190- // Updates shard map (key: shard; value: list of cluster matching the shard)
191- // for the old shard by adding cluster as a match
192- clusterPerShard := shardMap [oldShard ]
193- clusterPerShard .Erase (cluster )
194- shardMap [oldShard ] = clusterPerShard
195- logger .V (logs .LogInfo ).Info (fmt .Sprintf ("removed cluster from shard %q: %d cluster(s) remaining" ,
196- oldShard , clusterPerShard .Len ()))
193+ if oldClusterPerShard != nil {
194+ oldClusterPerShard .Erase (cluster )
195+ shardMap [oldShard ] = oldClusterPerShard
196+ logger .V (logs .LogInfo ).Info (fmt .Sprintf ("removed cluster from shard %q: %d cluster(s) remaining" ,
197+ oldShard , oldClusterPerShard .Len ()))
198+ }
197199 }
198200
199- // Update Cluster shard (key: cluster; value: cluster current shard)
200- clusterMap [* cluster ] = currentShardKey
201-
202201 // If cluster is first cluster matching this shard, deploy projectsveltos deployment for
203202 // currentShardKey
204203 if shardMap [currentShardKey ] == nil || shardMap [currentShardKey ].Len () == 0 {
@@ -208,14 +207,15 @@ func trackCluster(ctx context.Context, config *rest.Config, c client.Client, age
208207 }
209208 }
210209
211- // Updates shard map (key: shard; value: list of cluster matching the shard)
212- // for the current shard by adding cluster as a match
210+ // Update both maps only after deployControllers succeeds, keeping clusterMap
211+ // and shardMap consistent even when deployControllers returns an error.
213212 clusterPerShard := shardMap [currentShardKey ]
214213 if clusterPerShard == nil {
215214 clusterPerShard = & libsveltosset.Set {}
216215 }
217216 clusterPerShard .Insert (cluster )
218217 shardMap [currentShardKey ] = clusterPerShard
218+ clusterMap [* cluster ] = currentShardKey
219219 logger .V (logs .LogInfo ).Info (fmt .Sprintf ("added cluster to shard %q: %d cluster(s) total" ,
220220 currentShardKey , clusterPerShard .Len ()))
221221
0 commit comments