Skip to content

Commit ecc9d2d

Browse files
committed
support timeout in helm calls #4102
1 parent 0ccdc4e commit ecc9d2d

File tree

4 files changed

+42
-6
lines changed

4 files changed

+42
-6
lines changed

internal/cmd/helm-operator/run/cmd.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,13 @@ func run(cmd *cobra.Command, f *flags.Flags) {
145145
for _, w := range ws {
146146
// Register the controller with the factory.
147147
err := controller.Add(mgr, controller.WatchOptions{
148-
Namespace: namespace,
149-
GVK: w.GroupVersionKind,
150-
ManagerFactory: release.NewManagerFactory(mgr, w.ChartDir),
148+
Namespace: namespace,
149+
GVK: w.GroupVersionKind,
150+
ManagerFactory: release.NewManagerFactory(release.ManagerFactoryOptions{
151+
ChartDir: w.ChartDir,
152+
CRManager: mgr,
153+
Timeout: f.Timeout,
154+
}),
151155
ReconcilePeriod: f.ReconcilePeriod,
152156
WatchDependentResources: *w.WatchDependentResources,
153157
OverrideValues: w.OverrideValues,

internal/helm/flags/flag.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package flags
1616

1717
import (
18+
"flag"
1819
"runtime"
1920
"time"
2021

@@ -24,6 +25,7 @@ import (
2425
// Flags - Options to be used by a helm operator
2526
type Flags struct {
2627
ReconcilePeriod time.Duration
28+
Timeout time.Duration
2729
WatchesFile string
2830
MetricsAddress string
2931
EnableLeaderElection bool
@@ -34,6 +36,11 @@ type Flags struct {
3436

3537
// AddTo - Add the helm operator flags to the the flagset
3638
func (f *Flags) AddTo(flagSet *pflag.FlagSet) {
39+
flag.DurationVar(&f.Timeout,
40+
"timeout",
41+
time.Minute*5,
42+
"time to wait for any individual Kubernetes operation (like Jobs for hooks)",
43+
)
3744
flagSet.DurationVar(&f.ReconcilePeriod,
3845
"reconcile-period",
3946
time.Minute,

internal/helm/release/manager.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"errors"
2222
"fmt"
2323
"strings"
24+
"time"
2425

2526
jsonpatch "gomodules.xyz/jsonpatch/v3"
2627
"helm.sh/helm/v3/pkg/action"
@@ -66,6 +67,7 @@ type manager struct {
6667
values map[string]interface{}
6768
status *types.HelmAppStatus
6869

70+
timeout time.Duration
6971
isInstalled bool
7072
isUpgradeRequired bool
7173
deployedRelease *rpb.Release
@@ -152,13 +154,15 @@ func (m manager) getCandidateRelease(namespace, name string, chart *cpb.Chart,
152154
values map[string]interface{}) (*rpb.Release, error) {
153155
upgrade := action.NewUpgrade(m.actionConfig)
154156
upgrade.Namespace = namespace
157+
upgrade.Timeout = m.timeout
155158
upgrade.DryRun = true
156159
return upgrade.Run(name, chart, values)
157160
}
158161

159162
// InstallRelease performs a Helm release install.
160163
func (m manager) InstallRelease(ctx context.Context, opts ...InstallOption) (*rpb.Release, error) {
161164
install := action.NewInstall(m.actionConfig)
165+
install.Timeout = m.timeout
162166
install.ReleaseName = m.releaseName
163167
install.Namespace = m.namespace
164168
for _, o := range opts {
@@ -172,6 +176,7 @@ func (m manager) InstallRelease(ctx context.Context, opts ...InstallOption) (*rp
172176
// Workaround for helm/helm#3338
173177
if installedRelease != nil {
174178
uninstall := action.NewUninstall(m.actionConfig)
179+
uninstall.Timeout = m.timeout
175180
_, uninstallErr := uninstall.Run(m.releaseName)
176181

177182
// In certain cases, InstallRelease will return a partial release in
@@ -202,6 +207,7 @@ func ForceUpgrade(force bool) UpgradeOption {
202207
func (m manager) UpgradeRelease(ctx context.Context, opts ...UpgradeOption) (*rpb.Release, *rpb.Release, error) {
203208
upgrade := action.NewUpgrade(m.actionConfig)
204209
upgrade.Namespace = m.namespace
210+
upgrade.Timeout = m.timeout
205211
for _, o := range opts {
206212
if err := o(upgrade); err != nil {
207213
return nil, nil, fmt.Errorf("failed to apply upgrade option: %w", err)
@@ -213,6 +219,7 @@ func (m manager) UpgradeRelease(ctx context.Context, opts ...UpgradeOption) (*rp
213219
// Workaround for helm/helm#3338
214220
if upgradedRelease != nil {
215221
rollback := action.NewRollback(m.actionConfig)
222+
rollback.Timeout = m.timeout
216223
rollback.Force = true
217224

218225
// As of Helm 2.13, if UpgradeRelease returns a non-nil release, that
@@ -364,6 +371,7 @@ func (m manager) UninstallRelease(ctx context.Context, opts ...UninstallOption)
364371
}
365372

366373
uninstall := action.NewUninstall(m.actionConfig)
374+
uninstall.Timeout = m.timeout
367375
for _, o := range opts {
368376
if err := o(uninstall); err != nil {
369377
return nil, fmt.Errorf("failed to apply uninstall option: %w", err)

internal/helm/release/manager_factory.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package release
1616

1717
import (
1818
"fmt"
19+
"time"
1920

2021
"helm.sh/helm/v3/pkg/action"
2122
"helm.sh/helm/v3/pkg/chart/loader"
@@ -37,17 +38,32 @@ import (
3738
// improves decoupling between reconciliation logic and the Helm backend
3839
// components used to manage releases.
3940
type ManagerFactory interface {
40-
NewManager(r *unstructured.Unstructured, overrideValues map[string]string) (Manager, error)
41+
NewManager(*unstructured.Unstructured, map[string]string) (Manager, error)
4142
}
4243

4344
type managerFactory struct {
4445
mgr crmanager.Manager
4546
chartDir string
47+
timeout time.Duration
4648
}
4749

4850
// NewManagerFactory returns a new Helm manager factory capable of installing and uninstalling releases.
49-
func NewManagerFactory(mgr crmanager.Manager, chartDir string) ManagerFactory {
50-
return &managerFactory{mgr, chartDir}
51+
func NewManagerFactory(opts ManagerFactoryOptions) ManagerFactory {
52+
return &managerFactory{
53+
mgr: opts.CRManager,
54+
chartDir: opts.ChartDir,
55+
timeout: opts.Timeout,
56+
}
57+
}
58+
59+
// ManagerFactoryOptions enable configuration of Helm operators
60+
type ManagerFactoryOptions struct {
61+
// Timeout specifies how long helm should attempt an action ie. install --timeout 5m
62+
Timeout time.Duration
63+
// CRManager is the controller-runtime manager
64+
CRManager crmanager.Manager
65+
// ChartDir is the directory containing directories of helm charts
66+
ChartDir string
5167
}
5268

5369
func (f managerFactory) NewManager(cr *unstructured.Unstructured, overrideValues map[string]string) (Manager, error) {
@@ -104,6 +120,7 @@ func (f managerFactory) NewManager(cr *unstructured.Unstructured, overrideValues
104120
actionConfig: actionConfig,
105121
storageBackend: storageBackend,
106122
kubeClient: ownerRefClient,
123+
timeout: f.timeout,
107124

108125
releaseName: releaseName,
109126
namespace: cr.GetNamespace(),

0 commit comments

Comments
 (0)