From 6faafbd26354e5a7fda0d183eae56832ada28d2c Mon Sep 17 00:00:00 2001 From: Martin Catty Date: Thu, 21 May 2026 16:40:32 -0400 Subject: [PATCH] feat: mount probe bootstrap config only when schema is in the image Chart 0.1.1 adds config.schemaInImage (subPath mount) so ConfigMaps carry only the main YAML while schema.yml stays on disk from the probe image. Multi-file overrides via config.files and config.schemaContent remain supported. --- Chart.yaml | 2 +- README.md | 52 ++++++++++++++++++++++++++++++--------- templates/_helpers.tpl | 33 +++++++++++++++++++++++++ templates/configmap.yaml | 7 ++++-- templates/deployment.yaml | 7 ++++++ values.yaml | 9 ++++++- 6 files changed, 95 insertions(+), 15 deletions(-) diff --git a/Chart.yaml b/Chart.yaml index a3376d5..ffd9df6 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v2 name: fluid-workload description: Generic Helm chart for Fluid agents and probes type: application -version: 0.1.0 +version: 0.1.1 diff --git a/README.md b/README.md index 1ce3103..51f4b14 100644 --- a/README.md +++ b/README.md @@ -2,23 +2,53 @@ In the **`fluid`** monorepo this chart lives under `code/charts/fluid-workload/`; standalone Git (**`fluid-pub/chart-workload`**) uses the same layout at the repository root. -**Release (standalone repo)** — **`helm lint`** runs on PRs and `main` / `develop`; pushing a semver tag **without `v`** runs **`helm push … oci://ghcr.io//fluid-workload`** when the tag equals **`version`** in **`Chart.yaml`**. - -**Install / pull from GHCR** — Helm OCI on GitHub stores the chart under a path that repeats the chart **`name:`** (see the package page `fluid-workload/fluid-workload`). Use **`--version`** with the full OCI prefix, for example: +**Release** — push a semver tag **without `v`** matching **`version`** in **`Chart.yaml`** to publish **`oci://ghcr.io/fluid-pub/fluid-workload/fluid-workload:`**. ```text -helm pull oci://ghcr.io/fluid-pub/fluid-workload/fluid-workload --version 0.1.0 +helm pull oci://ghcr.io/fluid-pub/fluid-workload/fluid-workload --version 0.1.1 ``` -or the equivalent tag form **`oci://ghcr.io/fluid-pub/fluid-workload/fluid-workload:0.1.0`**. The shorter reference **`oci://ghcr.io/fluid-pub/fluid-workload`** (without the second **`fluid-workload`**) does **not** resolve with **`helm pull` / `helm install`** against this registry layout. +Generic chart for **one** Fluid agent or probe image: ConfigMap-mounted YAML, optional Secret/env credentials. + +## Configuration model + +| Layer | What | Where | +|-------|------|--------| +| **Cluster (GitOps values)** | Image, mounts, secrets (`envFrom`), minimal bootstrap YAML | Helm values + ESO | +| **Control plane** | `runtime_config` (entities, intervals, `fields.*.rag`, …) | Dashboard → probe record, fetched over WebSocket/HTTP | +| **Secrets** | Tokens, API keys, CP connection | Kubernetes Secret (e.g. AWS SM via ESO) | + +**Probes (all):** ship **`config/schema.yml`** in the **image** at `/etc/fluid/config/schema.yml` (same semver as the binary). Set **`config.schemaInImage: true`** so Helm mounts only the main config file (`subPath`); the schema file from the image stays on disk. -Generic chart for **one** Fluid agent or probe image: ConfigMap-mounted YAML config, optional Secret-mounted credentials, extra env. +Override only when needed: **`config.schemaContent`** or **`config.files.schema.yml`** (full-directory mount, hides the image schema). + +**Control plane:** operational YAML (`data.entities`, intervals, `fields.*.rag`, …) via **`runtime_config`**; schema contract is pushed at connect from the probe (`PushSchema`). + +**GitOps:** keep bootstrap in **`config.content`** (state dir, probe name, CP env placeholders, non-secret endpoints). ## Typical values -- `image.repository` / `image.tag` — GHCR image built for that workload. -- `config.content` — YAML passed to `-config` (default mount directory `/etc/fluid/config`, filename `config.yaml`). -- `args` — often `["-config", "/etc/fluid/config/config.yaml"]` for agents (adjust for probes). -- `credentialsSecret` — enable and set `secretName` when the binary reads credential files from disk. +```yaml +configMount: + mountPath: /etc/fluid/config + fileName: config.yaml + +config: + schemaInImage: true + content: | + probe: + name: confluence + # bootstrap only — entities/tuning → control plane runtime_config + +args: + - -config + - /etc/fluid/config/config.yaml + +extraEnvFrom: + - secretRef: + name: my-probe-connection +``` -Set `service.enabled` only if the workload exposes a TCP port you need to expose via a Service. \ No newline at end of file +- `image.repository` / `image.tag` — workload image (GHCR). +- `credentialsSecret` — optional file-based credentials mount. +- `service.enabled` — only if the workload exposes HTTP. diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index a9b25ba..3176297 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -33,3 +33,36 @@ fluid.io/workload-kind: {{ .Values.workload.kind | quote }} app.kubernetes.io/name: {{ include "fluid-workload.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} + +{{/* + Build ConfigMap data: filename -> file content. + Prefer config.files; legacy config.content + optional config.schemaContent remain supported. +*/}} +{{- define "fluid-workload.configFiles" -}} +{{- $files := default dict .Values.config.files -}} +{{- if .Values.config.content -}} +{{- $main := default "config.yaml" .Values.configMount.fileName -}} +{{- $files = merge $files (dict $main .Values.config.content) -}} +{{- end -}} +{{- if .Values.config.schemaContent | trim -}} +{{- $files = merge $files (dict "schema.yml" .Values.config.schemaContent) -}} +{{- end -}} +{{- $files | toYaml -}} +{{- end }} + +{{/* + When true, mount only the main config file (subPath) so schema.yml from the image + (probe semver) stays at configMount.mountPath/schema.yml. +*/}} +{{- define "fluid-workload.configMountSubPath" -}} +{{- if not .Values.config.schemaInImage -}} +false +{{- else -}} +{{- $files := fromYaml (include "fluid-workload.configFiles" .) -}} +{{- if eq (len $files) 1 -}} +true +{{- else -}} +false +{{- end -}} +{{- end -}} +{{- end }} diff --git a/templates/configmap.yaml b/templates/configmap.yaml index 72a0d67..4e161bc 100644 --- a/templates/configmap.yaml +++ b/templates/configmap.yaml @@ -5,5 +5,8 @@ metadata: labels: {{- include "fluid-workload.labels" . | nindent 4 }} data: - {{ .Values.configMount.fileName }}: | -{{ .Values.config.content | nindent 4 }} +{{- $files := fromYaml (include "fluid-workload.configFiles" .) }} +{{- range $name, $content := $files }} + {{ $name }}: | +{{ $content | nindent 4 }} +{{- end }} diff --git a/templates/deployment.yaml b/templates/deployment.yaml index 946db1a..dd824ea 100644 --- a/templates/deployment.yaml +++ b/templates/deployment.yaml @@ -45,9 +45,16 @@ spec: {{- toYaml . | nindent 12 }} {{- end }} volumeMounts: + {{- if eq (include "fluid-workload.configMountSubPath" .) "true" }} + - name: config + mountPath: {{ .Values.configMount.mountPath }}/{{ .Values.configMount.fileName }} + subPath: {{ .Values.configMount.fileName }} + readOnly: true + {{- else }} - name: config mountPath: {{ .Values.configMount.mountPath }} readOnly: true + {{- end }} {{- if .Values.credentialsSecret.enabled }} - name: credentials mountPath: {{ .Values.credentialsSecret.mountPath }} diff --git a/values.yaml b/values.yaml index df2e845..dac58b0 100644 --- a/values.yaml +++ b/values.yaml @@ -16,10 +16,17 @@ imagePullSecrets: [] nameOverride: "" fullnameOverride: "" -# Main YAML config file mounted read-only (path configurable below) +# Config files mounted under configMount.mountPath (one file per key). +# Prefer config.files for multiple files (e.g. config.yaml + schema.yml for probes). +# Legacy: config.content sets the main file; config.schemaContent adds schema.yml (override). config: + files: {} content: | # Replace with your agent or probe YAML + # Probes: bake config/schema.yml in the image (Dockerfile); set true to mount only the main file. + schemaInImage: false + # Optional override when schema is not baked in the image (dev / legacy). + schemaContent: "" configMount: # Directory where the ConfigMap is mounted (each data key becomes a file).