diff --git a/Dockerfile b/Dockerfile index f8458304d..39106b9cb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,12 +57,9 @@ FROM ubuntu:focal LABEL maintainer="Nolan Brubaker " -ARG BIN - RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* COPY --from=builder /output / USER nobody:nogroup -ENTRYPOINT ["/${BIN}"] diff --git a/changelogs/unreleased/2802-ashish-amarnath b/changelogs/unreleased/2802-ashish-amarnath new file mode 100644 index 000000000..66681273f --- /dev/null +++ b/changelogs/unreleased/2802-ashish-amarnath @@ -0,0 +1 @@ +🐛 Supply command to run restic-wait init container diff --git a/pkg/builder/container_builder.go b/pkg/builder/container_builder.go index 347c8838f..21b17462c 100644 --- a/pkg/builder/container_builder.go +++ b/pkg/builder/container_builder.go @@ -110,8 +110,8 @@ func (b *ContainerBuilder) Command(command []string) *ContainerBuilder { if b.object.Command == nil { b.object.Command = []string{} } - for _, c := range command { - b.object.Command = append(b.object.Command, c) - } + + b.object.Command = append(b.object.Command, command...) + return b } diff --git a/pkg/restore/restic_restore_action.go b/pkg/restore/restic_restore_action.go index f41022632..38aebd72c 100644 --- a/pkg/restore/restic_restore_action.go +++ b/pkg/restore/restic_restore_action.go @@ -44,6 +44,7 @@ const ( defaultImageBase = "velero/velero-restic-restore-helper" defaultCPURequestLimit = "100m" defaultMemRequestLimit = "128Mi" + defaultCommand = "/velero-restic-restore-helper" ) type ResticRestoreAction struct { @@ -148,6 +149,7 @@ func (a *ResticRestoreAction) Execute(input *velero.RestoreItemActionExecuteInpu } initContainerBuilder.VolumeMounts(mount) } + initContainerBuilder.Command(getCommand(log, config)) initContainer := *initContainerBuilder.Result() if len(pod.Spec.InitContainers) == 0 || pod.Spec.InitContainers[0].Name != restic.InitContainer { @@ -164,6 +166,21 @@ func (a *ResticRestoreAction) Execute(input *velero.RestoreItemActionExecuteInpu return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil } +func getCommand(log logrus.FieldLogger, config *corev1.ConfigMap) []string { + if config == nil { + log.Debug("No config found for plugin") + return []string{defaultCommand} + } + + if config.Data["command"] == "" { + log.Debugf("No custom command configured") + return []string{defaultCommand} + } + + log.Debugf("Using custom command %s", config.Data["command"]) + return []string{config.Data["command"]} +} + func getImage(log logrus.FieldLogger, config *corev1.ConfigMap) string { if config == nil { log.Debug("No config found for plugin") diff --git a/pkg/restore/restic_restore_action_test.go b/pkg/restore/restic_restore_action_test.go index a079dcbaf..6623cd3f5 100644 --- a/pkg/restore/restic_restore_action_test.go +++ b/pkg/restore/restic_restore_action_test.go @@ -137,8 +137,8 @@ func TestResticRestoreActionExecute(t *testing.T) { newResticInitContainerBuilder(initContainerImage(defaultImageBase), ""). Resources(&resourceReqs). SecurityContext(&securityContext). - VolumeMounts(builder.ForVolumeMount("myvol", "/restores/myvol").Result()).Result()). - Result(), + VolumeMounts(builder.ForVolumeMount("myvol", "/restores/myvol").Result()). + Command([]string{"/velero-restic-restore-helper"}).Result()).Result(), }, { name: "Restoring pod with other initContainers adds the restic initContainer as the first one", @@ -154,7 +154,8 @@ func TestResticRestoreActionExecute(t *testing.T) { newResticInitContainerBuilder(initContainerImage(defaultImageBase), ""). Resources(&resourceReqs). SecurityContext(&securityContext). - VolumeMounts(builder.ForVolumeMount("myvol", "/restores/myvol").Result()).Result(), + VolumeMounts(builder.ForVolumeMount("myvol", "/restores/myvol").Result()). + Command([]string{"/velero-restic-restore-helper"}).Result(), builder.ForContainer("first-container", "").Result()). Result(), }, @@ -194,7 +195,8 @@ func TestResticRestoreActionExecute(t *testing.T) { newResticInitContainerBuilder(initContainerImage(defaultImageBase), ""). Resources(&resourceReqs). SecurityContext(&securityContext). - VolumeMounts(builder.ForVolumeMount("vol-1", "/restores/vol-1").Result(), builder.ForVolumeMount("vol-2", "/restores/vol-2").Result()).Result(), + VolumeMounts(builder.ForVolumeMount("vol-1", "/restores/vol-1").Result(), builder.ForVolumeMount("vol-2", "/restores/vol-2").Result()). + Command([]string{"/velero-restic-restore-helper"}).Result(), builder.ForContainer("first-container", "").Result()). Result(), }, @@ -250,5 +252,47 @@ func TestResticRestoreActionExecute(t *testing.T) { assert.Equal(t, tc.want, updatedPod) }) } - +} + +func TestGetCommand(t *testing.T) { + configMapWithData := func(key, val string) *corev1api.ConfigMap { + return &corev1api.ConfigMap{ + Data: map[string]string{ + key: val, + }, + } + } + testCases := []struct { + name string + configMap *corev1api.ConfigMap + expected []string + }{ + { + name: "should get default command when config key is missing", + configMap: configMapWithData("non-matching-key", "val"), + expected: []string{defaultCommand}, + }, + { + name: "should get default command when config key is empty", + configMap: configMapWithData("command", ""), + expected: []string{defaultCommand}, + }, + { + name: "should get default command when config is nil", + configMap: nil, + expected: []string{defaultCommand}, + }, + { + name: "should get command from config", + configMap: configMapWithData("command", "foobarbz"), + expected: []string{"foobarbz"}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actual := getCommand(velerotest.NewLogger(), tc.configMap) + assert.Equal(t, tc.expected, actual) + }) + } }