add --skip-charts for destroy for disable prepare charts (#637)

* add --skip-charts for destroy for disable prepare charts

Signed-off-by: yxxhero <aiopsclub@163.com>

* add --skip-charts for delete subcmd

Signed-off-by: yxxhero <aiopsclub@163.com>

* add docs and e2e test

Signed-off-by: yxxhero <aiopsclub@163.com>

Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
yxxhero 2023-01-21 10:54:59 +08:00 committed by GitHub
parent f3a24dd99a
commit 1664edd0b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 63 additions and 20 deletions

View File

@ -36,6 +36,7 @@ func NewDeleteCmd(globalCfg *config.GlobalImpl) *cobra.Command {
f.IntVar(&deleteOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") f.IntVar(&deleteOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited")
f.BoolVar(&deleteOptions.Purge, "purge", false, "purge releases i.e. free release names and histories") f.BoolVar(&deleteOptions.Purge, "purge", false, "purge releases i.e. free release names and histories")
f.BoolVar(&deleteOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) f.BoolVar(&deleteOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`)
f.BoolVar(&deleteOptions.SkipCharts, "skip-charts", false, "don't prepare charts when deleting releases")
return cmd return cmd
} }

View File

@ -34,6 +34,7 @@ func NewDestroyCmd(globalCfg *config.GlobalImpl) *cobra.Command {
f.StringVar(&globalCfg.GlobalOptions.Args, "args", "", "pass args to helm exec") f.StringVar(&globalCfg.GlobalOptions.Args, "args", "", "pass args to helm exec")
f.IntVar(&destroyOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") f.IntVar(&destroyOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited")
f.BoolVar(&destroyOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) f.BoolVar(&destroyOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`)
f.BoolVar(&destroyOptions.SkipCharts, "skip-charts", false, "don't prepare charts when destroying releases")
return cmd return cmd
} }

View File

@ -605,6 +605,7 @@ The `helmfile destroy` sub-command uninstalls and purges all the releases define
`helmfile --interactive destroy` instructs Helmfile to request your confirmation before actually deleting releases. `helmfile --interactive destroy` instructs Helmfile to request your confirmation before actually deleting releases.
`destroy` basically runs `helm uninstall --purge` on all the targeted releases. If you don't want purging, use `helmfile delete` instead. `destroy` basically runs `helm uninstall --purge` on all the targeted releases. If you don't want purging, use `helmfile delete` instead.
If `--skip-charts` flag is not set, destory would prepare all releases, by fetching charts and templating them.
### delete (DEPRECATED) ### delete (DEPRECATED)
@ -613,6 +614,7 @@ The `helmfile delete` sub-command deletes all the releases defined in the manife
`helmfile --interactive delete` instructs Helmfile to request your confirmation before actually deleting releases. `helmfile --interactive delete` instructs Helmfile to request your confirmation before actually deleting releases.
Note that `delete` doesn't purge releases. So `helmfile delete && helmfile sync` results in sync failed due to that releases names are not deleted but preserved for future references. If you really want to remove releases for reuse, add `--purge` flag to run it like `helmfile delete --purge`. Note that `delete` doesn't purge releases. So `helmfile delete && helmfile sync` results in sync failed due to that releases names are not deleted but preserved for future references. If you really want to remove releases for reuse, add `--purge` flag to run it like `helmfile delete --purge`.
If `--skip-charts` flag is not set, destory would prepare all releases, by fetching charts and templating them.
### secrets ### secrets

View File

