diff --git a/components/ws-daemon/pkg/controller/workspace_controller.go b/components/ws-daemon/pkg/controller/workspace_controller.go index 085e8d3dd49687..ea82a2f08fbd36 100644 --- a/components/ws-daemon/pkg/controller/workspace_controller.go +++ b/components/ws-daemon/pkg/controller/workspace_controller.go @@ -258,62 +258,68 @@ func (wsc *WorkspaceController) handleWorkspaceRunning(ctx context.Context, ws * } func (wsc *WorkspaceController) handleWorkspaceStop(ctx context.Context, ws *workspacev1.Workspace, req ctrl.Request) (result ctrl.Result, err error) { - log := log.FromContext(ctx) span, ctx := opentracing.StartSpanFromContext(ctx, "handleWorkspaceStop") defer tracing.FinishSpan(span, &err) if ws.IsConditionTrue(workspacev1.WorkspaceConditionPodRejected) { + // edge case only exercised for rejected workspace pods if ws.IsConditionPresent(workspacev1.WorkspaceConditionStateWiped) { // we are done here return ctrl.Result{}, nil } - // in this case we are not interested in any backups, but instead are concerned with completely wiping all state that might be dangling somewhere - if ws.IsConditionTrue(workspacev1.WorkspaceConditionContainerRunning) { - // Container is still running, we need to wait for it to stop. - // We should get an event when the condition changes, but requeue - // anyways to make sure we act on it in time. - return ctrl.Result{RequeueAfter: 500 * time.Millisecond}, nil - } + return wsc.doWipeWorkspace(ctx, ws, req) + } - if wsc.latestWorkspace(ctx, ws) != nil { - return ctrl.Result{Requeue: true, RequeueAfter: 100 * time.Millisecond}, nil - } + // regular case + return wsc.doWorkspaceContentBackup(ctx, span, ws, req) +} - setStateWipedCondition := func(s bool) { - err := retry.RetryOnConflict(retryParams, func() error { - if err := wsc.Get(ctx, req.NamespacedName, ws); err != nil { - return err - } +func (wsc *WorkspaceController) doWipeWorkspace(ctx context.Context, ws *workspacev1.Workspace, req ctrl.Request) (result ctrl.Result, err error) { + log := log.FromContext(ctx) - if s { - ws.Status.SetCondition(workspacev1.NewWorkspaceConditionStateWiped("", metav1.ConditionTrue)) - } else { - ws.Status.SetCondition(workspacev1.NewWorkspaceConditionStateWiped("", metav1.ConditionFalse)) - } - return wsc.Client.Status().Update(ctx, ws) - }) - if err != nil { - log.Error(err, "failed to set StateWiped condition") + // in this case we are not interested in any backups, but instead are concerned with completely wiping all state that might be dangling somewhere + if ws.IsConditionTrue(workspacev1.WorkspaceConditionContainerRunning) { + // Container is still running, we need to wait for it to stop. + // We should get an event when the condition changes, but requeue + // anyways to make sure we act on it in time. + return ctrl.Result{RequeueAfter: 500 * time.Millisecond}, nil + } + + if wsc.latestWorkspace(ctx, ws) != nil { + return ctrl.Result{Requeue: true, RequeueAfter: 100 * time.Millisecond}, nil + } + + setStateWipedCondition := func(s bool) { + err := retry.RetryOnConflict(retryParams, func() error { + if err := wsc.Get(ctx, req.NamespacedName, ws); err != nil { + return err } - } - log.Info("handling workspace stop - wiping mode") - err = wsc.operations.WipeWorkspace(ctx, ws.Name) + if s { + ws.Status.SetCondition(workspacev1.NewWorkspaceConditionStateWiped("", metav1.ConditionTrue)) + } else { + ws.Status.SetCondition(workspacev1.NewWorkspaceConditionStateWiped("", metav1.ConditionFalse)) + } + return wsc.Client.Status().Update(ctx, ws) + }) if err != nil { - setStateWipedCondition(false) - wsc.emitEvent(ws, "Wiping", fmt.Errorf("failed to wipe workspace: %w", err)) - return ctrl.Result{}, fmt.Errorf("failed to wipe workspace: %w", err) + log.Error(err, "failed to set StateWiped condition") } + } + log.Info("handling workspace stop - wiping mode") + defer log.Info("handling workspace stop - wiping done.") - setStateWipedCondition(true) - - log.Info("handling workspace stop - wiping done.") - return ctrl.Result{}, nil + err = wsc.operations.WipeWorkspace(ctx, ws.Name) + if err != nil { + setStateWipedCondition(false) + wsc.emitEvent(ws, "Wiping", fmt.Errorf("failed to wipe workspace: %w", err)) + return ctrl.Result{}, fmt.Errorf("failed to wipe workspace: %w", err) } - // regular case - return wsc.doWorkspaceContentBackup(ctx, span, ws, req) + setStateWipedCondition(true) + + return ctrl.Result{}, nil } func (wsc *WorkspaceController) doWorkspaceContentBackup(ctx context.Context, span opentracing.Span, ws *workspacev1.Workspace, req ctrl.Request) (result ctrl.Result, err error) {