pull/10603/merge
Michelle Fernandez Bieber 2 years ago committed by GitHub
commit 7f9e427b61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -54,7 +54,7 @@ func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command
} }
return compListReleases(toComplete, args, cfg) return compListReleases(toComplete, args, cfg)
}, },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) (returnError error) {
client.Namespace = settings.Namespace() client.Namespace = settings.Namespace()
notName := regexp.MustCompile(`^!\s?name=`) notName := regexp.MustCompile(`^!\s?name=`)
for _, f := range filter { for _, f := range filter {
@ -64,7 +64,16 @@ func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command
client.Filters[action.ExcludeNameFilter] = append(client.Filters[action.ExcludeNameFilter], notName.ReplaceAllLiteralString(f, "")) client.Filters[action.ExcludeNameFilter] = append(client.Filters[action.ExcludeNameFilter], notName.ReplaceAllLiteralString(f, ""))
} }
} }
rel, runErr := client.Run(args[0])
rel, shutdown, runErr := client.Run(args[0])
defer func() {
if shutdownErr := shutdown(); shutdownErr != nil {
if returnError == nil {
returnError = shutdownErr
}
}
}()
// We only return an error if we weren't even able to get the // We only return an error if we weren't even able to get the
// release, otherwise we keep going so we can print status and logs // release, otherwise we keep going so we can print status and logs
// if requested // if requested

@ -28,6 +28,27 @@ import (
// execHook executes all of the hooks for the given hook event. // execHook executes all of the hooks for the given hook event.
func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent, timeout time.Duration) error { func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent, timeout time.Duration) error {
shutdown, err := cfg.execHookWithDelayedShutdown(rl, hook, timeout)
if shutdown == nil {
return nil
}
if err != nil {
if err := shutdown(); err != nil {
return err
}
return err
}
return shutdown()
}
type ExecuteShutdownHooks = func() error
func ShutdownNoOp() error {
return nil
}
// execHookWithDelayedShutdown executes all of the hooks for the given hook event and returns a shutdownHook function to trigger deletions after doing other things like e.g. retrieving logs.
func (cfg *Configuration) execHookWithDelayedShutdown(rl *release.Release, hook release.HookEvent, timeout time.Duration) (ExecuteShutdownHooks, error) {
executingHooks := []*release.Hook{} executingHooks := []*release.Hook{}
for _, h := range rl.Hooks { for _, h := range rl.Hooks {
@ -52,12 +73,12 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent,
} }
if err := cfg.deleteHookByPolicy(h, release.HookBeforeHookCreation); err != nil { if err := cfg.deleteHookByPolicy(h, release.HookBeforeHookCreation); err != nil {
return err return ShutdownNoOp, err
} }
resources, err := cfg.KubeClient.Build(bytes.NewBufferString(h.Manifest), true) resources, err := cfg.KubeClient.Build(bytes.NewBufferString(h.Manifest), true)
if err != nil { if err != nil {
return errors.Wrapf(err, "unable to build kubernetes object for %s hook %s", hook, h.Path) return ShutdownNoOp, errors.Wrapf(err, "unable to build kubernetes object for %s hook %s", hook, h.Path)
} }
// Record the time at which the hook was applied to the cluster // Record the time at which the hook was applied to the cluster
@ -76,7 +97,7 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent,
if _, err := cfg.KubeClient.Create(resources); err != nil { if _, err := cfg.KubeClient.Create(resources); err != nil {
h.LastRun.CompletedAt = helmtime.Now() h.LastRun.CompletedAt = helmtime.Now()
h.LastRun.Phase = release.HookPhaseFailed h.LastRun.Phase = release.HookPhaseFailed
return errors.Wrapf(err, "warning: Hook %s %s failed", hook, h.Path) return ShutdownNoOp, errors.Wrapf(err, "warning: Hook %s %s failed", hook, h.Path)
} }
// Watch hook resources until they have completed // Watch hook resources until they have completed
@ -88,14 +109,17 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent,
h.LastRun.Phase = release.HookPhaseFailed h.LastRun.Phase = release.HookPhaseFailed
// If a hook is failed, check the annotation of the hook to determine whether the hook should be deleted // If a hook is failed, check the annotation of the hook to determine whether the hook should be deleted
// under failed condition. If so, then clear the corresponding resource object in the hook // under failed condition. If so, then clear the corresponding resource object in the hook
return func() error {
if err := cfg.deleteHookByPolicy(h, release.HookFailed); err != nil { if err := cfg.deleteHookByPolicy(h, release.HookFailed); err != nil {
return err return err
} }
return err return err
}, err
} }
h.LastRun.Phase = release.HookPhaseSucceeded h.LastRun.Phase = release.HookPhaseSucceeded
} }
return func() error {
// If all hooks are successful, check the annotation of each hook to determine whether the hook should be deleted // If all hooks are successful, check the annotation of each hook to determine whether the hook should be deleted
// under succeeded condition. If so, then clear the corresponding resource object in each hook // under succeeded condition. If so, then clear the corresponding resource object in each hook
for _, h := range executingHooks { for _, h := range executingHooks {
@ -103,8 +127,8 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent,
return err return err
} }
} }
return nil return nil
}, nil
} }
// hookByWeight is a sorter for hooks // hookByWeight is a sorter for hooks

@ -55,19 +55,19 @@ func NewReleaseTesting(cfg *Configuration) *ReleaseTesting {
} }
// Run executes 'helm test' against the given release. // Run executes 'helm test' against the given release.
func (r *ReleaseTesting) Run(name string) (*release.Release, error) { func (r *ReleaseTesting) Run(name string) (*release.Release, ExecuteShutdownHooks, error) {
if err := r.cfg.KubeClient.IsReachable(); err != nil { if err := r.cfg.KubeClient.IsReachable(); err != nil {
return nil, err return nil, ShutdownNoOp, err
} }
if err := chartutil.ValidateReleaseName(name); err != nil { if err := chartutil.ValidateReleaseName(name); err != nil {
return nil, errors.Errorf("releaseTest: Release name is invalid: %s", name) return nil, ShutdownNoOp, errors.Errorf("releaseTest: Release name is invalid: %s", name)
} }
// finds the non-deleted release with the given name // finds the non-deleted release with the given name
rel, err := r.cfg.Releases.Last(name) rel, err := r.cfg.Releases.Last(name)
if err != nil { if err != nil {
return rel, err return rel, ShutdownNoOp, err
} }
skippedHooks := []*release.Hook{} skippedHooks := []*release.Hook{}
@ -94,14 +94,16 @@ func (r *ReleaseTesting) Run(name string) (*release.Release, error) {
rel.Hooks = executingHooks rel.Hooks = executingHooks
} }
if err := r.cfg.execHook(rel, release.HookTest, r.Timeout); err != nil { shutdown, err := r.cfg.execHookWithDelayedShutdown(rel, release.HookTest, r.Timeout)
if err != nil {
rel.Hooks = append(skippedHooks, rel.Hooks...) rel.Hooks = append(skippedHooks, rel.Hooks...)
r.cfg.Releases.Update(rel) r.cfg.Releases.Update(rel)
return rel, err return rel, shutdown, err
} }
rel.Hooks = append(skippedHooks, rel.Hooks...) rel.Hooks = append(skippedHooks, rel.Hooks...)
return rel, r.cfg.Releases.Update(rel) return rel, shutdown, r.cfg.Releases.Update(rel)
} }
// GetPodLogs will write the logs for all test pods in the given release into // GetPodLogs will write the logs for all test pods in the given release into

Loading…
Cancel
Save