Helm Plugin
The Helm plugin provides support for Kubernetes Helm chart repositories.
Overview
Status: ✅ Available
The Helm plugin consists of:
HelmSyncer - Syncs Helm charts from upstream chart repositories
HelmPublisher - Publishes Helm chart repositories with metadata
Features
✅ index.yaml parsing
✅ Helm chart downloading (.tgz files)
✅ SHA256 checksum verification
✅ Pattern-based chart filtering
✅ Version filtering (only latest)
✅ Metadata generation (index.yaml)
✅ Chart deduplication via content-addressed storage
✅ Snapshot support
✅ Mirror Mode - Byte-for-byte identical repositories with snapshot versioning
🚧 Chart signing/verification - Planned
🚧 OCI registry support - Planned
Repository Modes
The Helm plugin supports mirror mode for byte-for-byte identical repository copies.
Mirror Mode (Default)
Status: ✅ Available
In mirror mode, Chantal stores the original index.yaml metadata file in the content-addressed pool as a RepositoryFile. When publishing, the original metadata is hardlinked from the pool to the published directory.
Benefits:
Byte-for-byte identical to upstream repository
Snapshot versioning of metadata (track index.yaml changes over time)
Metadata deduplication across repositories and snapshots
Historical tracking of metadata changes
How it works:
Sync Process:
Downloads index.yaml from upstream
Stores index.yaml in content-addressed pool by SHA256
Creates RepositoryFile database record
Links metadata to repository/snapshot
Publish Process:
Queries RepositoryFile for stored index.yaml
Hardlinks original index.yaml from pool to published directory
Creates hardlinks for all chart .tgz files
Result: Byte-for-byte identical copy of upstream
Example:
repositories:
- id: ingress-nginx
name: Ingress NGINX Helm Charts
type: helm
feed: https://kubernetes.github.io/ingress-nginx
enabled: true
# Mirror mode is automatic - no additional config needed
Use Cases:
Offline/air-gapped environments requiring exact upstream mirrors
Compliance requirements for unmodified upstream metadata
Snapshot versioning for reproducible deployments
Bandwidth optimization (metadata reused across snapshots)
Dynamic Generation Mode (Fallback)
If no RepositoryFile is found (e.g., for older repositories or filtered repositories), Chantal falls back to dynamic index.yaml generation from database metadata.
This mode:
Generates index.yaml from HelmMetadata in database
Allows filtered repositories (subset of charts)
Supports post-processing (e.g., only latest versions)
Note: For filtered repositories (pattern-based chart selection), dynamic generation is used automatically.
Configuration
Basic Helm Repository
repositories:
- id: ingress-nginx
name: Ingress NGINX Helm Charts
type: helm
feed: https://kubernetes.github.io/ingress-nginx
enabled: true
With Filters
repositories:
- id: bitnami-databases
name: Bitnami Charts - Databases Only
type: helm
feed: https://charts.bitnami.com/bitnami
enabled: true
filters:
patterns:
include: ["^postgresql$", "^mysql$", "^mongodb$", "^redis$"]
post_processing:
only_latest_version: true
With Authentication
Some Helm repositories require authentication:
repositories:
- id: private-charts
name: Private Helm Charts
type: helm
feed: https://charts.example.com/
enabled: true
ssl:
ca_bundle: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
client_cert: /etc/pki/helm/client.pem
client_key: /etc/pki/helm/client-key.pem
verify: true
How It Works
Sync Process
Fetch index.yaml
GET https://charts.example.com/index.yaml
Parse to find available charts and versions
Parse chart metadata
Chart name and version
Chart URL (may be relative or absolute)
Chart digest (SHA256)
Dependencies, maintainers, etc.
Apply filters
Pattern matching (include/exclude regex)
Version filtering (only latest)
Download charts
Download .tgz files to content-addressed pool
Verify SHA256 checksums
Deduplicate identical charts
Store metadata
Create ContentItem records
Store Helm metadata in database
Link charts to repository
Publish Process
Query database for charts in repository/snapshot
Create directory structure for published repository
Create hardlinks from pool to published directory
Generate index.yaml with chart metadata and URLs
Set correct file permissions for web server access
Chart Filtering
Pattern Filters
Include specific charts by name:
filters:
patterns:
include:
- "^nginx-.*" # All nginx-related charts
- "^prometheus$" # Exact match: prometheus chart
- "^grafana-.*" # All grafana-related charts
Exclude charts by pattern:
filters:
patterns:
exclude:
- ".*-alpha$" # Exclude alpha versions
- ".*-beta$" # Exclude beta versions
- "^deprecated-.*" # Exclude deprecated charts
Version Filtering
Keep only the latest version of each chart:
filters:
post_processing:
only_latest_version: true
This is useful for:
Reducing storage usage
Simplifying chart selection for users
Automatically staying current with upstream
Common Use Cases
Mirror Official Kubernetes Charts
repositories:
- id: kubernetes-charts
name: Official Kubernetes Charts
type: helm
feed: https://kubernetes.github.io/ingress-nginx
enabled: true
Mirror Bitnami Charts (Selective)
repositories:
- id: bitnami-webservers
name: Bitnami - Web Servers
type: helm
feed: https://charts.bitnami.com/bitnami
enabled: true
filters:
patterns:
include: ["^nginx$", "^apache$"]
post_processing:
only_latest_version: true
Mirror Harbor Registry
repositories:
- id: harbor
name: Harbor Helm Charts
type: helm
feed: https://helm.goharbor.io
enabled: true
Private Chart Repository
repositories:
- id: company-charts
name: Company Internal Charts
type: helm
feed: https://charts.internal.company.com/
enabled: true
ssl:
client_cert: /etc/pki/helm/company-client.pem
client_key: /etc/pki/helm/company-client-key.pem
verify: true
Publishing Helm Repositories
Publish Latest Repository
chantal publish repo --repo-id ingress-nginx
Published structure:
/var/www/repos/ingress-nginx/latest/
├── index.yaml
├── ingress-nginx-4.0.15.tgz
├── ingress-nginx-4.0.14.tgz
└── ...
Publish Snapshot
chantal snapshot create --repo-id ingress-nginx --name 2025-01-10
chantal publish snapshot --snapshot ingress-nginx-2025-01-10
Published structure:
/var/www/repos/ingress-nginx/snapshots/2025-01-10/
├── index.yaml
└── ingress-nginx-4.0.15.tgz
Configure Helm Client
Point Helm CLI to your mirrored repository:
# Add repository
helm repo add ingress-nginx http://mirror.example.com/repos/ingress-nginx/latest/
# Update repository index
helm repo update
# Install chart
helm install my-ingress ingress-nginx/ingress-nginx
Configure Helm with Snapshot
Use a specific snapshot for reproducible deployments:
# Add snapshot repository
helm repo add ingress-nginx-2025-01-10 \
http://mirror.example.com/repos/ingress-nginx/snapshots/2025-01-10/
# Install from snapshot
helm install my-ingress ingress-nginx-2025-01-10/ingress-nginx
Chart Metadata
Chantal stores comprehensive metadata for each chart:
name - Chart name
version - Chart version (SemVer)
description - Chart description
home - Project home page URL
sources - Source code URLs
keywords - Chart keywords
maintainers - Maintainer information
icon - Chart icon URL
appVersion - Application version
deprecated - Deprecation status
annotations - Chart annotations
dependencies - Chart dependencies
type - Chart type (application/library)
apiVersion - Helm API version
This metadata is:
Stored in the database for querying
Included in published index.yaml
Available via Chantal CLI commands
Troubleshooting
Charts Not Syncing
Check index.yaml is accessible:
curl -I https://charts.example.com/index.yaml
Verify repository configuration:
chantal repo show --repo-id my-helm-repo
Check sync logs for errors:
chantal repo sync --repo-id my-helm-repo
Publishing Issues
Verify charts were synced:
chantal package list --repo-id my-helm-repo
Check published directory permissions:
ls -la /var/www/repos/my-helm-repo/latest/
Verify index.yaml was generated:
cat /var/www/repos/my-helm-repo/latest/index.yaml
Client Certificate Issues
Verify certificate files exist and are readable:
ls -la /etc/pki/helm/client.pem
ls -la /etc/pki/helm/client-key.pem
Test with curl:
curl --cert /etc/pki/helm/client.pem \
--key /etc/pki/helm/client-key.pem \
https://charts.example.com/index.yaml
Best Practices
Use snapshots for production - Create dated snapshots for reproducible deployments
Filter by patterns - Only mirror charts you need to reduce storage
Keep latest only - Use
only_latest_version: trueunless you need version historyRegular syncing - Schedule regular syncs to stay current
Verify checksums - Chantal automatically verifies SHA256 checksums
Document your mirrors - Keep notes on why specific charts are mirrored
Test before production - Test snapshots in staging before promoting to production
Integration with CI/CD
GitOps Workflow
# ArgoCD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
spec:
source:
repoURL: http://mirror.example.com/repos/ingress-nginx/snapshots/2025-01-10/
chart: ingress-nginx
targetRevision: 4.0.15
Jenkins Pipeline
pipeline {
stages {
stage('Sync Helm Charts') {
steps {
sh 'chantal repo sync --repo-id ingress-nginx'
}
}
stage('Create Snapshot') {
steps {
sh 'chantal snapshot create --repo-id ingress-nginx --name ${BUILD_ID}'
}
}
stage('Publish Snapshot') {
steps {
sh 'chantal publish snapshot --snapshot ingress-nginx-${BUILD_ID}'
}
}
}
}
Further Reading
Plugins Overview - Plugin architecture
Custom Plugins - Creating custom plugins
Repository Configuration - Repository settings
CLI Commands - Command reference