Skip to content

feat: add init-plugins container for ClawHub plugin installation#3

Open
aehrt55 wants to merge 3 commits intofix/gateway-token-stabilityfrom
feat/clawhub-plugin-init
Open

feat: add init-plugins container for ClawHub plugin installation#3
aehrt55 wants to merge 3 commits intofix/gateway-token-stabilityfrom
feat/clawhub-plugin-init

Conversation

@aehrt55
Copy link
Copy Markdown

@aehrt55 aehrt55 commented Mar 29, 2026

Summary

  • Add init-plugins init container that installs plugins from ClawHub on pod startup
  • Plugins specified via values.plugins list, skipped if already present on PVC
  • ClawHub auth token managed as a dedicated K8s Secret (clawhub.token) for authenticated downloads with higher rate limits
  • Token only injected into init-plugins container, not exposed to main container

Configuration

plugins:
  - marxbiotech-moltbot-utils
  - marxbiotech-ssh-tools
  - marxbiotech-git-tools

clawhub:
  token: "clh_xxx"  # optional, for higher rate limits

Test plan

  • Deploy with plugins list and verify init-plugins installs from ClawHub
  • Verify plugins are skipped on subsequent pod restarts (idempotent)
  • Verify clawhub.token creates Secret and init-plugins uses authenticated download
  • Verify main container does not have CLAWHUB_TOKEN env var
  • Deploy without clawhub.token and verify unauthenticated install still works

🤖 Generated with Claude Code

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an automated plugin installation process using an init container in the deployment template, supported by a new Secret for ClawHub authentication tokens. Feedback points out a critical error regarding a missing Helm template helper for the init container image and recommends removing error suppression in the installation script to ensure that failures are properly surfaced during deployment.


{{- if .Values.plugins }}
- name: init-plugins
image: "{{ include "openclaw-helm.image" . }}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The Helm template helper openclaw-helm.image is not defined in this chart's _helpers.tpl. This will cause a template rendering error and fail the deployment if .Values.plugins is enabled. You should use the image configuration from .Values directly, similar to the other containers in this deployment.

        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

{{- range .Values.plugins }}
if [ ! -d "/home/node/.openclaw/extensions/{{ . }}" ]; then
echo "Installing plugin {{ . }} from ClawHub..."
node dist/index.js plugins install "clawhub:{{ . }}" || true
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using || true will suppress any errors from the plugin installation command. This means that if a plugin fails to install (e.g., due to a network issue, a typo in the plugin name, or an invalid token), the init container will still succeed, and the main application will start without the required plugin. This can lead to unexpected runtime failures that are difficult to debug. It's better to let the init container fail so that the problem is immediately visible from the pod status, and Kubernetes can retry according to the pod's restartPolicy.

            node dist/index.js plugins install "clawhub:{{ . }}"

@aehrt55
Copy link
Copy Markdown
Author

aehrt55 commented Mar 29, 2026

🤖 PR Review

Branch: feat/clawhub-plugin-initfix/gateway-token-stability
Round: 1 | Updated: 2026-03-29
Reviewer: claude-opus-4-6 via pr-review-toolkit


📊 Summary

Category Total Fixed Remaining
🔴 Critical 3 3 0
🟡 Important 4 4 0
💡 Suggestions 5 4 1

Status: ✅ Ready for merge (1 suggestion deferred to backlog)


🔴 Critical Issues

1. ✅ Undefined openclaw-helm.image helper — template will fail to render

File: charts/openclaw-helm/templates/deployment.yaml:86
Agents: code-reviewer, code-simplifier, silent-failure-hunter, pr-test-analyzer, comment-analyzer

Problem: The init-plugins container uses {{ include "openclaw-helm.image" . }} but this named template is not defined in _helpers.tpl. Every other container in the Deployment uses the inline pattern {{ .Values.image.repository }}:{{ .Values.image.tag }}. This will cause a Helm rendering error whenever .Values.plugins is non-empty, making the feature entirely non-functional.

