11package cmd
22
33import (
4+ "context"
45 "fmt"
6+ "log"
7+ "os"
58
9+ helmclient "github.com/mittwald/go-helm-client"
610 "github.com/spf13/cobra"
11+ "github.com/wunderio/silta-cli/internal/common"
12+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13+ "k8s.io/client-go/kubernetes"
14+ "k8s.io/client-go/tools/clientcmd"
715)
816
917var ciReleaseCleanfailedCmd = & cobra.Command {
@@ -13,40 +21,75 @@ var ciReleaseCleanfailedCmd = &cobra.Command{
1321 releaseName , _ := cmd .Flags ().GetString ("release-name" )
1422 namespace , _ := cmd .Flags ().GetString ("namespace" )
1523
16- command := fmt .Sprintf (`
17- NAMESPACE='%s'
18- RELEASE_NAME='%s'
19-
20- failed_revision=$(helm list -n "${NAMESPACE}" --failed --pending --filter="(\s|^)(${RELEASE_NAME})(\s|$)" | tail -1 | cut -f3)
21-
22- if [[ "${failed_revision}" -eq 1 ]]; then
23- # Remove any existing post-release hook, since it's technically not part of the release.
24- kubectl delete job -n "${NAMESPACE}" "${RELEASE_NAME}-post-release" 2> /dev/null || true
25-
26- echo "Removing failed first release."
27- helm delete -n "${NAMESPACE}" "${RELEASE_NAME}"
28-
29- echo "Delete persistent volume claims left over from statefulsets."
30- kubectl delete pvc -n "${NAMESPACE}" -l release="${RELEASE_NAME}"
31- kubectl delete pvc -n "${NAMESPACE}" -l app="${RELEASE_NAME}-es"
32-
33- echo -n "Waiting for volumes to be deleted."
34- until [[ -z $(kubectl get pv | grep "${NAMESPACE}/${RELEASE_NAME}-") ]]
35- do
36- echo -n "."
37- sleep 5
38- done
39- fi
40-
41- # Workaround for previous Helm release stuck in pending state
42- pending_release=$(helm list -n "${NAMESPACE}" --pending --filter="(\s|^)(${RELEASE_NAME})(\s|$)"| tail -1 | cut -f1)
43-
44- if [[ "${pending_release}" == "${RELEASE_NAME}" ]]; then
45- secret_to_delete=$(kubectl get secret -l owner=helm,status=pending-upgrade,name="${RELEASE_NAME}" -n "${NAMESPACE}" | awk '{print $1}' | grep -v NAME)
46- kubectl delete secret -n "${NAMESPACE}" "${secret_to_delete}"
47- fi
48- ` , namespace , releaseName )
49- pipedExec (command , "" , "ERROR: " , debug )
24+ // ----
25+
26+ homeDir , err := os .UserHomeDir ()
27+ if err != nil {
28+ log .Fatalf ("cannot read user home dir" )
29+ }
30+ kubeConfigPath := homeDir + "/.kube/config"
31+
32+ kubeConfig , err := os .ReadFile (kubeConfigPath )
33+ if err != nil {
34+ log .Fatalf ("cannot read kubeConfig from path" )
35+ }
36+
37+ //k8s go client init logic
38+ config , err := clientcmd .BuildConfigFromFlags ("" , kubeConfigPath )
39+ if err != nil {
40+ log .Fatalf ("cannot read kubeConfig from path: %s" , err )
41+ }
42+ clientset , err := kubernetes .NewForConfig (config )
43+ if err != nil {
44+ log .Fatalf ("cannot initialize k8s client: %s" , err )
45+ }
46+
47+ //Helm client init logic
48+ opt := & helmclient.KubeConfClientOptions {
49+ Options : & helmclient.Options {
50+ Namespace : namespace ,
51+ RepositoryCache : "/tmp/.helmcache" ,
52+ RepositoryConfig : "/tmp/.helmrepo" ,
53+ Debug : false ,
54+ Linting : false , // Change this to false if you don't want linting.
55+ },
56+ KubeContext : "" ,
57+ KubeConfig : kubeConfig ,
58+ }
59+
60+ helmClient , err := helmclient .NewClientFromKubeConf (opt )
61+ if err != nil {
62+ log .Fatalf ("Cannot create client from kubeConfig" )
63+ }
64+
65+ // Get release info
66+ release , err := helmClient .GetRelease (releaseName )
67+ if err != nil {
68+ return // Release not found or there was an error
69+ }
70+
71+ // Check if there's only one revision and it's failed
72+ if release .Version == 1 && release .Info .Status == "failed" {
73+
74+ fmt .Println ("Removing failed first release." )
75+
76+ // Remove release
77+ common .UninstallHelmRelease (clientset , helmClient , releaseName , namespace , true )
78+ }
79+
80+ // Workaround for previous Helm release stuck in pending state
81+ // This is a workaround for a known issue with Helm where a release can get stuck in a pending-upgrade state
82+ // and the secret is not deleted. This is a workaround to delete the secret if it exists.
83+ if release .Info .Status == "pending-upgrade" {
84+ secretName := fmt .Sprintf ("%s.%s.v%d" , releaseName , namespace , release .Version )
85+ if err == nil {
86+ fmt .Printf ("Deleting secret %s\n " , secretName )
87+ err := clientset .CoreV1 ().Secrets (namespace ).Delete (context .TODO (), secretName , v1.DeleteOptions {})
88+ if err != nil {
89+ log .Fatalf ("Error deleting secret %s: %s" , secretName , err )
90+ }
91+ }
92+ }
5093 },
5194}
5295
0 commit comments