@ -455,36 +455,41 @@ func (a *App) Status(c StatusesConfigProvider) error {
// TODO: Remove this function once Helmfile v0.x // TODO: Remove this function once Helmfile v0.x
func (a *App) Delete(c DeleteConfigProvider) error { func (a *App) Delete(c DeleteConfigProvider) error {
return a.ForEachState(func(run *Run) (ok bool, errs []error) { return a.ForEachState(func(run *Run) (ok bool, errs []error) {
err := run.withPreparedCharts("delete", state.ChartPrepareOptions{ if !c.SkipCharts() {
SkipRepos: c.SkipDeps(), err := run.withPreparedCharts("delete", state.ChartPrepareOptions{
SkipDeps: c.SkipDeps(), SkipRepos: c.SkipDeps(),
Concurrency: c.Concurrency(), SkipDeps: c.SkipDeps(),
}, func() { Concurrency: c.Concurrency(),
}, func() {
ok, errs = a.delete(run, c.Purge(), c)
})
if err != nil {
errs = append(errs, err)
}
} else {
ok, errs = a.delete(run, c.Purge(), c) ok, errs = a.delete(run, c.Purge(), c)
})
if err != nil {
errs = append(errs, err)
} }
return return
}, false, SetReverse(true)) }, false, SetReverse(true))
} }
func (a *App) Destroy(c DestroyConfigProvider) error { func (a *App) Destroy(c DestroyConfigProvider) error {
return a.ForEachState(func(run *Run) (ok bool, errs []error) { return a.ForEachState(func(run *Run) (ok bool, errs []error) {
err := run.withPreparedCharts("destroy", state.ChartPrepareOptions{ if !c.SkipCharts() {
SkipRepos: c.SkipDeps(), err := run.withPreparedCharts("destroy", state.ChartPrepareOptions{
SkipDeps: c.SkipDeps(), SkipRepos: c.SkipDeps(),
Concurrency: c.Concurrency(), SkipDeps: c.SkipDeps(),
}, func() { Concurrency: c.Concurrency(),
}, func() {
ok, errs = a.delete(run, true, c)
})
if err != nil {
errs = append(errs, err)
}
} else {
ok, errs = a.delete(run, true, c) ok, errs = a.delete(run, true, c)
})
if err != nil {
errs = append(errs, err)
} }
return return
}, false, SetReverse(true)) }, false, SetReverse(true))
} }

View File

@ -142,6 +142,7 @@ type DeleteConfigProvider interface {
Purge() bool Purge() bool
SkipDeps() bool SkipDeps() bool
SkipCharts() bool
interactive interactive
loggingConfig loggingConfig
@ -152,6 +153,7 @@ type DestroyConfigProvider interface {
Args() string Args() string
SkipDeps() bool SkipDeps() bool
SkipCharts() bool
interactive interactive
loggingConfig loggingConfig

View File

@ -39,12 +39,17 @@ type destroyConfig struct {
skipDeps bool skipDeps bool
logger *zap.SugaredLogger logger *zap.SugaredLogger
includeTransitiveNeeds bool includeTransitiveNeeds bool
skipCharts bool
} }
func (d destroyConfig) Args() string { func (d destroyConfig) Args() string {
return d.args return d.args
} }
func (d destroyConfig) SkipCharts() bool {
return d.skipCharts
}
func (d destroyConfig) Interactive() bool { func (d destroyConfig) Interactive() bool {
return d.interactive return d.interactive
} }

View File

@ -9,6 +9,8 @@ type DeleteOptions struct {
Purge bool Purge bool
// SkipDeps is the skip deps flag // SkipDeps is the skip deps flag
SkipDeps bool SkipDeps bool
// SkipCharts makes Delete skip `withPreparedCharts`
SkipCharts bool
} }
// NewDeleteOptions creates a new Apply // NewDeleteOptions creates a new Apply
@ -44,3 +46,8 @@ func (c *DeleteImpl) Purge() bool {
func (c *DeleteImpl) SkipDeps() bool { func (c *DeleteImpl) SkipDeps() bool {
return c.DeleteOptions.SkipDeps return c.DeleteOptions.SkipDeps
} }
// SkipCharts returns skipCharts flag
func (c *DeleteImpl) SkipCharts() bool {
return c.DeleteOptions.SkipCharts
}

View File

@ -6,6 +6,8 @@ type DestroyOptions struct {
Concurrency int Concurrency int
// SkipDeps is the skip deps flag // SkipDeps is the skip deps flag
SkipDeps bool SkipDeps bool
// SkipCharts makes Destroy skip `withPreparedCharts`
SkipCharts bool
} }
// NewDestroyOptions creates a new Apply // NewDestroyOptions creates a new Apply
@ -36,3 +38,8 @@ func (c *DestroyImpl) Concurrency() int {
func (c *DestroyImpl) SkipDeps() bool { func (c *DestroyImpl) SkipDeps() bool {
return c.DestroyOptions.SkipDeps return c.DestroyOptions.SkipDeps
} }
// SkipCharts returns skipCharts flag
func (c *DestroyImpl) SkipCharts() bool {
return c.DestroyOptions.SkipCharts
}

View File

@ -70,6 +70,19 @@ ${helm} status --namespace=${test_ns} httpbin &> /dev/null && fail "release shou
info "Ensuring \"helmfile destroy\" doesn't fail when no releases installed" info "Ensuring \"helmfile destroy\" doesn't fail when no releases installed"
${helmfile} -f ${happypath_case_input_dir}/${config_file} destroy || fail "\"helmfile delete\" shouldn't fail when there are no installed releases" ${helmfile} -f ${happypath_case_input_dir}/${config_file} destroy || fail "\"helmfile delete\" shouldn't fail when there are no installed releases"
info "Re-applying ${happypath_case_input_dir}/${config_file} with locked dependencies"
${helmfile} -f ${happypath_case_input_dir}/${config_file} apply
code=$?
[ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile apply: ${code}"
${helm} list --namespace=${test_ns} || fail "unable to list releases"
info "Deleting release with --skip-charts"
${helmfile} -f ${happypath_case_input_dir}/${config_file} destroy --skip-charts
${helm} status --namespace=${test_ns} httpbin &> /dev/null && fail "release should not exist anymore after a delete"
info "Ensuring \"helmfile destroy --skip-charts\" doesn't fail when no releases installed"
${helmfile} -f ${happypath_case_input_dir}/${config_file} destroy --skip-charts || fail "\"helmfile delete\" shouldn't fail when there are no installed releases"
info "Ensuring \"helmfile template\" output does contain only YAML docs" info "Ensuring \"helmfile template\" output does contain only YAML docs"
(${helmfile} -f ${happypath_case_input_dir}/${config_file} template | kubectl apply -f -) || fail "\"helmfile template | kubectl apply -f -\" shouldn't fail" (${helmfile} -f ${happypath_case_input_dir}/${config_file} template | kubectl apply -f -) || fail "\"helmfile template | kubectl apply -f -\" shouldn't fail"