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")
+}