diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 7d1a761f8..4c10e23b4 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -177,7 +177,8 @@ func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Instal f.BoolVar(&client.Force, "force", false, "force resource updates through a replacement strategy") f.BoolVar(&client.DisableHooks, "no-hooks", false, "prevent hooks from running during install") f.BoolVar(&client.Replace, "replace", false, "re-use the given name, only if that name is a deleted release which remains in the history. This is unsafe in production") - f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)") + f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation") + f.DurationVar(&client.HookTimeout, "hook-timeout", 300*time.Second, "time to wait for any individual hook") f.BoolVar(&client.Wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout") f.BoolVar(&client.WaitForJobs, "wait-for-jobs", false, "if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout") f.BoolVarP(&client.GenerateName, "generate-name", "g", false, "generate the name (and omit the NAME parameter)") diff --git a/cmd/helm/release_testing.go b/cmd/helm/release_testing.go index 668d30206..c68951425 100644 --- a/cmd/helm/release_testing.go +++ b/cmd/helm/release_testing.go @@ -89,7 +89,8 @@ func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command } f := cmd.Flags() - f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)") + f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation") + f.DurationVar(&client.HookTimeout, "hook-timeout", 300*time.Second, "time to wait for any individual hooks") f.BoolVar(&outputLogs, "logs", false, "dump the logs from test pods (this runs after all tests are complete, but before any cleanup)") f.StringSliceVar(&filter, "filter", []string{}, "specify tests by attribute (currently \"name\") using attribute=value syntax or '!attribute=value' to exclude a test (can specify multiple or separate values with commas: name=test1,name=test2)") diff --git a/cmd/helm/rollback.go b/cmd/helm/rollback.go index ea4b75cb1..7f50be571 100644 --- a/cmd/helm/rollback.go +++ b/cmd/helm/rollback.go @@ -80,7 +80,8 @@ func newRollbackCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.BoolVar(&client.Recreate, "recreate-pods", false, "performs pods restart for the resource if applicable") f.BoolVar(&client.Force, "force", false, "force resource update through delete/recreate if needed") f.BoolVar(&client.DisableHooks, "no-hooks", false, "prevent hooks from running during rollback") - f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)") + f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation") + f.DurationVar(&client.HookTimeout, "hook-timeout", 300*time.Second, "time to wait for any individual hooks") f.BoolVar(&client.Wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout") f.BoolVar(&client.WaitForJobs, "wait-for-jobs", false, "if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout") f.BoolVar(&client.CleanupOnFail, "cleanup-on-fail", false, "allow deletion of new resources created in this rollback when rollback fails") diff --git a/cmd/helm/uninstall.go b/cmd/helm/uninstall.go index 9ced8fef0..32331cbf6 100644 --- a/cmd/helm/uninstall.go +++ b/cmd/helm/uninstall.go @@ -78,7 +78,8 @@ func newUninstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.BoolVar(&client.KeepHistory, "keep-history", false, "remove all associated resources and mark the release as deleted, but retain the release history") f.BoolVar(&client.Wait, "wait", false, "if set, will wait until all the resources are deleted before returning. It will wait for as long as --timeout") f.StringVar(&client.DeletionPropagation, "cascade", "background", "Must be \"background\", \"orphan\", or \"foreground\". Selects the deletion cascading strategy for the dependents. Defaults to background.") - f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)") + f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation") + f.DurationVar(&client.HookTimeout, "hook-timeout", 300*time.Second, "time to wait for any individual hooks") f.StringVar(&client.Description, "description", "", "add a custom description") return cmd diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 1eaa2e350..59887484e 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -248,7 +248,8 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.BoolVar(&client.DisableHooks, "no-hooks", false, "disable pre/post upgrade hooks") f.BoolVar(&client.DisableOpenAPIValidation, "disable-openapi-validation", false, "if set, the upgrade process will not validate rendered templates against the Kubernetes OpenAPI Schema") f.BoolVar(&client.SkipCRDs, "skip-crds", false, "if set, no CRDs will be installed when an upgrade is performed with install flag enabled. By default, CRDs are installed if not already present, when an upgrade is performed with install flag enabled") - f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)") + f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation") + f.DurationVar(&client.HookTimeout, "hook-timeout", 300*time.Second, "time to wait for any individual hooks") f.BoolVar(&client.ResetValues, "reset-values", false, "when upgrading, reset the values to the ones built into the chart") f.BoolVar(&client.ReuseValues, "reuse-values", false, "when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored") f.BoolVar(&client.Wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout") diff --git a/pkg/action/install.go b/pkg/action/install.go index 11fdc4374..14fed3433 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -81,6 +81,7 @@ type Install struct { Devel bool DependencyUpdate bool Timeout time.Duration + HookTimeout time.Duration Namespace string ReleaseName string GenerateName bool @@ -406,7 +407,7 @@ func (i *Install) performInstall(c chan<- resultMessage, rel *release.Release, t // pre-install hooks if !i.DisableHooks { - if err := i.cfg.execHook(rel, release.HookPreInstall, i.Timeout); err != nil { + if err := i.cfg.execHook(rel, release.HookPreInstall, i.HookTimeout); err != nil { i.reportToRun(c, rel, fmt.Errorf("failed pre-install: %s", err)) return } @@ -442,7 +443,7 @@ func (i *Install) performInstall(c chan<- resultMessage, rel *release.Release, t } if !i.DisableHooks { - if err := i.cfg.execHook(rel, release.HookPostInstall, i.Timeout); err != nil { + if err := i.cfg.execHook(rel, release.HookPostInstall, i.HookTimeout); err != nil { i.reportToRun(c, rel, fmt.Errorf("failed post-install: %s", err)) return } diff --git a/pkg/action/release_testing.go b/pkg/action/release_testing.go index 3522a0c98..a108afba5 100644 --- a/pkg/action/release_testing.go +++ b/pkg/action/release_testing.go @@ -38,8 +38,9 @@ const ( // // It provides the implementation of 'helm test'. type ReleaseTesting struct { - cfg *Configuration - Timeout time.Duration + cfg *Configuration + Timeout time.Duration + HookTimeout time.Duration // Used for fetching logs from test pods Namespace string Filters map[string][]string @@ -93,7 +94,7 @@ func (r *ReleaseTesting) Run(name string) (*release.Release, error) { rel.Hooks = executingHooks } - if err := r.cfg.execHook(rel, release.HookTest, r.Timeout); err != nil { + if err := r.cfg.execHook(rel, release.HookTest, r.HookTimeout); err != nil { rel.Hooks = append(skippedHooks, rel.Hooks...) r.cfg.Releases.Update(rel) return rel, err diff --git a/pkg/action/rollback.go b/pkg/action/rollback.go index dda8c700b..2eea926db 100644 --- a/pkg/action/rollback.go +++ b/pkg/action/rollback.go @@ -37,6 +37,7 @@ type Rollback struct { Version int Timeout time.Duration + HookTimeout time.Duration Wait bool WaitForJobs bool DisableHooks bool @@ -157,7 +158,7 @@ func (r *Rollback) performRollback(currentRelease, targetRelease *release.Releas // pre-rollback hooks if !r.DisableHooks { - if err := r.cfg.execHook(targetRelease, release.HookPreRollback, r.Timeout); err != nil { + if err := r.cfg.execHook(targetRelease, release.HookPreRollback, r.HookTimeout); err != nil { return targetRelease, err } } else { @@ -224,7 +225,7 @@ func (r *Rollback) performRollback(currentRelease, targetRelease *release.Releas // post-rollback hooks if !r.DisableHooks { - if err := r.cfg.execHook(targetRelease, release.HookPostRollback, r.Timeout); err != nil { + if err := r.cfg.execHook(targetRelease, release.HookPostRollback, r.HookTimeout); err != nil { return targetRelease, err } } diff --git a/pkg/action/uninstall.go b/pkg/action/uninstall.go index 40d82243e..a9868ecfd 100644 --- a/pkg/action/uninstall.go +++ b/pkg/action/uninstall.go @@ -44,6 +44,7 @@ type Uninstall struct { Wait bool DeletionPropagation string Timeout time.Duration + HookTimeout time.Duration Description string } @@ -106,7 +107,7 @@ func (u *Uninstall) Run(name string) (*release.UninstallReleaseResponse, error) res := &release.UninstallReleaseResponse{Release: rel} if !u.DisableHooks { - if err := u.cfg.execHook(rel, release.HookPreDelete, u.Timeout); err != nil { + if err := u.cfg.execHook(rel, release.HookPreDelete, u.HookTimeout); err != nil { return res, err } } else { @@ -139,7 +140,7 @@ func (u *Uninstall) Run(name string) (*release.UninstallReleaseResponse, error) } if !u.DisableHooks { - if err := u.cfg.execHook(rel, release.HookPostDelete, u.Timeout); err != nil { + if err := u.cfg.execHook(rel, release.HookPostDelete, u.HookTimeout); err != nil { errs = append(errs, err) } } diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index ebe3dd2ee..866b634cd 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -64,6 +64,8 @@ type Upgrade struct { SkipCRDs bool // Timeout is the timeout for this operation Timeout time.Duration + // HookTimeout is the timeout for any hooks in this operation + HookTimeout time.Duration // Wait determines whether the wait operation should be performed after the upgrade is requested. Wait bool // WaitForJobs determines whether the wait operation for the Jobs should be performed after the upgrade is requested. @@ -391,7 +393,7 @@ func (u *Upgrade) releasingUpgrade(c chan<- resultMessage, upgradedRelease *rele // pre-upgrade hooks if !u.DisableHooks { - if err := u.cfg.execHook(upgradedRelease, release.HookPreUpgrade, u.Timeout); err != nil { + if err := u.cfg.execHook(upgradedRelease, release.HookPreUpgrade, u.HookTimeout); err != nil { u.reportToPerformUpgrade(c, upgradedRelease, kube.ResourceList{}, fmt.Errorf("pre-upgrade hooks failed: %s", err)) return } @@ -437,7 +439,7 @@ func (u *Upgrade) releasingUpgrade(c chan<- resultMessage, upgradedRelease *rele // post-upgrade hooks if !u.DisableHooks { - if err := u.cfg.execHook(upgradedRelease, release.HookPostUpgrade, u.Timeout); err != nil { + if err := u.cfg.execHook(upgradedRelease, release.HookPostUpgrade, u.HookTimeout); err != nil { u.reportToPerformUpgrade(c, upgradedRelease, results.Created, fmt.Errorf("post-upgrade hooks failed: %s", err)) return }