Add functions to validate and compare the E2E Velero version.
Some checks failed
Run the E2E test on kind / get-go-version (push) Failing after 1m12s
Run the E2E test on kind / build (push) Has been skipped
Run the E2E test on kind / setup-test-matrix (push) Successful in 2s
Run the E2E test on kind / run-e2e-test (push) Has been skipped

Remove 'self' from MIGRATE_FROM_VELERO_VERSION.
  * Need to modify the BYOT case to specify MIGRATE_FROM_VELERO_VERSION.
Remove the CSI plugin installation check for no older than v1.14

Signed-off-by: Xun Jiang <xun.jiang@broadcom.com>
This commit is contained in:
Xun Jiang
2025-12-23 13:21:06 +08:00
parent 327ea3ea13
commit ccb25ec5b0
5 changed files with 147 additions and 47 deletions

View File

@@ -62,6 +62,8 @@ GINKGO_LABELS ?=
# https://onsi.github.io/ginkgo/#mental-model-how-ginkgo-handles-failure
FAIL_FAST ?= false
VERSION ?= main
VELERO_CLI ?=$$(pwd)/../_output/bin/$(GOOS)/$(GOARCH)/velero
VELERO_IMAGE ?= velero/velero:main
@@ -83,7 +85,7 @@ UPGRADE_FROM_VELERO_VERSION ?= v1.15.2,v1.16.2
# to the end, nil string will be set if UPGRADE_FROM_VELERO_CLI is shorter than UPGRADE_FROM_VELERO_VERSION
UPGRADE_FROM_VELERO_CLI ?=
MIGRATE_FROM_VELERO_VERSION ?= v1.15.2,self
MIGRATE_FROM_VELERO_VERSION ?= v1.16.2,$(VERSION)
MIGRATE_FROM_VELERO_CLI ?=
VELERO_NAMESPACE ?= velero

View File

