Skip to content

Commit 125e3bb

Browse files
committed
VEP 104: initial VEP proposal
Signed-off-by: Itamar Holder <[email protected]>
1 parent 5f80a18 commit 125e3bb

File tree

1 file changed

+253
-0
lines changed
  • veps/sig-compute/104_allow_disabling_feature_gates

1 file changed

+253
-0
lines changed
Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
# VEP #NNNN: Your short, descriptive title
2+
3+
## Release Signoff Checklist
4+
5+
Items marked with (R) are required *prior to targeting to a milestone / release*.
6+
7+
- [X] (R) Enhancement issue created, which links to VEP dir in [kubevirt/enhancements] (not the initial VEP PR)
8+
- [ ] (R) Target version is explicitly mentioned and approved
9+
- [ ] (R) Graduation criteria filled
10+
11+
## Overview
12+
13+
Today, Kubevirt's API for feature gate management is a `kv.spec.configuration.developerConfiguration.featureGates`
14+
which is a [list of strings](https://github.com/kubevirt/kubevirt/blob/18c78c0f4d5f4c155ff2b425d0a213b563ac720e/staging/src/kubevirt.io/api/core/v1/types.go#L2813-L2815),
15+
each string is an enabled feature gate.
16+
17+
The API is defined as follows:
18+
```go
19+
type DeveloperConfiguration struct {
20+
// FeatureGates is the list of experimental features to enable. Defaults to none
21+
FeatureGates []string `json:"featureGates,omitempty"
22+
```
23+
24+
With this approach it is impossible to explicitly disable a feature gate.
25+
This VEP aims to make it possible.
26+
27+
## Motivation
28+
29+
Disabling a feature gate is very important for different reasons, the main one arguably being that it opens the door to
30+
enable beta feature gates by default.
31+
This capability is very important, because it allows widely testing a feature upstream
32+
(which will at least be tested by CI and developers, alongside small users) while possibly disabling it downstream.
33+
34+
This approach enables to gain wider feedback and confidence before the feature becomes GA,
35+
which has the potential to ensure features are much more stable and get a much wider feedback before graduating.
36+
37+
This VEP however is only scoped to allow disabling feature gates.
38+
Enabling Beta feature gates is out-of-scope for this VEP and should be addressed in a follow-up.
39+
40+
## Goals
41+
42+
* Allow to explicitly disable feature gates.
43+
44+
## Non Goals
45+
46+
* Enable feature gates by default.
47+
48+
## Definition of Users
49+
50+
* Feature developers.
51+
* Cluster admins.
52+
53+
## User Stories
54+
55+
* As a feature developer, I want my feature to be widely tested and used before graduating,
56+
so I can gain wide feedback and confidence in it.
57+
* As a cluster administrator, I want to be able to decide on whether to use Alpha/Beta features or not.
58+
59+
## Repos
60+
61+
kubevirt/kubevirt.
62+
63+
## Design
64+
65+
Kubevirt CR's API needs to change in order to allow disablement of feature gates.
66+
67+
See the different alternatives below.
68+
69+
## API Examples
70+
71+
See below.
72+
73+
## Alternatives
74+
75+
Before deciding to create a VEP, this change was re-implemented three times as part of PR [#14427](https://github.com/kubevirt/kubevirt/pull/14427).
76+
77+
In this section, I'll outline the three approaches so we can discuss which of them is the best moving forward.
78+
I'd be happy for more pros and cons from reviewers if you can think of any.
79+
80+
### Approach #1 - Use a `FeatureGateConfiguration` struct slice with an `Enabled` field
81+
82+
As part of this approach, a feature enablement is determined by its configuration in the new `kv.spec.configuration.featureGates` field.
83+
This field is a slice of `FeatureGateConfiguration` objects which currently contain two fields, `name` and `enabled`:
84+
```go
85+
type FeatureGateConfiguration struct {
86+
Name string `json:"name"`
87+
// Enabled indicates whether the feature gate is enabled or not. Defaults to true.
88+
// +optional
89+
Enabled *bool `json:"enabled,omitempty"`
90+
}
91+
```
92+
93+
`kv.spec.configuration.featureGates` has precedence over `kv.spec.configuration.developerConfiguration.featureGates`.
94+
In addition, `kv.spec.configuration.developerConfiguration.featureGates` would be marked as deprecated and discouraged.
95+
However, if a feature gate exists only in the legacy feature gate slice, it would be considered enabled.
96+
This way we keep backward compatibility.
97+
98+
Usage Example:
99+
```go
100+
kind: KubeVirt
101+
spec:
102+
configuration:
103+
featureGates:
104+
- name: VMExport
105+
enabled: true
106+
- name: ImageVolume
107+
enabled: false
108+
- name: DownwardMetrics
109+
# defaults to true
110+
developerConfiguration:
111+
featureGates:
112+
- IncrementalBackup # This enables the FG
113+
- ImageVolume # Being ignored since the same FG is listed in the above config which takes precedence
114+
```
115+
116+
Pros:
117+
* Extensible: a struct opens the door for further configuration moving forward.
118+
* Aligns with Kubernetes best practices: "the convention is to use a list of subobjects containing name fields ...
119+
This rule maintains the invariant that all JSON/YAML keys are fields in API objects".
120+
See [Kubernetes api conventions](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#lists-of-named-subobjects-preferred-over-maps)
121+
for more info.
122+
123+
Cons:
124+
* Verbose: when there is no desire to disable feature gates, the admin would now have to supply the `name: ` boilerplate
125+
which makes the manifest more verbose.
126+
127+
### Approach #2 - Use a new map structure from a string to bool
128+
129+
As part of this approach, a new `kv.spec.configuration.featureGateMap` will be added of type `map[string]bool`.
130+
That is a map from string to bool types, i.e. feature name to whether it's enabled or not.
131+
132+
`kv.spec.configuration.featureGates` has precedence over `kv.spec.configuration.developerConfiguration.featureGates`.
133+
However, if a feature gate exists only in the legacy feature gate slice, it would be considered enabled.
134+
This way we keep backward compatibility.
135+
136+
Usage Example:
137+
```go
138+
kind: KubeVirt
139+
spec:
140+
configuration:
141+
featureGateMap:
142+
VMExport: true
143+
ImageVolume: false
144+
DownwardMetrics: false
145+
developerConfiguration:
146+
featureGates:
147+
- IncrementalBackup # This enables the FG
148+
- ImageVolume # Being ignored since the same FG is listed in the above config which takes precedence
149+
```
150+
151+
Pros:
152+
* Simplicity (?): Easy to implement and understand.
153+
154+
Cons:
155+
* Goes against Kubernetes best practices: "the convention is to use a list of subobjects containing name fields".
156+
The api conventions specifically mention using maps as an anti-pattern:
157+
"Lists of named subobjects preferred over maps ... There are no maps of subobjects in any API objects".
158+
See [Kubernetes api conventions](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#lists-of-named-subobjects-preferred-over-maps)
159+
for more info.
160+
* Maps are, by definition, unordered. This means that users/clients always have to sort it in a consistent manner
161+
to avoid entities mistakenly assuming that the state had changed because a change of ordering.
162+
* Non-extensible: If we'll need to add more configurations to feature gates in the future, we'll be in the same problem
163+
of having to extend the API.
164+
165+
### Approach #3 - Use a complementary slice for disabled feature gates
166+
167+
As part of this approach, a complementary `kv.spec.configuration.developerConfiguration.disabledFeatureGates` string slice will be added.
168+
The same feature gate cannot be provided to both slices, this should result with an error.
169+
170+
Usage Example:
171+
```go
172+
kind: KubeVirt
173+
spec:
174+
configuration:
175+
developerConfiguration:
176+
featureGates:
177+
- IncrementalBackup
178+
- ImageVolume
179+
disabledFeatureGates:
180+
- VMExport
181+
- DownwardMetrics
182+
# - ImageVolume -> invalid, would result in an error since already provided above
183+
```
184+
185+
Pros:
186+
* No need to deprecate the old `kv.spec.configuration.developerConfiguration.featureGates` field.
187+
* Easy adoption: the API is very familiar to what we have to day.
188+
189+
Cons:
190+
* Non-extensible: If we'll need to add more configurations to feature gates in the future, we'll be in the same problem
191+
of having to extend the API.
192+
* We keep both API fields under `kv.spec.configuration.developerConfiguration` instead of finding a new home under `kv.spec.configuration`.
193+
194+
### Approach #4 - Reuse the current string slice, allow special syntax for disablement
195+
196+
As part of this approach no new API fields will be added, but the current `kv.spec.configuration.developerConfiguration.featureGates`
197+
will be reused to allow disabling feature gates.
198+
199+
This will be achieved by allowing the following special syntax: `<gate>=<true|false>`,
200+
or just `<gate>` that will be interpreted as `<gate>=true`.
201+
202+
Usage Example:
203+
```go
204+
kind: KubeVirt
205+
spec:
206+
configuration:
207+
developerConfiguration:
208+
featureGates:
209+
- "IncrementalBackup: true"
210+
- "ImageVolume: false"
211+
- VMExport # defaults to true
212+
```
213+
214+
Pros:
215+
* Avoid adding / changing API fields.
216+
* Syntax is fairly simple and elegant.
217+
218+
Cons:
219+
* Special parsing would be needed by any user/client. This means:
220+
* Kubevirt's code would need to include many parsing logic.
221+
* Standard tooling would have trouble working with that.
222+
* We keep the API field under `kv.spec.configuration.developerConfiguration` instead of finding a new home under `kv.spec.configuration`.
223+
224+
## Scalability
225+
226+
No scalability issues are expected.
227+
228+
## Update/Rollback Compatibility
229+
230+
In all of the approached above backward compatibility will be kept.
231+
232+
In some of the approaches above `kv.spec.configuration.developerConfiguration` will be deprecated, but will not be
233+
removed in the foreseen future.
234+
235+
## Functional Testing Approach
236+
237+
## Implementation History
238+
239+
<!--
240+
For example:
241+
01-02-1921: Implemented mechanism for doing great stuff. PR: <LINK>.
242+
03-04-1922: Added support for doing even greater stuff. PR: <LINK>.
243+
-->
244+
245+
## Graduation Requirements
246+
247+
This VEP is intended to jump straight to GA, for the following reasons:
248+
* This VEP has an effect on all other feature-gates.
249+
* It is essential for enabling beta features by default.
250+
* It is not really a feature, more of a formal API review. The logic and implementation is straight forward.
251+
* It doesn't make sense to create a feature gate for feature gate management.
252+
253+
I would ask for an approval from each SIG approver in order to ensure this approach is widely accepted.

0 commit comments

Comments
 (0)