Evans Mungai
5895a7e8f9
fix: default to foreground cascade when --wait is used in uninstall
...
When `helm uninstall --wait` is called, the default deletion propagation
is now "foreground" instead of "background". This ensures dependent
resources (like Pods, ReplicaSets created by controllers) are fully
cleaned up before the command returns.
Previously, with background deletion, parent resources were deleted
immediately while garbage collection handled dependents asynchronously.
This caused subsequent namespace deletions to hang for 2+ minutes waiting
for those dependent resources to be cleaned up.
With foreground deletion, Kubernetes waits for all dependents to be
deleted before removing the parent resource, ensuring `--wait` truly
waits for all cleanup to complete.
Cascade behavior by command:
| Command | Cascade |
|----------------------------------------------|------------|
| `helm uninstall release` | background |
| `helm uninstall release --wait` | foreground |
| `helm uninstall release --wait=hookOnly` | background |
| `helm uninstall release --wait --cascade=background` | background |
Users can still explicitly set `--cascade=background` to restore the
previous behavior if needed.
Fixes #31651
Signed-off-by: Evans Mungai <mbuevans@gmail.com>
8 months ago
Robert Sirchia
4cf7d8d025
Merge pull request #31641 from wangjingcun/main
...
chore: fix some comments to improve readability
8 months ago
wangjingcun
858cf31583
chore: fix some comments to improve readability
...
Signed-off-by: wangjingcun <wangjingcun@aliyun.com>
8 months ago
Mads Jensen
a18e59e465
Enable the sloglint linter
...
Signed-off-by: Mads Jensen <atombrella@users.noreply.github.com>
8 months ago
Matt Farina
61d289c119
Merge pull request #31518 from gjenkins8/gjenkins/fix_update_create
...
fix: Use server-side apply for object create during update
8 months ago
shuv0id
2dc5864f44
fix: add missing context to debug logs
...
Adds chart name to dependency logs, namespace to resource waiting logs,
and confirmation message when all resources are ready.
Addresses #31520
Signed-off-by: shuv0id <110290476+shuv0id@users.noreply.github.com>
9 months ago
George Jenkins
f8a49f1852
fixup test
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
9 months ago
George Jenkins
a9cdc78116
logs
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
9 months ago
George Jenkins
b1a976073f
fix
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
9 months ago
George Jenkins
18616e6ce9
fix: Use server-side apply for object create during update
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
9 months ago
Benoit Tigeot
02312a1cf2
Update pkg/cmd/flags.go
...
Co-authored-by: George Jenkins <gvjenkins@gmail.com>
Signed-off-by: Benoit Tigeot <benoittgt@users.noreply.github.com>
Signed-off-by: Benoit Tigeot <benoit.tigeot@lifen.fr>
9 months ago
Benoit Tigeot
5f6fa437b2
Prevent surprising failure with SDK when timeout is not set
...
While testing SDK features for v4. I was surprised with the error:
"reporter failed to start: event funnel closed: context deadline exceeded"
This occurs when no timeout is set:
```
upgradeClient := action.NewUpgrade(actionConfig)
upgradeClient.WaitStrategy = kube.StatusWatcherStrategy
// When Timeout is zero, the status wait uses a context with zero timeout which
// immediately expires causing "context deadline exceeded" errors.
upgradeClient.Timeout = 2 * time.Minute
```
With this patch it will work without specifying.
Signed-off-by: Benoit Tigeot <benoit.tigeot@lifen.fr>
9 months ago
Benoit Tigeot
11128659aa
Provide more help for SDK user when setting up WaitStrategy
...
Signed-off-by: Benoit Tigeot <benoit.tigeot@lifen.fr>
9 months ago
Benoit Tigeot
5cbd9b3035
While testing SDK features for v4. I was surprised with the error:
...
> "reporter failed to start: event funnel closed: context deadline exceeded"
It happens when you forget to set a minimal timeout:
```go
upgradeClient := action.NewUpgrade(actionConfig)
upgradeClient.WaitStrategy = kube.StatusWatcherStrategy
// When Timeout is zero, the status wait uses a context with zero timeout which
// immediately expires causing "context deadline exceeded" errors.
upgradeClient.Timeout = 2 * time.Minute
```
Also maybe it might be worth documenting this more clearly. Initial [PR](https://github.com/helm/helm/pull/13604 ) say:
> I have not written any docs, I assume that can be done when we are closer to Helm 4, a lot of it is covered by linking to - https://github.com/kubernetes-sigs/cli-utils/blob/master/pkg/kstatus/README.md
Related:
- https://github.com/helm/helm/pull/31411#issuecomment-3443925663
Signed-off-by: Benoit Tigeot <benoit.tigeot@lifen.fr>
9 months ago
Matheus Pimenta
efc1702657
Introduce a context for canceling wait operations
...
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
9 months ago
Evans Mungai
b6eca1c0f1
Refactor logging functionality to use slog.Handler
...
Signed-off-by: Evans Mungai <mbuevans@gmail.com>
9 months ago
Evans Mungai
5ab4ca5490
Embed logging functionality to DRY code
...
Signed-off-by: Evans Mungai <mbuevans@gmail.com>
10 months ago
Evans Mungai
50e43f4017
nil logger should be handled by discard handler
...
Signed-off-by: Evans Mungai <mbuevans@gmail.com>
10 months ago
Evans Mungai
7a5816b106
Self review changes
...
Signed-off-by: Evans Mungai <mbuevans@gmail.com>
10 months ago
Evans Mungai
0f90c83118
Merge remote-tracking branch 'upstream/main' into em/reinstate-logger-param
10 months ago
Evans Mungai
b1d4dc680d
feat: reinstate logger parameter to actions package
...
Fixes : #31399
Signed-off-by: Evans Mungai <mbuevans@gmail.com>
10 months ago
Matt Farina
752354074c
Merge pull request #31393 from benoittgt/12299
...
Return errors during upgrade when the deletion of resources fails
10 months ago
Jesse Simpson
3f860e83fb
fix: use empty results instead of nil
...
Signed-off-by: Jesse Simpson <jesse.simpson36@gmail.com>
10 months ago
Jesse Simpson
96b4c363c8
fix: Update returns nil on error, test should reflect this
...
Signed-off-by: Jesse Simpson <jesse.simpson36@gmail.com>
10 months ago
Benoit Tigeot
7097c8e2e5
Replicate as unit test case where we fail once a resource deletion
...
Signed-off-by: Benoit Tigeot <benoit.tigeot@lifen.fr>
10 months ago
Benoit Tigeot
054eabddd7
Return errors on upgrade when deletion fails
...
This is a rebase of https://github.com/helm/helm/pull/12299
as the pull request was tagged for Helm v4.
Closes: https://github.com/helm/helm/issues/11375
Related: https://github.com/helm/helm/pull/7929
It was a pain to reproduce, here is a script:
```
set -u
NS=default
RELEASE=test-release
CHART=./test-chart
SA=limited-helm-sa
HELM=${HELM:-./bin/helm}
echo "Helm: $($HELM version)"
echo "Cleaning…"
$HELM uninstall "$RELEASE" -n "$NS" >/dev/null 2>&1 || true
kubectl -n "$NS" delete sa "$SA" role "${SA}-role" rolebinding "${SA}-rb" >/dev/null 2>&1 || true
kubectl -n "$NS" delete cronjob "$RELEASE-test-chart-cronjob" >/dev/null 2>&1 || true
rm -rf "$CHART" /tmp/limited-helm-kubeconfig
echo "Create minimal chart with only a CronJob"
$HELM create "$CHART" >/dev/null
rm -f "$CHART"/templates/{deployment.yaml,service.yaml,hpa.yaml,tests/test-connection.yaml,serviceaccount.yaml}
cat > "$CHART/templates/cronjob.yaml" <<'YAML'
apiVersion: batch/v1
kind: CronJob
metadata:
name: {{ include "test-chart.fullname" . }}-cronjob
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: hello
image: busybox
command: ["/bin/sh","-c","date; echo Hello from CronJob"]
YAML
echo "RBAC: allow Helm storage, basic reads/creates, but NO delete on cronjobs"
kubectl -n "$NS" apply -f - >/dev/null <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: $SA
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: ${SA}-role
rules:
- apiGroups: [""]
resources: ["secrets","configmaps"]
verbs: ["get","list","watch","create","patch","update","delete"]
- apiGroups: [""]
resources: ["pods","events"]
verbs: ["get","list","watch"]
- apiGroups: ["batch"]
resources: ["cronjobs"]
verbs: ["get","list","watch","create","patch","update"]
EOF
kubectl -n "$NS" apply -f - >/dev/null <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ${SA}-rb
subjects:
- kind: ServiceAccount
name: $SA
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ${SA}-role
EOF
echo "Create kubeconfig for that SA"
TOKEN=$(kubectl -n "$NS" create token "$SA")
SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
CA_DATA=$(kubectl config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')
KCFG=/tmp/limited-helm-kubeconfig
cat > "$KCFG" <<EOF
apiVersion: v1
kind: Config
clusters:
- name: local
cluster:
server: $SERVER
certificate-authority-data: $CA_DATA
contexts:
- name: limited
context:
cluster: local
namespace: $NS
user: $SA
current-context: limited
users:
- name: $SA
user:
token: $TOKEN
EOF
set +e
echo "Install (as limited SA)"
KUBECONFIG="$KCFG" $HELM upgrade --install "$RELEASE" "$CHART" -n "$NS" --wait
echo "CronJob after install:"
kubectl -n "$NS" get cronjob "$RELEASE-test-chart-cronjob" || true
echo "Remove CronJob from chart and add a small ConfigMap to force an upgrade"
rm -f "$CHART/templates/cronjob.yaml"
cat > "$CHART/templates/configmap.yaml" <<'YAML'
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "test-chart.fullname" . }}-config
data:
hello: world
YAML
echo "Upgrade without CronJob (as limited SA)"
KUBECONFIG="$KCFG" $HELM upgrade --install "$RELEASE" "$CHART" -n "$NS"
RC=$?
echo "Post-upgrade verification"
if kubectl -n "$NS" get cronjob "$RELEASE-test-chart-cronjob" >/dev/null 2>&1; then
echo "OK: Stale CronJob still present: $RELEASE-test-chart-cronjob"
else
echo "NO_OK: CronJob deleted"
fi
echo "Helm exit code: $RC"
exit 0
```
With the current build:
```sh
./reproduce-helm-issue.sh
Helm: version.BuildInfo{Version:"v4.0+unreleased", GitCommit:"f19bb9cd4c99943f7a4980d6670de44affe3e472", GitTreeState:"dirty", GoVersion:"go1.24.0"}
Cleaning…
Create minimal chart with CronJob + ConfigMap (we will remove both in v2)
RBAC: allow Helm storage + delete for configmaps, but NO delete on cronjobs
Create kubeconfig for that SA
Install v1 (as limited SA)
Release "test-release" does not exist. Installing it now.
NAME: test-release
LAST DEPLOYED: Tue Oct 14 18:55:57 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=test-chart,app.kubernetes.io/instance=test-release" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
Verify v1 objects exist
NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE
test-release-test-chart-cronjob */5 * * * * <none> False 0 <none> 0s
NAME DATA AGE
test-release-test-chart-config 1 0s
Prepare v2: remove BOTH CronJob and ConfigMap from the chart
Upgrade to v2 (as limited SA) — expecting CronJob delete first, then ConfigMap
- CronJob delete should FAIL (no delete permission)
- ConfigMap delete should SUCCEED (delete allowed) — proves 'continue on error' and inverted order
level=DEBUG msg="getting history for release" release=test-release
level=DEBUG msg="getting release history" name=test-release
level=DEBUG msg="preparing upgrade" name=test-release
level=DEBUG msg="getting last revision" name=test-release
level=DEBUG msg="getting release history" name=test-release
level=DEBUG msg="number of dependencies in the chart" dependencies=0
level=DEBUG msg="determined release apply method" server_side_apply=true previous_release_apply_method=ssa
level=DEBUG msg="performing update" name=test-release
level=DEBUG msg="creating upgraded release" name=test-release
level=DEBUG msg="creating release" key=sh.helm.release.v1.test-release.v2
level=DEBUG msg="getting release history" name=test-release
level=DEBUG msg="using server-side apply for resource update" forceConflicts=false dryRun=false fieldValidationDirective=Strict upgradeClientSideFieldManager=false
level=DEBUG msg="checking resources for changes" resources=0
level=DEBUG msg="deleting resource" namespace=default name=test-release-test-chart-config kind=ConfigMap
level=DEBUG msg="deleting resource" namespace=default name=test-release-test-chart-cronjob kind=CronJob
level=DEBUG msg="failed to delete resource" namespace=default name=test-release-test-chart-cronjob kind=CronJob error="cronjobs.batch \"test-release-test-chart-cronjob\" is forbidden: User \"system:serviceaccount:default:limited-helm-sa\" cannot delete resource \"cronjobs\" in API group \"batch\" in the namespace \"default\""
level=INFO msg="update completed" created=0 updated=0 deleted=1
level=WARN msg="update completed with errors" errors=1
level=DEBUG msg="updating release" key=sh.helm.release.v1.test-release.v1
level=WARN msg="upgrade failed" name=test-release error="failed to delete resource test-release-test-chart-cronjob: cronjobs.batch \"test-release-test-chart-cronjob\" is forbidden: User \"system:serviceaccount:default:limited-helm-sa\" cannot delete resource \"cronjobs\" in API group \"batch\" in the namespace \"default\""
level=DEBUG msg="updating release" key=sh.helm.release.v1.test-release.v2
Error: UPGRADE FAILED: failed to delete resource test-release-test-chart-cronjob: cronjobs.batch "test-release-test-chart-cronjob" is forbidden: User "system:serviceaccount:default:limited-helm-sa" cannot delete resource "cronjobs" in API group "batch" in the namespace "default"
Post-upgrade verification
Stale CronJob still present: test-release-test-chart-cronjob (expected if delete is forbidden)
ConfigMap deleted as expected: test-release-test-chart-config (and after CronJob attempt)
Helm exit code: 1
```
With last version v3.19:
```
HELM=/usr/local/bin/helm ./reproduce-helm-issue.sh
Helm: version.BuildInfo{Version:"v3.19.0", GitCommit:"3d8990f0836691f0229297773f3524598f46bda6", GitTreeState:"clean", GoVersion:"go1.24.7"}
Cleaning…
Create minimal chart with only a CronJob
RBAC: allow Helm storage, basic reads/creates, but NO delete on cronjobs
Create kubeconfig for that SA
Install (as limited SA)
Release "test-release" does not exist. Installing it now.
NAME: test-release
LAST DEPLOYED: Tue Oct 14 19:07:01 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=test-chart,app.kubernetes.io/instance=test-release" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
CronJob after install:
NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE
test-release-test-chart-cronjob */5 * * * * <none> False 0 <none> 0s
Remove CronJob from chart and add a small ConfigMap to force an upgrade
Upgrade without CronJob (as limited SA)
Release "test-release" has been upgraded. Happy Helming!
NAME: test-release
LAST DEPLOYED: Tue Oct 14 19:07:01 2025
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=test-chart,app.kubernetes.io/instance=test-release" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
Post-upgrade verification
OK: Stale CronJob still present: test-release-test-chart-cronjob
Helm exit code: 0
```
Co-authored-by: dayeguilaiye <979014041@qq.com>
Signed-off-by: Benoit Tigeot <benoit.tigeot@lifen.fr>
10 months ago
Dirk Müller
9cd40c612a
Avoid accessing .Items on nil object
...
When listing fails for whatever reason, the return value is nil, err.
so handle err explicitly.
Signed-off-by: Dirk Müller <dirk@dmllr.de>
10 months ago
Matt Farina
fbf02e494e
Merge pull request #30980 from gjenkins8/gjenkins/cleanup_kubeclient_interfaces
...
cleanup: Remove/consolidate redundant kube client Interfaces
10 months ago
George Jenkins
c75026c318
doc string
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
10 months ago
George Jenkins
1581eaa034
Apply suggestions from code review
...
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
10 months ago
George Jenkins
b861de5696
Update pkg/kube/interface.go
...
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
10 months ago
George Jenkins
61e3d95a94
Merge pull request #31143 from TerryHowe/fix-remove-redundant-error-check
...
fix: remove redundant error check
10 months ago
juejinyuxitu
69dbd6115e
chore: fix some typos in comment
...
Signed-off-by: juejinyuxitu <juejinyuxitu@outlook.com>
10 months ago
George Jenkins
b5de5b1591
chore: Cleanup additional/redundant kube client Interfaces
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
11 months ago
Stephanie Hohenberg
e19d9fb6ee
Refactor unreachableKubeClient for testing into failingKubeClient
...
Signed-off-by: Stephanie Hohenberg <stephanie.hohenberg@gmail.com>
11 months ago
tzchenxixi
89aca09e5e
chore: fix function name
...
Signed-off-by: tzchenxixi <tzchenxixi@icloud.com>
11 months ago
George Jenkins
ebc874ef84
fix client-side to server-side field manager migration
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
12 months ago
George Jenkins
b4b2392f7e
mergefix
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
12 months ago
George Jenkins
e2dcbe28bf
Helm client/SDK support server-side apply
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
12 months ago
Terry Howe
1e22b2fe7c
fix: remove redundant error check
...
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
12 months ago
George Jenkins
b2dc411f9d
code review (error checks, collapse forceConflicts, UpdateApplyFunc)
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
12 months ago
George Jenkins
99dc23f00b
switch target<->original
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
12 months ago
George Jenkins
741facca43
Update pkg/kube/client_test.go
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
12 months ago
George Jenkins
45141451b4
Kube client support server-side apply
...
Signed-off-by: George Jenkins <gvjenkins@gmail.com>
12 months ago
Pavani Pogula
6597fecce3
test(pkg/kube/wait): Add unit tests for waitForPodSuccess, waitForJob and SelectorsForObject.
...
Signed-off-by: Pavani Pogula <pogulapavani@gmail.com>
1 year ago
Pavani Pogula
d4ed9210df
test(pkg/kube/roundtripper): Add unit tests for roundtripper.go
...
Signed-off-by: Pavani Pogula <pogulapavani@gmail.com>
1 year ago
Atish Kumar
008bd7fc82
test(pkg/kube/client): add test for isReachable
...
Signed-off-by: Atish Kumar <allolro@gmail.com>
1 year ago
curlwget
bfc1af68fb
chore: fix function in comment
...
Signed-off-by: curlwget <curlwget@icloud.com>
1 year ago
Terry Howe
744c6b5a97
fix: kube client create mutex
...
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
1 year ago
Scott Rigby
de745ea34b
Merge pull request #12581 from Nordix/considerAllGroupVersionKind
...
Consider full GroupVersionKind when matching resources
1 year ago