본문으로 건너뛰기
버전: 3.19.0

예제

이 문서에서는 Helm SDK 사용 예제를 다룬다. 다양한 SDK 기능을 문서화하기 위한 것이다.

마지막 예제는 main.go 드라이버(링크)를 보여준다. 이 드라이버는 아래 작업들을 실행하며 필요한 헬퍼 함수들을 포함한다.

예제 코드는 helm/helm-www/sdkexamples/ 디렉토리에 있다. 완전히 동작하는 코드이다.

작업

Install 작업

이 예제는 지정된 차트/릴리스를 주어진 버전과 values로 설치한다:

package main

import (
"context"
"fmt"
"log"

"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/downloader"
"helm.sh/helm/v3/pkg/getter"
)

func runInstall(ctx context.Context, logger *log.Logger, settings *cli.EnvSettings, releaseName string, chartRef string, chartVersion string, releaseValues map[string]interface{}) error {

actionConfig, err := initActionConfig(settings, logger)
if err != nil {
return fmt.Errorf("failed to init action config: %w", err)
}

installClient := action.NewInstall(actionConfig)

installClient.DryRunOption = "none"
installClient.ReleaseName = releaseName
installClient.Namespace = settings.Namespace()
installClient.Version = chartVersion

registryClient, err := newRegistryClientTLS(
settings,
logger,
installClient.CertFile,
installClient.KeyFile,
installClient.CaFile,
installClient.InsecureSkipTLSverify,
installClient.PlainHTTP)
if err != nil {
return fmt.Errorf("failed to created registry client: %w", err)
}
installClient.SetRegistryClient(registryClient)

chartPath, err := installClient.ChartPathOptions.LocateChart(chartRef, settings)
if err != nil {
return err
}

providers := getter.All(settings)

chart, err := loader.Load(chartPath)
if err != nil {
return err
}

// Check chart dependencies to make sure all are present in /charts
if chartDependencies := chart.Metadata.Dependencies; chartDependencies != nil {
if err := action.CheckDependencies(chart, chartDependencies); err != nil {
err = fmt.Errorf("failed to check chart dependencies: %w", err)
if !installClient.DependencyUpdate {
return err
}

manager := &downloader.Manager{
Out: logger.Writer(),
ChartPath: chartPath,
Keyring: installClient.ChartPathOptions.Keyring,
SkipUpdate: false,
Getters: providers,
RepositoryConfig: settings.RepositoryConfig,
RepositoryCache: settings.RepositoryCache,
Debug: settings.Debug,
RegistryClient: installClient.GetRegistryClient(),
}
if err := manager.Update(); err != nil {
return err
}
// Reload the chart with the updated Chart.lock file.
if chart, err = loader.Load(chartPath); err != nil {
return fmt.Errorf("failed to reload chart after repo update: %w", err)
}
}
}

release, err := installClient.RunWithContext(ctx, chart, releaseValues)
if err != nil {
return fmt.Errorf("failed to run install: %w", err)
}

logger.Printf("release created:\n%+v", *release)

return nil
}

Upgrade 작업

이 예제는 지정된 릴리스를 주어진 차트, 버전, values로 업그레이드한다:

package main

import (
"context"
"fmt"
"log"

"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/downloader"
"helm.sh/helm/v3/pkg/getter"
)