Resolution: ✅ Resolved by rebasing onto fix/gateway-token-stability (PR #2), which defines the openclaw-helm.image helper in _helpers.tpl.

2. ✅ || true suppresses all plugin installation failures

File: charts/openclaw-helm/templates/deployment.yaml:94
Agent: silent-failure-hunter

Problem: node dist/index.js plugins install "clawhub:{{ . }}" || true unconditionally swallows every failure mode: network errors, auth failures, disk full, corrupt downloads, plugin not found. The init container reports success even when all plugins fail to install. The pod starts without requested plugins, and operators get zero indication of the failure.

Resolution: ✅ Replaced with tolerate-partial-failures pattern: each plugin install is wrapped in if ! command, failures are counted, and the script exits with error code if any failed. Also added set -e for defense-in-depth.

3. ✅ [Gemini] Undefined `openclaw-helm.image` helper — template will fail

Source: Gemini Code Assist
File: charts/openclaw-helm/templates/deployment.yaml:86

Problem: The Helm template helper openclaw-helm.image is not defined in this chart's _helpers.tpl. This will cause a template rendering error and fail the deployment if .Values.plugins is enabled. You should use the image configuration from .Values directly, similar to the other containers in this deployment.

Resolution: ✅ Duplicate of Critical #1 — resolved by rebasing onto PR #2.


🟡 Important Issues

1. ✅ Shell injection risk via unquoted plugin names

File: charts/openclaw-helm/templates/deployment.yaml:91-97
Agents: code-reviewer, type-design-analyzer

Problem: Plugin names from .Values.plugins are interpolated directly into shell commands without quoting or validation. A malformed plugin name could break out of the shell command. While values are operator-controlled, defense-in-depth matters.

Resolution: ✅ Verified that all plugin name interpolations are already within shell double-quoted strings ("clawhub:{{ . }}", "/home/node/.openclaw/extensions/{{ . }}"). Format validation deferred to values.schema.json (backlog).

2. ⏭️ Inconsistent HOME env var compared to existing init containers

File: charts/openclaw-helm/templates/deployment.yaml:101
Agents: code-reviewer, code-simplifier

Problem: The init-plugins container sets HOME: /home/node, while the existing init-skills container sets HOME: /tmp. If the container runs as non-root without write access to /home/node, this could cause failures. Need to confirm whether /home/node is writable or align with the existing /tmp pattern.

Resolution: ⏭️ N/A — Source code analysis confirms plugin install resolves extensions dir from $HOME/.openclaw/extensions/, which must match the persistent volume mount at /home/node/.openclaw. init-skills uses HOME=/tmp because it uses explicit cd to the workspace dir. Design Decision comment added in code.

3. ✅ Missing set -e in shell script

File: charts/openclaw-helm/templates/deployment.yaml:88-98
Agent: silent-failure-hunter

Problem: The shell script does not use set -e. Even if || true is removed, other command failures within the script would not cause the init container to fail. The script's exit code is determined by the last command only.

Resolution: ✅ Added set -e at the top of the script block, consistent with init-config.

4. ✅ [Gemini] Suppress stderr with `|| true` hides plugin installation failures

Source: Gemini Code Assist
File: charts/openclaw-helm/templates/deployment.yaml:94

Problem: Using || true will suppress any errors from the plugin installation command. This means that if a plugin fails to install (e.g., due to a network issue, a typo in the plugin name, or an invalid token), the init container will still succeed, and the main application will start without the required plugin. This can lead to unexpected runtime failures that are difficult to debug. It's better to let the init container fail so that the problem is immediately visible from the pod status, and Kubernetes can retry according to the pod's restartPolicy.

Resolution: ✅ Duplicate of Critical #2 — resolved with tolerate-partial-failures pattern.


💡 Suggestions

View 5 suggestions (4 addressed)
# Suggestion Agent Status
1 Add optional: true to secretKeyRef for resilience (matches init-config pattern) code-reviewer ✅ Fixed
2 Directory existence is an unreliable install-success indicator; partial installs persist forever silent-failure-hunter ⏭️ N/A — openclaw uses staging + rename pattern; risk is low
3 Reword sops-specific comment to be tool-agnostic: "Provide via encrypted values file or --set" comment-analyzer ✅ Fixed
4 Soften "higher rate limits" claim — avoid embedding external service behavior assumptions comment-analyzer ✅ Fixed — changed to "may provide higher rate limits" and marked as optional
5 Consider adding values.schema.json for type validation of plugins list and clawhub config type-design-analyzer ⏭️ Deferred to backlog

✨ Strengths

  • Clean conditional structure: {{- if .Values.plugins }} correctly wraps the entire init container, avoiding unnecessary containers on default installs
  • Proper Secret management: Token stored in K8s Secret, not as plain env var; Secret only created when both plugins and token are configured
  • Idempotent design: Directory existence check prevents re-installing on pod restarts
  • Good separation of concerns: ClawHub token only exposed to init-plugins container, not the main container
  • Consistent with existing patterns: Follows the init-skills container structure for volume mounts and conditional logic
  • Runtime observability: Echo messages in the shell script improve debuggability over the echo-less init-skills container

📋 Type Design Ratings

Type Encap. Express. Useful. Enforce. Overall
plugins (list of strings) 5/10 4/10 7/10 3/10 5/10
clawhub (object w/ token) 6/10 5/10 7/10 4/10 6/10

Key concern: No values.schema.json exists for validation. Plugin names have no format enforcement.


🧪 Test Coverage

No automated template tests exist in this chart. The only test is a live cluster integration test (test-connection.yaml) that does not exercise init container logic.

Recommended tests (via helm-unittest):

  • helm template renders successfully with plugins enabled
  • Secret created only when both plugins and token are set (4 combinations)
  • Init container absent when plugins: []
  • Multiple plugins produce correct install commands
  • CLAWHUB_TOKEN env var conditionally included

🎯 Action Plan

Before Merge:

After Merge (Backlog):

  • Add values.schema.json for plugin/clawhub validation
  • Add helm-unittest template tests
  • Fix same || true pattern in pre-existing init-skills container
  • Consider version-aware plugin updates (not just directory existence)

Generated by pr-review-and-document skill | Round 1 | [View edit history](click edited)

@aehrt55 aehrt55 force-pushed the feat/clawhub-plugin-init branch from 690bc80 to 43bbaee Compare March 29, 2026 11:33
@aehrt55 aehrt55 changed the base branch from main to fix/gateway-token-stability March 29, 2026 11:33
aehrt55 and others added 2 commits April 1, 2026 19:22
- New init container installs plugins from ClawHub on pod startup
- Plugins specified via values.plugins list, skipped if already on PVC
- ClawHub auth token managed as a dedicated Secret (clawhub.token)
  for authenticated downloads with higher rate limits
- Token only injected into init-plugins container, not main container

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace || true with tolerate-partial-failures pattern that reports
each failed plugin while still attempting all installations. Add set -e,
optional: true on secretKeyRef, and clarify values.yaml comments.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@aehrt55 aehrt55 force-pushed the feat/clawhub-plugin-init branch from f21295a to a298c0c Compare April 1, 2026 11:23
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@aehrt55 aehrt55 force-pushed the feat/clawhub-plugin-init branch from a298c0c to 94f0710 Compare April 1, 2026 11:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant