From cf28c0405c02e82e1028193a4ce1aa75d473ae8e Mon Sep 17 00:00:00 2001 From: Jefftree Date: Tue, 10 Dec 2024 16:34:34 +0000 Subject: [PATCH] Expand emulated version range to n-3 with 1.31 floor --- .../server/options/server_run_options_test.go | 6 +- .../featuregate/registry_test.go | 2 +- .../k8s.io/component-base/version/version.go | 29 +++--- .../component-base/version/version_test.go | 88 +++++++++++++++++-- 4 files changed, 105 insertions(+), 20 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/server_run_options_test.go b/staging/src/k8s.io/apiserver/pkg/server/options/server_run_options_test.go index 71c66002821..69c09ccc4c7 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/server_run_options_test.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/server_run_options_test.go @@ -34,8 +34,8 @@ import ( func TestServerRunOptionsValidate(t *testing.T) { testRegistry := featuregate.NewComponentGlobalsRegistry() featureGate := utilfeature.DefaultFeatureGate.DeepCopy() - effectiveVersion := utilversion.NewEffectiveVersion("1.30") - effectiveVersion.SetEmulationVersion(version.MajorMinor(1, 32)) + effectiveVersion := utilversion.NewEffectiveVersion("1.35") + effectiveVersion.SetEmulationVersion(version.MajorMinor(1, 31)) testComponent := "test" utilruntime.Must(testRegistry.Register(testComponent, effectiveVersion, featureGate)) @@ -197,7 +197,7 @@ func TestServerRunOptionsValidate(t *testing.T) { ComponentName: testComponent, ComponentGlobalsRegistry: testRegistry, }, - expectErr: "emulation version 1.32 is not between [1.29, 1.30.0]", + expectErr: "emulation version 1.31 is not between [1.32, 1.35.0]", }, { name: "Test when ServerRunOptions is valid", diff --git a/staging/src/k8s.io/component-base/featuregate/registry_test.go b/staging/src/k8s.io/component-base/featuregate/registry_test.go index 85046063c27..b825fd3d758 100644 --- a/staging/src/k8s.io/component-base/featuregate/registry_test.go +++ b/staging/src/k8s.io/component-base/featuregate/registry_test.go @@ -118,7 +118,7 @@ func TestVersionFlagOptions(t *testing.T) { func TestVersionFlagOptionsWithMapping(t *testing.T) { r := testRegistry(t) utilruntime.Must(r.SetEmulationVersionMapping(testComponent, DefaultKubeComponent, - func(from *version.Version) *version.Version { return from.OffsetMinor(3) })) + func(from *version.Version) *version.Version { return version.MajorMinor(1, from.Minor()+23) })) emuVers := strings.Join(r.unsafeVersionFlagOptions(true), "\n") expectedEmuVers := "test=2.8..2.8 (default=2.8)" if emuVers != expectedEmuVers { diff --git a/staging/src/k8s.io/component-base/version/version.go b/staging/src/k8s.io/component-base/version/version.go index 99d3685348a..0c62305839c 100644 --- a/staging/src/k8s.io/component-base/version/version.go +++ b/staging/src/k8s.io/component-base/version/version.go @@ -25,6 +25,8 @@ import ( apimachineryversion "k8s.io/apimachinery/pkg/version" ) +var minimumKubeEmulationVersion *version.Version = version.MajorMinor(1, 31) + type EffectiveVersion interface { BinaryVersion() *version.Version EmulationVersion() *version.Version @@ -121,8 +123,11 @@ func (m *effectiveVersion) Set(binaryVersion, emulationVersion, minCompatibility func (m *effectiveVersion) SetEmulationVersion(emulationVersion *version.Version) { m.emulationVersion.Store(majorMinor(emulationVersion)) + // set the default minCompatibilityVersion to be emulationVersion - 1 + m.minCompatibilityVersion.Store(majorMinor(emulationVersion.SubtractMinor(1))) } +// SetMinCompatibilityVersion should be called after SetEmulationVersion func (m *effectiveVersion) SetMinCompatibilityVersion(minCompatibilityVersion *version.Version) { m.minCompatibilityVersion.Store(majorMinor(minCompatibilityVersion)) } @@ -134,15 +139,15 @@ func (m *effectiveVersion) Validate() []error { emulationVersion := m.emulationVersion.Load() minCompatibilityVersion := m.minCompatibilityVersion.Load() - // emulationVersion can only be 1.{binaryMinor-1}...1.{binaryMinor}. + // emulationVersion can only be 1.{binaryMinor-3}...1.{binaryMinor} maxEmuVer := binaryVersion - minEmuVer := binaryVersion.SubtractMinor(1) + minEmuVer := binaryVersion.SubtractMinor(3) if emulationVersion.GreaterThan(maxEmuVer) || emulationVersion.LessThan(minEmuVer) { errs = append(errs, fmt.Errorf("emulation version %s is not between [%s, %s]", emulationVersion.String(), minEmuVer.String(), maxEmuVer.String())) } - // minCompatibilityVersion can only be 1.{binaryMinor-1} for alpha. - maxCompVer := binaryVersion.SubtractMinor(1) - minCompVer := binaryVersion.SubtractMinor(1) + // minCompatibilityVersion can only be 1.{binaryMinor-3} to 1.{binaryMinor} + maxCompVer := emulationVersion + minCompVer := binaryVersion.SubtractMinor(4) if minCompatibilityVersion.GreaterThan(maxCompVer) || minCompatibilityVersion.LessThan(minCompVer) { errs = append(errs, fmt.Errorf("minCompatibilityVersion version %s is not between [%s, %s]", minCompatibilityVersion.String(), minCompVer.String(), maxCompVer.String())) } @@ -187,13 +192,15 @@ func DefaultKubeEffectiveVersion() MutableEffectiveVersion { return newEffectiveVersion(binaryVersion, false) } -// ValidateKubeEffectiveVersion validates the EmulationVersion is equal to the binary version at 1.31 for kube components. -// emulationVersion is introduced in 1.31, so it is only allowed to be equal to the binary version at 1.31. +// ValidateKubeEffectiveVersion validates the EmulationVersion is at least 1.31 and MinCompatibilityVersion +// is at least 1.30 for kube components. func ValidateKubeEffectiveVersion(effectiveVersion EffectiveVersion) error { - binaryVersion := version.MajorMinor(effectiveVersion.BinaryVersion().Major(), effectiveVersion.BinaryVersion().Minor()) - if binaryVersion.EqualTo(version.MajorMinor(1, 31)) && !effectiveVersion.EmulationVersion().EqualTo(binaryVersion) { - return fmt.Errorf("emulation version needs to be equal to binary version(%s) in compatibility-version alpha, got %s", - binaryVersion.String(), effectiveVersion.EmulationVersion().String()) + if !effectiveVersion.EmulationVersion().AtLeast(minimumKubeEmulationVersion) { + return fmt.Errorf("emulation version needs to be greater or equal to 1.31, got %s", effectiveVersion.EmulationVersion().String()) } + if !effectiveVersion.MinCompatibilityVersion().AtLeast(minimumKubeEmulationVersion.SubtractMinor(1)) { + return fmt.Errorf("minCompatibilityVersion version needs to be greater or equal to 1.30, got %s", effectiveVersion.MinCompatibilityVersion().String()) + } + return nil } diff --git a/staging/src/k8s.io/component-base/version/version_test.go b/staging/src/k8s.io/component-base/version/version_test.go index aff8a8e4a0b..3f6c34bd46e 100644 --- a/staging/src/k8s.io/component-base/version/version_test.go +++ b/staging/src/k8s.io/component-base/version/version_test.go @@ -43,9 +43,22 @@ func TestValidate(t *testing.T) { minCompatibilityVersion: "v1.31.0", }, { - name: "emulation version two minor lower than binary not ok", + name: "emulation version two minor lower than binary ok", binaryVersion: "v1.33.2", emulationVersion: "v1.31.0", + minCompatibilityVersion: "v1.31.0", + expectErrors: false, + }, + { + name: "emulation version three minor lower than binary ok", + binaryVersion: "v1.35.0", + emulationVersion: "v1.32.0", + minCompatibilityVersion: "v1.32.0", + }, + { + name: "emulation version four minor lower than binary not ok", + binaryVersion: "v1.36.0", + emulationVersion: "v1.32.0", minCompatibilityVersion: "v1.32.0", expectErrors: true, }, @@ -64,18 +77,25 @@ func TestValidate(t *testing.T) { expectErrors: true, }, { - name: "compatibility version same as binary not ok", + name: "compatibility version same as binary ok", binaryVersion: "v1.32.2", emulationVersion: "v1.32.0", minCompatibilityVersion: "v1.32.0", - expectErrors: true, + expectErrors: false, }, { - name: "compatibility version two minor lower than binary not ok", + name: "compatibility version two minor lower than binary ok", binaryVersion: "v1.32.2", emulationVersion: "v1.32.0", minCompatibilityVersion: "v1.30.0", - expectErrors: true, + expectErrors: false, + }, + { + name: "compatibility version three minor lower than binary ok", + binaryVersion: "v1.34.2", + emulationVersion: "v1.33.0", + minCompatibilityVersion: "v1.31.0", + expectErrors: false, }, { name: "compatibility version one minor higher than binary not ok", @@ -84,6 +104,13 @@ func TestValidate(t *testing.T) { minCompatibilityVersion: "v1.33.0", expectErrors: true, }, + { + name: "emulation version lower than compatibility version not ok", + binaryVersion: "v1.34.2", + emulationVersion: "v1.32.0", + minCompatibilityVersion: "v1.33.0", + expectErrors: true, + }, } for _, test := range tests { @@ -105,3 +132,54 @@ func TestValidate(t *testing.T) { }) } } + +func TestValidateKubeEffectiveVersion(t *testing.T) { + tests := []struct { + name string + emulationVersion string + minCompatibilityVersion string + expectErr bool + }{ + { + name: "valid versions", + emulationVersion: "v1.31.0", + minCompatibilityVersion: "v1.31.0", + expectErr: false, + }, + { + name: "emulationVersion too low", + emulationVersion: "v1.30.0", + minCompatibilityVersion: "v1.31.0", + expectErr: true, + }, + { + name: "minCompatibilityVersion too low", + emulationVersion: "v1.31.0", + minCompatibilityVersion: "v1.29.0", + expectErr: true, + }, + { + name: "both versions too low", + emulationVersion: "v1.30.0", + minCompatibilityVersion: "v1.30.0", + expectErr: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + + effective := NewEffectiveVersion("1.32") + effective.SetEmulationVersion(version.MustParseGeneric(test.emulationVersion)) + effective.SetMinCompatibilityVersion(version.MustParseGeneric(test.minCompatibilityVersion)) + + err := ValidateKubeEffectiveVersion(effective) + if test.expectErr && err == nil { + t.Error("expected error, but got nil") + } + if !test.expectErr && err != nil { + t.Errorf("unexpected error: %v", err) + } + }) + } +}