Skip to main content
edited title
Link
PJEM
  • 143
  • 4

Installing charts in parallel using go routines

added 282 characters in body
Source Link
PJEM
  • 143
  • 4
    package main
    
    import (
        "fmt"
        "os"
        "strings"
        "sync"
    )
    
    func main() {
      log.Info("tools Installation")

    kcfgFilePath, err := tmpfilekubeFile(cfg)
    defer os.NameRemove(kcfgFilePath)
    if err != nil {
        return err
    }
    settings := cli.New()
    acactionConfig := new(action.Configuration)
    clientGetter := genericclioptions.NewConfigFlags(false)
    clientGetter.KubeConfig = &kcfgFilePath
    var wg sync.WaitGroup

// install all relevant //components
 here I start thevar concurrencywg sync.WaitGroup

    for _, chartInstallation := range charts {
        wg.addAdd(1)
         go installChart(&wg, chartInstallation.Path)
   , }

releaseName, actionConfig, clientGetter, settings, fmt.Println("Installing..."log)
    wg.Wait()}
    fmt.Println("Installed!")return nil
}

func installChart(wg *sync.WaitGroup,chartInstallation chartInstallationPathInstallation, releaseName string, actionConfig *action.Configuration, clientGetter *genericclioptions.ConfigFlags, settings *cli.EnvSettings, log logr.Logger) (error, bool) {
    defer wg.Done()
 
    chart, err := loader.Load(chartInstallationPathchartInstallation.Path)
    if err != nil {
        return err, true
    }
 
    releaseName := releaseName + "-" + chartInstallation.Name
    if err := acactionConfig.Init(clientGetter, settings.Namespace(), os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
        r := fmt.Sprintf(format, v)
        log.Info("Helm Installation", "deploy status", r)
    }); err != nil {
        return err, true
    }
    releasePresent := true
    statusActionstatus, err := action.NewStatus(acactionConfig).Run(releaseName)
    status,if err :!= statusAction.Run(releaseName)nil {
        //if errors.Is(err !=, nildriver.ErrReleaseNotFound) {
        if strings.Contains(err.Error(), driver.ErrReleaseNotFound.Error()) {
            releasePresent = false
        } else {
            return err, true
        }
    }

    if !releasePresent {
        // install chart
        installAction := action.NewInstall(acactionConfig)
        installAction.CreateNamespace = true
        installAction.Namespace = chartInstallation.Namespace
        installAction.ReleaseName = releaseName
        
        installAction.Wait = true
        // install new
        _, err := installAction.Run(chart, nil)
        if err != nil {
            return err, true
        }
        log.Info("chart installed"installed: ", "releaseName", releaseName)
    }

    if status != nil {
        if releasePresent && status.Info.Status.String() == release.StatusFailed.String() { // upgrade if broken
            upgradeAction := action.NewUpgrade(acactionConfig)
            //upgradeAction.Atomic HERE= ITfalse
 WAIT FOR THE CHART TO VERIFY THAT EVERYTHING IS UP  upgradeAction.CleanupOnFail = true
            upgradeAction.Wait = true
            upgradeAction.ReuseValues = false
            upgradeAction.Recreate = false
            _, err := upgradeAction.Run(releaseName, chart, nil)
            if err != nil {
                return err, true
            }
        }
    }
    return nil, false
}
package main

import (
    "fmt"
    "os"
    "strings"
    "sync"
)

func main() {
    kcfgFilePath := tmpfile.Name()
    settings := cli.New()
    ac := new(action.Configuration)
    clientGetter := genericclioptions.NewConfigFlags(false)
    clientGetter.KubeConfig = &kcfgFilePath
    var wg sync.WaitGroup

    // here I start the concurrency 
    for _, chartInstallation := range charts {
        wg.add(1)
        go installChart(&wg, chartInstallation.Path)
    }

    fmt.Println("Installing...")
    wg.Wait()
    fmt.Println("Installed!")
}

