From bc49963f1e8561ee7758ea1f7e64565630f8b1d5 Mon Sep 17 00:00:00 2001 From: R4mbo Date: Mon, 24 Aug 2026 23:54:04 +0530 Subject: [PATCH] prevent panic when the restore hook init container command annotation is empty (#10371) * prevent panic when the restore hook init container command annotation is empty Signed-off-by: samay43 * add changelog entry Signed-off-by: samay43 --------- Signed-off-by: samay43 Co-authored-by: Daniel Jiang --- changelogs/unreleased/10371-samay43 | 1 + internal/hook/item_hook_handler.go | 6 ++++++ internal/hook/item_hook_handler_test.go | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 changelogs/unreleased/10371-samay43 diff --git a/changelogs/unreleased/10371-samay43 b/changelogs/unreleased/10371-samay43 new file mode 100644 index 000000000..d1ab7571e --- /dev/null +++ b/changelogs/unreleased/10371-samay43 @@ -0,0 +1 @@ +prevent panic when the restore hook init container command annotation is empty diff --git a/internal/hook/item_hook_handler.go b/internal/hook/item_hook_handler.go index bed48c5ea..dc4a37bfa 100644 --- a/internal/hook/item_hook_handler.go +++ b/internal/hook/item_hook_handler.go @@ -365,6 +365,12 @@ func getPodExecHookFromAnnotations(annotations map[string]string, phase HookPhas func parseStringToCommand(commandValue string) []string { var command []string + // An empty command means the container image's own entrypoint should be used. + // Callers that require a command already return early; getInitContainerFromAnnotation + // deliberately allows this case, so return nil rather than indexing an empty string. + if commandValue == "" { + return nil + } // check for json array if commandValue[0] == '[' { if err := json.Unmarshal([]byte(commandValue), &command); err != nil { diff --git a/internal/hook/item_hook_handler_test.go b/internal/hook/item_hook_handler_test.go index 1f2df9469..792bcd66e 100644 --- a/internal/hook/item_hook_handler_test.go +++ b/internal/hook/item_hook_handler_test.go @@ -1287,6 +1287,25 @@ func TestGetInitContainerFromAnnotations(t *testing.T) { podRestoreHookInitContainerCommandAnnotationKey: "[foobarbaz", }, }, + { + name: "should use the image's default entrypoint when the command annotation is empty", + expectNil: false, + expected: builder.ForContainer("restore-init1", "busy-box").Result(), + inputAnnotations: map[string]string{ + podRestoreHookInitContainerImageAnnotationKey: "busy-box", + podRestoreHookInitContainerNameAnnotationKey: "restore-init", + podRestoreHookInitContainerCommandAnnotationKey: "", + }, + }, + { + name: "should use the image's default entrypoint when the command annotation is missing", + expectNil: false, + expected: builder.ForContainer("restore-init1", "busy-box").Result(), + inputAnnotations: map[string]string{ + podRestoreHookInitContainerImageAnnotationKey: "busy-box", + podRestoreHookInitContainerNameAnnotationKey: "restore-init", + }, + }, } for _, tc := range testCases {