Skip to content

Commit 41f0524

Browse files
feat: add xset feature gates (#15)
* feat: add feature gate * add xset feature-gate * refactor feature gate
1 parent 2e91e72 commit 41f0524

File tree

3 files changed

+108
-0
lines changed

3 files changed

+108
-0
lines changed

features/feature.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2024-2025 KusionStack Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package features
18+
19+
import (
20+
"k8s.io/apimachinery/pkg/util/runtime"
21+
"k8s.io/component-base/featuregate"
22+
)
23+
24+
const (
25+
// ReclaimScaleStrategy enables reclaim of xset.spec.scaleStrategy.targetToDelete
26+
ReclaimScaleStrategy featuregate.Feature = "ReclaimScaleStrategy"
27+
)
28+
29+
func init() {
30+
runtime.Must(DefaultMutableFeatureGate.Add(defaultKubernetesFeatureGates))
31+
}
32+
33+
// defaultKubernetesFeatureGates consists of all known Kubernetes-specific feature keys.
34+
// To add a new feature, define a key for it above and add it here. The features will be
35+
// available throughout Kubernetes binaries.
36+
var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{
37+
ReclaimScaleStrategy: {Default: false, PreRelease: featuregate.Alpha},
38+
}

features/featuregate.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2024-2025 KusionStack Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package features
18+
19+
import (
20+
"fmt"
21+
"strings"
22+
23+
"github.com/spf13/pflag"
24+
"k8s.io/component-base/featuregate"
25+
)
26+
27+
var (
28+
// DefaultMutableFeatureGate is a mutable version of DefaultFeatureGate.
29+
// Only top-level commands/options setup and the k8s.io/component-base/featuregate/testing package should make use of this.
30+
// Tests that need to modify feature gates for the duration of their test should use:
31+
// defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.<FeatureName>, <value>)()
32+
DefaultMutableFeatureGate featuregate.MutableFeatureGate = NewXSetFeatureGate()
33+
34+
// DefaultFeatureGate is a shared global FeatureGate.
35+
// Top-level commands/options setup that needs to modify this feature gate should use DefaultMutableFeatureGate.
36+
DefaultFeatureGate featuregate.FeatureGate = DefaultMutableFeatureGate
37+
)
38+
39+
var flagName = "xset-feature-gates"
40+
41+
type xsetFeatureGate struct {
42+
featuregate.MutableFeatureGate
43+
}
44+
45+
func NewXSetFeatureGate() featuregate.MutableFeatureGate {
46+
return &xsetFeatureGate{
47+
MutableFeatureGate: featuregate.NewFeatureGate(),
48+
}
49+
}
50+
51+
func (g *xsetFeatureGate) AddFlag(fs *pflag.FlagSet) {
52+
known := g.KnownFeatures()
53+
fs.Var(g, flagName, ""+
54+
"A set of key=value pairs that describe feature gates for alpha/experimental features. "+
55+
"Options are:\n"+strings.Join(known, "\n"))
56+
}
57+
58+
func (g *xsetFeatureGate) String() string {
59+
return g.MutableFeatureGate.(fmt.Stringer).String()
60+
}
61+
62+
func (g *xsetFeatureGate) Type() string {
63+
return "mapStringBool"
64+
}

synccontrols/x_scale.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"sigs.k8s.io/controller-runtime/pkg/client"
3636

3737
"kusionstack.io/kube-xset/api"
38+
"kusionstack.io/kube-xset/features"
3839
"kusionstack.io/kube-xset/opslifecycle"
3940
"kusionstack.io/kube-xset/subresources"
4041
"kusionstack.io/kube-xset/xcontrol"
@@ -240,6 +241,11 @@ func (r *RealSyncControl) includeTarget(ctx context.Context, xsetObject api.XSet
240241

241242
// reclaimScaleStrategy updates targetToDelete, targetToExclude, targetToInclude in scaleStrategy
242243
func (r *RealSyncControl) reclaimScaleStrategy(ctx context.Context, deletedTargets, excludedTargets, includedTargets sets.String, xsetObject api.XSetObject) error {
244+
// ReclaimScaleStrategy FeatureGate defaults to false
245+
// Add '--feature-gates=ReclaimScaleStrategy=false' to container args, to disable reclaim of podToDelete, podToExclude, podToInclude
246+
if !features.DefaultFeatureGate.Enabled(features.ReclaimScaleStrategy) {
247+
return nil
248+
}
243249
xspec := r.xsetController.GetXSetSpec(xsetObject)
244250
// reclaim TargetToDelete
245251
toDeleteTargets := sets.NewString(xspec.ScaleStrategy.TargetToDelete...)

0 commit comments

Comments
 (0)