Add subcommand init for checks and installs helmfile deps (#389)
* Add subcommand init for checks and installs helmfile deps Signed-off-by: xiaomudk <xiaomudk@gmail.com>
This commit is contained in:
		
							parent
							
								
									008e92de37
								
							
						
					
					
						commit
						6dcde20d7a
					
				|  | @ -132,3 +132,25 @@ jobs: | |||
|         TERM: xterm | ||||
|         EXTRA_HELMFILE_FLAGS: ${{ matrix.extra-helmfile-flags }} | ||||
|       run: make integration | ||||
|   e2e_tests: | ||||
|     needs: tests | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|         with: | ||||
|           fetch-depth: 0 | ||||
|       - name: Install package | ||||
|         run: | | ||||
|             sudo apt-get -y install expect | ||||
|       - name: Download built binaries | ||||
|         uses: actions/download-artifact@v2 | ||||
|         with: | ||||
|           name: built-binaries-${{ github.run_id }} | ||||
|       - name: Extract tar to get built binaries | ||||
|         run: tar -xvf built-binaries.tar | ||||
|       - name: Display built binaries | ||||
|         run: ls -l helmfile diff-yamls yamldiff | ||||
|       - name: Run helmfile init | ||||
|         env: | ||||
|           TERM: xterm | ||||
|         run: bash test/e2e/helmfile-init/init_linux.sh | ||||
|  |  | |||
|  | @ -0,0 +1,35 @@ | |||
| package cmd | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/spf13/cobra" | ||||
| 
 | ||||
| 	"github.com/helmfile/helmfile/pkg/app" | ||||
| 	"github.com/helmfile/helmfile/pkg/config" | ||||
| ) | ||||
| 
 | ||||
| // NewInitCmd helmfile checks and installs deps
 | ||||
| func NewInitCmd(globalCfg *config.GlobalImpl) *cobra.Command { | ||||
| 	options := config.NewInitOptions() | ||||
| 	cmd := &cobra.Command{ | ||||
| 		Use:   "init", | ||||
| 		Short: "Initialize the helmfile, includes version checking and installation of helm and plug-ins", | ||||
| 		RunE: func(cmd *cobra.Command, args []string) error { | ||||
| 			initImpl := config.NewInitImpl(globalCfg, options) | ||||
| 			err := config.NewCLIConfigImpl(initImpl.GlobalImpl) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			if err := initImpl.ValidateConfig(); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			a := app.New(initImpl) | ||||
| 			return toCLIError(initImpl.GlobalImpl, a.Init(initImpl)) | ||||
| 		}, | ||||
| 	} | ||||
| 	f := cmd.Flags() | ||||
| 	f.BoolVar(&options.Force, "force", false, "Do not prompt, install dependencies required by helmfile") | ||||
| 
 | ||||
| 	return cmd | ||||
| } | ||||
|  | @ -81,6 +81,7 @@ func NewRootCmd(globalConfig *config.GlobalOptions) (*cobra.Command, error) { | |||
| 	} | ||||
| 
 | ||||
