🐛 Supply command to run restic-wait init container

Signed-off-by: Ashish Amarnath <ashisham@vmware.com>
pull/2802/head
Ashish Amarnath 2020-08-07 11:01:17 -07:00
parent 5b28d70e49
commit e391e43192
5 changed files with 70 additions and 11 deletions

View File

@ -57,12 +57,9 @@ FROM ubuntu:focal
LABEL maintainer="Nolan Brubaker <brubakern@vmware.com>"
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}"]

View File

@ -0,0 +1 @@
🐛 Supply command to run restic-wait init container

View File

@ -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
}

View File

@ -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")

View File

@ -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)
})
}
}