From 754c748ae8d71dd43b7b1ab6d2b39f5a25784b1b Mon Sep 17 00:00:00 2001 From: "Johannes M. Scheuermann" Date: Thu, 23 May 2024 13:52:41 +0200 Subject: [PATCH] Allow to override the image tag for specific versions --- e2e/Makefile | 3 + e2e/fixtures/factory.go | 14 +++- e2e/fixtures/fdb_operator_client.go | 114 ++++++++++++++++++++-------- e2e/fixtures/options.go | 45 ++++++++++- 4 files changed, 140 insertions(+), 36 deletions(-) diff --git a/e2e/Makefile b/e2e/Makefile index b9b5258b..784467e9 100644 --- a/e2e/Makefile +++ b/e2e/Makefile @@ -35,6 +35,8 @@ UPGRADE_VERSIONS?="$(FDB_VERSION):$(NEXT_FDB_VERSION)" FEATURE_UNIFIED_IMAGE?=false FEATURE_DNS?=false FEATURE_LOCALITIES?=false +# Allows to specify the tag for a specific FDB version. Format is 7.1.57:7.1.57-testing,7.3.35:7.3.35-debugging +FDB_VERSION_TAG_MAPPING?= # Make bash pickier about errors. SHELL=/bin/bash -euo pipefail @@ -131,4 +133,5 @@ nightly-tests: run --dump-operator-state=$(DUMP_OPERATOR_STATE) \ --cluster-name=$(CLUSTER_NAME) \ --storage-engine=$(STORAGE_ENGINE) \ + --fdb-version-tag-mapping=$(FDB_VERSION_TAG_MAPPING) \ | grep -v 'constructing many client instances from the same exec auth config can cause performance problems during cert rotation' &> $(BASE_DIR)/../logs/$<.log diff --git a/e2e/fixtures/factory.go b/e2e/fixtures/factory.go index 3b3af959..2958d422 100644 --- a/e2e/fixtures/factory.go +++ b/e2e/fixtures/factory.go @@ -210,11 +210,12 @@ func (factory *Factory) getContainerOverrides( GetDebugImage(debugSymbols, factory.GetFoundationDBImage()), ) - mainOverrides := fdbv1beta2.ContainerOverrides{ - EnableTLS: false, + // If the version tag mapping is define make use of that. + imageConfigs := factory.options.getImageVersionConfig(mainImage) + if len(imageConfigs) == 0 { // The first entry is version specific e.g. this image + tag (if specified) will be used for the provided version // the second entry ensures we set the base image for e.g. upgrades independent of the version. - ImageConfigs: []fdbv1beta2.ImageConfig{ + imageConfigs = []fdbv1beta2.ImageConfig{ { BaseImage: mainImage, Tag: mainTag, @@ -223,7 +224,12 @@ func (factory *Factory) getContainerOverrides( { BaseImage: mainImage, }, - }, + } + } + + mainOverrides := fdbv1beta2.ContainerOverrides{ + EnableTLS: false, + ImageConfigs: imageConfigs, } sidecarImage, sidecarTag := GetBaseImageAndTag( diff --git a/e2e/fixtures/fdb_operator_client.go b/e2e/fixtures/fdb_operator_client.go index 7f42d5c7..b8b5b729 100644 --- a/e2e/fixtures/fdb_operator_client.go +++ b/e2e/fixtures/fdb_operator_client.go @@ -28,7 +28,6 @@ import ( "html/template" "io" "log" - "strings" "time" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -179,15 +178,15 @@ rules: - watch - list --- - apiVersion: rbac.authorization.k8s.io/v1 - kind: ClusterRoleBinding - metadata: - name: {{ .Namespace }}-operator-manager-clusterrolebinding - roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ .Namespace }}-operator-manager-clusterrole - subjects: +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Namespace }}-operator-manager-clusterrolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Namespace }}-operator-manager-clusterrole +subjects: - kind: ServiceAccount name: fdb-kubernetes-operator-controller-manager namespace: {{ .Namespace }}` @@ -514,23 +513,18 @@ type SidecarConfig struct { CopyAsPrimary bool } -// GetSidecarConfigs returns the sidecar configs. The sidecar configs can be used to template applications that will use -// all provided sidecar versions to inject FDB client libraries. -func (factory *Factory) GetSidecarConfigs() []SidecarConfig { +// getSidecarConfigsSplitImage returns the sidecar config for the split image configuration. +func (factory *Factory) getSidecarConfigsSplitImage() []SidecarConfig { var hasCopyPrimarySet bool additionalSidecarVersions := factory.GetAdditionalSidecarVersions() sidecarConfigs := make([]SidecarConfig, 0, len(additionalSidecarVersions)+1) - - image := factory.GetSidecarImage() - if factory.options.featureOperatorUnifiedImage { - image = factory.GetFoundationDBImage() - } + baseImage, tag := GetBaseImageAndTag(factory.GetSidecarImage()) defaultConfig := getDefaultSidecarConfig( - image, + baseImage, + tag, factory.GetFDBVersion(), factory.getImagePullPolicy(), - factory.options.featureOperatorUnifiedImage, ) if factory.GetFDBVersion().SupportsDNSInClusterFile() { @@ -542,7 +536,6 @@ func (factory *Factory) GetSidecarConfigs() []SidecarConfig { sidecarConfigs, defaultConfig, ) - baseImage := sidecarConfigs[0].BaseImage // Add all other versions that are required e.g. for major or minor upgrades. for _, version := range additionalSidecarVersions { @@ -551,7 +544,7 @@ func (factory *Factory) GetSidecarConfigs() []SidecarConfig { continue } - sidecarConfig := getSidecarConfig(baseImage, "", version, factory.getImagePullPolicy(), factory.options.featureOperatorUnifiedImage) + sidecarConfig := getSidecarConfig(baseImage, fmt.Sprintf("%s-1", version), version, factory.getImagePullPolicy()) if !hasCopyPrimarySet && version.SupportsDNSInClusterFile() { sidecarConfig.CopyAsPrimary = true hasCopyPrimarySet = true @@ -566,22 +559,81 @@ func (factory *Factory) GetSidecarConfigs() []SidecarConfig { return sidecarConfigs } -func getDefaultSidecarConfig(sidecarImage string, version fdbv1beta2.Version, imagePullPolicy corev1.PullPolicy, useUnifiedImage bool) SidecarConfig { - defaultSidecarImage := strings.SplitN(sidecarImage, ":", 2) +func getTagFromImageConfig(imageConfigs []fdbv1beta2.ImageConfig, version fdbv1beta2.Version) string { + for _, imageConfig := range imageConfigs { + if imageConfig.Version == version.String() { + return imageConfig.Tag + } + } + + return version.String() +} - var tag string - if len(defaultSidecarImage) > 1 { - tag = defaultSidecarImage[1] +// getSidecarConfigsSplitImage returns the sidecar config for the split image configuration. +func (factory *Factory) getSidecarConfigsUnifiedImage() []SidecarConfig { + var hasCopyPrimarySet bool + additionalSidecarVersions := factory.GetAdditionalSidecarVersions() + sidecarConfigs := make([]SidecarConfig, 0, len(additionalSidecarVersions)+1) + baseImage, tag := GetBaseImageAndTag(factory.GetFoundationDBImage()) + imageConfigs := factory.options.getImageVersionConfig(baseImage) + if tag == "" || tag == factory.GetFDBVersionAsString() { + tag = getTagFromImageConfig(imageConfigs, factory.GetFDBVersion()) } - return getSidecarConfig(defaultSidecarImage[0], tag, version, imagePullPolicy, useUnifiedImage) + defaultConfig := getDefaultSidecarConfig( + baseImage, + tag, + factory.GetFDBVersion(), + factory.getImagePullPolicy(), + ) + + if factory.GetFDBVersion().SupportsDNSInClusterFile() { + defaultConfig.CopyAsPrimary = true + hasCopyPrimarySet = true + } + + sidecarConfigs = append( + sidecarConfigs, + defaultConfig, + ) + + // Add all other versions that are required e.g. for major or minor upgrades. + for _, version := range additionalSidecarVersions { + // Don't add the sidecar another time if we already added it + if version.Equal(factory.GetFDBVersion()) { + continue + } + + sidecarConfig := getSidecarConfig(baseImage, getTagFromImageConfig(imageConfigs, version), version, factory.getImagePullPolicy()) + if !hasCopyPrimarySet && version.SupportsDNSInClusterFile() { + sidecarConfig.CopyAsPrimary = true + hasCopyPrimarySet = true + } + + sidecarConfigs = append( + sidecarConfigs, + sidecarConfig, + ) + } + + return sidecarConfigs } -func getSidecarConfig(baseImage string, tag string, version fdbv1beta2.Version, imagePullPolicy corev1.PullPolicy, useUnifiedImage bool) SidecarConfig { - if tag == "" && !useUnifiedImage { - tag = fmt.Sprintf("%s-1", version) +// GetSidecarConfigs returns the sidecar configs. The sidecar configs can be used to template applications that will use +// all provided sidecar versions to inject FDB client libraries. +func (factory *Factory) GetSidecarConfigs() []SidecarConfig { + if factory.options.featureOperatorUnifiedImage { + return factory.getSidecarConfigsUnifiedImage() } + return factory.getSidecarConfigsSplitImage() +} + +func getDefaultSidecarConfig(sidecarImage string, tag string, version fdbv1beta2.Version, imagePullPolicy corev1.PullPolicy) SidecarConfig { + return getSidecarConfig(sidecarImage, tag, version, imagePullPolicy) +} + +func getSidecarConfig(baseImage string, tag string, version fdbv1beta2.Version, imagePullPolicy corev1.PullPolicy) SidecarConfig { return SidecarConfig{ BaseImage: baseImage, FDBVersion: version, diff --git a/e2e/fixtures/options.go b/e2e/fixtures/options.go index 4c710eff..475e70ec 100644 --- a/e2e/fixtures/options.go +++ b/e2e/fixtures/options.go @@ -46,6 +46,7 @@ type FactoryOptions struct { cloudProvider string clusterName string storageEngine string + fdbVersionTagMapping string enableChaosTests bool enableDataLoading bool cleanup bool @@ -189,6 +190,12 @@ func (options *FactoryOptions) BindFlags(fs *flag.FlagSet) { "", "if defined, the test suite will create a cluster with the specified name or update the setting of an existing cluster."+ "For multi-region clusters, this will define the prefix for all clusters.") + fs.StringVar(&options.fdbVersionTagMapping, + "fdb-version-tag-mapping", + "", + "if defined, the test suite will use this information to map the image tag to the specified version. Multiple entries can be"+ + "provided by separating them with a \",\". The mapping must have the format $version:$tag, e.g. 7.1.57:7.1.57-testing."+ + "This option will only work for the main container with the split image (sidecar).") } func (options *FactoryOptions) validateFlags() error { @@ -253,7 +260,7 @@ func (options *FactoryOptions) validateFlags() error { options.cloudProvider = strings.ToLower(options.cloudProvider) } - return nil + return options.validateFDBVersionTagMapping() } func validateVersion(label string, version string) error { @@ -276,3 +283,39 @@ func validateVersion(label string, version string) error { return nil } + +func (options *FactoryOptions) validateFDBVersionTagMapping() error { + if options.fdbVersionTagMapping == "" { + return nil + } + + mappings := strings.Split(options.fdbVersionTagMapping, ",") + for _, mapping := range mappings { + versionMapping := strings.Split(mapping, ":") + if len(versionMapping) != 2 { + return fmt.Errorf("mapping %s is invalid, expected format is $version:$tag", versionMapping) + } + } + + return nil +} + +func (options *FactoryOptions) getImageVersionConfig(baseImage string) []fdbv1beta2.ImageConfig { + if options.fdbVersionTagMapping == "" { + return nil + } + + mappings := strings.Split(options.fdbVersionTagMapping, ",") + imageConfig := make([]fdbv1beta2.ImageConfig, len(mappings)) + + for idx, mapping := range mappings { + versionMapping := strings.Split(mapping, ":") + imageConfig[idx] = fdbv1beta2.ImageConfig{ + BaseImage: baseImage, + Version: strings.TrimSpace(versionMapping[0]), + Tag: strings.TrimSpace(versionMapping[1]), + } + } + + return imageConfig +}