Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use kubeconfig for helm client install panding

Im using the helm SDK and it works great, for my testing using the fake option which works(for kubeconfig),

Now when I update the kubeconfig to my cluster I notice that during installation the chart is stuck on status pending, and it stuck forever in this state until I'm deleting & installing it again,(manually) My question is how to solve this issue with the Helm SDK (via code only) https://pkg.go.dev/helm.sh/helm/v3,

I mean wait for a while and if the status is pending after 3 min delete and reinstall it again... or try upgrade before

This is the code

    kubeConfigPath, err := findKubeConfig()
    if err != nil {
        fmt.Println()
    }

    actionConfig := &action.Configuration{
    }

    cfg := cli.New()
    clientGetter := genericclioptions.NewConfigFlags(false)
    clientGetter.KubeConfig = &kubeConfigPath

    actionConfig.Init(clientGetter, "def", "memory", log.Printf)
    if err != nil {
        fmt.Println(err)
    }

    chart, err := installation.InstallChart(cfg, "test", "chart1", "./charts/dns", nil, actionConfig)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(chart)
}

func findKubeConfig() (string, error) {
    env := os.Getenv("KUBECONFIG")
    if env != "" {
        return env, nil
    }
    path, err := homedir.Expand("~/.kube/config")
    if err != nil {
        return "", err
    }
    return path, nil
}
like image 919
Jenney Avatar asked Nov 06 '22 01:11

Jenney


1 Answers

Looking at the example, I don't know what the installation package is but I feel like you would need to use a Loader (maybe you are using it in that pkg)

from a quick search over the github issues I found someone with a similar problem - and they got the same suggestion. here is a derived example:

package main

import (
    "fmt"
    "os"

    "helm.sh/helm/v3/pkg/action"
    "helm.sh/helm/v3/pkg/chart/loader"
    "helm.sh/helm/v3/pkg/kube"
    "helm.sh/helm/v3/pkg/release"
    _ "k8s.io/client-go/plugin/pkg/client/auth"
)

func main() {
    chartPath := "./charts/dns"
    chart, err := loader.Load(chartPath)
    if err != nil {
        panic(err)
    }

    kubeconfigPath := findKubeConfig()
    releaseName := "test"
    releaseNamespace := "default"
    actionConfig := new(action.Configuration)
    if err := actionConfig.Init(kube.GetConfig(kubeconfigPath, "", releaseNamespace), releaseNamespace, os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
        fmt.Sprintf(format, v)
    }); err != nil {
        panic(err)
    }

    iCli := action.NewInstall(actionConfig)
    iCli.Namespace = releaseNamespace
    iCli.ReleaseName = releaseName
    rel, err := iCli.Run(chart, nil)
    if err != nil {
        panic(err)
    }
    fmt.Println("Successfully installed release: ", rel.Name)
rel.Info.Status
    // check Release Status, feel free to run it in a go routine along the deletetion logic
    upCli := action.NewUpgrade(actionConfig)  
    upgradedRel, err := pollAndUpdate(rel.Info.Status, upCli) // see if its better to just run that code here directly :shrug:

// if we still on pending, then delete it
    if upgradedRel.Info.Status.IsPending() {
      unCli := action.NewUninstall(actionConfig)
      res, err := unCli.Run(rel.Name)
      if err != nil {
          panic(err)
      }
    }
}

func pollAndUpdate(originalRel *release.Release, upgradeCli *action.Upgrade) (*release.Release, error) {
    if !originalRel.Info.Status.IsPending() {
        return originalRel, nil
    }
    c := time.Tick(10 * time.Second) // we gonna time it out besides checking repeatedly
    var rel *release.Release = originalRel
    for _ = range c {
         //check the status and try and upgrade
         for rel.Info.Status.IsPending() { // https://pkg.go.dev/helm.sh/helm/[email protected]/pkg/release#Status.IsPending
             // run the upgrade command you have
             // its this function: https://github.com/helm/helm/blob/main/pkg/action/upgrade.go#L111
             rel, err := upgradeCli.Run(/*you gotta get all the values this needs*/)
             if err != nil {
                 panic(err)
             }
         }
    }
    return rel, nil
}
like image 184
bjornaer Avatar answered Nov 11 '22 05:11

bjornaer