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

hanahmily pushed a commit to branch feature/helm-trace-pipeline-plugins
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb-helm.git

commit 018a159097376d615bb00c7fa0300a4edab69aa2
Author: Hongtao Gao <[email protected]>
AuthorDate: Thu Jul 16 02:06:47 2026 +0000

    Add trace-pipeline sampler plugin support to Helm chart
    
    - Add plugins.enabled, plugins.image, plugins.mountMode, 
plugins.initContainer,
      and plugins.thirdParty values.
    - Add plugin helper templates for host image, carrier image, third-party 
image,
      and configuration validation.
    - Mount the carrier image into data-node pods via initContainer+emptyDir and
      switch the data container to the -plugins host image when enabled.
    - Pass --trace-pipeline-native-plugin-enabled and 
--trace-pipeline-trusted-plugin-dir
      flags to data nodes when plugins are enabled.
    - Add validate-plugins.yaml to invoke plugin validation during rendering.
---
 .gitignore                                    |  1 +
 chart/templates/_helpers.tpl                  | 63 +++++++++++++++++++++
 chart/templates/cluster_data_statefulset.yaml | 81 ++++++++++++++++++++++++++-
 chart/templates/validate-plugins.yaml         | 18 ++++++
 chart/values.yaml                             | 50 +++++++++++++++++
 5 files changed, 210 insertions(+), 3 deletions(-)

diff --git a/.gitignore b/.gitignore
index a9501df..6abf4c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,3 +17,4 @@ build/
 .claude
 CLAUDE.md
 .cursor
+.omc/
diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl
index 6553b29..50fd741 100644
--- a/chart/templates/_helpers.tpl
+++ b/chart/templates/_helpers.tpl
@@ -147,6 +147,69 @@ StatefulSet names must leave room for the 
controller-revision-hash suffix
 {{- end }}
 {{- end }}
 