func runUpgrade(ctx context.Context, logger *log.Logger, settings *cli.EnvSettings, releaseName string, chartRef string, chartVersion string, releaseValues map[string]interface{}) error {
actionConfig, err := initActionConfig(settings, logger)
if err != nil {
return fmt.Errorf("failed to init action config: %w", err)
}

upgradeClient := action.NewUpgrade(actionConfig)

upgradeClient.Namespace = settings.Namespace()
upgradeClient.DryRunOption = "none"
upgradeClient.Version = chartVersion

registryClient, err := newRegistryClientTLS(
settings,
logger,
upgradeClient.CertFile,
upgradeClient.KeyFile,
upgradeClient.CaFile,
upgradeClient.InsecureSkipTLSverify,
upgradeClient.PlainHTTP)
if err != nil {
return fmt.Errorf("missing registry client: %w", err)
}
upgradeClient.SetRegistryClient(registryClient)

chartPath, err := upgradeClient.ChartPathOptions.LocateChart(chartRef, settings)
if err != nil {
return err
}

providers := getter.All(settings)

// Check chart dependencies to make sure all are present in /charts
chart, err := loader.Load(chartPath)
if err != nil {
return fmt.Errorf("failed to load chart: %w", err)
}
if req := chart.Metadata.Dependencies; req != nil {
if err := action.CheckDependencies(chart, req); err != nil {
err = fmt.Errorf("failed to check chart dependencies: %w", err)
if !upgradeClient.DependencyUpdate {
return err
}

man := &downloader.Manager{
Out: logger.Writer(),
ChartPath: chartPath,
Keyring: upgradeClient.ChartPathOptions.Keyring,
SkipUpdate: false,
Getters: providers,
RepositoryConfig: settings.RepositoryConfig,
RepositoryCache: settings.RepositoryCache,
Debug: settings.Debug,
}
if err := man.Update(); err != nil {
return err
}
// Reload the chart with the updated Chart.lock file.
if chart, err = loader.Load(chartPath); err != nil {
return fmt.Errorf("failed to reload chart after repo update: %w", err)
}
}
}

release, err := upgradeClient.RunWithContext(ctx, releaseName, chart, releaseValues)
if err != nil {
return fmt.Errorf("failed to run upgrade action: %w", err)
}

logger.Printf("release: %+v", release)

return nil
}

Uninstall 작업

이 예제는 지정된 릴리스를 삭제한다

package main

import (
"fmt"
"log"

"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli"
)

func runUninstall(logger *log.Logger, settings *cli.EnvSettings, releaseName string) error {

actionConfig, err := initActionConfig(settings, logger)
if err != nil {
return fmt.Errorf("failed to init action config: %w", err)
}

uninstallClient := action.NewUninstall(actionConfig)
uninstallClient.DeletionPropagation = "foreground" // "background" or "orphan"

result, err := uninstallClient.Run(releaseName)
if err != nil {
return fmt.Errorf("failed to run uninstall action: %w", err)
}
if result != nil {
logger.Printf("result: %+v\n", *result.Release)
}

logger.Printf("release \"%s\" uninstalled\n", releaseName)

return nil
}

List 작업

이 예제는 현재 설정된 네임스페이스의 모든 릴리스된 차트를 나열한다

package main

import (
"fmt"
"log"

"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli"
)

func runList(logger *log.Logger, settings *cli.EnvSettings) error {

actionConfig, err := initActionConfigList(settings, logger, false)
if err != nil {
return fmt.Errorf("failed to init action config: %w", err)
}

listClient := action.NewList(actionConfig)
// Only list deployed
//listClient.Deployed = true
listClient.All = true
listClient.SetStateMask()

results, err := listClient.Run()
if err != nil {
return fmt.Errorf("failed to run list action: %w", err)
}

for _, rel := range results {
logger.Printf("list result: %+v", rel)
}

return nil
}

Pull 작업

이 예제는 OCI 저장소에서 차트를 가져온다

package main

import (
"fmt"
"log"

"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli"
)

func runPull(logger *log.Logger, settings *cli.EnvSettings, chartRef, chartVersion string) error {

actionConfig, err := initActionConfig(settings, logger)
if err != nil {
return fmt.Errorf("failed to init action config: %w", err)
}

registryClient, err := newRegistryClient(settings, false)
if err != nil {
return fmt.Errorf("failed to created registry client: %w", err)
}
actionConfig.RegistryClient = registryClient

pullClient := action.NewPullWithOpts(
action.WithConfig(actionConfig))
// client.RepoURL = ""
pullClient.DestDir = "./"
pullClient.Settings = settings
pullClient.Version = chartVersion

result, err := pullClient.Run(chartRef)
if err != nil {
return fmt.Errorf("failed to pull chart: %w", err)
}

logger.Printf("%+v", result)

return nil
}

드라이버

여기서 드라이버는 Helm SDK 작업이 동작하는 데 필요한 보조 함수들을 보여준다. 그리고 위의 예제들을 실제로 실행하여 OCI 저장소에서 'podinfo' 차트를 가져오고, 설치하고, 업데이트하고, 삭제한다.

