Skip to content

fix(helm): fix security context and test discovery for SMG chart - #861

Merged
slin1237 merged 3 commits into
mainfrom
fix/helm-minimal-deploy
Mar 22, 2026
Merged

slin1237 merged 3 commits into
mainfrom
fix/helm-minimal-deploy

Conversation

@slin1237

@slin1237 slin1237 commented Mar 22, 2026 •

Copy link
Copy Markdown
Member

Description

Problem

The SMG Helm chart fails to deploy with the default values.yaml configuration:

  1. Pod CreateContainerConfigError: The chart sets runAsNonRoot: true but the lightseekorg/smg image runs as root (UID 0). This causes the container runtime to reject the pod immediately.
  2. Helm test not discoverable: The test pod template (test-connection.yaml) was placed in tests/ instead of templates/tests/, so helm test reported "TEST SUITE: None".
  3. ReadOnly filesystem risk: With readOnlyRootFilesystem: true and no /tmp volume, any temp file writes would fail.

Solution

  • Changed runAsNonRoot default from true to false to match the actual image
  • Added an emptyDir volume mounted at /tmp for temporary file writes
  • Moved test-connection.yaml from tests/ to templates/tests/ for Helm discovery

Changes

  • deploy/helm/smg/values.yaml: Set runAsNonRoot: false, added explanatory comment
  • deploy/helm/smg/templates/deployment-router.yaml: Added /tmp emptyDir volumeMount and volume
  • deploy/helm/smg/tests/test-connection.yaml -> deploy/helm/smg/templates/tests/test-connection.yaml: Moved for Helm test discovery

Test Plan

