Merge restore helper image into Velero server image

Merge restore helper image into Velero server image

Fixes #8484

Signed-off-by: Wenkai Yin(尹文开) <yinw@vmware.com>
This commit is contained in:
Wenkai Yin(尹文开)
2024-12-23 15:50:23 +08:00
parent 78c97d93b5
commit eb5230e12f
9 changed files with 60 additions and 35 deletions

View File

@@ -42,6 +42,8 @@ RUN mkdir -p /output/usr/bin && \
export GOARM=$( echo "${GOARM}" | cut -c2-) && \ export GOARM=$( echo "${GOARM}" | cut -c2-) && \
go build -o /output/${BIN} \ go build -o /output/${BIN} \
-ldflags "${LDFLAGS}" ${PKG}/cmd/${BIN} && \ -ldflags "${LDFLAGS}" ${PKG}/cmd/${BIN} && \
go build -o /output/velero-restore-helper \
-ldflags "${LDFLAGS}" ${PKG}/cmd/velero-restore-helper && \
go build -o /output/velero-helper \ go build -o /output/velero-helper \
-ldflags "${LDFLAGS}" ${PKG}/cmd/velero-helper && \ -ldflags "${LDFLAGS}" ${PKG}/cmd/velero-helper && \
go clean -modcache -cache go clean -modcache -cache

View File

@@ -148,17 +148,14 @@ GOBIN=$$(pwd)/.go/bin
# If you want to build all containers, see the 'all-containers' rule. # If you want to build all containers, see the 'all-containers' rule.
all: all:
@$(MAKE) build @$(MAKE) build
@$(MAKE) build BIN=velero-restore-helper
build-%: build-%:
@$(MAKE) --no-print-directory ARCH=$* build @$(MAKE) --no-print-directory ARCH=$* build
@$(MAKE) --no-print-directory ARCH=$* build BIN=velero-restore-helper
all-build: $(addprefix build-, $(CLI_PLATFORMS)) all-build: $(addprefix build-, $(CLI_PLATFORMS))
all-containers: all-containers:
@$(MAKE) --no-print-directory container @$(MAKE) --no-print-directory container
@$(MAKE) --no-print-directory container BIN=velero-restore-helper
local: build-dirs local: build-dirs
# Add DEBUG=1 to enable debug locally # Add DEBUG=1 to enable debug locally

View File

@@ -0,0 +1 @@
Merge restore helper image into Velero server image

View File

@@ -43,9 +43,3 @@ func ImageTag() string {
func DefaultVeleroImage() string { func DefaultVeleroImage() string {
return fmt.Sprintf("%s/%s:%s", imageRegistry(), "velero", ImageTag()) return fmt.Sprintf("%s/%s:%s", imageRegistry(), "velero", ImageTag())
} }
// DefaultRestoreHelperImage returns the default container image to use for the restore helper
// for this version of Velero.
func DefaultRestoreHelperImage() string {
return fmt.Sprintf("%s/%s:%s", imageRegistry(), "velero-restore-helper", ImageTag())
}

View File

@@ -134,7 +134,3 @@ func testDefaultImage(t *testing.T, defaultImageFn func() string, imageName stri
func TestDefaultVeleroImage(t *testing.T) { func TestDefaultVeleroImage(t *testing.T) {
testDefaultImage(t, DefaultVeleroImage, "velero") testDefaultImage(t, DefaultVeleroImage, "velero")
} }
func TestDefaultRestoreHelperImage(t *testing.T) {
testDefaultImage(t, DefaultRestoreHelperImage, "velero-restore-helper")
}

View File

@@ -295,7 +295,7 @@ func newPodVolumeRestoreItemAction(f client.Factory) plugincommon.HandlerInitial
return nil, err return nil, err
} }
return ria.NewPodVolumeRestoreAction(logger, client.CoreV1().ConfigMaps(f.Namespace()), crClient), nil return ria.NewPodVolumeRestoreAction(logger, client.CoreV1().ConfigMaps(f.Namespace()), crClient, f.Namespace())
} }
} }