| 	cmd.AddCommand( | ||||
| 		NewInitCmd(globalImpl), | ||||
| 		NewApplyCmd(globalImpl), | ||||
| 		NewBuildCmd(globalImpl), | ||||
| 		NewCacheCmd(globalImpl), | ||||
|  |  | |||
|  | @ -505,6 +505,7 @@ Available Commands: | |||
|   diff         Diff releases defined in state file | ||||
|   fetch        Fetch charts from state file | ||||
|   help         Help about any command | ||||
|   init         Initialize the helmfile, includes version checking and installation of helm and plug-ins | ||||
|   lint         Lint charts from state file (helm lint) | ||||
|   list         List releases defined in state file | ||||
|   repos        Repos releases defined in state file | ||||
|  | @ -543,6 +544,11 @@ Flags: | |||
| Use "helmfile [command] --help" for more information about a command. | ||||
| ``` | ||||
| 
 | ||||
| ### init | ||||
| 
 | ||||
| The `helmfile init` sub-command checks the dependencies required for helmfile operation, such as `helm`, `helm diff plugin`, `helm secrets plugin`, `helm helm-git plugin`, `helm s3 plugin`. When it does not exist or the version is too low, it can be installed automatically. | ||||
| 
 | ||||
| 
 | ||||
| ### sync | ||||
| 
 | ||||
| The `helmfile sync` sub-command sync your cluster state as described in your `helmfile`. The default helmfile is `helmfile.yaml`, but any YAML file can be passed by specifying a `--file path/to/your/yaml/file` flag. | ||||
|  |  | |||
|  | @ -93,6 +93,14 @@ func Init(app *App) *App { | |||
| 	return app | ||||
| } | ||||
| 
 | ||||
| func (a *App) Init(c InitConfigProvider) error { | ||||
| 	runner := &helmexec.ShellRunner{ | ||||
| 		Logger: a.Logger, | ||||
| 	} | ||||
| 	helmfileInit := NewHelmfileInit(a.OverrideHelmBinary, c, a.Logger, runner) | ||||
| 	return helmfileInit.Initialize() | ||||
| } | ||||
| 
 | ||||
| func (a *App) Deps(c DepsConfigProvider) error { | ||||
| 	return a.ForEachState(func(run *Run) (_ bool, errs []error) { | ||||
| 		prepErr := run.withPreparedCharts("deps", state.ChartPrepareOptions{ | ||||
|  |  | |||
|  | @ -247,6 +247,10 @@ type ListConfigProvider interface { | |||
| 
 | ||||
| type CacheConfigProvider interface{} | ||||
| 
 | ||||
| type InitConfigProvider interface { | ||||
| 	Force() bool | ||||
| } | ||||
| 
 | ||||
| // when enable reuse-values, reuse the last release's values and merge in any overrides values.
 | ||||
| type valuesControlMode interface { | ||||
| 	ReuseValues() bool | ||||
|  |  | |||
|  | @ -0,0 +1,238 @@ | |||
| package app | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"runtime" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/Masterminds/semver/v3" | ||||
| 	"go.uber.org/zap" | ||||
| 	"helm.sh/helm/v3/pkg/cli" | ||||
| 
 | ||||
| 	"github.com/helmfile/helmfile/pkg/helmexec" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	HelmRequiredVersion           = "v2.10.0" | ||||
| 	HelmRecommendedVersion        = "v3.10.1" | ||||
| 	HelmDiffRecommendedVersion    = "v3.4.0" | ||||
| 	HelmSecretsRecommendedVersion = "v4.1.1" | ||||
| 	HelmGitRecommendedVersion     = "v0.12.0" | ||||
| 	HelmS3RecommendedVersion      = "v0.14.0" | ||||
| 	HelmInstallCommand            = "https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	manuallyInstallCode   = 1 | ||||
| 	windowPackageManagers = map[string]string{ | ||||
| 		"scoop": fmt.Sprintf("scoop install helm@%s", strings.TrimLeft(HelmRecommendedVersion, "v")), | ||||
| 		"choco": fmt.Sprintf("choco install kubernetes-helm --version %s", strings.TrimLeft(HelmRecommendedVersion, "v")), | ||||
| 	} | ||||
| 	helmPlugins = []helmRecommendedPlugin{ | ||||
| 		{ | ||||
| 			name:    "diff", | ||||
| 			version: HelmDiffRecommendedVersion, | ||||
| 			repo:    "https://github.com/databus23/helm-diff", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:    "secrets", | ||||
| 			version: HelmSecretsRecommendedVersion, | ||||
| 			repo:    "https://github.com/jkroepke/helm-secrets", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:    "s3", | ||||
| 			version: HelmS3RecommendedVersion, | ||||
| 			repo:    "https://github.com/hypnoglow/helm-s3.git", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:    "helm-git", | ||||
| 			version: HelmGitRecommendedVersion, | ||||
| 			repo:    "https://github.com/aslafy-z/helm-git.git", | ||||
| 		}, | ||||
| 	} | ||||
| ) | ||||
| 
 | ||||
| type helmRecommendedPlugin struct { | ||||
| 	name    string | ||||
| 	version string | ||||
| 	repo    string | ||||
| } | ||||
| 
 | ||||
| type HelmfileInit struct { | ||||
| 	helmBinary     string | ||||
| 	configProvider InitConfigProvider | ||||
| 	logger         *zap.SugaredLogger | ||||
| 	runner         helmexec.Runner | ||||
| } | ||||
| 
 | ||||
| func downloadfile(filepath string, url string) error { | ||||
| 	file, err := os.Create(filepath) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer func() { _ = file.Close() }() | ||||
| 	resp, err := http.Get(url) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if resp.StatusCode/100 != 2 { | ||||
| 		return fmt.Errorf("download %s error, code: %d", url, resp.StatusCode) | ||||
| 	} | ||||
| 	defer func() { _ = resp.Body.Close() }() | ||||
| 	_, err = io.Copy(file, resp.Body) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func NewHelmfileInit(helmBinary string, c InitConfigProvider, logger *zap.SugaredLogger, runner helmexec.Runner) *HelmfileInit { | ||||
| 	return &HelmfileInit{helmBinary: helmBinary, configProvider: c, logger: logger, runner: runner} | ||||
| } | ||||
| func (h *HelmfileInit) UpdateHelm() error { | ||||
| 	return h.InstallHelm() | ||||
| } | ||||
| 
 | ||||
| func (h *HelmfileInit) installHelmOnWindows() error { | ||||
| 	for name, command := range windowPackageManagers { | ||||
| 		_, err := exec.LookPath(name) | ||||
| 		if err != nil { | ||||
| 			continue | ||||
| 		} | ||||
| 		err = h.WhetherContinue(fmt.Sprintf("use: '%s'", command)) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		_, err = h.runner.Execute("cmd", []string{ | ||||
| 			"/c", | ||||
| 			command, | ||||
| 		}, nil, true) | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return &Error{msg: "windows platform, please install helm manually, installation steps: https://helm.sh/docs/intro/install/", code: &manuallyInstallCode} | ||||
| } | ||||
| 
 | ||||
| func (h *HelmfileInit) InstallHelm() error { | ||||
| 	if runtime.GOOS == "windows" { | ||||
| 		return h.installHelmOnWindows() | ||||
| 	} | ||||
| 
 | ||||
| 	err := h.WhetherContinue(fmt.Sprintf("use: '%s'", HelmInstallCommand)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	getHelmScript, err := os.CreateTemp("", "get-helm-3.sh") | ||||
| 	defer func() { | ||||
| 		_ = getHelmScript.Close() | ||||
| 		_ = os.Remove(getHelmScript.Name()) | ||||
| 	}() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	err = downloadfile(getHelmScript.Name(), HelmInstallCommand) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	_, err = h.runner.Execute("bash", []string{ | ||||
| 		getHelmScript.Name(), | ||||
| 		"--version", | ||||
| 		HelmRecommendedVersion, | ||||
| 	}, nil, true) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	h.helmBinary = DefaultHelmBinary | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (h *HelmfileInit) WhetherContinue(ask string) error { | ||||
| 	if h.configProvider.Force() { | ||||
| 		return nil | ||||
| 	} | ||||
| 	askYes := AskForConfirmation(ask) | ||||
| 	if !askYes { | ||||
| 		return &Error{msg: "cancel automatic installation, please install manually", code: &manuallyInstallCode} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (h *HelmfileInit) CheckHelmPlugins() error { | ||||
| 	settings := cli.New() | ||||
| 	helm := helmexec.New(h.helmBinary, false, h.logger, "", h.runner) | ||||
| 	for _, p := range helmPlugins { | ||||
| 		pluginVersion, err := helmexec.GetPluginVersion(p.name, settings.PluginsDirectory) | ||||
| 		if err != nil { | ||||
| 			if !strings.Contains(err.Error(), "not installed") { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			err = h.WhetherContinue(fmt.Sprintf("The helm plugin %s is not installed, do you need to install it", p.name)) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			err = helm.AddPlugin(p.name, p.repo, p.version) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			pluginVersion, _ = helmexec.GetPluginVersion(p.name, settings.PluginsDirectory) | ||||
| 		} | ||||
| 		requiredVersion, _ := semver.NewVersion(p.version) | ||||
| 		if pluginVersion.LessThan(requiredVersion) { | ||||
| 			err = h.WhetherContinue(fmt.Sprintf("The helm plugin %s version is too low, do you need to update it", p.name)) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			err = helm.UpdatePlugin(p.name) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (h *HelmfileInit) CheckHelm() error { | ||||
| 	helmExits := true | ||||
| 	_, err := exec.LookPath(h.helmBinary) | ||||
| 	if err != nil { | ||||
| 		helmExits = false | ||||
| 	} | ||||
| 	if !helmExits { | ||||
| 		h.logger.Info("helm not found, needs to be installed") | ||||
| 		err = h.InstallHelm() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	helmversion, err := helmexec.GetHelmVersion(h.helmBinary, h.runner) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	requiredHelmVersion, _ := semver.NewVersion(HelmRequiredVersion) | ||||
| 	if helmversion.LessThan(requiredHelmVersion) { | ||||
| 		h.logger.Infof("helm version is too low, the current version is %s, the required version is %s", helmversion, requiredHelmVersion) | ||||
| 		err = h.UpdateHelm() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (h *HelmfileInit) Initialize() error { | ||||
| 	err := h.CheckHelm() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	err = h.CheckHelmPlugins() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	h.logger.Info("helmfile initialization completed!") | ||||
| 	return nil | ||||
| } | ||||
|  | @ -0,0 +1,89 @@ | |||
| package app | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"os" | ||||
| 	"path" | ||||
| 	"regexp" | ||||
| 	"testing" | ||||
| ) | ||||
| 
 | ||||
| func TestDownloadfile(t *testing.T) { | ||||
| 	var ts *httptest.Server | ||||
| 	cases := []struct { | ||||
| 		name        string | ||||
| 		handler     func(http.ResponseWriter, *http.Request) | ||||
| 		url         string | ||||
| 		filepath    string | ||||
| 		wantContent string | ||||
| 		wantError   string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "download success", | ||||
| 			handler: func(w http.ResponseWriter, r *http.Request) { | ||||
| 				fmt.Fprint(w, "helmfile") | ||||
| 			}, | ||||
| 			wantContent: "helmfile", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "download 404", | ||||
| 			handler: func(w http.ResponseWriter, r *http.Request) { | ||||
| 				w.WriteHeader(404) | ||||
| 				fmt.Fprint(w, "not found") | ||||
| 			}, | ||||
| 			wantError: "download .*? error, code: 404", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "download 500", | ||||
| 			handler: func(w http.ResponseWriter, r *http.Request) { | ||||
| 				w.WriteHeader(500) | ||||
| 				fmt.Fprint(w, "server error") | ||||
| 			}, | ||||
| 			wantError: "download .*? error, code: 500", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "download path error", | ||||
| 			handler: func(w http.ResponseWriter, r *http.Request) { | ||||
| 				fmt.Fprint(w, "helmfile") | ||||
| 			}, | ||||
| 			filepath:  "abc/down.txt", | ||||
| 			wantError: "open .*? no such file or directory", | ||||
| 		}, | ||||
| 	} | ||||
| 	for _, c := range cases { | ||||
| 		t.Run(c.name, func(t *testing.T) { | ||||
| 			dir := t.TempDir() | ||||
| 			downfile := path.Join(dir, "down.txt") | ||||
| 			if c.filepath != "" { | ||||
| 				downfile = path.Join(dir, c.filepath) | ||||
| 			} | ||||
| 
 | ||||
| 			ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 				c.handler(w, r) | ||||
| 			})) | ||||
| 			defer ts.Close() | ||||
| 			url := ts.URL | ||||
| 			if c.url != "" { | ||||
| 				url = c.url | ||||
| 			} | ||||
| 			err := downloadfile(downfile, url) | ||||
| 			if c.wantError != "" { | ||||
| 				if err == nil { | ||||
| 					t.Errorf("download got no error, want error: %v", c.wantError) | ||||
| 				} else if matched, regexErr := regexp.MatchString(c.wantError, err.Error()); regexErr != nil || !matched { | ||||
| 					t.Errorf("download got error: %v, want error: %v", err, c.wantError) | ||||
| 				} | ||||
| 				return | ||||
| 			} | ||||
| 			content, err := os.ReadFile(downfile) | ||||
| 			if err != nil { | ||||
| 				t.Errorf("read download file error: %v", err) | ||||
| 			} | ||||
| 			if string(content) != c.wantContent { | ||||
| 				t.Errorf("download file content got: %v, want content: %v", string(content), c.wantContent) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,30 @@ | |||
| package config | ||||
| 
 | ||||
| // InitOptions is the options for the init command
 | ||||
| type InitOptions struct { | ||||
| 	Force bool | ||||
| } | ||||
| 
 | ||||
| // NewInitOptions creates a new InitOptions
 | ||||
| func NewInitOptions() *InitOptions { | ||||
| 	return &InitOptions{} | ||||
| } | ||||
| 
 | ||||
| // InitImpl is impl for InitOptions
 | ||||
| type InitImpl struct { | ||||
| 	*GlobalImpl | ||||
| 	*InitOptions | ||||
| } | ||||
| 
 | ||||
| // NewInitImpl creates a new InitImpl
 | ||||
| func NewInitImpl(g *GlobalImpl, b *InitOptions) *InitImpl { | ||||
| 	return &InitImpl{ | ||||
| 		GlobalImpl:  g, | ||||
| 		InitOptions: b, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Force returns the Force.
 | ||||
| func (b *InitImpl) Force() bool { | ||||
| 	return b.InitOptions.Force | ||||
| } | ||||
|  | @ -79,7 +79,7 @@ func parseHelmVersion(versionStr string) (semver.Version, error) { | |||
| 	return *ver, nil | ||||
| } | ||||
| 
 | ||||
| func getHelmVersion(helmBinary string, runner Runner) (semver.Version, error) { | ||||
| func GetHelmVersion(helmBinary string, runner Runner) (semver.Version, error) { | ||||
| 	// Autodetect from `helm version`
 | ||||
| 	outBytes, err := runner.Execute(helmBinary, []string{"version", "--client", "--short"}, nil, false) | ||||
| 	if err != nil { | ||||
|  | @ -115,7 +115,7 @@ func redactedURL(chart string) string { | |||
| // nolint: golint
 | ||||
| func New(helmBinary string, enableLiveOutput bool, logger *zap.SugaredLogger, kubeContext string, runner Runner) *execer { | ||||
| 	// TODO: proper error handling
 | ||||
| 	version, err := getHelmVersion(helmBinary, runner) | ||||
| 	version, err := GetHelmVersion(helmBinary, runner) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
|  | @ -521,6 +521,20 @@ func (helm *execer) TestRelease(context HelmContext, name string, flags ...strin | |||
| 	return err | ||||
| } | ||||
| 
 | ||||
| func (helm *execer) AddPlugin(name, path, version string) error { | ||||
| 	helm.logger.Infof("Install helm plugin %v", name) | ||||
| 	out, err := helm.exec([]string{"plugin", "install", path, "--version", version}, map[string]string{}, nil) | ||||
| 	helm.info(out) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| func (helm *execer) UpdatePlugin(name string) error { | ||||
| 	helm.logger.Infof("Update helm plugin %v", name) | ||||
| 	out, err := helm.exec([]string{"plugin", "update", name}, map[string]string{}, nil) | ||||
| 	helm.info(out) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| func (helm *execer) exec(args []string, env map[string]string, overrideEnableLiveOutput *bool) ([]byte, error) { | ||||
| 	cmdargs := args | ||||
| 	if len(helm.extra) > 0 { | ||||
|  |  | |||
|  | @ -0,0 +1,49 @@ | |||
| #!/usr/bin/env bash | ||||
| # vim: set tabstop=4 shiftwidth=4 | ||||
| 
 | ||||
| set -e | ||||
| set -o pipefail | ||||
| 
 | ||||
| # IMPORTS ----------------------------------------------------------------------------------------------------------- | ||||
| 
 | ||||
| # determine working directory to use to relative paths irrespective of starting directory | ||||
| dir="${BASH_SOURCE%/*}" | ||||
| if [[ ! -d "${dir}" ]]; then dir="${PWD}"; fi | ||||
| 
 | ||||
| . "${dir}/../../integration/lib/output.sh" | ||||
| 
 | ||||
| helmfile="./helmfile" | ||||
| helm_dir="${PWD}/${dir}/.helm" | ||||
| helm=`which helm` | ||||
| export HELM_DATA_HOME="${helm_dir}/data" | ||||
| export HELM_HOME="${HELM_DATA_HOME}" | ||||
| export HELM_PLUGINS="${HELM_DATA_HOME}/plugins" | ||||
| export HELM_CONFIG_HOME="${helm_dir}/config" | ||||
| 
 | ||||
| function cleanup() { | ||||
|     set +e | ||||
|     info "Deleting ${helm_dir}" | ||||
|     rm -rf ${helm_dir} # remove helm data so reinstalling plugins does not fail | ||||
| } | ||||
| 
 | ||||
| function removehelm() { | ||||
|   [ -f $helm ] && rm -rf $helm | ||||
| } | ||||
| 
 | ||||
| set -e | ||||
| trap cleanup EXIT | ||||
| 
 | ||||
| removehelm | ||||
| 
 | ||||
| expect <<EOF | ||||
| set timeout -1 | ||||
| spawn ${helmfile} init | ||||
| expect { | ||||
|     "*y/n" {send "y\r";exp_continue} | ||||
|     eof | ||||
| } | ||||
| EOF | ||||
| 
 | ||||
| helm plugin ls | grep diff || fail "helmfile init run fail" | ||||
| 
 | ||||
| all_tests_passed | ||||
		Loading…
	
		Reference in New Issue