Skip to content

Commit 661c656

Browse files
authored
Merge pull request #362 from tinakurian/338-cleanup-workspace-resources-on-failure
cleaning up workspace on failure
2 parents 81b939e + bfb8062 commit 661c656

File tree

2 files changed

+57
-6
lines changed

2 files changed

+57
-6
lines changed

controllers/workspace/devworkspace_controller.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ func (r *DevWorkspaceReconciler) Reconcile(req ctrl.Request) (reconcileResult ct
171171
flattenedWorkspace, err := flatten.ResolveDevWorkspace(&workspace.Spec.Template, flattenHelpers)
172172
if err != nil {
173173
reqLogger.Info("DevWorkspace start failed")
174+
// Clean up cluster deployment
175+
err := provision.ScaleDeploymentToZero(workspace, r.Client)
176+
if err != nil {
177+
return reconcile.Result{}, err
178+
}
174179
reconcileStatus.Phase = devworkspace.WorkspaceStatusFailed
175180
// TODO: Handle error more elegantly
176181
reconcileStatus.Conditions[devworkspace.WorkspaceFailedStart] = fmt.Sprintf("Error processing devfile: %s", err)
@@ -181,6 +186,11 @@ func (r *DevWorkspaceReconciler) Reconcile(req ctrl.Request) (reconcileResult ct
181186
storageProvisioner, err := storage.GetProvisioner(workspace)
182187
if err != nil {
183188
reqLogger.Info("DevWorkspace start failed")
189+
// Clean up cluster deployment
190+
err := provision.ScaleDeploymentToZero(workspace, r.Client)
191+
if err != nil {
192+
return reconcile.Result{}, err
193+
}
184194
reconcileStatus.Phase = devworkspace.WorkspaceStatusFailed
185195
reconcileStatus.Conditions[devworkspace.WorkspaceFailedStart] = fmt.Sprintf("Error provisioning storage: %s", err)
186196
return reconcile.Result{}, nil
@@ -197,6 +207,11 @@ func (r *DevWorkspaceReconciler) Reconcile(req ctrl.Request) (reconcileResult ct
197207
devfilePodAdditions, err := containerlib.GetKubeContainersFromDevfile(&workspace.Spec.Template)
198208
if err != nil {
199209
reqLogger.Info("DevWorkspace start failed")
210+
// Clean up cluster deployment
211+
err := provision.ScaleDeploymentToZero(workspace, r.Client)
212+
if err != nil {
213+
return reconcile.Result{}, err
214+
}
200215
reconcileStatus.Phase = devworkspace.WorkspaceStatusFailed
201216
reconcileStatus.Conditions[devworkspace.WorkspaceFailedStart] = fmt.Sprintf("Error processing devfile: %s", err)
202217
return reconcile.Result{}, nil
@@ -210,6 +225,11 @@ func (r *DevWorkspaceReconciler) Reconcile(req ctrl.Request) (reconcileResult ct
210225
return reconcile.Result{Requeue: true, RequeueAfter: storageErr.RequeueAfter}, nil
211226
case *storage.ProvisioningError:
212227
reqLogger.Info(fmt.Sprintf("DevWorkspace start failed: %s", storageErr))
228+
// Clean up cluster deployment
229+
err := provision.ScaleDeploymentToZero(workspace, r.Client)
230+
if err != nil {
231+
return reconcile.Result{}, err
232+
}
213233
reconcileStatus.Phase = devworkspace.WorkspaceStatusFailed
214234
reconcileStatus.Conditions[devworkspace.WorkspaceFailedStart] = fmt.Sprintf("Error provisioning storage: %s", storageErr)
215235
return reconcile.Result{}, nil
@@ -234,6 +254,11 @@ func (r *DevWorkspaceReconciler) Reconcile(req ctrl.Request) (reconcileResult ct
234254
if !routingStatus.Continue {
235255
if routingStatus.FailStartup {
236256
reqLogger.Info("DevWorkspace start failed")
257+
// Clean up cluster deployment
258+
err := provision.ScaleDeploymentToZero(workspace, r.Client)
259+
if err != nil {
260+
return reconcile.Result{}, err
261+
}
237262
reconcileStatus.Phase = devworkspace.WorkspaceStatusFailed
238263
// TODO: Propagate failure reason from devWorkspaceRouting
239264
reconcileStatus.Conditions[devworkspace.WorkspaceFailedStart] = "Failed to install network objects required for devworkspace"
@@ -265,6 +290,11 @@ func (r *DevWorkspaceReconciler) Reconcile(req ctrl.Request) (reconcileResult ct
265290
return reconcile.Result{Requeue: true, RequeueAfter: provisionErr.RequeueAfter}, nil
266291
case *metadata.ProvisioningError:
267292
reqLogger.Info(fmt.Sprintf("DevWorkspace start failed: %s", provisionErr))
293+
// Clean up cluster deployment
294+
err := provision.ScaleDeploymentToZero(workspace, r.Client)
295+
if err != nil {
296+
return reconcile.Result{}, err
297+
}
268298
reconcileStatus.Phase = devworkspace.WorkspaceStatusFailed
269299
reconcileStatus.Conditions[devworkspace.WorkspaceFailedStart] = fmt.Sprintf("Error provisioning metadata configmap: %s", provisionErr)
270300
return reconcile.Result{}, nil
@@ -307,6 +337,12 @@ func (r *DevWorkspaceReconciler) Reconcile(req ctrl.Request) (reconcileResult ct
307337
if !deploymentStatus.Continue {
308338
if deploymentStatus.FailStartup {
309339
reqLogger.Info("Workspace start failed")
340+
// Clean up cluster deployment
341+
err := provision.ScaleDeploymentToZero(workspace, r.Client)
342+
if err != nil {
343+
return reconcile.Result{}, err
344+
}
345+
310346
reconcileStatus.Phase = devworkspace.WorkspaceStatusFailed
311347
reconcileStatus.Conditions[devworkspace.WorkspaceFailedStart] = fmt.Sprintf("Devworkspace spec is invalid: %s", deploymentStatus.Err)
312348
return reconcile.Result{}, deploymentStatus.Err

controllers/workspace/provision/deployment.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ import (
1818
"fmt"
1919
"strings"
2020

21+
"github.com/devfile/devworkspace-operator/apis/controller/v1alpha1"
22+
"github.com/devfile/devworkspace-operator/controllers/workspace/env"
2123
maputils "github.com/devfile/devworkspace-operator/internal/map"
24+
"github.com/devfile/devworkspace-operator/pkg/common"
25+
"github.com/devfile/devworkspace-operator/pkg/config"
2226
"github.com/devfile/devworkspace-operator/pkg/constants"
2327
"github.com/devfile/devworkspace-operator/pkg/infrastructure"
2428

25-
"github.com/devfile/devworkspace-operator/pkg/common"
26-
2729
devworkspace "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
2830
"github.com/google/go-cmp/cmp"
2931
"github.com/google/go-cmp/cmp/cmpopts"
@@ -35,10 +37,6 @@ import (
3537
"k8s.io/apimachinery/pkg/types"
3638
runtimeClient "sigs.k8s.io/controller-runtime/pkg/client"
3739
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
38-
39-
"github.com/devfile/devworkspace-operator/apis/controller/v1alpha1"
40-
"github.com/devfile/devworkspace-operator/controllers/workspace/env"
41-
"github.com/devfile/devworkspace-operator/pkg/config"
4240
)
4341

4442
type DeploymentProvisioningStatus struct {
@@ -140,6 +138,23 @@ func DeleteWorkspaceDeployment(ctx context.Context, workspace *devworkspace.DevW
140138
return true, nil
141139
}
142140

141+
// ScaleDeploymentToZero scales the cluster deployment to zero
142+
func ScaleDeploymentToZero(workspace *devworkspace.DevWorkspace, client runtimeClient.Client) error {
143+
patch := []byte(`{"spec":{"replicas": 0}}`)
144+
err := client.Patch(context.Background(), &appsv1.Deployment{
145+
ObjectMeta: metav1.ObjectMeta{
146+
Namespace: workspace.Namespace,
147+
Name: common.DeploymentName(workspace.Status.WorkspaceId),
148+
},
149+
}, runtimeClient.RawPatch(types.StrategicMergePatchType, patch))
150+
151+
if err != nil {
152+
return err
153+
}
154+
155+
return nil
156+
}
157+
143158
func GetDevWorkspaceSecurityContext() *corev1.PodSecurityContext {
144159
if !infrastructure.IsOpenShift() {
145160
uID := int64(1234)

0 commit comments

Comments
 (0)