You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2026/06/17 12:05:59 UTC

(camel-k) 01/03: feat(builder): add support for custom pipeline tasks and environment variable control

This is an automated email from the ASF dual-hosted git repository.

squakez pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit f024bac42f80e5fb6a9333a418676dea5ab84d63
Author: Harsh Mehta <ha...@gmail.com>
AuthorDate: Tue Jun 16 12:54:55 2026 +0530

    feat(builder): add support for custom pipeline tasks and environment variable control
    
    Signed-off-by: Harsh Mehta <ha...@gmail.com>
---
 docs/modules/ROOT/pages/installation/builds.adoc |  4 +++
 docs/modules/traits/pages/builder.adoc           |  8 ++++-
 pkg/platform/env_platform.go                     |  8 +++++
 pkg/platform/env_platform_test.go                | 25 +++++++++++++++
 pkg/trait/builder.go                             | 19 ++++++-----
 pkg/trait/builder_test.go                        | 41 ++++++++++++++++++++++--
 6 files changed, 94 insertions(+), 11 deletions(-)

diff --git a/docs/modules/ROOT/pages/installation/builds.adoc b/docs/modules/ROOT/pages/installation/builds.adoc
index e8c3a0bd3..86d1d62b6 100644
--- a/docs/modules/ROOT/pages/installation/builds.adoc
+++ b/docs/modules/ROOT/pages/installation/builds.adoc
@@ -47,6 +47,10 @@ Here a quick resume of the parameters you can configure as environment variables
 | Maximum number of builds that can run concurrently.
 | `3` if build strategy is `routine`, `10` if `pod`
 
+| BUILDER_TASKS_ENABLED
+| Controls whether CR authors are permitted to inject custom pipeline tasks via the `builder.tasks` trait. Set to `false` to disable custom task injection for all integrations managed by this operator. When unset or set to any value other than `false`, custom tasks are allowed (default behavior).
+| `true`
+
 | BUILDER_NODE_SELECTOR_ALLOWED_LABELS
 | Comma-separated list of node-selector label keys that CR authors are permitted to set via the `builder.nodeSelector` trait. When unset or empty all keys are accepted. Unlisted keys are dropped and an info message is logged. Example: `kubernetes.io/hostname,topology.kubernetes.io/zone`.
 |
diff --git a/docs/modules/traits/pages/builder.adoc b/docs/modules/traits/pages/builder.adoc
index b4a820604..2778beffc 100755
--- a/docs/modules/traits/pages/builder.adoc
+++ b/docs/modules/traits/pages/builder.adoc
@@ -158,4 +158,10 @@ Node selectors can be specified when running an integration with the CLI:
 $ kamel run --trait builder.node-selector.'size'=large integration.yaml
 ----
 
-NOTE: Operators can restrict which node-selector label keys CR authors are permitted to use by setting the `BUILDER_NODE_SELECTOR_ALLOWED_LABELS` environment variable on the operator deployment to a comma-separated list of allowed keys (e.g. `kubernetes.io/hostname,topology.kubernetes.io/zone`). Any key not in the list is dropped and an info message is logged. When the variable is unset or empty, all keys are accepted (default behavior). See Camel K operator tuning documentation for details.
+NOTE: Operators can restrict which node-selector label keys CR authors are permitted to use by setting the `BUILDER_NODE_SELECTOR_ALLOWED_LABELS` environment variable on the operator deployment to a comma-separated list of allowed keys (e.g. `kubernetes.io/hostname,topology.kubernetes.io/zone`). Any key not in the list is dropped and an info message is logged. When the variable is unset or empty, all keys are accepted (default behavior). See xref:installation:builds.adoc#env-var-config[b [...]
+
+== Custom Pipeline Tasks
+
+The `builder.tasks` trait option lets CR authors inject arbitrary containers into the build pipeline (only when using the `pod` build strategy). Each task entry has the format `<name>;<image>;<command>[;<userID>]`.
+
+NOTE: Operators can disable custom task injection entirely by setting `BUILDER_TASKS_ENABLED=false` on the operator deployment. When disabled, any `builder.tasks` values provided by CR authors are silently ignored and an info message is logged. The default is `true` (tasks are allowed). See xref:installation:builds.adoc#env-var-config[build environment variables] for details.
diff --git a/pkg/platform/env_platform.go b/pkg/platform/env_platform.go
index ca2f596a8..04589b6bc 100644
--- a/pkg/platform/env_platform.go
+++ b/pkg/platform/env_platform.go
@@ -173,6 +173,14 @@ func publishStrategy() v1.IntegrationPlatformBuildPublishStrategy {
 	return DefaultPublishStrategy
 }
 
+// BuilderTasksEnabled reports whether CR authors are permitted to inject custom pipeline tasks
+// via the builder.tasks trait. Controlled by the BUILDER_TASKS_ENABLED operator environment
+// variable (default true for backward compatibility). Set to "false" to prevent custom task
+// injection across all integrations managed by this operator.
+func BuilderTasksEnabled() bool {
+	return strings.ToLower(strings.TrimSpace(GetEnvOrDefault("BUILDER_TASKS_ENABLED", "true"))) != "false"
+}
+
 // BuilderNodeSelectorAllowList returns the list of node-selector keys that are allowed to be set
 // by the builder trait. When the list is empty (BUILDER_NODE_SELECTOR_ALLOWED_LABELS is unset or blank),
 // any key is permitted. When the list is non-empty only the listed keys are accepted; unlisted keys