@@ -127,7 +127,7 @@ func init() {
flag.StringVar(
&test.VeleroCfg.UpgradeFromVeleroVersion,
"upgrade-from-velero-version",
"v1.7.1",
"v1.16.2",
"comma-separated list of Velero version to be tested with for the pre-upgrade velero server.",
)
flag.StringVar(
@@ -139,7 +139,7 @@ func init() {
flag.StringVar(
&test.VeleroCfg.MigrateFromVeleroVersion,
"migrate-from-velero-version",
"self",
"v1.17.1",
"comma-separated list of Velero version to be tested with on source cluster.",
)
flag.StringVar(
@@ -727,6 +727,36 @@ func TestE2e(t *testing.T) {
}
}
// Validate the Velero version
if len(test.VeleroCfg.VeleroVersion) > 0 {
if err := veleroutil.ValidateVeleroVersion(test.VeleroCfg.VeleroVersion); err != nil {
fmt.Println("VeleroVersion is invalid: ", test.VeleroCfg.VeleroVersion)
t.Error(err)
}
}
// Validate the UpgradeFromVeleroVersion if provided
if len(test.VeleroCfg.UpgradeFromVeleroVersion) > 0 {
versions := strings.Split(test.VeleroCfg.UpgradeFromVeleroVersion, ",")
for _, version := range versions {
if err := veleroutil.ValidateVeleroVersion(version); err != nil {
fmt.Println("UpgradeFromVeleroVersion is invalid: ", version)
t.Error(err)
}
}
}
// Validate the MigrateFromVeleroVersion if provided
if len(test.VeleroCfg.MigrateFromVeleroVersion) > 0 {
versions := strings.Split(test.VeleroCfg.MigrateFromVeleroVersion, ",")
for _, version := range versions {
if err := veleroutil.ValidateVeleroVersion(version); err != nil {
fmt.Println("MigrateFromVeleroVersion is invalid: ", version)
t.Error(err)
}
}
}
var err error
if err = GetKubeConfigContext(); err != nil {
fmt.Println(err)

View File

@@ -23,7 +23,6 @@ import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"golang.org/x/mod/semver"
"github.com/vmware-tanzu/velero/test"
framework "github.com/vmware-tanzu/velero/test/e2e/test"
@@ -130,22 +129,17 @@ func (m *migrationE2E) Backup() error {
fmt.Sprintf("Install the expected version Velero CLI %s",
m.veleroCLI2Version.VeleroVersion),
func() {
// "self" represents 1.14.x and future versions
if m.veleroCLI2Version.VeleroVersion == "self" {
m.veleroCLI2Version.VeleroCLI = m.VeleroCfg.VeleroCLI
} else {
OriginVeleroCfg, err = veleroutil.SetImagesToDefaultValues(
OriginVeleroCfg,
m.veleroCLI2Version.VeleroVersion,
)
Expect(err).To(Succeed(),
"Fail to set images for the migrate-from Velero installation.")
OriginVeleroCfg, err = veleroutil.SetImagesToDefaultValues(
OriginVeleroCfg,
m.veleroCLI2Version.VeleroVersion,
)
Expect(err).To(Succeed(),
"Fail to set images for the migrate-from Velero installation.")
m.veleroCLI2Version.VeleroCLI, err = veleroutil.InstallVeleroCLI(
m.Ctx,
m.veleroCLI2Version.VeleroVersion)
Expect(err).To(Succeed())
}
m.veleroCLI2Version.VeleroCLI, err = veleroutil.InstallVeleroCLI(
m.Ctx,
m.veleroCLI2Version.VeleroVersion)
Expect(err).To(Succeed())
},
)
}
@@ -165,9 +159,11 @@ func (m *migrationE2E) Backup() error {
version, err := veleroutil.GetVeleroVersion(m.Ctx, OriginVeleroCfg.VeleroCLI, true)
Expect(err).To(Succeed(), "Fail to get Velero version")
OriginVeleroCfg.VeleroVersion = version
if OriginVeleroCfg.WorkerOS == common.WorkerOSWindows &&
(version != "main" && semver.Compare(version, "v1.16") < 0) {
Skip(fmt.Sprintf("Velero CLI version %s doesn't support Windows migration test.", version))
if OriginVeleroCfg.WorkerOS == common.WorkerOSWindows {
result, err := veleroutil.VersionNoOlderThan(version, "v1.16")
if err != nil || !result {
Skip(fmt.Sprintf("Velero CLI version %s doesn't support Windows migration test.", version))
}
}
if OriginVeleroCfg.SnapshotMoveData {
@@ -175,13 +171,11 @@ func (m *migrationE2E) Backup() error {
}
Expect(veleroutil.VeleroInstall(m.Ctx, &OriginVeleroCfg, false)).To(Succeed())
if m.veleroCLI2Version.VeleroVersion != "self" {
Expect(veleroutil.CheckVeleroVersion(
m.Ctx,
OriginVeleroCfg.VeleroCLI,
OriginVeleroCfg.MigrateFromVeleroVersion,
)).To(Succeed())
}
Expect(veleroutil.CheckVeleroVersion(
m.Ctx,
OriginVeleroCfg.VeleroCLI,
OriginVeleroCfg.MigrateFromVeleroVersion,
)).To(Succeed())
},
)

View File

@@ -23,6 +23,7 @@ import (
"fmt"
"os"
"os/exec"
"regexp"
"slices"
"strings"
"time"
@@ -311,6 +312,80 @@ func cleanVSpherePluginConfig(c clientset.Interface, ns, secretName, configMapNa
return nil
}
// ValidateVeleroVersion checks if the given version is valid
// version can be in the format of 'main', 'release-x.y(-dev)', or 'vX.Y(.Z)'
func ValidateVeleroVersion(version string) error {
mainRe := regexp.MustCompile(`^main$`)
releaseRe := regexp.MustCompile(`^release-(\d)\.(\d)(-dev)?$`)
tagRe := regexp.MustCompile(`^v(\d+)\.(\d+)(\.\d+)?$`)
if mainRe.MatchString(version) || releaseRe.MatchString(version) || tagRe.MatchString(version) {
return nil
}
return fmt.Errorf("invalid Velero version: %s, Velero version must be 'main', 'release-x.y(-dev)', or 'vX.Y.Z'", version)
}
// VersionNoOlderThan checks if the given version is no older than the targetVersion
// version can be in the format of 'main', 'release-x.y(-dev)', or 'vX.Y(.Z)'
// targetVersion must be in the format of 'main', or 'vX.Y.(Z)'
// return true if version is no older than targetVersion
func VersionNoOlderThan(version string, targetVersion string) (bool, error) {
mainRe := regexp.MustCompile(`^main$`)
releaseRe := regexp.MustCompile(`^release-(\d)\.(\d)(-dev)?$`)
tagRe := regexp.MustCompile(`^v(\d)\.(\d)(\.\d+)?$`)
if err := ValidateVeleroVersion(version); err != nil {
return false, err
}
if !tagRe.MatchString(targetVersion) && !mainRe.MatchString(targetVersion) {
return false, fmt.Errorf("targetVersion is invalid. it must be in the format of 'main', or 'vX.Y.(Z)'.")
}
fmt.Printf("version: %s, targetVersion: %s\n", version, targetVersion)
switch {
case mainRe.MatchString(version):
// main is always the latest
return true, nil
case releaseRe.MatchString(version):
// release-x.y(-dev) is treated as vX.Y.0
matches := releaseRe.FindStringSubmatch(version)
major := matches[1]
minor := matches[2]
switch {
case mainRe.MatchString(targetVersion):
return false, nil
default:
matches := tagRe.FindStringSubmatch(targetVersion)
targetMajor := matches[1]
targetMinor := matches[2]
if major > targetMajor && minor >= targetMinor {
return true, nil
} else {
return false, nil
}
}
case tagRe.MatchString(version):
switch {
case mainRe.MatchString(targetVersion):
return false, nil
default:
if semver.Compare(version, targetVersion) >= 0 {
return true, nil
} else {
return false, nil
}
}
}
return false, fmt.Errorf("unknown error in VersionNoOlderThan")
}
func installVeleroServer(
ctx context.Context,
cli string,
@@ -333,10 +408,12 @@ func installVeleroServer(
// TODO: need to consider align options.UseNodeAgentWindows usage
// with options.UseNodeAgent
// Only version after v1.16.0 support windows node agent.
if options.WorkerOS == common.WorkerOSWindows &&
(semver.Compare(version, "v1.16") >= 0 || version == "main") {
fmt.Println("Install node-agent-windows. The Velero version is ", version)
args = append(args, "--use-node-agent-windows")
if options.WorkerOS == common.WorkerOSWindows {
result, err := VersionNoOlderThan(version, "v1.16")
if err == nil && result {
fmt.Println("Install node-agent-windows. The Velero version is ", version)
args = append(args, "--use-node-agent-windows")
}
}
if options.DefaultVolumesToFsBackup {
@@ -452,10 +529,12 @@ func installVeleroServer(
}
// Only version no older than v1.15 support --backup-repository-configmap.
if options.BackupRepoConfigMap != "" &&
(semver.Compare(version, "v1.15") >= 0 || version == "main") {
fmt.Println("Associate backup repository ConfigMap. The Velero version is ", version)
args = append(args, fmt.Sprintf("--backup-repository-configmap=%s", options.BackupRepoConfigMap))
if options.BackupRepoConfigMap != "" {
result, err := VersionNoOlderThan(version, "v1.15")
if err == nil && result {
fmt.Println("Associate backup repository ConfigMap. The Velero version is ", version)
args = append(args, fmt.Sprintf("--backup-repository-configmap=%s", options.BackupRepoConfigMap))
}
}
if options.RepoMaintenanceJobConfigMap != "" {

View File

@@ -128,7 +128,11 @@ func SetImagesToDefaultValues(config VeleroConfig, version string) (VeleroConfig
ret.Plugins = ""
versionWithoutPatch := semver.MajorMinor(version)
versionWithoutPatch := "main"
if version != "main" {
versionWithoutPatch = semver.MajorMinor(version)
}
// Read migration case needs images from the PluginsMatrix map.
images, ok := ImagesMatrix[versionWithoutPatch]
if !ok {
@@ -153,12 +157,6 @@ func SetImagesToDefaultValues(config VeleroConfig, version string) (VeleroConfig
ret.Plugins = images[AWS][0]
}
// Because Velero CSI plugin is deprecated in v1.14,
// only need to install it for version lower than v1.14.
if strings.Contains(ret.Features, FeatureCSI) &&
semver.Compare(versionWithoutPatch, "v1.14") < 0 {
ret.Plugins = ret.Plugins + "," + images[CSI][0]
}
if ret.SnapshotMoveData && ret.CloudProvider == Azure {
ret.Plugins = ret.Plugins + "," + images[AWS][0]
}
@@ -1567,9 +1565,6 @@ func RestorePVRNum(ctx context.Context, veleroNamespace, restoreName string) (in
}
func IsSupportUploaderType(version string) (bool, error) {
if strings.Contains(version, "self") {
return true, nil
}
verSupportUploaderType, err := ver.ParseSemantic("v1.10.0")
if err != nil {
return false, err