예제

예제

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

마지막 예제는 아래 액션들을 실행하고 필요한 헬퍼 함수를 포함한 main.go 드라이버(링크)를 보여 줘요.

예제 코드는 helm/helm-www/sdkexamples/ 디렉터리에 있어요. 완전히 동작하도록 의도됐어요.

출처: 문서

본문

액션들

Install 액션

이 예제는 주어진 버전과 값으로 주어진 차트/릴리스를 설치해요:

sdkexamples/install.go

package main

import (
	"context"
	"fmt"
	"log"

	"helm.sh/helm/v4/pkg/action"
	"helm.sh/helm/v4/pkg/chart"
	"helm.sh/helm/v4/pkg/chart/loader"
	"helm.sh/helm/v4/pkg/cli"
	"helm.sh/helm/v4/pkg/downloader"
	"helm.sh/helm/v4/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.DryRunStrategy = "none"
	installClient.WaitStrategy = "watcher"
	installClient.ReleaseName = releaseName
	installClient.Namespace = settings.Namespace()
	installClient.Version = chartVersion

	registryClient, err := newRegistryClient(
		settings,
		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)

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

	chartAccessor, err := chart.NewDefaultAccessor(charter)
	if err != nil {
		return fmt.Errorf("error creating chart accessor: %w", err)
	}

	// Check chart dependencies to make sure all are present in /charts
	if chartDependencies := chartAccessor.MetaDependencies(); chartDependencies != nil {
		if err := action.CheckDependencies(charter, 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 charter, err = loader.Load(chartPath); err != nil {
				return fmt.Errorf("failed to reload chart after repo update: %w", err)
			}
		}
	}

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

	logger.Printf("release created")

	return nil
}

Upgrade 액션

이 예제는 주어진 차트·버전·값으로 주어진 릴리스를 업그레이드해요:

sdkexamples/upgrade.go

package main

import (
	"context"
	"fmt"
	"log"

	"helm.sh/helm/v4/pkg/action"
	"helm.sh/helm/v4/pkg/chart"
	"helm.sh/helm/v4/pkg/chart/loader"
	"helm.sh/helm/v4/pkg/cli"
	"helm.sh/helm/v4/pkg/downloader"
	"helm.sh/helm/v4/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.DryRunStrategy = "none"
	upgradeClient.Version = chartVersion
	upgradeClient.WaitStrategy = "watcher"

	registryClient, err := newRegistryClient(
		settings,
		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
	charter, err := loader.Load(chartPath)
	if err != nil {
		return fmt.Errorf("failed to load chart: %w", err)
	}

	chartAccessor, err := chart.NewDefaultAccessor(charter)
	if err != nil {
		return fmt.Errorf("error creating chart accessor: %w", err)
	}

	if chartDependencies := chartAccessor.MetaDependencies(); chartDependencies != nil {
		if err := action.CheckDependencies(charter, chartDependencies); 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 charter, err = loader.Load(chartPath); err != nil {
				return fmt.Errorf("failed to reload chart after repo update: %w", err)
			}
		}
	}

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

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

	return nil
}

Uninstall 액션

이 예제는 주어진 릴리스를 제거해요:

sdkexamples/uninstall.go

package main

import (
	"fmt"
	"log"

	"helm.sh/helm/v4/pkg/action"
	"helm.sh/helm/v4/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"
	uninstallClient.WaitStrategy = "watcher"

	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.Info)
	}

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

	return nil
}

List 액션

이 예제는 (현재 설정된 네임스페이스에서) 모든 릴리스된 차트를 나열해요:

sdkexamples/list.go

package main

import (
	"fmt"
	"log"

	"helm.sh/helm/v4/pkg/action"
	"helm.sh/helm/v4/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 저장소에서 차트를 내려 받아요:

sdkexamples/pull.go

package main

import (
	"fmt"
	"log"

	"helm.sh/helm/v4/pkg/action"
	"helm.sh/helm/v4/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)
	}

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

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

	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' 차트를 내려 받고 설치·업그레이드·제거하는 동작을 보여 줘요:

sdkexamples/main.go

package main

import (
	"bufio"
	"context"
	"fmt"
	"log"
	"net/http"
	"os"

	"helm.sh/helm/v4/pkg/action"
	"helm.sh/helm/v4/pkg/cli"
	"helm.sh/helm/v4/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); err != nil {
		return nil, err
	}

	return actionConfig, nil
}

func newRegistryClient(settings *cli.EnvSettings, certFile, keyFile, caFile string, insecureSkipTLSVerify, 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())
	}

	if certFile != "" && keyFile != "" || caFile != "" || insecureSkipTLSVerify {
		tlsConf, err := NewTLSConfig(
			WithInsecureSkipVerify(insecureSkipTLSVerify),
			WithCertKeyPairFiles(certFile, keyFile),
			WithCAFile(caFile),
		)
		if err != nil {
			return nil, fmt.Errorf("failed to load client TLS certs: %w", err)
		}

		opts = append(opts, registry.ClientOptHTTPClient(&http.Client{
			Transport: &http.Transport{
				TLSClientConfig: tlsConf,
				Proxy:           http.ProxyFromEnvironment,
			},
		}))
	}

	// Create a new registry client
	registryClient, err := registry.NewClient(opts...)
	if err != nil {
		return nil, fmt.Errorf("failed to initialize registry client: %w", 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)
	}
}

더 알아보기 (Learn more)