diff --git a/pkg/platform/env_platform_test.go b/pkg/platform/env_platform_test.go
index 7710725be..0ea541518 100644
--- a/pkg/platform/env_platform_test.go
+++ b/pkg/platform/env_platform_test.go
@@ -168,3 +168,28 @@ func TestBuilderNodeSelectorAllowList_MultipleKeys(t *testing.T) {
 	assert.Equal(t, []string{"kubernetes.io/hostname", "node-role.kubernetes.io/worker", "topology.kubernetes.io/zone"}, allowList)
 }
 
+func TestBuilderTasksEnabled_NotSet(t *testing.T) {
+	// env var not set – default is enabled
+	assert.True(t, BuilderTasksEnabled())
+}
+
+func TestBuilderTasksEnabled_True(t *testing.T) {
+	t.Setenv("BUILDER_TASKS_ENABLED", "true")
+	assert.True(t, BuilderTasksEnabled())
+}
+
+func TestBuilderTasksEnabled_False(t *testing.T) {
+	t.Setenv("BUILDER_TASKS_ENABLED", "false")
+	assert.False(t, BuilderTasksEnabled())
+}
+
+func TestBuilderTasksEnabled_FalseUpperCase(t *testing.T) {
+	t.Setenv("BUILDER_TASKS_ENABLED", "FALSE")
+	assert.False(t, BuilderTasksEnabled())
+}
+
+func TestBuilderTasksEnabled_Empty(t *testing.T) {
+	t.Setenv("BUILDER_TASKS_ENABLED", "")
+	// empty string is not "false" – treat as enabled
+	assert.True(t, BuilderTasksEnabled())
+}
diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go
index d1eda3399..7353eb7b1 100644
--- a/pkg/trait/builder.go
+++ b/pkg/trait/builder.go
@@ -246,15 +246,18 @@ func (t *builderTrait) Apply(e *Environment) error {
 
 	// Custom tasks
 	if t.Tasks != nil {
-		ct, err := t.determineCustomTasks(e, builderTask, tasksConf)
-		if err != nil {
-			return err
-		}
-		if ct == nil {
-			return nil
+		if !platform.BuilderTasksEnabled() {
+			t.L.Info("builder.tasks is disabled by operator configuration and will be ignored")
+		} else {
+			ct, err := t.determineCustomTasks(e, builderTask, tasksConf)
+			if err != nil {
+				return err
+			}
+			if ct == nil {
+				return nil
+			}
+			pipelineTasks = append(pipelineTasks, ct...)
 		}
-
-		pipelineTasks = append(pipelineTasks, ct...)
 	}
 
 	// Packaging task
diff --git a/pkg/trait/builder_test.go b/pkg/trait/builder_test.go
index 42b84861b..06555f116 100644
--- a/pkg/trait/builder_test.go
+++ b/pkg/trait/builder_test.go
@@ -652,8 +652,8 @@ func TestBuilderTraitOrderStrategy(t *testing.T) {
 func TestFilterNodeSelector_NoAllowList(t *testing.T) {
 	bt := createNominalBuilderTraitTest()
 	bt.NodeSelector = map[string]string{
-		"kubernetes.io/hostname":          "node-1",
-		"node-role.kubernetes.io/worker":  "true",
+		"kubernetes.io/hostname":         "node-1",
+		"node-role.kubernetes.io/worker": "true",
 	}
 
 	// env var not set – nil allow list means everything is allowed
@@ -753,3 +753,40 @@ func TestBuilderTraitNodeSelectorAppliedWithAllowList(t *testing.T) {
 	assert.NotContains(t, ns, "node-role.kubernetes.io/worker")
 }
 
+// TestBuilderTraitTasksDisabledByOperator verifies that when BUILDER_TASKS_ENABLED=false the
+// custom tasks are not added to the pipeline even when the CR author sets builder.tasks.
+func TestBuilderTraitTasksDisabledByOperator(t *testing.T) {
+	t.Setenv("BUILDER_TASKS_ENABLED", "false")
+
+	env := createBuilderTestEnv(v1.BuildStrategyPod)
+	bt := createNominalBuilderTraitTest()
+	bt.Tasks = []string{"custom;alpine;echo hello"}
+
+	err := bt.Apply(env)
+	require.NoError(t, err)
+
+	// pipeline must contain only the builder task, no custom task appended
+	for _, task := range env.Pipeline {
+		assert.Nil(t, task.Custom, "custom task must not be present when builder.tasks is disabled")
+	}
+}
+
+// TestBuilderTraitTasksEnabledByDefault verifies that when BUILDER_TASKS_ENABLED is unset
+// custom tasks flow through normally.
+func TestBuilderTraitTasksEnabledByDefault(t *testing.T) {
+	env := createBuilderTestEnv(v1.BuildStrategyPod)
+	bt := createNominalBuilderTraitTest()
+	bt.Tasks = []string{"custom;alpine;echo hello"}
+
+	err := bt.Apply(env)
+	require.NoError(t, err)
+
+	found := false
+	for _, task := range env.Pipeline {
+		if task.Custom != nil && task.Custom.Name == "custom" {
+			found = true
+			break
+		}
+	}
+	assert.True(t, found, "custom task must be present when builder.tasks is enabled")
+}