[api] Delete previous instance when changing type (#1579)

## What this PR does

It was observed during upgrades to the `cozystack-api` Helm release that
when enabling the local endpoint for the traffic locality feature, hence
switching from a deployment to a daemonset, the deployment may remain
unpruned and the pods of the deployment will continue to run
indefinitely. This patch adds a post-upgrade hook that explicitly
deletes the deployment in case it exists and was not pruned.

### Release-note

```release-note
[api] Delete the cozystack-api deployment in a post-upgrade hook when
migrating to a daemonset and vice-versa.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Automatic post-upgrade cleanup that removes outdated cluster resources
when the local Kubernetes API endpoint is disabled.
* Cleanup runs in the release namespace during upgrades and includes
necessary permissions for the cleanup job to complete.

* **Configuration**
* New release value toggles the local Kubernetes API endpoint to enable
or skip the cleanup behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Timofei Larkin
2025-11-03 19:27:01 +04:00
committed by GitHub
2 changed files with 91 additions and 0 deletions

View File

@@ -40,6 +40,10 @@ releases:
chart: cozy-cozystack-api
namespace: cozy-system
dependsOn: [cozystack-controller]
values:
cozystackAPI:
localK8sAPIEndpoint:
enabled: false
- name: cozystack-controller
releaseName: cozystack-controller

View File

@@ -0,0 +1,87 @@
{{- $shouldRunUpdateHook := false }}
{{- $previousKind := "Deployment" }}
{{- $previousKindPlural := "deployments" }}
{{- if not .Values.cozystackAPI.localK8sAPIEndpoint.enabled }}
{{- $previousKind = "DaemonSet" }}
{{- $previousKindPlural = "daemonsets" }}
{{- end }}
{{- $previous := lookup "apps/v1" $previousKind .Release.Namespace "cozystack-api" }}
{{- if $previous }}
{{- $shouldRunUpdateHook = true }}
{{- end }}
{{- if $shouldRunUpdateHook }}
---
apiVersion: batch/v1
kind: Job
metadata:
name: "cozystack-api-hook"
annotations:
helm.sh/hook: post-upgrade
helm.sh/hook-weight: "1"
helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation
spec:
template:
metadata:
labels:
policy.cozystack.io/allow-to-apiserver: "true"
spec:
serviceAccountName: "cozystack-api-hook"
containers:
- name: kubectl
image: docker.io/alpine/k8s:1.33.4
command:
- sh
args:
- -exc
- |-
kubectl --namespace={{ .Release.Namespace }} delete --ignore-not-found \
{{ $previousKindPlural }}.apps cozystack-api
restartPolicy: Never
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations:
helm.sh/hook: post-upgrade
helm.sh/hook-weight: "1"
helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation
name: "cozystack-api-hook"
rules:
- apiGroups:
- "apps"
resources:
- "{{ $previousKindPlural }}"
verbs:
- get
- delete
resourceNames:
- "cozystack-api"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: "cozystack-api-hook"
annotations:
helm.sh/hook: post-upgrade
helm.sh/hook-weight: "1"
helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: "cozystack-api-hook"
subjects:
- kind: ServiceAccount
name: "cozystack-api-hook"
namespace: "{{ .Release.Namespace }}"
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: "cozystack-api-hook"
annotations:
helm.sh/hook: post-upgrade
helm.sh/hook-weight: "1"
helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation
{{- end }}