Commit 774789c7 authored by Taylor Thomas's avatar Taylor Thomas

feat(*): Adds support for timeout flag

Installs, rollback, upgrade, and delete now accept a `--timeout` flag
that allows the user to specify the maximum number of seconds that
any kubernetes command can take.

Closes #1678
parent 5fc020f0
...@@ -190,6 +190,8 @@ message UpdateReleaseRequest { ...@@ -190,6 +190,8 @@ message UpdateReleaseRequest {
bool disable_hooks = 5; bool disable_hooks = 5;
// Performs pods restart for resources if applicable // Performs pods restart for resources if applicable
bool recreate = 6; bool recreate = 6;
// timeout specifies the max amount of time any kubernetes client command can run.
int64 timeout = 7;
} }
// UpdateReleaseResponse is the response to an update request. // UpdateReleaseResponse is the response to an update request.
...@@ -208,6 +210,8 @@ message RollbackReleaseRequest { ...@@ -208,6 +210,8 @@ message RollbackReleaseRequest {
int32 version = 4; int32 version = 4;
// Performs pods restart for resources if applicable // Performs pods restart for resources if applicable
bool recreate = 5; bool recreate = 5;
// timeout specifies the max amount of time any kubernetes client command can run.
int64 timeout = 6;
} }
// RollbackReleaseResponse is the response to an update request. // RollbackReleaseResponse is the response to an update request.
...@@ -239,6 +243,9 @@ message InstallReleaseRequest { ...@@ -239,6 +243,9 @@ message InstallReleaseRequest {
// ReuseName requests that Tiller re-uses a name, instead of erroring out. // ReuseName requests that Tiller re-uses a name, instead of erroring out.
bool reuse_name = 7; bool reuse_name = 7;
// timeout specifies the max amount of time any kubernetes client command can run.
int64 timeout = 8;
} }
// InstallReleaseResponse is the response from a release installation. // InstallReleaseResponse is the response from a release installation.
...@@ -254,6 +261,8 @@ message UninstallReleaseRequest { ...@@ -254,6 +261,8 @@ message UninstallReleaseRequest {
bool disable_hooks = 2; bool disable_hooks = 2;
// Purge removes the release from the store and make its name free for later use. // Purge removes the release from the store and make its name free for later use.
bool purge = 3; bool purge = 3;
// timeout specifies the max amount of time any kubernetes client command can run.
int64 timeout = 4;
} }
// UninstallReleaseResponse represents a successful response to an uninstall request. // UninstallReleaseResponse represents a successful response to an uninstall request.
......
...@@ -39,6 +39,7 @@ type deleteCmd struct { ...@@ -39,6 +39,7 @@ type deleteCmd struct {
dryRun bool dryRun bool
disableHooks bool disableHooks bool
purge bool purge bool
timeout int64
out io.Writer out io.Writer
client helm.Interface client helm.Interface
...@@ -77,6 +78,7 @@ func newDeleteCmd(c helm.Interface, out io.Writer) *cobra.Command { ...@@ -77,6 +78,7 @@ func newDeleteCmd(c helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&del.dryRun, "dry-run", false, "simulate a delete") f.BoolVar(&del.dryRun, "dry-run", false, "simulate a delete")
f.BoolVar(&del.disableHooks, "no-hooks", false, "prevent hooks from running during deletion") f.BoolVar(&del.disableHooks, "no-hooks", false, "prevent hooks from running during deletion")
f.BoolVar(&del.purge, "purge", false, "remove the release from the store and make its name free for later use") f.BoolVar(&del.purge, "purge", false, "remove the release from the store and make its name free for later use")
f.Int64Var(&del.timeout, "timeout", 300, "time in seconds to wait for any individual kubernetes operation (like Jobs for hooks)")
return cmd return cmd
} }
...@@ -86,6 +88,7 @@ func (d *deleteCmd) run() error { ...@@ -86,6 +88,7 @@ func (d *deleteCmd) run() error {
helm.DeleteDryRun(d.dryRun), helm.DeleteDryRun(d.dryRun),
helm.DeleteDisableHooks(d.disableHooks), helm.DeleteDisableHooks(d.disableHooks),
helm.DeletePurge(d.purge), helm.DeletePurge(d.purge),
helm.DeleteTimeout(d.timeout),
} }
res, err := d.client.DeleteRelease(d.name, opts...) res, err := d.client.DeleteRelease(d.name, opts...)
if res != nil && res.Info != "" { if res != nil && res.Info != "" {
......
...@@ -33,6 +33,13 @@ func TestDelete(t *testing.T) { ...@@ -33,6 +33,13 @@ func TestDelete(t *testing.T) {
expected: "", // Output of a delete is an empty string and exit 0. expected: "", // Output of a delete is an empty string and exit 0.
resp: releaseMock(&releaseOptions{name: "aeneas"}), resp: releaseMock(&releaseOptions{name: "aeneas"}),
}, },
{
name: "delete with timeout",
args: []string{"aeneas"},
flags: []string{"--timeout", "120"},
expected: "",
resp: releaseMock(&releaseOptions{name: "aeneas"}),
},
{ {
name: "delete without hooks", name: "delete without hooks",
args: []string{"aeneas"}, args: []string{"aeneas"},
......
...@@ -104,6 +104,7 @@ type installCmd struct { ...@@ -104,6 +104,7 @@ type installCmd struct {
values string values string
nameTemplate string nameTemplate string
version string version string
timeout int64
} }
type valueFiles []string type valueFiles []string
...@@ -160,6 +161,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command { ...@@ -160,6 +161,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&inst.verify, "verify", false, "verify the package before installing it") f.BoolVar(&inst.verify, "verify", false, "verify the package before installing it")
f.StringVar(&inst.keyring, "keyring", defaultKeyring(), "location of public keys used for verification") f.StringVar(&inst.keyring, "keyring", defaultKeyring(), "location of public keys used for verification")
f.StringVar(&inst.version, "version", "", "specify the exact chart version to install. If this is not specified, the latest version is installed") f.StringVar(&inst.version, "version", "", "specify the exact chart version to install. If this is not specified, the latest version is installed")
f.Int64Var(&inst.timeout, "timeout", 300, "time in seconds to wait for any individual kubernetes operation (like Jobs for hooks)")
return cmd return cmd
} }
...@@ -195,7 +197,8 @@ func (i *installCmd) run() error { ...@@ -195,7 +197,8 @@ func (i *installCmd) run() error {
helm.ReleaseName(i.name), helm.ReleaseName(i.name),
helm.InstallDryRun(i.dryRun), helm.InstallDryRun(i.dryRun),
helm.InstallReuseName(i.replace), helm.InstallReuseName(i.replace),
helm.InstallDisableHooks(i.disableHooks)) helm.InstallDisableHooks(i.disableHooks),
helm.InstallTimeout(i.timeout))
if err != nil { if err != nil {
return prettyError(err) return prettyError(err)
} }
......
...@@ -82,6 +82,14 @@ func TestInstall(t *testing.T) { ...@@ -82,6 +82,14 @@ func TestInstall(t *testing.T) {
expected: "aeneas", expected: "aeneas",
resp: releaseMock(&releaseOptions{name: "aeneas"}), resp: releaseMock(&releaseOptions{name: "aeneas"}),
}, },
// Install, with timeout
{
name: "install with a timeout",
args: []string{"testdata/testcharts/alpine"},
flags: strings.Split("--timeout 120", " "),
expected: "foobar",
resp: releaseMock(&releaseOptions{name: "foobar"}),
},
// Install, using the name-template // Install, using the name-template
{ {
name: "install with name-template", name: "install with name-template",
......
...@@ -39,6 +39,7 @@ type rollbackCmd struct { ...@@ -39,6 +39,7 @@ type rollbackCmd struct {
disableHooks bool disableHooks bool
out io.Writer out io.Writer
client helm.Interface client helm.Interface
timeout int64
} }
func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command { func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
...@@ -74,6 +75,7 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command { ...@@ -74,6 +75,7 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&rollback.dryRun, "dry-run", false, "simulate a rollback") f.BoolVar(&rollback.dryRun, "dry-run", false, "simulate a rollback")
f.BoolVar(&rollback.recreate, "recreate-pods", false, "performs pods restart for the resource if applicable") f.BoolVar(&rollback.recreate, "recreate-pods", false, "performs pods restart for the resource if applicable")
f.BoolVar(&rollback.disableHooks, "no-hooks", false, "prevent hooks from running during rollback") f.BoolVar(&rollback.disableHooks, "no-hooks", false, "prevent hooks from running during rollback")
f.Int64Var(&rollback.timeout, "timeout", 300, "time in seconds to wait for any individual kubernetes operation (like Jobs for hooks)")
return cmd return cmd
} }
...@@ -85,7 +87,7 @@ func (r *rollbackCmd) run() error { ...@@ -85,7 +87,7 @@ func (r *rollbackCmd) run() error {
helm.RollbackRecreate(r.recreate), helm.RollbackRecreate(r.recreate),
helm.RollbackDisableHooks(r.disableHooks), helm.RollbackDisableHooks(r.disableHooks),
helm.RollbackVersion(r.revision), helm.RollbackVersion(r.revision),
) helm.RollbackTimeout(r.timeout))
if err != nil { if err != nil {
return prettyError(err) return prettyError(err)
} }
......
...@@ -31,6 +31,12 @@ func TestRollbackCmd(t *testing.T) { ...@@ -31,6 +31,12 @@ func TestRollbackCmd(t *testing.T) {
args: []string{"funny-honey", "1"}, args: []string{"funny-honey", "1"},
expected: "Rollback was a success! Happy Helming!", expected: "Rollback was a success! Happy Helming!",
}, },
{
name: "rollback a release with timeout",
args: []string{"funny-honey", "1"},
flags: []string{"--timeout", "120"},
expected: "Rollback was a success! Happy Helming!",
},
{ {
name: "rollback a release without revision", name: "rollback a release without revision",
args: []string{"funny-honey"}, args: []string{"funny-honey"},
......
...@@ -63,6 +63,7 @@ type upgradeCmd struct { ...@@ -63,6 +63,7 @@ type upgradeCmd struct {
install bool install bool
namespace string namespace string
version string version string
timeout int64
} }
func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command { func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
...@@ -102,6 +103,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command { ...@@ -102,6 +103,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.BoolVarP(&upgrade.install, "install", "i", false, "if a release by this name doesn't already exist, run an install") f.BoolVarP(&upgrade.install, "install", "i", false, "if a release by this name doesn't already exist, run an install")
f.StringVar(&upgrade.namespace, "namespace", "default", "namespace to install the release into (only used if --install is set)") f.StringVar(&upgrade.namespace, "namespace", "default", "namespace to install the release into (only used if --install is set)")
f.StringVar(&upgrade.version, "version", "", "specify the exact chart version to use. If this is not specified, the latest version is used") f.StringVar(&upgrade.version, "version", "", "specify the exact chart version to use. If this is not specified, the latest version is used")
f.Int64Var(&upgrade.timeout, "timeout", 300, "time in seconds to wait for any individual kubernetes operation (like Jobs for hooks)")
f.MarkDeprecated("disable-hooks", "use --no-hooks instead") f.MarkDeprecated("disable-hooks", "use --no-hooks instead")
...@@ -136,6 +138,7 @@ func (u *upgradeCmd) run() error { ...@@ -136,6 +138,7 @@ func (u *upgradeCmd) run() error {
keyring: u.keyring, keyring: u.keyring,
values: u.values, values: u.values,
namespace: u.namespace, namespace: u.namespace,
timeout: u.timeout,
} }
return ic.run() return ic.run()
} }
...@@ -152,7 +155,8 @@ func (u *upgradeCmd) run() error { ...@@ -152,7 +155,8 @@ func (u *upgradeCmd) run() error {
helm.UpdateValueOverrides(rawVals), helm.UpdateValueOverrides(rawVals),
helm.UpgradeDryRun(u.dryRun), helm.UpgradeDryRun(u.dryRun),
helm.UpgradeRecreate(u.recreate), helm.UpgradeRecreate(u.recreate),
helm.UpgradeDisableHooks(u.disableHooks)) helm.UpgradeDisableHooks(u.disableHooks),
helm.UpgradeTimeout(u.timeout))
if err != nil { if err != nil {
return fmt.Errorf("UPGRADE FAILED: %v", prettyError(err)) return fmt.Errorf("UPGRADE FAILED: %v", prettyError(err))
} }
......
...@@ -62,6 +62,23 @@ func TestUpgradeCmd(t *testing.T) { ...@@ -62,6 +62,23 @@ func TestUpgradeCmd(t *testing.T) {
t.Errorf("Error loading updated chart: %v", err) t.Errorf("Error loading updated chart: %v", err)
} }
// update chart version again
cfile = &chart.Metadata{
Name: "testUpgradeChart",
Description: "A Helm chart for Kubernetes",
Version: "0.1.3",
}
chartPath, err = chartutil.Create(cfile, tmpChart)
if err != nil {
t.Errorf("Error creating chart: %v", err)
}
var ch2 *chart.Chart
ch2, err = chartutil.Load(chartPath)
if err != nil {
t.Errorf("Error loading updated chart: %v", err)
}
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "upgrade a release", name: "upgrade a release",
...@@ -69,6 +86,13 @@ func TestUpgradeCmd(t *testing.T) { ...@@ -69,6 +86,13 @@ func TestUpgradeCmd(t *testing.T) {
resp: releaseMock(&releaseOptions{name: "funny-bunny", version: 2, chart: ch}), resp: releaseMock(&releaseOptions{name: "funny-bunny", version: 2, chart: ch}),
expected: "funny-bunny has been upgraded. Happy Helming!\n", expected: "funny-bunny has been upgraded. Happy Helming!\n",
}, },
{
name: "upgrade a release with timeout",
args: []string{"funny-bunny", chartPath},
flags: []string{"--timeout", "120"},
resp: releaseMock(&releaseOptions{name: "funny-bunny", version: 3, chart: ch2}),
expected: "funny-bunny has been upgraded. Happy Helming!\n",
},
{ {
name: "install a release with 'upgrade --install'", name: "install a release with 'upgrade --install'",
args: []string{"zany-bunny", chartPath}, args: []string{"zany-bunny", chartPath},
...@@ -76,6 +100,13 @@ func TestUpgradeCmd(t *testing.T) { ...@@ -76,6 +100,13 @@ func TestUpgradeCmd(t *testing.T) {
resp: releaseMock(&releaseOptions{name: "zany-bunny", version: 1, chart: ch}), resp: releaseMock(&releaseOptions{name: "zany-bunny", version: 1, chart: ch}),
expected: "zany-bunny has been upgraded. Happy Helming!\n", expected: "zany-bunny has been upgraded. Happy Helming!\n",
}, },
{
name: "install a release with 'upgrade --install' and timeout",
args: []string{"crazy-bunny", chartPath},
flags: []string{"-i", "--timeout", "120"},
resp: releaseMock(&releaseOptions{name: "crazy-bunny", version: 1, chart: ch}),
expected: "crazy-bunny has been upgraded. Happy Helming!\n",
},
} }
cmd := func(c *fakeReleaseClient, out io.Writer) *cobra.Command { cmd := func(c *fakeReleaseClient, out io.Writer) *cobra.Command {
......
...@@ -151,6 +151,34 @@ func ReleaseName(name string) InstallOption { ...@@ -151,6 +151,34 @@ func ReleaseName(name string) InstallOption {
} }
} }
// InstallTimeout specifies the number of seconds before kubernetes calls timeout
func InstallTimeout(timeout int64) InstallOption {
return func(opts *options) {
opts.instReq.Timeout = timeout
}
}
// UpgradeTimeout specifies the number of seconds before kubernetes calls timeout
func UpgradeTimeout(timeout int64) UpdateOption {
return func(opts *options) {
opts.updateReq.Timeout = timeout
}
}
// DeleteTimeout specifies the number of seconds before kubernetes calls timeout
func DeleteTimeout(timeout int64) DeleteOption {
return func(opts *options) {
opts.uninstallReq.Timeout = timeout
}
}
// RollbackTimeout specifies the number of seconds before kubernetes calls timeout
func RollbackTimeout(timeout int64) RollbackOption {
return func(opts *options) {
opts.rollbackReq.Timeout = timeout
}
}
// UpdateValueOverrides specifies a list of values to include when upgrading // UpdateValueOverrides specifies a list of values to include when upgrading
func UpdateValueOverrides(raw []byte) UpdateOption { func UpdateValueOverrides(raw []byte) UpdateOption {
return func(opts *options) { return func(opts *options) {
......
...@@ -258,6 +258,12 @@ func skipIfNotFound(err error) error { ...@@ -258,6 +258,12 @@ func skipIfNotFound(err error) error {
return err return err
} }
func watchTimeout(t time.Duration) ResourceActorFunc {
return func(info *resource.Info) error {
return watchUntilReady(t, info)
}
}
// WatchUntilReady watches the resource given in the reader, and waits until it is ready. // WatchUntilReady watches the resource given in the reader, and waits until it is ready.
// //
// This function is mainly for hook implementations. It watches for a resource to // This function is mainly for hook implementations. It watches for a resource to
...@@ -270,10 +276,10 @@ func skipIfNotFound(err error) error { ...@@ -270,10 +276,10 @@ func skipIfNotFound(err error) error {
// ascertained by watching the Status fields in a job's output. // ascertained by watching the Status fields in a job's output.
// //
// Handling for other kinds will be added as necessary. // Handling for other kinds will be added as necessary.
func (c *Client) WatchUntilReady(namespace string, reader io.Reader) error { func (c *Client) WatchUntilReady(namespace string, reader io.Reader, timeout int64) error {
// For jobs, there's also the option to do poll c.Jobs(namespace).Get(): // For jobs, there's also the option to do poll c.Jobs(namespace).Get():
// https://github.com/adamreese/kubernetes/blob/master/test/e2e/job.go#L291-L300 // https://github.com/adamreese/kubernetes/blob/master/test/e2e/job.go#L291-L300
return perform(c, namespace, reader, watchUntilReady) return perform(c, namespace, reader, watchTimeout(time.Duration(timeout)*time.Second))
} }
func perform(c *Client, namespace string, reader io.Reader, fn ResourceActorFunc) error { func perform(c *Client, namespace string, reader io.Reader, fn ResourceActorFunc) error {
...@@ -382,15 +388,14 @@ func recreatePods(client *internalclientset.Clientset, namespace string, selecto ...@@ -382,15 +388,14 @@ func recreatePods(client *internalclientset.Clientset, namespace string, selecto
return nil return nil
} }
func watchUntilReady(info *resource.Info) error { func watchUntilReady(timeout time.Duration, info *resource.Info) error {
w, err := resource.NewHelper(info.Client, info.Mapping).WatchSingle(info.Namespace, info.Name, info.ResourceVersion) w, err := resource.NewHelper(info.Client, info.Mapping).WatchSingle(info.Namespace, info.Name, info.ResourceVersion)
if err != nil { if err != nil {
return err return err
} }
kind := info.Mapping.GroupVersionKind.Kind kind := info.Mapping.GroupVersionKind.Kind
log.Printf("Watching for changes to %s %s", kind, info.Name) log.Printf("Watching for changes to %s %s with timeout of %v", kind, info.Name, timeout)
timeout := time.Minute * 5
// What we watch for depends on the Kind. // What we watch for depends on the Kind.
// - For a Job, we watch for completion. // - For a Job, we watch for completion.
......
This diff is collapsed.
...@@ -122,7 +122,7 @@ type KubeClient interface { ...@@ -122,7 +122,7 @@ type KubeClient interface {
// For Jobs, "ready" means the job ran to completion (excited without error). // For Jobs, "ready" means the job ran to completion (excited without error).
// For all other kinds, it means the kind was created or modified without // For all other kinds, it means the kind was created or modified without
// error. // error.
WatchUntilReady(namespace string, reader io.Reader) error WatchUntilReady(namespace string, reader io.Reader, timeout int64) error
// Update updates one or more resources or creates the resource // Update updates one or more resources or creates the resource
// if it doesn't exist // if it doesn't exist
...@@ -161,7 +161,7 @@ func (p *PrintingKubeClient) Delete(ns string, r io.Reader) error { ...@@ -161,7 +161,7 @@ func (p *PrintingKubeClient) Delete(ns string, r io.Reader) error {
} }
// WatchUntilReady implements KubeClient WatchUntilReady. // WatchUntilReady implements KubeClient WatchUntilReady.
func (p *PrintingKubeClient) WatchUntilReady(ns string, r io.Reader) error { func (p *PrintingKubeClient) WatchUntilReady(ns string, r io.Reader, t int64) error {
_, err := io.Copy(p.Out, r) _, err := io.Copy(p.Out, r)
return err return err
} }
......
...@@ -47,7 +47,7 @@ func (k *mockKubeClient) Delete(ns string, r io.Reader) error { ...@@ -47,7 +47,7 @@ func (k *mockKubeClient) Delete(ns string, r io.Reader) error {
func (k *mockKubeClient) Update(ns string, currentReader, modifiedReader io.Reader, recreate bool) error { func (k *mockKubeClient) Update(ns string, currentReader, modifiedReader io.Reader, recreate bool) error {
return nil return nil
} }
func (k *mockKubeClient) WatchUntilReady(ns string, r io.Reader) error { func (k *mockKubeClient) WatchUntilReady(ns string, r io.Reader, t int64) error {
return nil return nil
} }
......
...@@ -333,9 +333,9 @@ func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.R ...@@ -333,9 +333,9 @@ func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.R
return res, nil return res, nil
} }
// pre-ugrade hooks // pre-upgrade hooks
if !req.DisableHooks { if !req.DisableHooks {
if err := s.execHook(updatedRelease.Hooks, updatedRelease.Name, updatedRelease.Namespace, preUpgrade); err != nil { if err := s.execHook(updatedRelease.Hooks, updatedRelease.Name, updatedRelease.Namespace, preUpgrade, req.Timeout); err != nil {
return res, err return res, err
} }
} }
...@@ -351,7 +351,7 @@ func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.R ...@@ -351,7 +351,7 @@ func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.R
// post-upgrade hooks // post-upgrade hooks
if !req.DisableHooks { if !req.DisableHooks {
if err := s.execHook(updatedRelease.Hooks, updatedRelease.Name, updatedRelease.Namespace, postUpgrade); err != nil { if err := s.execHook(updatedRelease.Hooks, updatedRelease.Name, updatedRelease.Namespace, postUpgrade, req.Timeout); err != nil {
return res, err return res, err
} }
} }
...@@ -473,7 +473,7 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R ...@@ -473,7 +473,7 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R
// pre-rollback hooks // pre-rollback hooks
if !req.DisableHooks { if !req.DisableHooks {
if err := s.execHook(targetRelease.Hooks, targetRelease.Name, targetRelease.Namespace, preRollback); err != nil { if err := s.execHook(targetRelease.Hooks, targetRelease.Name, targetRelease.Namespace, preRollback, req.Timeout); err != nil {
return res, err return res, err
} }
} }
...@@ -489,7 +489,7 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R ...@@ -489,7 +489,7 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R
// post-rollback hooks // post-rollback hooks
if !req.DisableHooks { if !req.DisableHooks {
if err := s.execHook(targetRelease.Hooks, targetRelease.Name, targetRelease.Namespace, postRollback); err != nil { if err := s.execHook(targetRelease.Hooks, targetRelease.Name, targetRelease.Namespace, postRollback, req.Timeout); err != nil {
return res, err return res, err
} }
} }
...@@ -809,7 +809,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install ...@@ -809,7 +809,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
// pre-install hooks // pre-install hooks
if !req.DisableHooks { if !req.DisableHooks {
if err := s.execHook(r.Hooks, r.Name, r.Namespace, preInstall); err != nil { if err := s.execHook(r.Hooks, r.Name, r.Namespace, preInstall, req.Timeout); err != nil {
return res, err return res, err
} }
} }
...@@ -854,7 +854,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install ...@@ -854,7 +854,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
// post-install hooks // post-install hooks
if !req.DisableHooks { if !req.DisableHooks {
if err := s.execHook(r.Hooks, r.Name, r.Namespace, postInstall); err != nil { if err := s.execHook(r.Hooks, r.Name, r.Namespace, postInstall, req.Timeout); err != nil {
log.Printf("warning: Release %q failed post-install: %s", r.Name, err) log.Printf("warning: Release %q failed post-install: %s", r.Name, err)
r.Info.Status.Code = release.Status_FAILED r.Info.Status.Code = release.Status_FAILED
s.recordRelease(r, false) s.recordRelease(r, false)
...@@ -875,7 +875,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install ...@@ -875,7 +875,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
return res, nil return res, nil
} }
func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook string) error { func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook string, timeout int64) error {
kubeCli := s.env.KubeClient kubeCli := s.env.KubeClient
code, ok := events[hook] code, ok := events[hook]
if !ok { if !ok {
...@@ -903,7 +903,7 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin ...@@ -903,7 +903,7 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin
// No way to rewind a bytes.Buffer()? // No way to rewind a bytes.Buffer()?
b.Reset() b.Reset()
b.WriteString(h.Manifest) b.WriteString(h.Manifest)
if err := kubeCli.WatchUntilReady(namespace, b); err != nil { if err := kubeCli.WatchUntilReady(namespace, b, timeout); err != nil {
log.Printf("warning: Release %q pre-install %s could not complete: %s", name, h.Path, err) log.Printf("warning: Release %q pre-install %s could not complete: %s", name, h.Path, err)
return err return err
} }
...@@ -964,7 +964,7 @@ func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallR ...@@ -964,7 +964,7 @@ func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallR
res := &services.UninstallReleaseResponse{Release: rel} res := &services.UninstallReleaseResponse{Release: rel}
if !req.DisableHooks { if !req.DisableHooks {
if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, preDelete); err != nil { if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, preDelete, req.Timeout); err != nil {
return res, err return res, err
} }
} }
...@@ -1010,7 +1010,7 @@ func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallR ...@@ -1010,7 +1010,7 @@ func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallR
} }
if !req.DisableHooks { if !req.DisableHooks {
if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, postDelete); err != nil { if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, postDelete, req.Timeout); err != nil {
es = append(es, err.Error()) es = append(es, err.Error())
} }
} }
......
...@@ -1375,7 +1375,7 @@ type hookFailingKubeClient struct { ...@@ -1375,7 +1375,7 @@ type hookFailingKubeClient struct {
environment.PrintingKubeClient environment.PrintingKubeClient
} }
func (h *hookFailingKubeClient) WatchUntilReady(ns string, r io.Reader) error { func (h *hookFailingKubeClient) WatchUntilReady(ns string, r io.Reader, t int64) error {
return errors.New("Failed watch") return errors.New("Failed watch")
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment