Skip to content

Commit

Permalink
Enhance hooks tracker by adding a returned error to record function
Browse files Browse the repository at this point in the history
Signed-off-by: allenxu404 <qix2@vmware.com>
  • Loading branch information
allenxu404 committed Dec 5, 2023
1 parent 85482ae commit be9e3fd
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 24 deletions.
1 change: 1 addition & 0 deletions changelogs/unreleased/7153-allenxu404
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enhance hooks tracker by adding a returned error to record function
15 changes: 13 additions & 2 deletions internal/hook/hook_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ limitations under the License.

package hook

import "sync"
import (
"fmt"
"sync"
)

const (
HookSourceAnnotation = "annotation"
Expand Down Expand Up @@ -69,6 +72,8 @@ func NewHookTracker() *HookTracker {
}

// Add adds a hook to the tracker
// Add must precede the Record for each individual hook.
// In other words, a hook must be added to the tracker before its execution result is recorded.
func (ht *HookTracker) Add(podNamespace, podName, container, source, hookName string, hookPhase hookPhase) {
ht.lock.Lock()
defer ht.lock.Unlock()
Expand All @@ -91,7 +96,9 @@ func (ht *HookTracker) Add(podNamespace, podName, container, source, hookName st
}

// Record records the hook's execution status
func (ht *HookTracker) Record(podNamespace, podName, container, source, hookName string, hookPhase hookPhase, hookFailed bool) {
// Add must precede the Record for each individual hook.
// In other words, a hook must be added to the tracker before its execution result is recorded.
func (ht *HookTracker) Record(podNamespace, podName, container, source, hookName string, hookPhase hookPhase, hookFailed bool) error {
ht.lock.Lock()
defer ht.lock.Unlock()

Expand All @@ -104,12 +111,16 @@ func (ht *HookTracker) Record(podNamespace, podName, container, source, hookName
hookName: hookName,
}

var err error
if _, ok := ht.tracker[key]; ok {
ht.tracker[key] = hookTrackerVal{
hookFailed: hookFailed,
hookExecuted: true,
}
} else {
err = fmt.Errorf("hook not exist in hooks tracker, hook key: %v", key)
}
return err
}

// Stat calculates the number of attempted hooks and failed hooks
Expand Down
7 changes: 6 additions & 1 deletion internal/hook/hook_tracker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func TestHookTracker_Add(t *testing.T) {
func TestHookTracker_Record(t *testing.T) {
tracker := NewHookTracker()
tracker.Add("ns1", "pod1", "container1", HookSourceAnnotation, "h1", PhasePre)
tracker.Record("ns1", "pod1", "container1", HookSourceAnnotation, "h1", PhasePre, true)
err := tracker.Record("ns1", "pod1", "container1", HookSourceAnnotation, "h1", PhasePre, true)

key := hookTrackerKey{
podNamespace: "ns1",
Expand All @@ -63,6 +63,11 @@ func TestHookTracker_Record(t *testing.T) {

info := tracker.tracker[key]
assert.True(t, info.hookFailed)
assert.Nil(t, err)

err = tracker.Record("ns2", "pod2", "container1", HookSourceAnnotation, "h1", PhasePre, true)
assert.NotNil(t, err)

}

func TestHookTracker_Stat(t *testing.T) {
Expand Down
19 changes: 10 additions & 9 deletions internal/hook/item_hook_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,14 @@ func (h *DefaultItemHookHandler) HandleHooks(
},
)

hookTracker.Record(namespace, name, hookFromAnnotations.Container, HookSourceAnnotation, "", phase, false)
if err := h.PodCommandExecutor.ExecutePodCommand(hookLog, obj.UnstructuredContent(), namespace, name, "<from-annotation>", hookFromAnnotations); err != nil {
hookFailed := false
if err = h.PodCommandExecutor.ExecutePodCommand(hookLog, obj.UnstructuredContent(), namespace, name, "<from-annotation>", hookFromAnnotations); err != nil {
hookLog.WithError(err).Error("Error executing hook")
hookTracker.Record(namespace, name, hookFromAnnotations.Container, HookSourceAnnotation, "", phase, true)

if hookFromAnnotations.OnError == velerov1api.HookErrorModeFail {
return err
}
hookFailed = true
}
_ = hookTracker.Record(namespace, name, hookFromAnnotations.Container, HookSourceAnnotation, "", phase, hookFailed)
if err != nil && hookFromAnnotations.OnError == velerov1api.HookErrorModeFail {
return err
}

return nil
Expand Down Expand Up @@ -277,15 +277,16 @@ func (h *DefaultItemHookHandler) HandleHooks(
},
)

hookTracker.Record(namespace, name, hook.Exec.Container, HookSourceSpec, resourceHook.Name, phase, false)
hookFailed := false
err := h.PodCommandExecutor.ExecutePodCommand(hookLog, obj.UnstructuredContent(), namespace, name, resourceHook.Name, hook.Exec)
if err != nil {
hookLog.WithError(err).Error("Error executing hook")
hookTracker.Record(namespace, name, hook.Exec.Container, HookSourceSpec, resourceHook.Name, phase, true)
hookFailed = true
if hook.Exec.OnError == velerov1api.HookErrorModeFail {
modeFailError = err
}
}
_ = hookTracker.Record(namespace, name, hook.Exec.Container, HookSourceSpec, resourceHook.Name, phase, hookFailed)
}
}
}
Expand Down
40 changes: 28 additions & 12 deletions internal/hook/wait_exec_hook_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,11 @@ func (e *DefaultWaitExecHookHandler) HandleHooks(
err := fmt.Errorf("hook %s in container %s expired before executing", hook.HookName, hook.Hook.Container)
hookLog.Error(err)
errors = append(errors, err)
hookTracker.Record(newPod.Namespace, newPod.Name, hook.Hook.Container, hook.HookSource, hook.HookName, hookPhase(""), true)

trackerErr := hookTracker.Record(newPod.Namespace, newPod.Name, hook.Hook.Container, hook.HookSource, hook.HookName, hookPhase(""), true)
if trackerErr != nil {
hookLog.WithError(trackerErr).Warn("Error recording the hook in hook tracker")
}

if hook.Hook.OnError == velerov1api.HookErrorModeFail {
cancel()
Expand All @@ -179,17 +183,24 @@ func (e *DefaultWaitExecHookHandler) HandleHooks(
OnError: hook.Hook.OnError,
Timeout: hook.Hook.ExecTimeout,
}
hookTracker.Record(newPod.Namespace, newPod.Name, hook.Hook.Container, hook.HookSource, hook.HookName, hookPhase(""), false)
if err := e.PodCommandExecutor.ExecutePodCommand(hookLog, podMap, pod.Namespace, pod.Name, hook.HookName, eh); err != nil {
hookLog.WithError(err).Error("Error executing hook")
err = fmt.Errorf("hook %s in container %s failed to execute, err: %v", hook.HookName, hook.Hook.Container, err)
errors = append(errors, err)
hookTracker.Record(newPod.Namespace, newPod.Name, hook.Hook.Container, hook.HookSource, hook.HookName, hookPhase(""), true)

if hook.Hook.OnError == velerov1api.HookErrorModeFail {
cancel()
return
}
hookFailed := false
var hookErr error
if hookErr = e.PodCommandExecutor.ExecutePodCommand(hookLog, podMap, pod.Namespace, pod.Name, hook.HookName, eh); hookErr != nil {
hookLog.WithError(hookErr).Error("Error executing hook")
hookErr = fmt.Errorf("hook %s in container %s failed to execute, err: %v", hook.HookName, hook.Hook.Container, hookErr)
errors = append(errors, hookErr)
hookFailed = true
}

trackerErr := hookTracker.Record(newPod.Namespace, newPod.Name, hook.Hook.Container, hook.HookSource, hook.HookName, hookPhase(""), hookFailed)
if trackerErr != nil {
hookLog.WithError(trackerErr).Warn("Error recording the hook in hook tracker")
}

if hookErr != nil && hook.Hook.OnError == velerov1api.HookErrorModeFail {
cancel()
return
}
}
delete(byContainer, containerName)
Expand Down Expand Up @@ -233,7 +244,12 @@ func (e *DefaultWaitExecHookHandler) HandleHooks(
"hookPhase": "post",
},
)
hookTracker.Record(pod.Namespace, pod.Name, hook.Hook.Container, hook.HookSource, hook.HookName, hookPhase(""), true)

trackerErr := hookTracker.Record(pod.Namespace, pod.Name, hook.Hook.Container, hook.HookSource, hook.HookName, hookPhase(""), true)
if trackerErr != nil {
hookLog.WithError(trackerErr).Warn("Error recording the hook in hook tracker")
}

hookLog.Error(err)
errors = append(errors, err)
}
Expand Down
31 changes: 31 additions & 0 deletions internal/hook/wait_exec_hook_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1216,6 +1216,37 @@ func TestRestoreHookTrackerUpdate(t *testing.T) {
hookTracker: hookTracker3,
expectedFailed: 2,
},
{
name: "a hook was recorded before added to tracker",
groupResource: "pods",
initialPod: builder.ForPod("default", "my-pod").
Containers(&v1.Container{
Name: "container1",
}).
ContainerStatuses(&v1.ContainerStatus{
Name: "container1",
State: v1.ContainerState{
Waiting: &v1.ContainerStateWaiting{},
},
}).
Result(),
byContainer: map[string][]PodExecRestoreHook{
"container1": {
{
HookName: "my-hook-1",
HookSource: HookSourceSpec,
Hook: velerov1api.ExecRestoreHook{
Container: "container1",
Command: []string{"/usr/bin/foo"},
OnError: velerov1api.HookErrorModeContinue,
WaitTimeout: metav1.Duration{Duration: time.Millisecond},
},
},
},
},
hookTracker: NewHookTracker(),
expectedFailed: 0,
},
}

for _, test := range tests1 {
Expand Down

0 comments on commit be9e3fd

Please sign in to comment.