From 9d9a082bf01aae27e75d1080c39388d3743aeb1b Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Mon, 30 Jun 2025 21:31:52 +0530 Subject: [PATCH] fix : execute `preStart` devfile events after `project-clone` initContainer Change ordering of initContainers to ensure that `project-clone` initContainer is executed before preStart initContainers Signed-off-by: Rohan Kumar --- .../workspace/devworkspace_controller.go | 2 +- .../workspace/devworkspace_controller_test.go | 33 ++++++++++++ .../testdata/test-devworkspace-prestart.yaml | 50 +++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 controllers/workspace/testdata/test-devworkspace-prestart.yaml diff --git a/controllers/workspace/devworkspace_controller.go b/controllers/workspace/devworkspace_controller.go index 0fecaa364..fdf5d4f54 100644 --- a/controllers/workspace/devworkspace_controller.go +++ b/controllers/workspace/devworkspace_controller.go @@ -355,7 +355,7 @@ func (r *DevWorkspaceReconciler) Reconcile(ctx context.Context, req ctrl.Request if projectClone, err := projects.GetProjectCloneInitContainer(&workspace.Spec.Template, projectCloneOptions, workspace.Config.Routing.ProxyConfig); err != nil { return r.failWorkspace(workspace, fmt.Sprintf("Failed to set up project-clone init container: %s", err), metrics.ReasonInfrastructureFailure, reqLogger, &reconcileStatus), nil } else if projectClone != nil { - devfilePodAdditions.InitContainers = append(devfilePodAdditions.InitContainers, *projectClone) + devfilePodAdditions.InitContainers = append([]corev1.Container{*projectClone}, devfilePodAdditions.InitContainers...) } // Add ServiceAccount tokens into devfile containers diff --git a/controllers/workspace/devworkspace_controller_test.go b/controllers/workspace/devworkspace_controller_test.go index 9fae45d48..89badecdb 100644 --- a/controllers/workspace/devworkspace_controller_test.go +++ b/controllers/workspace/devworkspace_controller_test.go @@ -1052,6 +1052,39 @@ var _ = Describe("DevWorkspace Controller", func() { workspacecontroller.SetupHttpClientsForTesting(getBasicTestHttpClient()) }) + It("Ensures preStart initContainers are run after project-clone", func() { + createDevWorkspace(devWorkspaceName, "test-devworkspace-prestart.yaml") + defer deleteDevWorkspace(devWorkspaceName) + devWorkspace := getExistingDevWorkspace(devWorkspaceName) + workspaceID := devWorkspace.Status.DevWorkspaceId + + By("Manually making Routing ready to continue") + markRoutingReady("test-url", common.DevWorkspaceRoutingName(workspaceID)) + + By("Setting the deployment to have 1 ready replica") + markDeploymentReady(common.DeploymentName(workspaceID)) + + deployment := &appsv1.Deployment{} + err := k8sClient.Get(ctx, namespacedName(workspaceID, testNamespace), deployment) + Expect(err).ToNot(HaveOccurred(), "Failed to get DevWorkspace deployment") + + By("Checking initContainer order in the created Deployment") + initContainers := deployment.Spec.Template.Spec.InitContainers + Expect(len(initContainers)).To(BeNumerically(">", 0), "No initContainers found") + + expectedOrder := []string{ + "project-clone", + "go-mod-builder", + "go-builder", + } + + for i, name := range expectedOrder { + if i >= len(initContainers) { + Fail(fmt.Sprintf("Expected init container %s at position %d, but only %d containers found", name, i, len(initContainers))) + } + Expect(initContainers[i].Name).To(Equal(name), fmt.Sprintf("Init container at position %d is not %s", i, name)) + } + }) }) }) diff --git a/controllers/workspace/testdata/test-devworkspace-prestart.yaml b/controllers/workspace/testdata/test-devworkspace-prestart.yaml new file mode 100644 index 000000000..7439b1396 --- /dev/null +++ b/controllers/workspace/testdata/test-devworkspace-prestart.yaml @@ -0,0 +1,50 @@ +apiVersion: workspace.devfile.io/v1alpha2 +kind: DevWorkspace +metadata: + labels: + controller.devfile.io/creator: "" +spec: + started: true + template: + projects: + - name: my-app + clonePath: my-app + git: + remotes: + origin: https://github.com/che-samples/web-nodejs-sample.git + checkoutFrom: + revision: main + components: + - name: tools + container: + image: quay.io/devfile/universal-developer-image:ubi8-latest + memoryLimit: 256Mi + mountSources: true + sourceMapping: /projects + - name: go-mod-builder + container: + image: quay.io/devfile/universal-developer-image:ubi8-latest + command: + - "go" + - "mod" + - "download" + - name: go-builder + container: + image: quay.io/devfile/universal-developer-image:ubi8-latest + command: + - "go" + - "build" + - "-buildvcs=false" + - "-o" + - "./main" + commands: + - id: go-mod + apply: + component: go-mod-builder + - id: go-build + apply: + component: go-builder + events: + preStart: + - go-mod + - go-build