Skip to content

Commit 993a78e

Browse files
committed
Refactor HypervisorMaintenanceController: pass statusCfg into sub-functions
With SSA the status config is built once in Reconcile and passed to reconcileComputeService and reconcileEviction which mutate it directly. This eliminates the intermediate condition return values and makes the single-apply-per-reconcile explicit. The early-return guard for already-enabled/disabled state is inlined into each branch.
1 parent dfdffec commit 993a78e

1 file changed

Lines changed: 67 additions & 96 deletions

File tree

internal/controller/hypervisor_maintenance_controller.go

Lines changed: 67 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -67,37 +67,16 @@ func (hec *HypervisorMaintenanceController) Reconcile(ctx context.Context, req c
6767
return ctrl.Result{}, nil
6868
}
6969

70-
// Determine desired disabled condition and eviction state
71-
disabledCond, evictingCond, evicted, err := hec.reconcileComputeService(ctx, hv)
72-
if err != nil {
73-
return ctrl.Result{}, err
74-
}
75-
76-
evictingCond, evicted, err = hec.reconcileEviction(ctx, hv, evictingCond, evicted)
77-
if err != nil {
78-
return ctrl.Result{}, err
79-
}
80-
81-
// Build status apply config: always include conditions this controller owns;
82-
// omit ConditionTypeEvicting when it should be removed (SSA prunes it).
83-
statusCfg := apiv1.HypervisorStatus().WithEvicted(evicted)
70+
// Build status apply config upfront; sub-functions mutate it directly.
71+
statusCfg := apiv1.HypervisorStatus().WithEvicted(hv.Status.Evicted)
8472
statusCfg.Conditions = utils.ConditionsFromStatus(hv.Status.Conditions)
8573