Tested on OCI cluster (moirai-eu-frankfurt-1-dev) in helm-test-minimal namespace:

  1. helm install with --set global.image.tag=1.3.3 --set router.workerUrls[0]=http://nonexistent:8000 --set router.healthCheck.enabled=false -- PASS (pod reaches Running/Ready)
  2. kubectl logs -- PASS (clean startup, no errors, all CLI flags accepted)
  3. kubectl get svc -- PASS (ClusterIP service on ports 80 and 29000)
  4. Generated args inspection -- PASS (all flags from PR fix(helm): correct CLI flag names and defaults in chart templates #859 fixes render correctly)
  5. helm test -- PASS (test pod runs curl against /health, returns OK)
  6. Port-forward /health -- PASS (returns "OK", HTTP 200)
  7. Port-forward /v1/models -- PASS (returns "No models available", HTTP 200)
  8. Cleanup verified -- PASS (namespace deleted, NotFound confirmed)

Refs: #859

Checklist
  • Helm chart deploys successfully
  • Pod reaches Running state
  • Health endpoint responds
  • Helm test passes
  • Cleanup completed
  • (Optional) Please join us on Slack #sig-smg to discuss, review, and merge PRs

Summary by CodeRabbit

  • New Features

    • Added prefix_hash routing policy option for enhanced routing flexibility
    • Added ephemeral temporary storage for router pods
  • Improvements

    • Updated application version to 1.3.3
    • Increased cache eviction interval from 60 to 120 seconds
    • Modified router container security context to run as root
  • Chores

    • Updated router command-line argument names for consistency

What changed:
- deploy/helm/smg/templates/_helpers.tpl:
  - --eviction-interval-secs → --eviction-interval (field: eviction_interval, main.rs:169)
  - --postgres-pool-max → --postgres-pool-max-size (field: postgres_pool_max_size, main.rs:529)
  - --redis-pool-max → --redis-pool-max-size (field: redis_pool_max_size, main.rs:538)
  - --oracle-connect-descriptor → --oracle-dsn (field: oracle_dsn, main.rs:491)
  - --oracle-username → --oracle-user (field: oracle_user, main.rs:495)
- deploy/helm/smg/Chart.yaml:
  - appVersion: "0.7.0" → "1.3.3" (latest release tag v1.3.3)
- deploy/helm/smg/values.schema.json:
  - Added missing policy enum values: consistent_hashing, prefix_hash, bucket
    (all present in PolicyConfig enum in config/types.rs:247-320)
- deploy/helm/smg/values.yaml:
  - evictionIntervalSecs: 60 → 120 (matches default_value_t = 120, main.rs:168)
  - Updated policy comment to list all 8 valid values

Why:
The Helm chart generated incorrect CLI flags that would cause the SMG
binary to reject them at startup. Five flag names did not match the
actual clap field names in CliArgs, the eviction interval default was
wrong, the appVersion was stale, and three routing policies were
missing from the schema validation.

How:
Cross-referenced every --flag-name in _helpers.tpl against the CliArgs
struct fields in model_gateway/src/main.rs (clap converts field
snake_case to --kebab-case). Verified all default values in values.yaml
against default_value_t annotations. Checked PolicyConfig enum variants
in config/types.rs against values.schema.json. Validated with helm lint
and helm template rendering for all backend types (postgres, redis,
oracle).

Signed-off-by: Simo Lin <linsimo.mark@gmail.com>
The parse_policy function in main.rs (lines 795-826) lacks match arms
for consistent_hashing and bucket, causing them to silently fall back
to round_robin. Until the application code is fixed, excluding these
from the Helm schema prevents users from selecting non-functional
policies. prefix_hash is retained as it is correctly handled.

Addresses review feedback from Gemini Code Assist and CodeRabbit.

Signed-off-by: Simo Lin <linsimo.mark@gmail.com>
What changed:
- deploy/helm/smg/values.yaml: changed runAsNonRoot default from true
  to false, since the lightseekorg/smg:1.3.3 image runs as root and
  does not define a non-root USER. Added a comment explaining when to
  set it back to true.
- deploy/helm/smg/templates/deployment-router.yaml: added an emptyDir
  volume mounted at /tmp so readOnlyRootFilesystem: true does not
  prevent the process from writing temporary files.
- deploy/helm/smg/tests/test-connection.yaml: moved from tests/ to
  templates/tests/ so Helm can discover and render the test pod
  template. This fixes `helm test` returning "TEST SUITE: None".

Why:
The chart could not deploy at all — the pod entered
CreateContainerConfigError because the container runtime rejected
runAsNonRoot: true for an image that runs as UID 0. The helm test
suite was also invisible because it was placed outside templates/.

How:
Tested against OCI cluster (moirai-eu-frankfurt-1-dev) in the
helm-test-minimal namespace with image lightseekorg/smg:1.3.3.
Confirmed pod reaches Running/Ready, /health returns 200, and
`helm test` passes after these fixes.

Refs: #859
Signed-off-by: Simo Lin <linsimo.mark@gmail.com>
@slin1237
slin1237 requested a review from CatherineSue as a code owner March 22, 2026 00:04
@coderabbitai

coderabbitai Bot commented Mar 22, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR updates the SMG Helm chart to version 1.3.3, renames router CLI argument flags to match the updated application interface, adds an ephemeral tmp volume to the router container, extends the supported routing policies, and adjusts security and performance configuration values.

Changes

Cohort / File(s) Summary
Version & Schema Updates
deploy/helm/smg/Chart.yaml, deploy/helm/smg/values.schema.json
Bumped appVersion to 1.3.3 and extended router.policy enum with "prefix_hash" option.
Router CLI Arguments
deploy/helm/smg/templates/_helpers.tpl
Renamed five router CLI flags: --eviction-interval-secs → --eviction-interval, --postgres-pool-max → --postgres-pool-max-size, --redis-pool-max → --redis-pool-max-size, --oracle-connect-descriptor → --oracle-dsn, --oracle-username → --oracle-user.
Router Configuration & Deployment
deploy/helm/smg/values.yaml, deploy/helm/smg/templates/deployment-router.yaml
Added ephemeral tmp volume mount at /tmp in router container; increased evictionIntervalSecs from 60 to 120; changed runAsNonRoot from true to false; updated policy documentation to include prefix_hash.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested labels

tests

Suggested reviewers

  • CatherineSue
  • tonyluj
  • key4ng
  • llfl

Poem

🐰 A chart hops forward, version-bright,
Flags renamed with care, all set just right,
A tmp volume springs to aid the way,
New policies bloom—prefix_hash to stay!
From root to non-root, config takes flight! 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: fixing security context (runAsNonRoot: false) and test discovery (moving test pod template to templates/tests/) for the SMG Helm chart.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/helm-minimal-deploy

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the robustness and deployability of the SMG Helm chart. It resolves critical deployment failures related to container security contexts and read-only filesystems, while also improving the discoverability of Helm tests. Additionally, it incorporates minor configuration updates and introduces a new routing policy option, ensuring a more stable and flexible deployment experience.

Highlights

  • Security Context Fix: Resolved CreateContainerConfigError by changing the default runAsNonRoot setting to false in values.yaml, aligning with the smg image's root user execution.
  • Temporary Filesystem Support: Addressed readOnlyRootFilesystem issues by introducing an emptyDir volume mounted at /tmp in the router deployment for temporary file writes.
  • Helm Test Discoverability: Corrected Helm test discovery by moving the test-connection.yaml file from the tests/ directory to the templates/tests/ directory.
  • Configuration Updates: Updated the appVersion in Chart.yaml and adjusted several CLI argument names in _helpers.tpl for improved consistency.
  • New Routing Policy: Introduced prefix_hash as a new routing policy option, updating both values.schema.json and values.yaml.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@deploy/helm/smg/Chart.yaml`:
- Around line 5-6: The chart's version field in Chart.yaml still reads "0.1.0"
despite breaking template changes to CLI flags (e.g., renames like
--eviction-interval-secs → --eviction-interval and --postgres-pool-max →
--postgres-pool-max-size); update the Chart.yaml version to a new semver (e.g.,
bump to 0.2.0 or 1.0.0 depending on your versioning policy) so consumers know
this release contains breaking changes and can pin/upgrade appropriately.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8d27b1a5-5384-480b-b4e8-22061419596b

📥 Commits

Reviewing files that changed from the base of the PR and between 2ef54dd and 0ac16f2.

📒 Files selected for processing (6)
  • deploy/helm/smg/Chart.yaml
  • deploy/helm/smg/templates/_helpers.tpl
  • deploy/helm/smg/templates/deployment-router.yaml
  • deploy/helm/smg/templates/tests/test-connection.yaml
  • deploy/helm/smg/values.schema.json
  • deploy/helm/smg/values.yaml

Comment on lines 5 to +6
version: 0.1.0
appVersion: "0.7.0"
appVersion: "1.3.3"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider bumping chart version for breaking CLI flag changes.

The chart templates now emit different CLI flag names (e.g., --eviction-interval-secs → --eviction-interval, --postgres-pool-max → --postgres-pool-max-size). Since the chart version remains 0.1.0, users pinning to this version may encounter unexpected breakage if they upgrade the chart but not the application.

Helm best practice is to increment the chart version when templates change in ways that affect deployment behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deploy/helm/smg/Chart.yaml` around lines 5 - 6, The chart's version field in
Chart.yaml still reads "0.1.0" despite breaking template changes to CLI flags
(e.g., renames like --eviction-interval-secs → --eviction-interval and
--postgres-pool-max → --postgres-pool-max-size); update the Chart.yaml version
to a new semver (e.g., bump to 0.2.0 or 1.0.0 depending on your versioning
policy) so consumers know this release contains breaking changes and can
pin/upgrade appropriately.

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

Copy link
Copy Markdown
Contributor

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 primarily fixes deployment issues in the SMG Helm chart. It also includes updates to align with application changes, such as renaming several CLI arguments and introducing a new prefix_hash routing policy. The review focuses on the completeness of these updates. The prefix_hash policy has been added without exposing its configuration parameters in the Helm chart, limiting its usefulness.

replicas: 1

# -- Routing policy: cache_aware, round_robin, power_of_two, manual, random
# -- Routing policy: cache_aware, round_robin, power_of_two, manual, random, prefix_hash

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The prefix_hash policy was added to the schema, but its configurable parameters (prefix_token_count and load_factor) are not exposed in the Helm chart. This prevents users from tuning the new policy.

To provide full functionality, consider:

  1. Adding prefixTokenCount and loadFactor to values.yaml with appropriate defaults (e.g., 256 and 1.25).
  2. Updating templates/_helpers.tpl to pass these values as CLI arguments (e.g., --prefix-token-count and --load-factor) when policy is prefix_hash.

@github-actions github-actions Bot added the tests Test changes label Mar 22, 2026
slin1237 added a commit that referenced this pull request Mar 22, 2026
The chart's default securityContext sets readOnlyRootFilesystem: true,
which prevents the container from writing to any path in the image
filesystem. Python and other runtime components may need to write
temporary files to /tmp.

This was discovered during Helm chart testing against a live cluster
where the pod would fail to start or crash when the process attempted
to write temp files. The workaround branches (fix/helm-edge-cases,
fix/helm-minimal-deploy, fix/helm-observability) included this fix
alongside a runAsNonRoot: false change. Now that the Docker image runs
as non-root (previous commit), runAsNonRoot: true is correct and this
/tmp volume is the only remaining piece needed.

What changed:
- deploy/helm/smg/templates/deployment-router.yaml: added emptyDir
  volume "tmp" mounted at /tmp in the router container

Why:
- readOnlyRootFilesystem: true is a security best practice but requires
  writable mounts for directories that need runtime writes
- /tmp is the standard location for temporary files in Python processes

Refs: #860, #861, #862
Signed-off-by: Simo Lin <linsimo.mark@gmail.com>
@slin1237
slin1237 merged commit 844ad84 into main Mar 22, 2026
27 checks passed
@slin1237
slin1237 deleted the fix/helm-minimal-deploy branch March 22, 2026 00:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests Test changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant