Skip to content

Commit 529d007

Browse files
fwieselnotandy
authored andcommitted
Eviction: Consolidate handling of not found instance
We need to handle that an instance is gone in multiple places, so let's delegate that to a method.
1 parent 6454428 commit 529d007

File tree

1 file changed

+40
-53
lines changed

1 file changed

+40
-53
lines changed

internal/controller/eviction_controller.go

Lines changed: 40 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -238,30 +238,43 @@ func (r *EvictionReconciler) handlePreflight(ctx context.Context, eviction *kvmv
238238
return ctrl.Result{}, r.Status().Update(ctx, eviction)
239239
}
240240

241+
// Tries to handle the NotFound-error by updating the status
242+
func (r *EvictionReconciler) handleNotFound(ctx context.Context, eviction *kvmv1.Eviction, err error) error {
243+
if !gophercloud.ResponseCodeIs(err, http.StatusNotFound) {
244+
return err
245+
}
246+
logger.FromContext(ctx).Info("Instance is gone")
247+
instances := &eviction.Status.OutstandingInstances
248+
uuid := (*instances)[len(*instances)-1]
249+
*instances = (*instances)[:len(*instances)-1]
250+
meta.SetStatusCondition(&eviction.Status.Conditions, metav1.Condition{
251+
Type: kvmv1.ConditionTypeMigration,
252+
Status: metav1.ConditionFalse,
253+
Message: fmt.Sprintf("Instance %s is gone", uuid),
254+
Reason: kvmv1.ConditionReasonSucceeded,
255+
})
256+
return r.Status().Update(ctx, eviction)
257+
}
258+
241259
func (r *EvictionReconciler) evictNext(ctx context.Context, eviction *kvmv1.Eviction) (ctrl.Result, error) {
242260
instances := &eviction.Status.OutstandingInstances
243261
uuid := (*instances)[len(*instances)-1]
244262
log := logger.FromContext(ctx).WithName("Evict").WithValues("server", uuid)
263+
logger.IntoContext(ctx, log)
245264

246265
res := servers.Get(ctx, r.computeClient, uuid)
247266
vm, err := res.Extract()
248267

249268
if err != nil {
250-
if gophercloud.ResponseCodeIs(err, http.StatusNotFound) {
251-
log.Info("Instance is gone")
252-
*instances = (*instances)[:len(*instances)-1]
253-
meta.SetStatusCondition(&eviction.Status.Conditions, metav1.Condition{
254-
Type: kvmv1.ConditionTypeMigration,
255-
Status: metav1.ConditionFalse,
256-
Message: fmt.Sprintf("Instance %s is gone", uuid),
257-
Reason: kvmv1.ConditionReasonSucceeded,
258-
})
259-
return ctrl.Result{}, r.Status().Update(ctx, eviction)
269+
if err2 := r.handleNotFound(ctx, eviction, err); err2 != nil {
270+
return ctrl.Result{}, err2
271+
} else {
272+
return ctrl.Result{RequeueAfter: shortRetryTime}, nil
260273
}
261-
return ctrl.Result{}, err
262274
}
263275

264276
log = log.WithValues("server_status", vm.Status)
277+
logger.IntoContext(ctx, log)
265278

266279
// First, check the transient statuses
267280
switch vm.Status {
@@ -300,14 +313,13 @@ func (r *EvictionReconciler) evictNext(ctx context.Context, eviction *kvmv1.Evic
300313

301314
// So, it is already off this one, do we need to verify it?
302315
if vm.Status == "VERIFY_RESIZE" {
303-
if err := servers.ConfirmResize(ctx, r.computeClient, vm.ID).ExtractErr(); err != nil {
304-
if gophercloud.ResponseCodeIs(err, http.StatusNotFound) {
305-
log.Info("Instance is gone")
306-
// Fall-back to beginning, which will clean it out
307-
return ctrl.Result{RequeueAfter: shortRetryTime}, nil
308-
}
316+
err := servers.ConfirmResize(ctx, r.computeClient, vm.ID).ExtractErr()
317+
if err2 := r.handleNotFound(ctx, eviction, err); err2 != nil {
309318
// Retry confirm in next reconciliation
310-
return ctrl.Result{}, err
319+
return ctrl.Result{}, err2
320+
} else {
321+
// handled not found without errors
322+
return ctrl.Result{RequeueAfter: shortRetryTime}, nil
311323
}
312324
}
313325

@@ -332,48 +344,23 @@ func (r *EvictionReconciler) evictNext(ctx context.Context, eviction *kvmv1.Evic
332344
}
333345
} else if vm.Status == "ACTIVE" || vm.PowerState == 1 {
334346
log.Info("trigger live-migration")
335-
if err = r.liveMigrate(ctx, vm.ID, eviction); err != nil {
336-
if gophercloud.ResponseCodeIs(err, http.StatusNotFound) {
337-
log.Info("Instance is gone")
338-
// Fall-back to beginning, which will clean it out
347+
err := r.liveMigrate(ctx, vm.ID, eviction)
348+
if err != nil {
349+
if err2 := r.handleNotFound(ctx, eviction, err); err2 != nil {
350+
return ctrl.Result{}, err2
351+
} else {
339352
return ctrl.Result{RequeueAfter: shortRetryTime}, nil
340353
}
341-
copy((*instances)[1:], (*instances)[:len(*instances)-1])
342-
(*instances)[0] = uuid
343-
344-
meta.SetStatusCondition(&eviction.Status.Conditions, metav1.Condition{
345-
Type: kvmv1.ConditionTypeMigration,
346-
Status: metav1.ConditionTrue,
347-
Message: fmt.Sprintf("Live migration of instance %s triggered", vm.ID),
348-
Reason: kvmv1.ConditionReasonRunning,
349-
})
350-
if err2 := r.Status().Update(ctx, eviction); err2 != nil {
351-
return ctrl.Result{}, fmt.Errorf("could not live-migrate due to %w and %w", err, err2)
352-
}
353-
354-
return ctrl.Result{}, err
355354
}
356355
} else {
357356
log.Info("trigger cold-migration")
358-
if err := r.coldMigrate(ctx, vm.ID, eviction); err != nil {
359-
if gophercloud.ResponseCodeIs(err, http.StatusNotFound) {
360-
log.Info("Instance is gone")
357+
err := r.coldMigrate(ctx, vm.ID, eviction)
358+
if err != nil {
359+
if err2 := r.handleNotFound(ctx, eviction, err); err2 != nil {
360+
return ctrl.Result{}, err2
361+
} else {
361362
return ctrl.Result{RequeueAfter: shortRetryTime}, nil
362363
}
363-
copy((*instances)[1:], (*instances)[:len(*instances)-1])
364-
(*instances)[0] = uuid
365-
366-
meta.SetStatusCondition(&eviction.Status.Conditions, metav1.Condition{
367-
Type: kvmv1.ConditionTypeMigration,
368-
Status: metav1.ConditionTrue,
369-
Message: fmt.Sprintf("Cold-migration of instance %s triggered", vm.ID),
370-
Reason: kvmv1.ConditionReasonRunning,
371-
})
372-
if err2 := r.Status().Update(ctx, eviction); err2 != nil {
373-
return ctrl.Result{}, fmt.Errorf("could not cold-migrate due to %w and %w", err, err2)
374-
}
375-
376-
return ctrl.Result{}, err
377364
}
378365
}
379366

0 commit comments

Comments
 (0)