86-
if disabledCond != nil {
87-
utils.SetApplyConfigurationStatusCondition(&statusCfg.Conditions, *disabledCond)
74+
if err := hec.reconcileComputeService(ctx, hv, statusCfg); err != nil {
75+
return ctrl.Result{}, err
8876
}
8977

90-
if evictingCond != nil {
91-
utils.SetApplyConfigurationStatusCondition(&statusCfg.Conditions, *evictingCond)
92-
} else {
93-
// Remove ConditionTypeEvicting by omitting it — SSA prunes sole-owned entries.
94-
filtered := statusCfg.Conditions[:0]
95-
for _, c := range statusCfg.Conditions {
96-
if c.Type == nil || *c.Type != kvmv1.ConditionTypeEvicting {
97-
filtered = append(filtered, c)
98-
}
99-
}
100-
statusCfg.Conditions = filtered
78+
if err := hec.reconcileEviction(ctx, hv, statusCfg); err != nil {
79+
return ctrl.Result{}, err
10180
}
10281

10382
return ctrl.Result{}, hec.Status().Apply(ctx,
@@ -106,85 +85,67 @@ func (hec *HypervisorMaintenanceController) Reconcile(ctx context.Context, req c
10685
}
10786

10887
// reconcileComputeService enables/disables the nova-compute service based on
109-
// hv.Spec.Maintenance. Returns the desired HypervisorDisabled condition (nil if
110-
// service ID is unset) and the initial evicting/evicted state.
111-
func (hec *HypervisorMaintenanceController) reconcileComputeService(ctx context.Context, hv *kvmv1.Hypervisor) (
112-
disabledCond *k8sacmetav1.ConditionApplyConfiguration,
113-
evictingCond *k8sacmetav1.ConditionApplyConfiguration,
114-
evicted bool,
115-
err error,
116-
) {
88+
// hv.Spec.Maintenance and sets the HypervisorDisabled condition on statusCfg.
89+
func (hec *HypervisorMaintenanceController) reconcileComputeService(ctx context.Context, hv *kvmv1.Hypervisor, statusCfg *apiv1.HypervisorStatusApplyConfiguration) error {
11790
log := logger.FromContext(ctx)
11891
serviceId := hv.Status.ServiceID
11992

12093
if serviceId == "" {
12194
// We can only do something here, if there is a service to begin with.
12295
// The onboarding should take care of that.
123-
return nil, nil, false, nil
96+
return nil
12497
}
12598

12699
switch hv.Spec.Maintenance {
127100
case kvmv1.MaintenanceUnset:
128-
cond := k8sacmetav1.Condition().
129-
WithType(kvmv1.ConditionTypeHypervisorDisabled).
130-
WithStatus(metav1.ConditionFalse).
131-
WithMessage("Hypervisor is enabled").
132-
WithReason(kvmv1.ConditionReasonSucceeded)
133-
134101
existing := meta.FindStatusCondition(hv.Status.Conditions, kvmv1.ConditionTypeHypervisorDisabled)
135-
if existing != nil && existing.Status == metav1.ConditionFalse {
136-
// Already enabled, nothing to do
137-
return cond, nil, false, nil
138-
}
139-
140-
enableService := services.UpdateOpts{Status: services.ServiceEnabled}
141-
// We need to enable the host as per spec
142-
log.Info("Enabling hypervisor", "id", serviceId)
143-
if _, err := services.Update(ctx, hec.computeClient, serviceId, enableService).Extract(); err != nil {
144-
return nil, nil, false, fmt.Errorf("failed to enable hypervisor due to %w", err)
102+
if existing == nil || existing.Status != metav1.ConditionFalse {
103+
// We need to enable the host as per spec
104+
enableService := services.UpdateOpts{Status: services.ServiceEnabled}
105+
log.Info("Enabling hypervisor", "id", serviceId)
106+
if _, err := services.Update(ctx, hec.computeClient, serviceId, enableService).Extract(); err != nil {
107+
return fmt.Errorf("failed to enable hypervisor due to %w", err)
108+
}
145109
}
146-
return cond, nil, false, nil
110+
utils.SetApplyConfigurationStatusCondition(&statusCfg.Conditions,
111+
*k8sacmetav1.Condition().
112+
WithType(kvmv1.ConditionTypeHypervisorDisabled).
113+
WithStatus(metav1.ConditionFalse).
114+
WithMessage("Hypervisor is enabled").
115+
WithReason(kvmv1.ConditionReasonSucceeded))
147116

148117
case kvmv1.MaintenanceManual, kvmv1.MaintenanceAuto, kvmv1.MaintenanceHA, kvmv1.MaintenanceTermination:
149118
// Disable the compute service.
150119
// Also in case of HA, as it doesn't hurt to disable it twice, and this
151120
// allows us to enable the service again, when the maintenance field is
152121
// cleared in the case above.
153-
cond := k8sacmetav1.Condition().
154-
WithType(kvmv1.ConditionTypeHypervisorDisabled).
155-
WithStatus(metav1.ConditionTrue).
156-
WithMessage("Hypervisor is disabled").
157-
WithReason(kvmv1.ConditionReasonSucceeded)
158-
159122
existing := meta.FindStatusCondition(hv.Status.Conditions, kvmv1.ConditionTypeHypervisorDisabled)
160-
if existing != nil && existing.Status == metav1.ConditionTrue {
161-
// Already disabled, nothing to do
162-
return cond, nil, false, nil
163-
}
164-
165-
disableService := services.UpdateOpts{
166-
Status: services.ServiceDisabled,
167-
DisabledReason: "Hypervisor CRD: spec.maintenance=" + hv.Spec.Maintenance,
168-
}
169-
// We need to disable the host as per spec
170-
log.Info("Disabling hypervisor", "id", serviceId)
171-
if _, err := services.Update(ctx, hec.computeClient, serviceId, disableService).Extract(); err != nil {
172-
return nil, nil, false, fmt.Errorf("failed to disable hypervisor due to %w", err)
123+
if existing == nil || existing.Status != metav1.ConditionTrue {
124+
disableService := services.UpdateOpts{
125+
Status: services.ServiceDisabled,
126+
DisabledReason: "Hypervisor CRD: spec.maintenance=" + hv.Spec.Maintenance,
127+
}
128+
// We need to disable the host as per spec
129+
log.Info("Disabling hypervisor", "id", serviceId)
130+
if _, err := services.Update(ctx, hec.computeClient, serviceId, disableService).Extract(); err != nil {
131+
return fmt.Errorf("failed to disable hypervisor due to %w", err)
132+
}
173133
}
174-
return cond, nil, false, nil
134+
utils.SetApplyConfigurationStatusCondition(&statusCfg.Conditions,
135+
*k8sacmetav1.Condition().
136+
WithType(kvmv1.ConditionTypeHypervisorDisabled).
137+
WithStatus(metav1.ConditionTrue).
138+
WithMessage("Hypervisor is disabled").
139+
WithReason(kvmv1.ConditionReasonSucceeded))
175140
}
176141

177-
return nil, nil, false, nil
142+
return nil
178143
}
179144

180-
// reconcileEviction creates/deletes the Eviction CR and returns the desired
181-
// ConditionTypeEvicting apply configuration (nil means remove the condition).
182-
func (hec *HypervisorMaintenanceController) reconcileEviction(
183-
ctx context.Context,
184-
hv *kvmv1.Hypervisor,
185-
evictingCond *k8sacmetav1.ConditionApplyConfiguration,
186-
evicted bool,
187-
) (*k8sacmetav1.ConditionApplyConfiguration, bool, error) {
145+
// reconcileEviction creates/deletes the Eviction CR and sets the ConditionTypeEvicting
146+
// condition and Evicted scalar on statusCfg. When eviction should be removed, the
147+
// condition entry is filtered out so SSA prunes it.
148+
func (hec *HypervisorMaintenanceController) reconcileEviction(ctx context.Context, hv *kvmv1.Hypervisor, statusCfg *apiv1.HypervisorStatusApplyConfiguration) error {
188149
eviction := &kvmv1.Eviction{
189150
ObjectMeta: metav1.ObjectMeta{Name: hv.Name},
190151
}
@@ -193,45 +154,55 @@ func (hec *HypervisorMaintenanceController) reconcileEviction(
193154
case kvmv1.MaintenanceUnset:
194155
// Avoid deleting the eviction over and over.
195156
if !hv.Status.Evicted && meta.FindStatusCondition(hv.Status.Conditions, kvmv1.ConditionTypeEvicting) == nil {
196-
return nil, false, nil
157+
return nil
158+
}
159+
if err := k8sclient.IgnoreNotFound(hec.Delete(ctx, eviction)); err != nil {
160+
return err
197161
}
198-
err := k8sclient.IgnoreNotFound(hec.Delete(ctx, eviction))
199-
return nil, false, err // nil evictingCond → condition omitted from apply → SSA prunes it
162+
// Remove ConditionTypeEvicting by omitting it — SSA prunes sole-owned entries.
163+
filtered := statusCfg.Conditions[:0]
164+
for _, c := range statusCfg.Conditions {
165+
if c.Type == nil || *c.Type != kvmv1.ConditionTypeEvicting {
166+
filtered = append(filtered, c)
167+
}
168+
}
169+
statusCfg.Conditions = filtered
170+
statusCfg.WithEvicted(false)
200171

201172
case kvmv1.MaintenanceManual, kvmv1.MaintenanceAuto, kvmv1.MaintenanceTermination:
202173
// In case of "ha", the host gets emptied from the HA service
203174
if cond := meta.FindStatusCondition(hv.Status.Conditions, kvmv1.ConditionTypeEvicting); cond != nil {
204175
if cond.Reason == kvmv1.ConditionReasonSucceeded {
205176
// We are done here, no need to look at the eviction any more
206-
return evictingCond, evicted, nil
177+
return nil
207178
}
208179
}
209180

210181
status, err := hec.ensureEviction(ctx, eviction, hv)
211182
if err != nil {
212-
return evictingCond, evicted, err
183+
return err
213184
}
214185

215186
var reason, message string
216187
if status == metav1.ConditionFalse {
217188
message = "Evicted"
218189
reason = kvmv1.ConditionReasonSucceeded
219-
evicted = true
190+
statusCfg.WithEvicted(true)
220191
} else {
221192
message = "Evicting"
222193
reason = kvmv1.ConditionReasonRunning
223-
evicted = false
194+
statusCfg.WithEvicted(false)
224195
}
225196

226-
cond := k8sacmetav1.Condition().
227-
WithType(kvmv1.ConditionTypeEvicting).
228-
WithStatus(status).
229-
WithReason(reason).
230-
WithMessage(message)
231-
return cond, evicted, nil
197+
utils.SetApplyConfigurationStatusCondition(&statusCfg.Conditions,
198+
*k8sacmetav1.Condition().
199+
WithType(kvmv1.ConditionTypeEvicting).
200+
WithStatus(status).
201+
WithReason(reason).
202+
WithMessage(message))
232203
}
233204

234-
return evictingCond, evicted, nil
205+
return nil
235206
}
236207

237208
func (hec *HypervisorMaintenanceController) ensureEviction(ctx context.Context, eviction *kvmv1.Eviction, hypervisor *kvmv1.Hypervisor) (metav1.ConditionStatus, error) {

0 commit comments

Comments
 (0)