func installChart(wg *sync.WaitGroup, chartInstallationPath string) error {
    defer wg.Done()
 
    chart, err := loader.Load(chartInstallationPath)
    if err != nil {
        return err
    }
 
    releaseName := releaseName + "-" + chartInstallation.Name
    if err := ac.Init(clientGetter, settings.Namespace(), os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {

    }); err != nil {
        return err
    }
    releasePresent := true
    statusAction := action.NewStatus(ac)
    status, err := statusAction.Run(releaseName)
    if err != nil {
        if strings.Contains(err.Error(), driver.ErrReleaseNotFound.Error()) {
            releasePresent = false
        } else {
            return err
        }
    }

    if !releasePresent {
        // install chart
        installAction := action.NewInstall(ac)
        installAction.CreateNamespace = true
        installAction.Namespace = chartInstallation.Namespace
        installAction.ReleaseName = releaseName

        _, err := installAction.Run(chart, nil)
        if err != nil {
            return err
        }
        log.Info("chart installed: ", "releaseName", releaseName)
    }

    if status != nil {
        if releasePresent && status.Info.Status.String() == release.StatusFailed.String() {
            upgradeAction := action.NewUpgrade(ac)
            // HERE IT WAIT FOR THE CHART TO VERIFY THAT EVERYTHING IS UP
            upgradeAction.Wait = true
            upgradeAction.ReuseValues = false
            upgradeAction.Recreate = false
            _, err := upgradeAction.Run(releaseName, chart, nil)
            if err != nil {
                return err
            }
        }
    }
}
    package main
    
    import (
        "fmt"
        "os"
        "strings"
        "sync"
    )
    
    func main() {
      log.Info("tools Installation")

    kcfgFilePath, err := kubeFile(cfg)
    defer os.Remove(kcfgFilePath)
    if err != nil {
        return err
    }
    settings := cli.New()
    actionConfig := new(action.Configuration)
    clientGetter := genericclioptions.NewConfigFlags(false)
    clientGetter.KubeConfig = &kcfgFilePath
    // install all relevant components
    var wg sync.WaitGroup

    for _, chartInstallation := range charts {
        wg.Add(1)
         go installChart(&wg,chartInstallation, releaseName, actionConfig, clientGetter, settings, log)
    }
    return nil
}

func installChart(wg *sync.WaitGroup,chartInstallation Installation, releaseName string, actionConfig *action.Configuration, clientGetter *genericclioptions.ConfigFlags, settings *cli.EnvSettings, log logr.Logger) (error, bool) {
    defer wg.Done()
    chart, err := loader.Load(chartInstallation.Path)
    if err != nil {
        return err, true
    }
    releaseName = releaseName + "-" + chartInstallation.Name
    if err := actionConfig.Init(clientGetter, settings.Namespace(), os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
        r := fmt.Sprintf(format, v)
        log.Info("Helm Installation", "deploy status", r)
    }); err != nil {
        return err, true
    }
    releasePresent := true
    status, err := action.NewStatus(actionConfig).Run(releaseName)
    if err != nil {
        //if errors.Is(err, driver.ErrReleaseNotFound) {
        if strings.Contains(err.Error(), driver.ErrReleaseNotFound.Error()) {
            releasePresent = false
        } else {
            return err, true
        }
    }

    if !releasePresent {
        // install chart
        installAction := action.NewInstall(actionConfig)
        installAction.CreateNamespace = true
        installAction.Namespace = chartInstallation.Namespace
        installAction.ReleaseName = releaseName
        
        installAction.Wait = true
        // install new
        _, err := installAction.Run(chart, nil)
        if err != nil {
            return err, true
        }
        log.Info("installed: ", "releaseName", releaseName)
    }

    if status != nil {
        if releasePresent && status.Info.Status.String() == release.StatusFailed.String() { // upgrade if broken
            upgradeAction := action.NewUpgrade(actionConfig)
            upgradeAction.Atomic = false
            upgradeAction.CleanupOnFail = true
            upgradeAction.Wait = true
            upgradeAction.ReuseValues = false
            upgradeAction.Recreate = false
            _, err := upgradeAction.Run(releaseName, chart, nil)
            if err != nil {
                return err, true
            }
        }
    }
    return nil, false
}
added 2 characters in body
Source Link
PJEM
  • 143
  • 4

I use the following code which works and install helm chart (in the loop) in parallel, it get a kubeconfigkubeconfig file (to access to k8s) create a helm client and install the charts from the defined location and waits (upgradeAction.Wait = true) that each chart installation will finished successfully. at

At first I do it in sequence and now I added a wait.group to be able to reduce the installation time and install it in parallel, do I miss something? error handling etc?

I use the following code which works and install helm chart (in the loop) in parallel, it get a kubeconfig file (to access to k8s) create a helm client and install the charts from the defined location and waits (upgradeAction.Wait = true) that each chart installation will finished successfully. at first I do it in sequence and now I added a wait.group to be able to reduce the installation time and install in parallel, do I miss something? error handling etc?

I use the following code which works and install helm chart (in the loop) in parallel, it get a kubeconfig file (to access to k8s) create a helm client and install the charts from the defined location and waits (upgradeAction.Wait = true) that each chart installation will finished successfully.

At first I do it in sequence and now I added a wait.group to be able to reduce the installation time and install it in parallel, do I miss something? error handling etc?

Source Link
PJEM
  • 143
  • 4
Loading