Releases: Noksa/helm-in-pod
Release list
v0.8.1
v0.8.1
🐛 Bug Fixes
- Fix --copy with relative paths containing
..— when the source path passed to--copycontained../..components (common in Ansible playbooks referencing charts via relative paths), files were copied to their original absolute paths instead of the intended destination inside the pod. This causedhelm upgradeto fail with "unable to detect chart at /tmp/chart/Chart.yaml: no such file or directory".
🧪 Tested Kubernetes Versions
E2E tests run against: v1.28, v1.30, v1.32, v1.35
🔀 Merged Pull Requests
- #24 — fix(helmtar): --copy fails when source path contains .. components
Full changelog: compare v0.8.0...v0.8.1 on GitHub.
v0.8.0
v0.8.0
⚡ Performance
-
Single-transfer startup — all files (your
--copyentries, Helm repository config, and the execution script) are now bundled into one transfer to the pod. Previously this required multiple sequential round-trips, making startup noticeably slower on high-latency connections. -
Watch-based pod monitoring — the plugin now uses Kubernetes Watch instead of polling to detect when the pod finishes. This dramatically reduces API server load and speeds up completion detection, especially in CI environments running many concurrent instances.
-
Smarter retry logic — retries now use exponential backoff with jitter instead of fixed 1-second sleeps. The plugin also respects server-provided
Retry-Afterheaders and immediately fails on permanent errors (forbidden, not found) instead of wasting retries.
🛡️ Reliability
-
Fixed file descriptor leak — copying large directories (300+ files) no longer risks hitting OS limits on macOS.
-
Graceful timeout and cancellation —
--timeoutand Ctrl+C now interrupt retry waits immediately instead of waiting for the next attempt to start. -
Fewer API calls during startup — pod readiness is now checked via a single API call instead of repeated exec probes.
🧪 Tested Kubernetes Versions
E2E tests run against: v1.28, v1.30, v1.32, v1.35
🔀 Merged Pull Requests
- #19 — Watch-based pod phase detection
- #18 — File descriptor leak fix
- #16 — Batch file copy and bootstrap
- #15 — Pod readiness via API
🙏 Contributors
Full changelog: compare v0.7.0...v0.8.0 on GitHub.
v0.7.0
What's New
⏱️ --active-deadline-seconds flag (#8)
Set a hard time limit on pod lifetime, enforced by Kubernetes itself. When the deadline expires, the pod is terminated regardless of client connectivity — preventing orphaned pods in CI/CD pipelines, SSH disconnects, or machine crashes.
# Terminate the pod after 30 minutes if still running
helm in-pod exec --active-deadline-seconds 1800 -- "helm upgrade --install myapp repo/chart"
# Works with daemon mode too
helm in-pod daemon start --name ci-daemon --active-deadline-seconds 72000 (default) means no deadline. Can be combined with --timeout: the timeout kills the command, while the deadline kills the pod.
🔀 TopologySpreadConstraints for pod distribution (#14)
Pods are now automatically spread across nodes using a soft TopologySpreadConstraint on kubernetes.io/hostname. This reduces NodeRestriction admission denials caused by kubelet API call concentration on a single node in high-throughput CI/CD clusters.
🏷️ app.kubernetes.io/managed-by label
All pods (exec, daemon, and dry-run) now carry the standard app.kubernetes.io/managed-by: helm-in-pod label, making it easier to identify and query helm-in-pod resources cluster-wide.
Bug Fixes
🔒 Fix signal handler race condition and goroutine leak (#9)
The interrupt signal handler could race under concurrent use and leaked a goroutine after pod creation returned. Both issues are now fixed.
💥 Fix panic on invalid resource quantities (#10)
Invalid values for --cpu-request, --cpu-limit, --memory-request, or --memory-limit now return a descriptive error instead of crashing.
💥 Fix panic on missing or malformed kubeconfig (#11)
A missing or malformed kubeconfig now produces a clear error message instead of crashing.
🔗 Fix cancellation not stopping in-flight operations (#13)
Ctrl+C, --timeout, and context deadlines now correctly cancel all in-flight Kubernetes API calls. Previously, cancellations were ignored in several code paths, which could leave orphaned pods and PodDisruptionBudgets behind.
🗑️ Safer pod cleanup (#13)
Pod cleanup no longer force-deletes pods that are still running. Only completed pods are removed immediately; running pods get the default grace period so containers shut down cleanly.
🔀 Fix parallel execution on the same host (#13)
Two helm in-pod exec calls running in parallel on the same machine no longer interfere with each other. Each invocation now tracks its own pods and only cleans up after itself.
Contributors
What's Changed
- fix: replace resource.MustParse with ParseQuantity to avoid panics on invalid input by @marandalucas in #10
- fix: replace panic with error return in InitManagers for kubeconfig failures by @marandalucas in #11
- feat: add --active-deadline-seconds flag to limit pod lifetime by @marandalucas in #8
- feat: add TopologySpreadConstraints to distribute pods across nodes by @marandalucas in #14
- fix: eliminate data race and goroutine leak in signal handler by @marandalucas in #9
- fix: context propagation, safe pod deletion and concurrent instance isolation by @marandalucas in #13
New Contributors
- @marandalucas made their first contribution in #10
Full Changelog: v0.6.0...v0.7.0
v0.6.0
v0.6.0-beta2
v0.6.0-beta2
Installation
helm plugin uninstall in-pod 2>/dev/null || true
# helm 4
helm plugin install https://github.com/Noksa/helm-in-pod --version=v0.6.0-beta2 --verify=false
# helm 3
helm plugin install https://github.com/Noksa/helm-in-pod --version=v0.6.0-beta2Features
Improved Logging
Switched to structured logging with colored source labels in console output. Each log line now shows where it originates: [host] (cyan), [pod] (magenta), or [host+pod] (both).
Backward Compatibility with Older Kubernetes Versions
Resource requests and limits are now set at the container level instead of the pod level, ensuring compatibility with older Kubernetes versions that don't support pod-level resources.
PodDisruptionBudget Protection
Executor pods are now automatically protected from voluntary disruptions (like node drains) during operations. Disable with --create-pdb=false if needed.
Exit Code Propagation
Commands now properly return their exit codes, enabling correct error handling in CI/CD pipelines and scripts.
Separate Resource Requests and Limits
New flags for independent CPU and memory configuration:
--cpu-request/--cpu-limit--memory-request/--memory-limit
Old --cpu and --memory flags are deprecated but still work.
Volume Mounts (--volume)
Mount volumes in executor and daemon pods. Format: type:name:mountPath[:ro]
Supported types: pvc, secret, configmap, hostpath
helm in-pod exec --volume pvc:my-claim:/data -- helm install ...
helm in-pod exec --volume secret:my-secret:/etc/creds:ro -- helm install ...
helm in-pod exec --volume configmap:my-cm:/etc/config -- helm install ...
helm in-pod exec --volume hostpath:/var/log:/host-logs:ro -- helm install ...Multiple volumes can be specified by repeating the flag:
helm in-pod exec --volume pvc:data:/data --volume secret:creds:/etc/creds:ro -- helm install ...Service Account (--service-account)
Specify a custom Kubernetes service account for the executor or daemon pod. Defaults to helm-in-pod.
helm in-pod exec --service-account my-sa -- helm install ...
helm in-pod daemon start --name my-daemon --service-account my-saDry Run (--dry-run)
Print the pod spec as YAML without creating anything. Works with both exec and daemon start.
helm in-pod exec --dry-run -- helm install ...
helm in-pod daemon start --name my-daemon --dry-runCopy From Pod (--copy-from)
Copy files or directories from the pod back to the host after command execution. Format: /pod/path:/host/path. Works with both exec and daemon exec. Files are copied even if the command fails — useful for test artifacts, logs, etc.
helm in-pod exec --copy-from /tmp/output.yaml:./output.yaml -- helm template ...
helm in-pod exec --copy-from /tmp/report.html:./report.html \
--copy-from /tmp/logs:/tmp/local-logs -- my-command
helm in-pod daemon exec --name my-daemon \
--copy-from /tmp/result.txt:./result.txt -- generate-reportDaemon Status & List Commands
New subcommands for managing daemon pods:
helm in-pod daemon list(alias:ls) — shows all daemon pods in a table with name, pod, phase, node, age, helm version, and imagehelm in-pod daemon status --name <name>— shows detailed status of a specific daemon pod
Examples
# Set different requests and limits
helm in-pod exec --cpu-request 500m --cpu-limit 2000m \
--memory-request 512Mi --memory-limit 2Gi -- helm install ...
# Disable PDB if needed
helm in-pod exec --create-pdb=false -- helm install ...
# Mount a PVC and a read-only secret
helm in-pod exec --volume pvc:my-data:/data \
--volume secret:my-secret:/etc/creds:ro -- helm install ...
# Use a custom service account
helm in-pod exec --service-account deploy-sa -- helm upgrade myapp repo/chart
# Preview the pod spec without creating it
helm in-pod exec --dry-run -- helm install myapp repo/chart
# Copy test artifacts back from the pod
helm in-pod exec --copy-from /tmp/results.xml:./results.xml -- run-tests
# List all running daemons
helm in-pod daemon list
# Check status of a specific daemon
helm in-pod daemon status --name my-daemonv0.6.0-beta
v0.6.0-beta
Installation
helm plugin uninstall in-pod 2>/dev/null || true
# helm 4
helm plugin install https://github.com/Noksa/helm-in-pod --version=v0.6.0-beta --verify=false
# helm 3
helm plugin install https://github.com/Noksa/helm-in-pod --version=v0.6.0-betaFeatures
PodDisruptionBudget Protection
Executor pods are now automatically protected from voluntary disruptions (like node drains) during operations. Disable with --create-pdb=false if needed.
Exit Code Propagation
Commands now properly return their exit codes, enabling correct error handling in CI/CD pipelines and scripts.
Separate Resource Requests and Limits
New flags for independent CPU and memory configuration:
--cpu-request/--cpu-limit--memory-request/--memory-limit
Old --cpu and --memory flags are deprecated but still work.
Examples
# Set different requests and limits
helm in-pod exec --cpu-request 500m --cpu-limit 2000m \
--memory-request 512Mi --memory-limit 2Gi -- helm install ...
# Disable PDB if needed
helm in-pod exec --create-pdb=false -- helm install ...v0.5.0 - Add --kube-context support
v0.5.0
Bug Fixes
Multi-Cluster Support: --kube-context Flag (Fixes #2)
Fixed support for Helm's standard --kube-context flag, enabling seamless multi-cluster workflows.
Problem: The plugin did not respect Helm's --kube-context flag when targeting different Kubernetes clusters, making it difficult to use in multi-cluster environments without manually switching contexts via kubectl config use-context.
Solution: The plugin now properly reads and respects the HELM_KUBECONTEXT environment variable that Helm automatically sets based on the --kube-context flag.
Usage Examples:
# Target specific cluster context
helm --kube-context production in-pod exec -- "kubectl get pods"
# Works with daemon mode
helm --kube-context staging in-pod daemon start --name dev
# Works with all commands
helm --kube-context dev in-pod daemon exec --name my-daemon -- "helm upgrade myapp ./chart"Impact:
- ✅ Multi-cluster automation scripts now work without modifying global kubeconfig
- ✅ CI/CD pipelines can target different clusters dynamically
- ✅ No need to run
kubectl config use-contextbefore using the plugin - ✅ Consistent behavior with native Helm commands
Thanks to @marcosaranda-appspace for reporting this issue!
v0.4.1
Release Notes - v0.4.1
🔧 Daemon Mode Improvements
Force Recreate Flag
- Added --force (-f) flag to daemon start command
- Allows recreating an existing daemon pod without manual deletion
- Useful for updating daemon configuration or recovering from stuck states
v0.4.0 - Daemon mode
🚀 New Feature: Daemon Mode
Run long-lived pods in your Kubernetes cluster and execute multiple commands without recreating the pod each time.
Why Daemon Mode?
- Faster execution: No pod creation overhead for subsequent commands
- Persistent state: Keep helm repositories, files, and environment across multiple executions
- Resource efficiency: Reuse the same pod for multiple operations
Check https://github.com/Noksa/helm-in-pod/blob/main/DAEMON.md for documentation
Migration from exec
No changes needed! The exec command works exactly as before. Use daemon mode when you need to run multiple commands in the same environment.
v0.3.4 - allow omit resources in exec
It's now possible to pass --cpu and --memory with empty or zero value to completely remove resources from pod spec.
helm in-pod exec --cpu="" --memory="" -- echo hi