fix(cmd): print progress at resource wait boundary

Signed-off-by: Karthik Chowdary <21139050+Karthik-Chowdary@users.noreply.github.com>
pull/32549/head
Karthik Chowdary 2 weeks ago
parent 1c632eee59
commit 6a1a3d092f

@ -100,12 +100,14 @@ type Install struct {
Devel bool Devel bool
DependencyUpdate bool DependencyUpdate bool
Timeout time.Duration Timeout time.Duration
Namespace string // WaitProgress is called immediately before waiting for resources.
ReleaseName string WaitProgress func(time.Duration)
GenerateName bool Namespace string
NameTemplate string ReleaseName string
Description string GenerateName bool
OutputDir string NameTemplate string
Description string
OutputDir string
// RollbackOnFailure enables rolling back (uninstalling) the release on failure if set // RollbackOnFailure enables rolling back (uninstalling) the release on failure if set
RollbackOnFailure bool RollbackOnFailure bool
SkipCRDs bool SkipCRDs bool
@ -543,6 +545,10 @@ func (i *Install) performInstall(rel *release.Release, toBeAdopted kube.Resource
return rel, fmt.Errorf("failed to get waiter: %w", err) return rel, fmt.Errorf("failed to get waiter: %w", err)
} }
if i.WaitProgress != nil {
i.WaitProgress(i.Timeout)
}
if i.WaitForJobs { if i.WaitForJobs {
err = waiter.WaitWithJobs(resources, i.Timeout) err = waiter.WaitWithJobs(resources, i.Timeout)
} else { } else {

@ -76,6 +76,8 @@ type Upgrade struct {
WaitOptions []kube.WaitOption WaitOptions []kube.WaitOption
// WaitForJobs determines whether the wait operation for the Jobs should be performed after the upgrade is requested. // WaitForJobs determines whether the wait operation for the Jobs should be performed after the upgrade is requested.
WaitForJobs bool WaitForJobs bool
// WaitProgress is called immediately before waiting for resources.
WaitProgress func(time.Duration)
// DisableHooks disables hook processing if set to true. // DisableHooks disables hook processing if set to true.
DisableHooks bool DisableHooks bool
// DryRunStrategy can be set to prepare, but not execute the operation and whether or not to interact with the remote cluster // DryRunStrategy can be set to prepare, but not execute the operation and whether or not to interact with the remote cluster
@ -489,6 +491,10 @@ func (u *Upgrade) releasingUpgrade(c chan<- resultMessage, upgradedRelease *rele
u.reportToPerformUpgrade(c, upgradedRelease, results.Created, err) u.reportToPerformUpgrade(c, upgradedRelease, results.Created, err)
return return
} }
if u.WaitProgress != nil {
u.WaitProgress(u.Timeout)
}
if u.WaitForJobs { if u.WaitForJobs {
if err := waiter.WaitWithJobs(target, u.Timeout); err != nil { if err := waiter.WaitWithJobs(target, u.Timeout); err != nil {
u.cfg.recordRelease(originalRelease) u.cfg.recordRelease(originalRelease)

@ -158,7 +158,7 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
} }
client.DryRunStrategy = dryRunStrategy client.DryRunStrategy = dryRunStrategy
printWaitMessage(out, outfmt, client.WaitStrategy, client.RollbackOnFailure, client.DryRunStrategy, client.Timeout) configureWaitProgress(client, out, outfmt)
rel, err := runInstall(args, client, valueOpts, out) rel, err := runInstall(args, client, valueOpts, out)
if err != nil { if err != nil {
@ -373,9 +373,19 @@ func checkIfInstallable(ch chart.Accessor) error {
return fmt.Errorf("%s charts are not installable", meta["Type"]) return fmt.Errorf("%s charts are not installable", meta["Type"])
} }
func configureWaitProgress(client *action.Install, out io.Writer, outfmt output.Format) {
if outfmt != output.Table || client.DryRunStrategy != action.DryRunNone {
return
}
if client.WaitStrategy == kube.HookOnlyStrategy && !client.RollbackOnFailure {
return
}
client.WaitProgress = func(timeout time.Duration) {
printWaitMessage(out, outfmt, kube.StatusWatcherStrategy, false, action.DryRunNone, timeout)
}
}
func printWaitMessage(out io.Writer, outfmt output.Format, strategy kube.WaitStrategy, rollbackOnFailure bool, dryRun action.DryRunStrategy, timeout time.Duration) { func printWaitMessage(out io.Writer, outfmt output.Format, strategy kube.WaitStrategy, rollbackOnFailure bool, dryRun action.DryRunStrategy, timeout time.Duration) {
// Rollback-on-failure implicitly enables watcher waits in the action layer.
// Account for that here, before the action mutates its WaitStrategy.
if strategy == kube.HookOnlyStrategy && rollbackOnFailure { if strategy == kube.HookOnlyStrategy && rollbackOnFailure {
strategy = kube.StatusWatcherStrategy strategy = kube.StatusWatcherStrategy
} }

@ -38,6 +38,7 @@ import (
"helm.sh/helm/v4/pkg/cmd/require" "helm.sh/helm/v4/pkg/cmd/require"
"helm.sh/helm/v4/pkg/downloader" "helm.sh/helm/v4/pkg/downloader"
"helm.sh/helm/v4/pkg/getter" "helm.sh/helm/v4/pkg/getter"
"helm.sh/helm/v4/pkg/kube"
ri "helm.sh/helm/v4/pkg/release" ri "helm.sh/helm/v4/pkg/release"
"helm.sh/helm/v4/pkg/release/common" "helm.sh/helm/v4/pkg/release/common"
"helm.sh/helm/v4/pkg/storage/driver" "helm.sh/helm/v4/pkg/storage/driver"
@ -82,6 +83,18 @@ which can contain sensitive values. To hide Kubernetes Secrets use the
--hide-secret flag. Please carefully consider how and when these flags are used. --hide-secret flag. Please carefully consider how and when these flags are used.
` `
func configureUpgradeWaitProgress(client *action.Upgrade, out io.Writer, outfmt output.Format) {
if outfmt != output.Table || client.DryRunStrategy != action.DryRunNone {
return
}
if client.WaitStrategy == kube.HookOnlyStrategy && !client.RollbackOnFailure {
return
}
client.WaitProgress = func(timeout time.Duration) {
printWaitMessage(out, outfmt, kube.StatusWatcherStrategy, false, action.DryRunNone, timeout)
}
}
func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
client := action.NewUpgrade(cfg) client := action.NewUpgrade(cfg)
client.WaitOptions = append(client.WaitOptions, defaultCLIWaitOptions()...) client.WaitOptions = append(client.WaitOptions, defaultCLIWaitOptions()...)
@ -163,7 +176,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
instClient.Replace = true instClient.Replace = true
} }
printWaitMessage(out, outfmt, instClient.WaitStrategy, instClient.RollbackOnFailure, instClient.DryRunStrategy, instClient.Timeout) configureWaitProgress(instClient, out, outfmt)
rel, err := runInstall(args, instClient, valueOpts, out) rel, err := runInstall(args, instClient, valueOpts, out)
if err != nil { if err != nil {
@ -259,7 +272,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
cancel() cancel()
}() }()
printWaitMessage(out, outfmt, client.WaitStrategy, client.RollbackOnFailure, client.DryRunStrategy, client.Timeout) configureUpgradeWaitProgress(client, out, outfmt)
rel, err := client.RunWithContext(ctx, args[0], ch, vals) rel, err := client.RunWithContext(ctx, args[0], ch, vals)
if err != nil { if err != nil {

Loading…
Cancel
Save