+{{/*
+Trace-pipeline plugin helpers
+*/}}
+
+{{/*
+Return the data-node image to use when plugins are enabled.
+This is the -plugins host image tag derived from the main image tag.
+*/}}
+{{- define "banyandb.pluginsHostImage" -}}
+{{- $repo := .Values.image.repository -}}
+{{- $tag := required "banyandb.image.tag is required when plugins are enabled" 
.Values.image.tag -}}
+{{- printf "%s:%s-plugins" $repo $tag -}}
+{{- end -}}
+
+{{/*
+Return the plugin carrier image reference.
+The carrier tag defaults to <main-tag>-plugins-carrier to preserve lockstep 
parity.
+*/}}
+{{- define "banyandb.pluginsCarrierImage" -}}
+{{- $plugins := .Values.plugins | default dict -}}
+{{- $pluginsImage := $plugins.image | default dict -}}
+{{- $repo := $pluginsImage.repository | default .Values.image.repository -}}
+{{- $mainTag := required "banyandb.image.tag is required when plugins are 
enabled" .Values.image.tag -}}
+{{- $tag := $pluginsImage.tag | default (printf "%s-plugins-carrier" $mainTag) 
-}}
+{{- printf "%s:%s" $repo $tag -}}
+{{- end -}}
+
+{{/*
+Return the third-party plugin image reference, if configured.
+*/}}
+{{- define "banyandb.pluginsThirdPartyImage" -}}
+{{- $thirdParty := (default dict .Values.plugins).thirdParty | default dict -}}
+{{- $image := $thirdParty.image | default dict -}}
+{{- if and $image.repository $image.tag -}}
+{{- printf "%s:%s" $image.repository $image.tag -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Validate plugin configuration.
+*/}}
+{{- define "banyandb.validatePlugins" -}}
+{{- $plugins := .Values.plugins | default dict -}}
+{{- if $plugins.enabled }}
+{{- if .Values.standalone.enabled }}
+{{- fail "plugins.enabled cannot be used in standalone mode; plugins are 
supported on data nodes in cluster mode only" }}
+{{- end }}
+{{- if not .Values.cluster.enabled }}
+{{- fail "plugins.enabled requires cluster.enabled=true; plugins are supported 
on data nodes in cluster mode only" }}
+{{- end }}
+{{- if not .Values.cluster.data }}
+{{- fail "plugins.enabled requires cluster.data to be configured" }}
+{{- end }}
+{{- $mountMode := $plugins.mountMode | default "initContainer" }}
+{{- if and (ne $mountMode "initContainer") (ne $mountMode "imageVolume") }}
+{{- fail (printf "plugins.mountMode must be 'initContainer' or 'imageVolume', 
got '%s'" $mountMode) }}
+{{- end }}
+{{- if not .Values.image.tag }}
+{{- fail "banyandb.image.tag is required when plugins.enabled=true" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
 {{/*
 SchemaStoragePropertyServerEnv - injects property server env vars (data node 
only)
 Includes: repair cron, schema server parameters, schema server TLS
diff --git a/chart/templates/cluster_data_statefulset.yaml 
b/chart/templates/cluster_data_statefulset.yaml
index 3c68e55..dbd3de5 100644
--- a/chart/templates/cluster_data_statefulset.yaml
+++ b/chart/templates/cluster_data_statefulset.yaml
@@ -137,9 +137,61 @@ spec:
             {{- toYaml . | nindent 12 }}
           {{- end }}
         {{- end }}
+        {{- $plugins := $.Values.plugins | default dict -}}
+        {{- $pluginsMountMode := $plugins.mountMode | default "initContainer" 
-}}
+        {{- $pluginsImage := $plugins.image | default dict -}}
+        {{- $pluginsInitContainer := $plugins.initContainer | default dict -}}
+        {{- if and $plugins.enabled (eq $pluginsMountMode "initContainer") }}
+        - name: plugin-carrier
+          image: {{ include "banyandb.pluginsCarrierImage" $ }}
+          imagePullPolicy: {{ $pluginsImage.pullPolicy | default 
$.Values.image.pullPolicy }}
+          command:
+            - sh
+            - -c
+            - |
+              set -euo pipefail
+              mkdir -p /plugins-shared /plugins-shared/thirdparty
+              if [ -d /plugins ] && [ "$(ls -A /plugins)" ]; then
+                cp /plugins/*.so /plugins-shared/ 2>/dev/null || true
+              fi
+          volumeMounts:
+            - name: plugins-volume
+              mountPath: /plugins-shared
+          {{- with $pluginsInitContainer.resources }}
+          resources:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+        {{- end }}
+        {{- if and $plugins.enabled (eq $pluginsMountMode "initContainer") 
(include "banyandb.pluginsThirdPartyImage" $) }}
+        {{- $thirdParty := $plugins.thirdParty | default dict -}}
+        {{- $thirdPartyImage := $thirdParty.image | default dict -}}
+        - name: plugin-thirdparty
+          image: {{ include "banyandb.pluginsThirdPartyImage" $ }}
+          imagePullPolicy: {{ $thirdPartyImage.pullPolicy | default 
"IfNotPresent" }}
+          command:
+            - sh
+            - -c
+            - |
+              set -euo pipefail
+              mkdir -p /plugins-shared/thirdparty
+              if [ -d /plugins ] && [ "$(ls -A /plugins)" ]; then
+                cp /plugins/*.so /plugins-shared/thirdparty/ 2>/dev/null || 
true
+              fi
+          volumeMounts:
+            - name: plugins-volume
+              mountPath: /plugins-shared
+          {{- with $pluginsInitContainer.resources }}
+          resources:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+        {{- end }}
       containers:
         - name: data
+          {{- if $plugins.enabled }}
+          image: {{ include "banyandb.pluginsHostImage" $ }}
+          {{- else }}
           image: {{ $.Values.image.repository }}:{{ required 
"banyandb.image.tag is required" $.Values.image.tag }}-slim
+          {{- end }}
           imagePullPolicy: {{ $.Values.image.pullPolicy }}
           {{- with $roleConfig.containerSecurityContext }}
           securityContext:
@@ -206,6 +258,10 @@ spec:
 
           args:
             - data
+            {{- if $plugins.enabled }}
+            - --trace-pipeline-native-plugin-enabled=true
+            - --trace-pipeline-trusted-plugin-dir=/plugins
+            {{- end }}
           ports:
             - containerPort: 17912
               name: grpc
@@ -245,7 +301,7 @@ spec:
             timeoutSeconds: {{ $roleConfig.startupProbe.timeoutSeconds }}
             successThreshold: {{ $roleConfig.startupProbe.successThreshold }}
             failureThreshold: {{ $roleConfig.startupProbe.failureThreshold }}
-          {{- if $roleConfig.resources }}
+          {{- if or $roleConfig.resources.requests 
$roleConfig.resources.limits }}
           resources:
             {{- if $roleConfig.resources.requests }}
             requests:
@@ -265,7 +321,8 @@ spec:
           {{- $schemaClientTls := $schemaProperty.tls | default dict }}
           {{- $schemaServer := $schemaProperty.server | default dict }}
           {{- $schemaServerTls := $schemaServer.tls | default dict }}
-          {{- if or $.Values.storage.data.enabled $roleConfig.tls 
$schemaClientTls.secretName $schemaServerTls.secretName $nodeDiscoveryFileMode 
(and $.Values.cluster.fodc.enabled 
$.Values.cluster.fodc.agent.config.crashCollection.enabled) }}
+          {{- $dataPlugins := $.Values.plugins | default dict -}}
+          {{- if or $.Values.storage.data.enabled $roleConfig.tls 
$schemaClientTls.secretName $schemaServerTls.secretName $nodeDiscoveryFileMode 
(and $.Values.cluster.fodc.enabled 
$.Values.cluster.fodc.agent.config.crashCollection.enabled) 
$dataPlugins.enabled }}
           volumeMounts:
             {{- if $.Values.storage.data.enabled }}
             {{- range $claim := $.Values.storage.data.persistentVolumeClaims }}
@@ -310,6 +367,10 @@ spec:
             - name: crash-shared
               mountPath: {{ 
$.Values.cluster.fodc.agent.config.crashCollection.dir }}
             {{- end }}
+            {{- if $dataPlugins.enabled }}
+            - name: plugins-volume
+              mountPath: /plugins
+            {{- end }}
           {{- end }}
         {{- if and $.Values.cluster.enabled $.Values.cluster.fodc.enabled }}
         - name: fodc-agent
@@ -556,7 +617,9 @@ spec:
           {{- end }}
         {{- end }}
 
-      {{- if or $roleConfig.tls $schemaClientTls.secretName 
$schemaServerTls.secretName $nodeDiscoveryFileMode (and 
$roleConfig.lifecycleSidecar.enabled $.Values.cluster.fodc.enabled) (and 
$.Values.cluster.fodc.enabled 
$.Values.cluster.fodc.agent.config.crashCollection.enabled) (and 
$.Values.cluster.fodc.enabled $.Values.cluster.fodc.agent.pressureProfiler 
$.Values.cluster.fodc.agent.pressureProfiler.enabled) }}
+      {{- $volPlugins := $.Values.plugins | default dict -}}
+      {{- $volPluginsImage := $volPlugins.image | default dict -}}
+      {{- if or $roleConfig.tls $schemaClientTls.secretName 
$schemaServerTls.secretName $nodeDiscoveryFileMode (and 
$roleConfig.lifecycleSidecar.enabled $.Values.cluster.fodc.enabled) (and 
$.Values.cluster.fodc.enabled 
$.Values.cluster.fodc.agent.config.crashCollection.enabled) (and 
$.Values.cluster.fodc.enabled $.Values.cluster.fodc.agent.pressureProfiler 
$.Values.cluster.fodc.agent.pressureProfiler.enabled) $volPlugins.enabled }}
       volumes:
         {{- if $roleConfig.tls }}
         {{- if $roleConfig.tls.grpcSecretName }}
@@ -595,6 +658,18 @@ spec:
         - name: pressure-profiles
           emptyDir: {}
         {{- end }}
+        {{- if $volPlugins.enabled }}
+        {{- $volPluginsMode := $volPlugins.mountMode | default "initContainer" 
}}
+        {{- if eq $volPluginsMode "initContainer" }}
+        - name: plugins-volume
+          emptyDir: {}
+        {{- else if eq $volPluginsMode "imageVolume" }}
+        - name: plugins-volume
+          image:
+            reference: {{ include "banyandb.pluginsCarrierImage" $ }}
+            pullPolicy: {{ $volPluginsImage.pullPolicy | default 
$.Values.image.pullPolicy }}
+        {{- end }}
+        {{- end }}
       {{- end }}
 
       {{- if $roleConfig.tolerations }}
diff --git a/chart/templates/validate-plugins.yaml 
b/chart/templates/validate-plugins.yaml
new file mode 100644
index 0000000..9023c6f
--- /dev/null
+++ b/chart/templates/validate-plugins.yaml
@@ -0,0 +1,18 @@
+{{/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/}}
+
+{{- include "banyandb.validatePlugins" . }}
diff --git a/chart/values.yaml b/chart/values.yaml
index b93ec5a..a23b56a 100644
--- a/chart/values.yaml
+++ b/chart/values.yaml
@@ -44,6 +44,56 @@ image:
   ##
   pullPolicy: IfNotPresent
 
+## @section Trace-pipeline sampler plugin configuration
+##
+plugins:
+  ## @param plugins.enabled Enable trace-pipeline native sampler plugins on 
data nodes.
+  ## When enabled, the data-node container uses the -plugins host image and 
mounts
+  ## the carrier image at /plugins. Liaison and standalone pods never host 
plugins.
+  ##
+  enabled: false
+
+  ## Plugin carrier image configuration.
+  ## The carrier delivers first-party .so files and is mounted at /plugins.
+  ## Lockstep parity is required: the carrier must match the data-node host 
image tag.
+  ##
+  image:
+    ## @param plugins.image.repository Docker repository for the plugin 
carrier image
+    ##
+    repository: ghcr.io/apache/skywalking-banyandb
+    ## @param plugins.image.tag Carrier image tag (empty defaults to <main 
image tag>-plugins-carrier)
+    ##
+    tag: ""
+    ## @param plugins.image.pullPolicy Carrier image pull policy
+    ##
+    pullPolicy: IfNotPresent
+
+  ## @param plugins.mountMode How to deliver plugins into the data-node pod:
+  ## "initContainer" (default, portable) copies .so files from the carrier 
into a shared emptyDir.
+  ## "imageVolume" uses an OCI image volume (Kubernetes >= 1.31 beta).
+  ##
+  mountMode: initContainer
+
+  ## Init-container delivery configuration (used when mountMode=initContainer)
+  ##
+  initContainer:
+    ## @param plugins.initContainer.resources Resource requests/limits for the 
carrier copy init container
+    ##
+    resources: {}
+
+  ## Optional third-party plugin image mounted at /plugins/thirdparty.
+  ##
+  thirdParty:
+    ## @param plugins.thirdParty.image.repository Docker repository for 
third-party plugins
+    ##
+    repository: ""
+    ## @param plugins.thirdParty.image.tag Third-party plugin image tag
+    ##
+    tag: ""
+    ## @param plugins.thirdParty.image.pullPolicy Third-party plugin image 
pull policy
+    ##
+    pullPolicy: IfNotPresent
+
 ## @section Authentication configuration for BanyanDB
 ##
 auth:

Reply via email to