mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-09-05 15:47:15 +00:00
Allow registry to be configured at build time
This adds a new `buildinfo` variable `ImageRegistry` that can set at build time like the `Version` variable. This allows us to customise the Velero binary to use different registries. If the variable is set, this variable wille be used when creating the URIs for both the main `velero` and `velero-restic-restore-helper` images. If it is not set, default to using Dockerhub (`velero/velero`, `velero/velero-restic-restore-helper`). There are numerous ways in which the Velero binary can be built so all of them have been updated to add the new link time flag to set the variable: * `make local` (used for local developer builds to build for the local OS and ARCH) * `make build` (used by developers and also VMware internal builds to build a specific OS and ARCH) * Goreleaser config (used when creating OSS release binaries) * Dockerfile (used to build the Velero binary used within the image) All of these workflows are currently triggered from our Makefile where the variable `REGISTRY` is already available with the default value of `velero` and used to build the image tag. Where the new `ImageRegistry` build variable is needed, we pass through this Makefile variable to those tasks so it can be used accordingly. The GitHub action and the `./hack/docker-push.sh` script used to push container images has not been modified. This will continue to use the default registry specified in the Makefile and will not explicitly pass it in. Signed-off-by: Bridget McErlean <bmcerlean@vmware.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Velero contributors.
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -31,6 +31,10 @@ var (
|
||||
// GitTreeState indicates if the git tree is clean or dirty, set by the go linker's -X flag at build
|
||||
// time.
|
||||
GitTreeState string
|
||||
|
||||
// ImageRegistry is the image registry that this build of Velero should use by default to pull the
|
||||
// Velero and Restic Restore Helper images from.
|
||||
ImageRegistry string
|
||||
)
|
||||
|
||||
// FormattedGitSHA renders the Git SHA with an indicator of the tree state.
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2020 the Velero contributors.
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"github.com/spf13/pflag"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/velero"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/client"
|
||||
"github.com/vmware-tanzu/velero/pkg/cmd"
|
||||
@@ -111,7 +112,7 @@ func (o *InstallOptions) BindFlags(flags *pflag.FlagSet) {
|
||||
func NewInstallOptions() *InstallOptions {
|
||||
return &InstallOptions{
|
||||
Namespace: velerov1api.DefaultNamespace,
|
||||
Image: install.DefaultImage,
|
||||
Image: velero.DefaultVeleroImage(),
|
||||
BackupStorageConfig: flag.NewMap(),
|
||||
VolumeSnapshotConfig: flag.NewMap(),
|
||||
PodAnnotations: flag.NewMap(),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018, 2019, 2020 the Velero contributors.
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -23,11 +23,13 @@ import (
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/velero"
|
||||
)
|
||||
|
||||
func DaemonSet(namespace string, opts ...podTemplateOption) *appsv1.DaemonSet {
|
||||
c := &podTemplateConfig{
|
||||
image: DefaultImage,
|
||||
image: velero.DefaultVeleroImage(),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2020 the Velero contributors.
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/velero"
|
||||
"github.com/vmware-tanzu/velero/pkg/builder"
|
||||
)
|
||||
|
||||
@@ -117,7 +118,7 @@ func WithDefaultVolumesToRestic() podTemplateOption {
|
||||
func Deployment(namespace string, opts ...podTemplateOption) *appsv1.Deployment {
|
||||
// TODO: Add support for server args
|
||||
c := &podTemplateConfig{
|
||||
image: DefaultImage,
|
||||
image: velero.DefaultVeleroImage(),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
|
||||
@@ -29,20 +29,9 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/vmware-tanzu/velero/config/crd/crds"
|
||||
"github.com/vmware-tanzu/velero/pkg/buildinfo"
|
||||
)
|
||||
|
||||
// Use "latest" if the build process didn't supply a version
|
||||
func imageVersion() string {
|
||||
if buildinfo.Version == "" {
|
||||
return "latest"
|
||||
}
|
||||
return buildinfo.Version
|
||||
}
|
||||
|
||||
// DefaultImage is the default image to use for the Velero deployment and restic daemonset containers.
|
||||
var (
|
||||
DefaultImage = "velero/velero:" + imageVersion()
|
||||
DefaultVeleroPodCPURequest = "500m"
|
||||
DefaultVeleroPodMemRequest = "128Mi"
|
||||
DefaultVeleroPodCPULimit = "1000m"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018, 2019, 2020 the Velero contributors.
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -29,9 +29,9 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
|
||||
veleroimage "github.com/vmware-tanzu/velero/internal/velero"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/builder"
|
||||
"github.com/vmware-tanzu/velero/pkg/buildinfo"
|
||||
velerov1client "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/label"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
|
||||
@@ -41,7 +41,6 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
defaultImageBase = "velero/velero-restic-restore-helper"
|
||||
defaultCPURequestLimit = "100m"
|
||||
defaultMemRequestLimit = "128Mi"
|
||||
defaultCommand = "/velero-restic-restore-helper"
|
||||
@@ -193,13 +192,13 @@ func getCommand(log logrus.FieldLogger, config *corev1.ConfigMap) []string {
|
||||
func getImage(log logrus.FieldLogger, config *corev1.ConfigMap) string {
|
||||
if config == nil {
|
||||
log.Debug("No config found for plugin")
|
||||
return initContainerImage(defaultImageBase)
|
||||
return veleroimage.DefaultResticRestoreHelperImage()
|
||||
}
|
||||
|
||||
image := config.Data["image"]
|
||||
if image == "" {
|
||||
log.Debugf("No custom image configured")
|
||||
return initContainerImage(defaultImageBase)
|
||||
return veleroimage.DefaultResticRestoreHelperImage()
|
||||
}
|
||||
|
||||
log = log.WithField("image", image)
|
||||
@@ -207,15 +206,17 @@ func getImage(log logrus.FieldLogger, config *corev1.ConfigMap) string {
|
||||
parts := strings.Split(image, "/")
|
||||
|
||||
if len(parts) == 1 {
|
||||
defaultImage := veleroimage.DefaultResticRestoreHelperImage()
|
||||
// Image supplied without registry part
|
||||
log.Debugf("Plugin config contains image name without registry name. Return defaultImageBase")
|
||||
return initContainerImage(defaultImageBase)
|
||||
log.Debugf("Plugin config contains image name without registry name. Using default init container image: %q", defaultImage)
|
||||
return defaultImage
|
||||
}
|
||||
|
||||
if !(strings.Contains(parts[len(parts)-1], ":")) {
|
||||
// tag-less image name: add tag
|
||||
log.Debugf("Plugin config contains image name without tag. Adding tag.")
|
||||
return initContainerImage(image)
|
||||
tag := veleroimage.ImageTag()
|
||||
// tag-less image name: add default image tag for this version of Velero
|
||||
log.Debugf("Plugin config contains image name without tag. Adding tag: %q", tag)
|
||||
return fmt.Sprintf("%s:%s", image, tag)
|
||||
} else {
|
||||
// tagged image name
|
||||
log.Debugf("Plugin config contains image name with tag")
|
||||
@@ -306,12 +307,3 @@ func newResticInitContainerBuilder(image, restoreUID string) *builder.ContainerB
|
||||
},
|
||||
}...)
|
||||
}
|
||||
|
||||
func initContainerImage(imageBase string) string {
|
||||
tag := buildinfo.Version
|
||||
if tag == "" {
|
||||
tag = "latest"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s:%s", imageBase, tag)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2019 the Velero contributors.
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,6 @@ package restore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
@@ -31,6 +30,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
veleroimage "github.com/vmware-tanzu/velero/internal/velero"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/builder"
|
||||
"github.com/vmware-tanzu/velero/pkg/buildinfo"
|
||||
@@ -49,41 +49,40 @@ func TestGetImage(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
originalVersion := buildinfo.Version
|
||||
buildinfo.Version = "buildinfo-version"
|
||||
defer func() {
|
||||
buildinfo.Version = originalVersion
|
||||
}()
|
||||
defaultImage := veleroimage.DefaultResticRestoreHelperImage()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
configMap *corev1api.ConfigMap
|
||||
want string
|
||||
name string
|
||||
configMap *corev1api.ConfigMap
|
||||
buildInfoVersion string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "nil config map returns default image with buildinfo.Version as tag",
|
||||
name: "nil config map returns default image",
|
||||
configMap: nil,
|
||||
want: fmt.Sprintf("%s:%s", defaultImageBase, buildinfo.Version),
|
||||
want: defaultImage,
|
||||
},
|
||||
{
|
||||
name: "config map without 'image' key returns default image with buildinfo.Version as tag",
|
||||
name: "config map without 'image' key returns default image",
|
||||
configMap: configMapWithData("non-matching-key", "val"),
|
||||
want: fmt.Sprintf("%s:%s", defaultImageBase, buildinfo.Version),
|
||||
want: defaultImage,
|
||||
},
|
||||
{
|
||||
name: "config map without '/' in image name returns default image with buildinfo.Version as tag",
|
||||
name: "config map without '/' in image name returns default image",
|
||||
configMap: configMapWithData("image", "my-image"),
|
||||
want: fmt.Sprintf("%s:%s", defaultImageBase, buildinfo.Version),
|
||||
want: defaultImage,
|
||||
},
|
||||
{
|
||||
name: "config map with untagged image returns image with buildinfo.Version as tag",
|
||||
configMap: configMapWithData("image", "myregistry.io/my-image"),
|
||||
want: fmt.Sprintf("%s:%s", "myregistry.io/my-image", buildinfo.Version),
|
||||
name: "config map with untagged image returns image with buildinfo.Version as tag",
|
||||
configMap: configMapWithData("image", "myregistry.io/my-image"),
|
||||
buildInfoVersion: "buildinfo-version",
|
||||
want: "myregistry.io/my-image:buildinfo-version",
|
||||
},
|
||||
{
|
||||
name: "config map with untagged image and custom registry port with ':' returns image with buildinfo.Version as tag",
|
||||
configMap: configMapWithData("image", "myregistry.io:34567/my-image"),
|
||||
want: fmt.Sprintf("%s:%s", "myregistry.io:34567/my-image", buildinfo.Version),
|
||||
name: "config map with untagged image and custom registry port with ':' returns image with buildinfo.Version as tag",
|
||||
configMap: configMapWithData("image", "myregistry.io:34567/my-image"),
|
||||
buildInfoVersion: "buildinfo-version",
|
||||
want: "myregistry.io:34567/my-image:buildinfo-version",
|
||||
},
|
||||
{
|
||||
name: "config map with tagged image returns tagged image",
|
||||
@@ -99,6 +98,13 @@ func TestGetImage(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if test.buildInfoVersion != "" {
|
||||
originalVersion := buildinfo.Version
|
||||
buildinfo.Version = test.buildInfoVersion
|
||||
defer func() {
|
||||
buildinfo.Version = originalVersion
|
||||
}()
|
||||
}
|
||||
assert.Equal(t, test.want, getImage(velerotest.NewLogger(), test.configMap))
|
||||
})
|
||||
}
|
||||
@@ -119,6 +125,8 @@ func TestResticRestoreActionExecute(t *testing.T) {
|
||||
veleroNs = "velero"
|
||||
)
|
||||
|
||||
defaultResticRestoreHelperImage := veleroimage.DefaultResticRestoreHelperImage()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
pod *corev1api.Pod
|
||||
@@ -135,7 +143,7 @@ func TestResticRestoreActionExecute(t *testing.T) {
|
||||
ObjectMeta(
|
||||
builder.WithAnnotations("snapshot.velero.io/myvol", "")).
|
||||
InitContainers(
|
||||
newResticInitContainerBuilder(initContainerImage(defaultImageBase), "").
|
||||
newResticInitContainerBuilder(defaultResticRestoreHelperImage, "").
|
||||
Resources(&resourceReqs).
|
||||
SecurityContext(&securityContext).
|
||||
VolumeMounts(builder.ForVolumeMount("myvol", "/restores/myvol").Result()).
|
||||
@@ -152,7 +160,7 @@ func TestResticRestoreActionExecute(t *testing.T) {
|
||||
ObjectMeta(
|
||||
builder.WithAnnotations("snapshot.velero.io/myvol", "")).
|
||||
InitContainers(
|
||||
newResticInitContainerBuilder(initContainerImage(defaultImageBase), "").
|
||||
newResticInitContainerBuilder(defaultResticRestoreHelperImage, "").
|
||||
Resources(&resourceReqs).
|
||||
SecurityContext(&securityContext).
|
||||
VolumeMounts(builder.ForVolumeMount("myvol", "/restores/myvol").Result()).
|
||||
@@ -195,7 +203,7 @@ func TestResticRestoreActionExecute(t *testing.T) {
|
||||
ObjectMeta(
|
||||
builder.WithAnnotations("snapshot.velero.io/not-used", "")).
|
||||
InitContainers(
|
||||
newResticInitContainerBuilder(initContainerImage(defaultImageBase), "").
|
||||
newResticInitContainerBuilder(defaultResticRestoreHelperImage, "").
|
||||
Resources(&resourceReqs).
|
||||
SecurityContext(&securityContext).
|
||||
VolumeMounts(builder.ForVolumeMount("vol-1", "/restores/vol-1").Result(), builder.ForVolumeMount("vol-2", "/restores/vol-2").Result()).
|
||||
@@ -239,7 +247,7 @@ func TestResticRestoreActionExecute(t *testing.T) {
|
||||
builder.ForVolume("vol-2").PersistentVolumeClaimSource("pvc-2").Result(),
|
||||
).
|
||||
InitContainers(
|
||||
newResticInitContainerBuilder(initContainerImage(defaultImageBase), "").
|
||||
newResticInitContainerBuilder(defaultResticRestoreHelperImage, "").
|
||||
Resources(&resourceReqs).
|
||||
SecurityContext(&securityContext).
|
||||
VolumeMounts(builder.ForVolumeMount("vol-1", "/restores/vol-1").Result(), builder.ForVolumeMount("vol-2", "/restores/vol-2").Result()).
|
||||
|
||||
Reference in New Issue
Block a user