From 025827afadb8db0d3af91a1561b1ff0fe801cfc3 Mon Sep 17 00:00:00 2001 From: Marius Klumbys Date: Wed, 25 Mar 2026 14:16:34 +0200 Subject: [PATCH] feat: add node label support for kwasm jobs --- charts/kwasm-operator/Chart.yaml | 4 +- charts/kwasm-operator/values.yaml | 2 +- controllers/provisioner_controller.go | 2 +- controllers/provisioner_controller_test.go | 66 ++++++++++++++++++++++ 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/charts/kwasm-operator/Chart.yaml b/charts/kwasm-operator/Chart.yaml index ee71d0e..e750130 100644 --- a/charts/kwasm-operator/Chart.yaml +++ b/charts/kwasm-operator/Chart.yaml @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.2.3 +version: 0.2.4 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "0.2.3" +appVersion: "0.2.4" diff --git a/charts/kwasm-operator/values.yaml b/charts/kwasm-operator/values.yaml index 0a86c07..74bc85c 100644 --- a/charts/kwasm-operator/values.yaml +++ b/charts/kwasm-operator/values.yaml @@ -8,7 +8,7 @@ image: repository: ghcr.io/kwasm/kwasm-operator pullPolicy: IfNotPresent # Overrides the image tag whose default is the chart appVersion. - tag: kwasm-operator-0.2.2 + tag: kwasm-operator-0.2.4 imagePullSecrets: [] nameOverride: "" diff --git a/controllers/provisioner_controller.go b/controllers/provisioner_controller.go index bb6e85d..e612290 100644 --- a/controllers/provisioner_controller.go +++ b/controllers/provisioner_controller.go @@ -82,7 +82,7 @@ func (r *ProvisionerReconciler) Reconcile(ctx context.Context, req ctrl.Request) Step 1: Add or remove the label. */ - labelShouldBePresent := node.Annotations[addKWasmNodeLabelAnnotation] == "true" + labelShouldBePresent := node.Annotations[addKWasmNodeLabelAnnotation] == "true" || node.Labels[addKWasmNodeLabelAnnotation] == "true" labelIsPresent := node.Labels[nodeNameLabel] == node.Name if labelShouldBePresent == labelIsPresent && !r.AutoProvision { diff --git a/controllers/provisioner_controller_test.go b/controllers/provisioner_controller_test.go index 4302879..58e8fd8 100644 --- a/controllers/provisioner_controller_test.go +++ b/controllers/provisioner_controller_test.go @@ -79,6 +79,72 @@ var _ = Describe("ProvisionerController", func() { Expect(job).NotTo(BeNil()) }) + It("should reconcile the node and create a job when label is set", func() { + var nodeName = "test-node-with-label" + nodeNameNamespaced := types.NamespacedName{Name: nodeName, Namespace: ""} + node = &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + Labels: map[string]string{ + "kwasm.sh/kwasm-node": "true", + }, + }, + } + + kwasmReconciler := &controllers.ProvisionerReconciler{ + Client: k8sClient, + Scheme: k8sClient.Scheme(), + InstallerImage: installerImage, + } + err = k8sClient.Create(ctx, node) + Expect(err).NotTo(HaveOccurred()) + + _, err = kwasmReconciler.Reconcile(ctx, reconcile.Request{ + NamespacedName: nodeNameNamespaced, + }) + Expect(err).To(Not(HaveOccurred())) + + // Verify that the Node has the expected provisioned label. + err = k8sClient.Get(ctx, types.NamespacedName{Name: nodeName}, node) + Expect(err).NotTo(HaveOccurred()) + Expect(node.Labels["kwasm.sh/kwasm-provisioned"]).To(Equal(nodeName)) + + // Check that the job was created. + job = &batchv1.Job{} + err = k8sClient.Get(ctx, types.NamespacedName{Name: nodeName + "-provision-kwasm", Namespace: namespaceName}, job) + Expect(err).NotTo(HaveOccurred()) + Expect(job).NotTo(BeNil()) + }) + + It("should ignore Nodes with no annotation or label", func() { + nodeName := "test-node-without-annotation-or-label" + nodeNameNamespaced := types.NamespacedName{Name: nodeName, Namespace: ""} + + kwasmReconciler := &controllers.ProvisionerReconciler{ + Client: k8sClient, + Scheme: k8sClient.Scheme(), + InstallerImage: installerImage, + } + + node = &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + }, + } + err := k8sClient.Create(ctx, node) + Expect(err).NotTo(HaveOccurred()) + + _, err = kwasmReconciler.Reconcile(ctx, reconcile.Request{ + NamespacedName: nodeNameNamespaced, + }) + Expect(err).To(Not(HaveOccurred())) + + // Check that the job was NOT created. + job = &batchv1.Job{} + err = k8sClient.Get(ctx, types.NamespacedName{Name: nodeName + "-provision-kwasm", Namespace: namespaceName}, job) + Expect(err).To(HaveOccurred()) + }) + It("should not set autoProvision to true by default", func() { r := controllers.ProvisionerReconciler{}.AutoProvision Expect(r).To(BeFalse())