From 5433eb308166d0850efd583dc8fbbcadfc874d9f Mon Sep 17 00:00:00 2001 From: Gabriele Fedi Date: Wed, 1 Apr 2026 20:27:18 +0200 Subject: [PATCH] feat: support backup hooks on native sidecars (#9403) * feat: support backup hooks on sidecars Add support for configuring Kubernates native Sidecars as target containrs for Backup Hooks commands. This is purely a validation level patch as the actual pods/exec API doesn't make any distinction between standard and sidecar containers. Signed-off-by: Gabriele Fedi * test: extend unit tests Signed-off-by: Gabriele Fedi * chore: changelog Signed-off-by: Gabriele Fedi * style: fix linter issues Signed-off-by: Gabriele Fedi --------- Signed-off-by: Gabriele Fedi --- changelogs/unreleased/9403-GabriFedi97 | 1 + pkg/podexec/pod_command_executor.go | 21 +++++++++++++++++---- pkg/podexec/pod_command_executor_test.go | 18 +++++++++++++++++- 3 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 changelogs/unreleased/9403-GabriFedi97 diff --git a/changelogs/unreleased/9403-GabriFedi97 b/changelogs/unreleased/9403-GabriFedi97 new file mode 100644 index 000000000..515549220 --- /dev/null +++ b/changelogs/unreleased/9403-GabriFedi97 @@ -0,0 +1 @@ +Include InitContainer configured as Sidecars when validating the existence of the target containers configured for the Backup Hooks diff --git a/pkg/podexec/pod_command_executor.go b/pkg/podexec/pod_command_executor.go index b1d7fbf59..0dbc28e95 100644 --- a/pkg/podexec/pod_command_executor.go +++ b/pkg/podexec/pod_command_executor.go @@ -20,6 +20,7 @@ import ( "bytes" "context" "net/url" + "slices" "time" "github.com/pkg/errors" @@ -184,10 +185,22 @@ func (e *defaultPodCommandExecutor) ExecutePodCommand(log logrus.FieldLogger, it } func ensureContainerExists(pod *corev1api.Pod, container string) error { - for _, c := range pod.Spec.Containers { - if c.Name == container { - return nil - } + existsAsMainContainer := slices.ContainsFunc(pod.Spec.Containers, func(c corev1api.Container) bool { + return c.Name == container + }) + + if existsAsMainContainer { + return nil + } + + existsAsSidecar := slices.ContainsFunc(pod.Spec.InitContainers, func(c corev1api.Container) bool { + return c.RestartPolicy != nil && + *c.RestartPolicy == corev1api.ContainerRestartPolicyAlways && + c.Name == container + }) + + if existsAsSidecar { + return nil } return errors.Errorf("no such container: %q", container) diff --git a/pkg/podexec/pod_command_executor_test.go b/pkg/podexec/pod_command_executor_test.go index e28eb0458..3286ba42d 100644 --- a/pkg/podexec/pod_command_executor_test.go +++ b/pkg/podexec/pod_command_executor_test.go @@ -35,6 +35,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/rest" "k8s.io/client-go/tools/remotecommand" + "k8s.io/utils/ptr" v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" velerotest "github.com/vmware-tanzu/velero/pkg/test" @@ -253,6 +254,15 @@ func TestEnsureContainerExists(t *testing.T) { Name: "foo", }, }, + InitContainers: []corev1api.Container{ + { + Name: "baz", + }, + { + Name: "qux", + RestartPolicy: ptr.To(corev1api.ContainerRestartPolicyAlways), + }, + }, }, } @@ -260,7 +270,13 @@ func TestEnsureContainerExists(t *testing.T) { require.EqualError(t, err, `no such container: "bar"`) err = ensureContainerExists(pod, "foo") - assert.NoError(t, err) + require.NoError(t, err) + + err = ensureContainerExists(pod, "baz") + require.EqualError(t, err, `no such container: "baz"`) + + err = ensureContainerExists(pod, "qux") + require.NoError(t, err) } func TestPodCompeted(t *testing.T) {