package main

import (
"bufio"
"context"
"fmt"
"log"
"os"

"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/registry"
)

var helmDriver string = os.Getenv("HELM_DRIVER")

func initActionConfig(settings *cli.EnvSettings, logger *log.Logger) (*action.Configuration, error) {
return initActionConfigList(settings, logger, false)
}

func initActionConfigList(settings *cli.EnvSettings, logger *log.Logger, allNamespaces bool) (*action.Configuration, error) {

actionConfig := new(action.Configuration)

namespace := func() string {
// For list action, you can pass an empty string instead of settings.Namespace() to list
// all namespaces
if allNamespaces {
return ""
}
return settings.Namespace()
}()

if err := actionConfig.Init(
settings.RESTClientGetter(),
namespace,
helmDriver,
logger.Printf); err != nil {
return nil, err
}

return actionConfig, nil
}

func newRegistryClient(settings *cli.EnvSettings, plainHTTP bool) (*registry.Client, error) {
opts := []registry.ClientOption{
registry.ClientOptDebug(settings.Debug),
registry.ClientOptEnableCache(true),
registry.ClientOptWriter(os.Stderr),
registry.ClientOptCredentialsFile(settings.RegistryConfig),
}
if plainHTTP {
opts = append(opts, registry.ClientOptPlainHTTP())
}

// Create a new registry client
registryClient, err := registry.NewClient(opts...)
if err != nil {
return nil, err
}
return registryClient, nil
}

func newRegistryClientTLS(settings *cli.EnvSettings, logger *log.Logger, certFile, keyFile, caFile string, insecureSkipTLSverify, plainHTTP bool) (*registry.Client, error) {
if certFile != "" && keyFile != "" || caFile != "" || insecureSkipTLSverify {
registryClient, err := registry.NewRegistryClientWithTLS(
logger.Writer(),
certFile,
keyFile,
caFile,
insecureSkipTLSverify,
settings.RegistryConfig,
settings.Debug)

if err != nil {
return nil, err
}
return registryClient, nil
}
registryClient, err := newRegistryClient(settings, plainHTTP)
if err != nil {
return nil, err
}
return registryClient, nil
}

func main() {

logger := log.Default()

// For convenience, initialize SDK setting via CLI mechanism
settings := cli.New()

// Release name, chart and values
releaseName := "helm-sdk-example"
chartRef := "oci://ghcr.io/stefanprodan/charts/podinfo"
releaseValues := map[string]interface{}{
"replicaCount": "2",
}

// Pull the chart to the local filesystem
if err := runPull(logger, settings, chartRef, "6.4.1"); err != nil {
fmt.Printf("failed to run pull: %+v", err)
os.Exit(1)
}

// Install the chart (from the pulled chart local archive)
if err := runInstall(context.TODO(), logger, settings, releaseName, "./podinfo-6.4.1.tgz", "", releaseValues); err != nil {
fmt.Printf("failed to run install: %+v", err)
os.Exit(1)
}

// List installed charts
if err := runList(logger, settings); err != nil {
fmt.Printf("failed to run list: %+v", err)
os.Exit(1)
}

//
fmt.Print("Chart installed. Press 'Return' to continue...")
bufio.NewReader(os.Stdin).ReadBytes('\n')

// Upgrade to version 6.5.4, updating the replicaCount to three
releaseValues["replicaCount"] = "3"
if err := runUpgrade(context.TODO(), logger, settings, releaseName, chartRef, "6.5.4", releaseValues); err != nil {
fmt.Printf("failed to run upgrade: %+v", err)
os.Exit(1)
}

// List installed charts
if err := runList(logger, settings); err != nil {
fmt.Printf("failed to run list: %+v", err)
os.Exit(1)
}

//
fmt.Print("Chart upgraded. Press 'Return' to continue...")
bufio.NewReader(os.Stdin).ReadBytes('\n')

// Uninstall the chart
if err := runUninstall(logger, settings, releaseName); err != nil {
fmt.Printf("failed to run uninstall: %+v", err)
os.Exit(1)
}
}