View File

@@ -25,9 +25,11 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1" corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
@@ -40,6 +42,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/podvolume" "github.com/vmware-tanzu/velero/pkg/podvolume"
"github.com/vmware-tanzu/velero/pkg/restorehelper" "github.com/vmware-tanzu/velero/pkg/restorehelper"
"github.com/vmware-tanzu/velero/pkg/util/kube" "github.com/vmware-tanzu/velero/pkg/util/kube"
veleroutil "github.com/vmware-tanzu/velero/pkg/util/velero"
) )
const ( const (
@@ -50,17 +53,24 @@ const (
) )
type PodVolumeRestoreAction struct { type PodVolumeRestoreAction struct {
logger logrus.FieldLogger logger logrus.FieldLogger
client corev1client.ConfigMapInterface client corev1client.ConfigMapInterface
crClient ctrlclient.Client crClient ctrlclient.Client
veleroImage string
} }
func NewPodVolumeRestoreAction(logger logrus.FieldLogger, client corev1client.ConfigMapInterface, crClient ctrlclient.Client) *PodVolumeRestoreAction { func NewPodVolumeRestoreAction(logger logrus.FieldLogger, client corev1client.ConfigMapInterface, crClient ctrlclient.Client, namespace string) (*PodVolumeRestoreAction, error) {
return &PodVolumeRestoreAction{ deployment := &appsv1.Deployment{}
logger: logger, if err := crClient.Get(context.TODO(), types.NamespacedName{Name: "velero", Namespace: namespace}, deployment); err != nil {
client: client, return nil, err
crClient: crClient,
} }
image := veleroutil.GetVeleroServerImage(deployment)
return &PodVolumeRestoreAction{
logger: logger,
client: client,
crClient: crClient,
veleroImage: image,
}, nil
} }
func (a *PodVolumeRestoreAction) AppliesTo() (velero.ResourceSelector, error) { func (a *PodVolumeRestoreAction) AppliesTo() (velero.ResourceSelector, error) {
@@ -117,7 +127,7 @@ func (a *PodVolumeRestoreAction) Execute(input *velero.RestoreItemActionExecuteI
return nil, err return nil, err
} }
image := getImage(log, config) image := getImage(log, config, a.veleroImage)
log.Infof("Using image %q", image) log.Infof("Using image %q", image)
cpuRequest, memRequest := getResourceRequests(log, config) cpuRequest, memRequest := getResourceRequests(log, config)
@@ -200,16 +210,16 @@ func getCommand(log logrus.FieldLogger, config *corev1.ConfigMap) []string {
return []string{config.Data["command"]} return []string{config.Data["command"]}
} }
func getImage(log logrus.FieldLogger, config *corev1.ConfigMap) string { func getImage(log logrus.FieldLogger, config *corev1.ConfigMap, defaultImage string) string {
if config == nil { if config == nil {
log.Debug("No config found for plugin") log.Debug("No config found for plugin")
return veleroimage.DefaultRestoreHelperImage() return defaultImage
} }
image := config.Data["image"] image := config.Data["image"]
if image == "" { if image == "" {
log.Debugf("No custom image configured") log.Debugf("No custom image configured")
return veleroimage.DefaultRestoreHelperImage() return defaultImage
} }
log = log.WithField("image", image) log = log.WithField("image", image)
@@ -217,7 +227,6 @@ func getImage(log logrus.FieldLogger, config *corev1.ConfigMap) string {
parts := strings.Split(image, "/") parts := strings.Split(image, "/")
if len(parts) == 1 { if len(parts) == 1 {
defaultImage := veleroimage.DefaultRestoreHelperImage()
// Image supplied without registry part // Image supplied without registry part
log.Infof("Plugin config contains image name without registry name. Using default init container image: %q", defaultImage) log.Infof("Plugin config contains image name without registry name. Using default init container image: %q", defaultImage)
return defaultImage return defaultImage

View File

@@ -25,12 +25,13 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
corev1api "k8s.io/api/core/v1" corev1api "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
veleroimage "github.com/vmware-tanzu/velero/internal/velero"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/builder" "github.com/vmware-tanzu/velero/pkg/builder"
"github.com/vmware-tanzu/velero/pkg/buildinfo" "github.com/vmware-tanzu/velero/pkg/buildinfo"
@@ -48,7 +49,7 @@ func TestGetImage(t *testing.T) {
} }
} }
defaultImage := veleroimage.DefaultRestoreHelperImage() defaultImage := "velero/velero:v1.0"
tests := []struct { tests := []struct {
name string name string
@@ -104,7 +105,7 @@ func TestGetImage(t *testing.T) {
buildinfo.Version = originalVersion buildinfo.Version = originalVersion
}() }()
} }
assert.Equal(t, test.want, getImage(velerotest.NewLogger(), test.configMap)) assert.Equal(t, test.want, getImage(velerotest.NewLogger(), test.configMap, defaultImage))
}) })
} }
} }
@@ -134,7 +135,7 @@ func TestPodVolumeRestoreActionExecute(t *testing.T) {
veleroNs = "velero" veleroNs = "velero"
) )
defaultRestoreHelperImage := veleroimage.DefaultRestoreHelperImage() defaultRestoreHelperImage := "velero/velero:v1.0"
tests := []struct { tests := []struct {
name string name string
@@ -265,10 +266,34 @@ func TestPodVolumeRestoreActionExecute(t *testing.T) {
}, },
} }
veleroDeployment := &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
APIVersion: appsv1.SchemeGroupVersion.String(),
Kind: "Deployment",
},
ObjectMeta: metav1.ObjectMeta{
Namespace: "velero",
Name: "velero",
},
Spec: appsv1.DeploymentSpec{
Template: corev1api.PodTemplateSpec{
Spec: corev1api.PodSpec{
Containers: []corev1api.Container{
{
Image: "velero/velero:v1.0",
},
},
},
},
},
}
for _, tc := range tests { for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
clientset := fake.NewSimpleClientset() clientset := fake.NewSimpleClientset()
crClient := velerotest.NewFakeControllerRuntimeClient(t, tc.podVolumeBackups...)
objects := []runtime.Object{veleroDeployment}
objects = append(objects, tc.podVolumeBackups...)
crClient := velerotest.NewFakeControllerRuntimeClient(t, objects...)
unstructuredPod, err := runtime.DefaultUnstructuredConverter.ToUnstructured(tc.pod) unstructuredPod, err := runtime.DefaultUnstructuredConverter.ToUnstructured(tc.pod)
require.NoError(t, err) require.NoError(t, err)
@@ -295,11 +320,13 @@ func TestPodVolumeRestoreActionExecute(t *testing.T) {
Result(), Result(),
} }
a := NewPodVolumeRestoreAction( a, err := NewPodVolumeRestoreAction(
logrus.StandardLogger(), logrus.StandardLogger(),
clientset.CoreV1().ConfigMaps(veleroNs), clientset.CoreV1().ConfigMaps(veleroNs),
crClient, crClient,
"velero",
) )
require.NoError(t, err)
// method under test // method under test
res, err := a.Execute(input) res, err := a.Execute(input)

View File

@@ -356,8 +356,7 @@ with an infinite sleep) to mount these PVC/PV pairs prior taking a Velero backup
## Customize Restore Helper Container ## Customize Restore Helper Container
Velero uses a helper init container when performing a FSB restore. By default, the image for this container is Velero uses a helper init container when performing a FSB restore. By default, the image for this container is same with the Velero server container.
`velero/velero-restore-helper:<VERSION>`, where `VERSION` matches the version/tag of the main Velero image.
You can customize the image that is used for this helper by creating a ConfigMap in the Velero namespace with the alternate image. You can customize the image that is used for this helper by creating a ConfigMap in the Velero namespace with the alternate image.
In addition, you can customize the resource requirements for the init container, should you need. In addition, you can customize the resource requirements for the init container, should you need.