From a161796dc4455845c6049669669a52b1e2f0b83e Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Tue, 6 Apr 2021 12:20:41 +0800 Subject: [PATCH] feat: Allow overriding chart via flag (#1751) Adds `--chart` flag for overriding the selected release's chart ad-hoc-ly like `helmfile --chart $CHART template`. This is handy when e.g. you want to have an ArgoCD application per each release in your helmfile.yaml, while also providing the ability to customize the release's chart without touching helmfile.yaml. See https://github.com/roboll/helmfile/issues/1690#issuecomment-812321354 for more context. Closes #1690 --- main.go | 8 ++++++++ pkg/app/app.go | 3 +++ pkg/app/config.go | 1 + pkg/app/desired_state_file_loader.go | 8 ++++++++ pkg/app/two_pass_renderer.go | 3 ++- pkg/event/bus.go | 1 + pkg/state/state.go | 6 ++++++ pkg/state/state_exec_tmpl.go | 1 + pkg/state/types.go | 4 ++++ 9 files changed, 34 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index a708e4b9..abd4e0f3 100644 --- a/main.go +++ b/main.go @@ -89,6 +89,10 @@ func main() { Name: "namespace, n", Usage: "Set namespace. Uses the namespace set in the context by default, and is available in templates as {{ .Namespace }}", }, + cli.StringFlag{ + Name: "chart, c", + Usage: "Set chart. Uses the chart set in release by default, and is available in template as {{ .Chart }}", + }, cli.StringSliceFlag{ Name: "selector, l", Usage: `Only run using the releases that match labels. Labels can take the form of foo=bar or foo!=bar. @@ -776,6 +780,10 @@ func (c configImpl) Namespace() string { return c.c.GlobalString("namespace") } +func (c configImpl) Chart() string { + return c.c.GlobalString("chart") +} + func (c configImpl) FileOrDir() string { return c.c.GlobalString("file") } diff --git a/pkg/app/app.go b/pkg/app/app.go index 70cc2541..a8e5e996 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -30,6 +30,7 @@ type App struct { Logger *zap.SugaredLogger Env string Namespace string + Chart string Selectors []string Args string ValuesFiles []string @@ -72,6 +73,7 @@ func New(conf ConfigProvider) *App { Logger: conf.Logger(), Env: conf.Env(), Namespace: conf.Namespace(), + Chart: conf.Chart(), Selectors: conf.Selectors(), Args: conf.Args(), FileOrDir: conf.FileOrDir(), @@ -640,6 +642,7 @@ func (a *App) loadDesiredStateFromYaml(file string, opts ...LoadOpts) (*state.He directoryExistsAt: a.directoryExistsAt, env: a.Env, namespace: a.Namespace, + chart: a.Chart, logger: a.Logger, abs: a.abs, remote: a.remote, diff --git a/pkg/app/config.go b/pkg/app/config.go index 2bbe2409..2915432c 100644 --- a/pkg/app/config.go +++ b/pkg/app/config.go @@ -9,6 +9,7 @@ type ConfigProvider interface { FileOrDir() string KubeContext() string Namespace() string + Chart() string Selectors() []string StateValuesSet() map[string]interface{} StateValuesFiles() []string diff --git a/pkg/app/desired_state_file_loader.go b/pkg/app/desired_state_file_loader.go index c106d80d..14445d4a 100644 --- a/pkg/app/desired_state_file_loader.go +++ b/pkg/app/desired_state_file_loader.go @@ -25,6 +25,7 @@ type desiredStateLoader struct { env string namespace string + chart string readFile func(string) ([]byte, error) deleteFile func(string) error @@ -82,6 +83,13 @@ func (ld *desiredStateLoader) Load(f string, opts LoadOpts) (*state.HelmState, e st.OverrideNamespace = ld.namespace } + if ld.chart != "" { + if st.OverrideChart != "" { + return nil, errors.New("err: Cannot use option --chart and set attribute chart.") + } + st.OverrideChart = ld.chart + } + return st, nil } diff --git a/pkg/app/two_pass_renderer.go b/pkg/app/two_pass_renderer.go index 2b927ec4..a8715474 100644 --- a/pkg/app/two_pass_renderer.go +++ b/pkg/app/two_pass_renderer.go @@ -3,11 +3,12 @@ package app import ( "bytes" "fmt" + "strings" + "github.com/google/go-cmp/cmp" "github.com/roboll/helmfile/pkg/environment" "github.com/roboll/helmfile/pkg/state" "github.com/roboll/helmfile/pkg/tmpl" - "strings" ) func prependLineNumbers(text string) string { diff --git a/pkg/event/bus.go b/pkg/event/bus.go index b52b815a..2b58581e 100644 --- a/pkg/event/bus.go +++ b/pkg/event/bus.go @@ -32,6 +32,7 @@ type Bus struct { BasePath string StateFilePath string Namespace string + Chart string Env environment.Environment diff --git a/pkg/state/state.go b/pkg/state/state.go index 066832fe..ba0e5656 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -54,6 +54,7 @@ type ReleaseSetSpec struct { DeprecatedContext string `yaml:"context,omitempty"` DeprecatedReleases []ReleaseSpec `yaml:"charts,omitempty"` OverrideNamespace string `yaml:"namespace,omitempty"` + OverrideChart string `yaml:"chart,omitempty"` Repositories []RepositorySpec `yaml:"repositories,omitempty"` CommonLabels map[string]string `yaml:"commonLabels,omitempty"` Releases []ReleaseSpec `yaml:"releases,omitempty"` @@ -999,6 +1000,9 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre }, func(workerIndex int) { for release := range jobQueue { + if st.OverrideChart != "" { + release.Chart = st.OverrideChart + } // Call user-defined `prepare` hooks to create/modify local charts to be used by // the later process. // @@ -2062,6 +2066,7 @@ func (st *HelmState) triggerGlobalReleaseEvent(evt string, evtErr error, helmfil StateFilePath: st.FilePath, BasePath: st.basePath, Namespace: st.OverrideNamespace, + Chart: st.OverrideChart, Env: st.Env, Logger: st.logger, ReadFile: st.readFile, @@ -2094,6 +2099,7 @@ func (st *HelmState) triggerReleaseEvent(evt string, evtErr error, r *ReleaseSpe StateFilePath: st.FilePath, BasePath: st.basePath, Namespace: st.OverrideNamespace, + Chart: st.OverrideChart, Env: st.Env, Logger: st.logger, ReadFile: st.readFile, diff --git a/pkg/state/state_exec_tmpl.go b/pkg/state/state_exec_tmpl.go index 023287f5..01ea35bc 100644 --- a/pkg/state/state_exec_tmpl.go +++ b/pkg/state/state_exec_tmpl.go @@ -20,6 +20,7 @@ func (st *HelmState) createReleaseTemplateData(release *ReleaseSpec, vals map[st tmplData := releaseTemplateData{ Environment: st.Env, Namespace: st.OverrideNamespace, + Chart: st.OverrideChart, Values: vals, Release: releaseTemplateDataRelease{ Name: release.Name, diff --git a/pkg/state/types.go b/pkg/state/types.go index 9e28c840..a8c094ff 100644 --- a/pkg/state/types.go +++ b/pkg/state/types.go @@ -34,6 +34,10 @@ type releaseTemplateData struct { // You should better use Release.Namespace as it might work as you'd expect even if OverrideNamespace is not set. // See releaseTemplateDataRelease.Namespace for more information. Namespace string + // Chart is HelmState.OverrideChart. + // You should better use Release.Chart as it might work as you'd expect even if OverrideChart is not set. + // See releaseTemplateDataRelease.Chart for more information. + Chart string } type releaseTemplateDataRelease struct {