Skip to content

Commit 63728f2

Browse files
committed
VEP 104: initial VEP proposal
Signed-off-by: Itamar Holder <[email protected]>
1 parent 10313a4 commit 63728f2

File tree

1 file changed

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

1 file changed

+264
-0
lines changed
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
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+
## Goals
38+
39+
* Allow to explicitly disable feature gates.
40+
41+
## Non Goals
42+
43+
## Definition of Users
44+
45+
* Feature developers.
46+
* Cluster admins.
47+
48+
## User Stories
49+
50+
* As a feature developer, I want my feature to be widely tested and used before graduating,
51+
so I can gain wide feedback and confidence in it.
52+
* As a cluster administrator, I want to be able to decide on whether to use Alpha/Beta features or not.
53+
54+
## Repos
55+
56+
kubevirt/kubevirt.
57+
58+
## Design
59+
60+
Kubevirt CR's API needs to change in order to allow disablement of feature gates.
61+
62+
See the different alternatives below.
63+
64+
## API Examples
65+
66+
See below.
67+
68+
## Alternatives
69+
70+
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).
71+
72+
In this section, I'll outline the three approaches so we can discuss which of them is the best moving forward.
73+
I'd be happy for more pros and cons from reviewers if you can think of any.
74+
75+
### Approach #1 - Use a `FeatureGateConfiguration` struct slice with an `Enabled` field
76+
77+
As part of this approach, a feature enablement is determined by its configuration in the new `kv.spec.configuration.featureGates` field.
78+
This field is a slice of `FeatureGateConfiguration` objects which currently contain two fields, `name` and `enabled`:
79+
```go
80+
type FeatureGateConfiguration struct {
81+
Name string `json:"name"`
82+
// Enabled indicates whether the feature gate is enabled or not. Defaults to true.
83+
// +optional
84+
Enabled *bool `json:"enabled,omitempty"`
85+
}
86+
```
87+
88+
`kv.spec.configuration.featureGates` has precedence over `kv.spec.configuration.developerConfiguration.featureGates`.
89+
However, if a feature gate exists only in the legacy feature gate slice, it would be considered enabled.
90+
This way we keep backward compatibility.
91+
92+
Usage Example:
93+
```go
94+
kind: KubeVirt
95+
spec:
96+
configuration:
97+
featureGates:
98+
- name: VMExport
99+
enabled: true
100+
- name: ImageVolume
101+
enabled: false
102+
- name: DownwardMetrics
103+
# defaults to true
104+
developerConfiguration:
105+
featureGates:
106+
- IncrementalBackup # This enables the FG
107+
- ImageVolume # Being ignored since the same FG is listed in the above config which takes precedence
108+
```
109+
110+
Pros:
111+
* Extensible: a struct opens the door for further configuration moving forward.
112+
* Aligns with Kubernetes best practices: "the convention is to use a list of subobjects containing name fields ...
113+
This rule maintains the invariant that all JSON/YAML keys are fields in API objects".
114+
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)
115+
for more info.
116+
117+
Cons:
118+
* Verbose: when there is no desire to disable feature gates, the admin would now have to supply the `name: ` boilerplate
119+
which makes the manifest more verbose.
120+
121+
### Approach #2 - Use a new map structure from a string to bool
122+
123+
As part of this approach, a new `kv.spec.configuration.featureGateMap` will be added of type `map[string]bool`.
124+
That is a map from string to bool types, i.e. feature name to whether it's enabled or not.
125+
126+
`kv.spec.configuration.featureGates` has precedence over `kv.spec.configuration.developerConfiguration.featureGates`.
127+
However, if a feature gate exists only in the legacy feature gate slice, it would be considered enabled.
128+
This way we keep backward compatibility.
129+
130+
Usage Example:
131+
```go
132+
kind: KubeVirt
133+
spec:
134+
configuration:
135+
featureGateMap:
136+
VMExport: true
137+
ImageVolume: false
138+
DownwardMetrics: false
139+
developerConfiguration:
140+
featureGates:
141+
- IncrementalBackup # This enables the FG
142+
- ImageVolume # Being ignored since the same FG is listed in the above config which takes precedence
143+
```
144+
145+
Pros:
146+
* Simplicity (?): Easy to implement and understand.
147+
148+
Cons:
149+
* Goes against Kubernetes best practices: "the convention is to use a list of subobjects containing name fields".
150+
The api conventions specifically mention using maps as an anti-pattern:
151+
"Lists of named subobjects preferred over maps ... There are no maps of subobjects in any API objects".
152+
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)
153+
for more info.
154+
* Maps are, by definition, unordered. This means that users/clients always have to sort it in a consistent manner
155+
to avoid entities mistakenly assuming that the state had changed because a change of ordering.
156+
* Non-extensible: If we'll need to add more configurations to feature gates in the future, we'll be in the same problem
157+
of having to extend the API.
158+
159+
### Approach #3 - Use a complementary slice for disabled feature gates
160+
161+
As part of this approach, a complementary `kv.spec.configuration.developerConfiguration.disabledFeatureGates` string slice will be added.
162+
The same feature gate cannot be provided to both slices, this should result with an error.
163+
164+
Usage Example:
165+
```go
166+
kind: KubeVirt
167+
spec:
168+
configuration:
169+
developerConfiguration:
170+
featureGates:
171+
- IncrementalBackup
172+
- ImageVolume
173+
disabledFeatureGates:
174+
- VMExport
175+
- DownwardMetrics
176+
# - ImageVolume -> invalid, would result in an error since already provided above
177+
```
178+
179+
Pros:
180+
* No need to deprecate the old `kv.spec.configuration.developerConfiguration.featureGates` field.
181+
* Easy adoption: the API is very familiar to what we have to day.
182+
183+
Cons:
184+
* Non-extensible: If we'll need to add more configurations to feature gates in the future, we'll be in the same problem
185+
of having to extend the API.
186+
* We keep both API fields under `kv.spec.configuration.developerConfiguration` instead of finding a new home under `kv.spec.configuration`.
187+
188+
### Approach #4 - Reuse the current string slice, allow special syntax for disablement
189+
190+
As part of this approach no new API fields will be added, but the current `kv.spec.configuration.developerConfiguration.featureGates`
191+
will be reused to allow disabling feature gates.
192+
193+
This will be achieved by allowing the following special syntax: `<gate>=<true|false>`,
194+
or just `<gate>` that will be interpreted as `<gate>=true`.
195+
196+
Usage Example:
197+
```go
198+
kind: KubeVirt
199+
spec:
200+
configuration:
201+
developerConfiguration:
202+
featureGates:
203+
- "IncrementalBackup: true"
204+
- "ImageVolume: false"
205+
- VMExport # defaults to true
206+
```
207+
208+
Pros:
209+
* Avoid adding / changing API fields.
210+
* Syntax is fairly simple and elegant.
211+
212+
Cons:
213+
* Special parsing would be needed by any user/client. This means:
214+
* Kubevirt's code would need to include many parsing logic.
215+
* Standard tooling would have trouble working with that.
216+
* We keep the API field under `kv.spec.configuration.developerConfiguration` instead of finding a new home under `kv.spec.configuration`.
217+
218+
## Scalability
219+
220+
No scalability issues are expected.
221+
222+
## Update/Rollback Compatibility
223+
224+
In all of the approached above backward compatibility will be kept.
225+
226+
In some of the approaches above `kv.spec.configuration.developerConfiguration` will be deprecated, but will not be
227+
removed in the foreseen future.
228+
229+
## Functional Testing Approach
230+
231+
## Implementation History
232+
233+
<!--
234+
For example:
235+
01-02-1921: Implemented mechanism for doing great stuff. PR: <LINK>.
236+
03-04-1922: Added support for doing even greater stuff. PR: <LINK>.
237+
-->
238+
239+
## Graduation Requirements
240+
241+
<!--
242+
The requirements for graduating to each stage.
243+
Example:
244+
### Alpha
245+
- [ ] Feature gate guards all code changes
246+
- [ ] Initial implementation supporting only X and Y use-cases
247+
248+
### Beta
249+
- [ ] Implementation supports all X use-cases
250+
251+
It is not necessary to have all the requirements for all stages in the initial VEP.
252+
They can be added later as the feature progresses, and there is more clarity towards its future.
253+
254+
Refer to https://github.com/kubevirt/community/blob/main/design-proposals/feature-lifecycle.md#releases for more details
255+
-->
256+
257+
### Alpha
258+
259+
- [ ] Feature gate guards all code changes.
260+
- [ ] It is possible to explicitly disable feature gates in Kubevirt CR.
261+
262+
### Beta
263+
264+
### GA

0 commit comments

Comments
 (0)