From 53c6d2f9884c29eb69302f84e9e09d51bbdee982 Mon Sep 17 00:00:00 2001 From: Quan TRAN Date: Tue, 30 Mar 2021 09:26:31 +0200 Subject: [PATCH] Add helmfile-fetch command to downloading and generating charts (#1734) --- main.go | 30 ++++++++++++++++++++++++++++++ pkg/app/app.go | 18 ++++++++++++++++++ pkg/app/config.go | 7 +++++++ pkg/app/run.go | 26 +++++++++++++++++--------- pkg/state/state.go | 1 + pkg/state/temp_test.go | 3 ++- 6 files changed, 75 insertions(+), 10 deletions(-) diff --git a/main.go b/main.go index 2ea7c1f8..8d588633 100644 --- a/main.go +++ b/main.go @@ -327,6 +327,28 @@ func main() { return run.Lint(c) }), }, + { + Name: "fetch", + Usage: "fetch charts from state file", + Flags: []cli.Flag{ + cli.IntFlag{ + Name: "concurrency", + Value: 0, + Usage: "maximum number of concurrent downloads of release charts", + }, + cli.BoolFlag{ + Name: "skip-deps", + Usage: `skip running "helm repo update" and "helm dependency build"`, + }, + cli.StringFlag{ + Name: "output-dir", + Usage: "directory to store charts (default: temporary directory which is deleted when the command terminates)", + }, + }, + Action: action(func(a *app.App, c configImpl) error { + return a.Fetch(c) + }), + }, { Name: "sync", Usage: "sync all resources from state file (repos, releases and chart deps)", @@ -553,6 +575,10 @@ func main() { Value: "", Usage: "output releases list as a json string", }, + cli.BoolFlag{ + Name: "keep-temp-dir", + Usage: "Keep temporary directory", + }, }, Action: action(func(run *app.App, c configImpl) error { return run.ListReleases(c) @@ -720,6 +746,10 @@ func (c configImpl) Output() string { return c.c.String("output") } +func (c configImpl) KeepTempDir() bool { + return c.c.Bool("keep-temp-dir") +} + // GlobalConfig func (c configImpl) HelmBinary() string { diff --git a/pkg/app/app.go b/pkg/app/app.go index 8a78c9c3..70cc2541 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -291,6 +291,24 @@ func (a *App) Lint(c LintConfigProvider) error { }, SetFilter(true)) } +func (a *App) Fetch(c FetchConfigProvider) error { + return a.ForEachState(func(run *Run) (ok bool, errs []error) { + prepErr := run.withPreparedCharts("pull", state.ChartPrepareOptions{ + ForceDownload: true, + SkipRepos: c.SkipDeps(), + SkipDeps: c.SkipDeps(), + OutputDir: c.OutputDir(), + }, func() { + }) + + if prepErr != nil { + errs = append(errs, prepErr) + } + + return + }, SetFilter(true)) +} + func (a *App) Sync(c SyncConfigProvider) error { return a.ForEachState(func(run *Run) (ok bool, errs []error) { prepErr := run.withPreparedCharts("sync", state.ChartPrepareOptions{ diff --git a/pkg/app/config.go b/pkg/app/config.go index edfa4610..db348af5 100644 --- a/pkg/app/config.go +++ b/pkg/app/config.go @@ -131,6 +131,13 @@ type LintConfigProvider interface { concurrencyConfig } +type FetchConfigProvider interface { + SkipDeps() bool + OutputDir() string + + concurrencyConfig +} + type TemplateConfigProvider interface { Args() string diff --git a/pkg/app/run.go b/pkg/app/run.go index 221ba098..a293148a 100644 --- a/pkg/app/run.go +++ b/pkg/app/run.go @@ -2,13 +2,14 @@ package app import ( "fmt" - "github.com/roboll/helmfile/pkg/argparser" - "github.com/roboll/helmfile/pkg/helmexec" - "github.com/roboll/helmfile/pkg/state" "io/ioutil" "os" "sort" "strings" + + "github.com/roboll/helmfile/pkg/argparser" + "github.com/roboll/helmfile/pkg/helmexec" + "github.com/roboll/helmfile/pkg/state" ) type Run struct { @@ -49,13 +50,20 @@ func (r *Run) withPreparedCharts(helmfileCommand string, opts state.ChartPrepare } // Create tmp directory and bail immediately if it fails - dir, err := ioutil.TempDir("", "") - if err != nil { - return err + var dir string + if len(opts.OutputDir) == 0 { + tempDir, err := ioutil.TempDir("", "helmfile*") + if err != nil { + return err + } + defer os.RemoveAll(tempDir) + dir = tempDir + } else { + dir = opts.OutputDir + fmt.Printf("Charts will be downloaded to: %s\n", dir) } - defer os.RemoveAll(dir) - if _, err = r.state.TriggerGlobalPrepareEvent(helmfileCommand); err != nil { + if _, err := r.state.TriggerGlobalPrepareEvent(helmfileCommand); err != nil { return err } @@ -82,7 +90,7 @@ func (r *Run) withPreparedCharts(helmfileCommand string, opts state.ChartPrepare f() - _, err = r.state.TriggerGlobalCleanupEvent(helmfileCommand) + _, err := r.state.TriggerGlobalCleanupEvent(helmfileCommand) return err } diff --git a/pkg/state/state.go b/pkg/state/state.go index 491ab549..a8839a81 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -896,6 +896,7 @@ type ChartPrepareOptions struct { SkipResolve bool Wait bool WaitForJobs bool + OutputDir string } type chartPrepareResult struct { diff --git a/pkg/state/temp_test.go b/pkg/state/temp_test.go index c19f5622..ffb609b5 100644 --- a/pkg/state/temp_test.go +++ b/pkg/state/temp_test.go @@ -1,8 +1,9 @@ package state import ( - "github.com/google/go-cmp/cmp" "testing" + + "github.com/google/go-cmp/cmp" ) func TestGenerateID(t *testing.T) {