-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathfeaturegates.go
More file actions
360 lines (319 loc) · 12.8 KB
/
Copy pathfeaturegates.go
File metadata and controls
360 lines (319 loc) · 12.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
/*
Copyright The Kubernetes Authors
Copyright 2026 coldzerofear
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package featuregates
import (
"fmt"
"sync"
_ "unsafe"
"github.com/coldzerofear/vgpu-manager/pkg/util"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/version"
"k8s.io/component-base/featuregate"
logsapi "k8s.io/component-base/logs/api/v1"
//"sigs.k8s.io/dra-driver-nvidia-gpu/internal/info"
)
// featureGateEmulationVersion is the version passed to component-base's versioned
// feature gate. It must use Kubernetes-style versions (major.minor matching the
// Kubernetes release line), not the driver SemVer from VERSION.
//
// k8s.io/component-base/logs registers gates such as ContextualLogging at v1.24+
// / v1.30+. If emulation were driver v0.4, those specs compare as "newer than"
// emulation and the gate falls through to PreAlpha, which makes SetFromMap panic.
//
// Driver-local gates below use 0.x Version fields, they remain visible because
// 0.x < 1.y under apimachinery version ordering.
//
// Keep this major.minor aligned with the Kubernetes release we vendor in go.mod
// (k8s.io/* modules) and bump it whenever those dependencies move to a new kube minor.
//
// TODO: optionally isolate driver-only gates in their own registry so emulation can
// stay purely on driver SemVer without sharing a single version stream with component-base.
var featureGateEmulationVersion = version.MajorMinor(1, 37)
const (
// VGPUSupport allows vgpu-control to be mounted into containers for GPU device sharing
VGPUSupport featuregate.Feature = "VGPUSupport"
// TimeSlicingSettings allows timeslicing settings to be customized.
TimeSlicingSettings featuregate.Feature = "TimeSlicingSettings"
// MPSSupport allows MPS (Multi-Process Service) settings to be specified.
MPSSupport featuregate.Feature = "MPSSupport"
// IMEXDaemonsWithDNSNames allows using DNS names instead of raw IPs for IMEX daemons.
IMEXDaemonsWithDNSNames featuregate.Feature = "IMEXDaemonsWithDNSNames"
// PassthroughSupport allows gpus to be configured with the vfio-pci driver.
PassthroughSupport featuregate.Feature = "PassthroughSupport"
// NVMLDeviceHealthCheck allows Device Health Checking using NVML.
NVMLDeviceHealthCheck featuregate.Feature = "NVMLDeviceHealthCheck"
// DynamicMIG Enable dynamic MIG device management.
DynamicMIG featuregate.Feature = "DynamicMIG"
// DeviceMetadata allows the kubelet plugin to generate device metadata files
// in the workloads for prepared devices.
DeviceMetadata featuregate.Feature = "DeviceMetadata"
// FabricManagerPartitioning enables Fabric Manager (NVSwitch) partition
// management for full-GPU (gpu.nvidia.com) devices and Passthrough VFIO
// devices. When enabled, Prepare activates the FM partition whose member
// set exactly matches the claim's allocated physical GPUs; a non-matching
// set fails Prepare. ResourceClaims should constrain allocation with
// matchAttribute on gpu.nvidia.com/partitionN. Requires Fabric Manager
// running with FABRIC_MODE=1. Independent of PassthroughSupport: with both
// gates on, full-GPU and VFIO claims are partitioned; with only this gate
// on, only full-GPU claims are.
FabricManagerPartitioning featuregate.Feature = "FabricManagerPartitioning"
// DRAListTypeAttributes allows the GPU kubelet plugin to publish list-valued
// DRA device attributes. The cluster must have the Kubernetes feature gate
// of the same name enabled before enabling this in the driver.
DRAListTypeAttributes featuregate.Feature = "DRAListTypeAttributes"
// ConsumableShares enables publishing consumable capacity and multi-allocation
// (AllowMultipleAllocations) support for devices in ResourceSlices, allowing
// multiple ResourceClaims to share the same GPU or MIG device when configured
// via --consumable-shares. Note: MPS sharing is not supported when consumable
// shares is enabled.
ConsumableShares featuregate.Feature = "ConsumableShares"
SharedSMUtilizationWatcher featuregate.Feature = util.SharedSMUtilizationWatcher
DevicePluginClientMode featuregate.Feature = util.DevicePluginClientMode
// NRISupport enables the in-process NRI plugin path (per-container partition
// mounts injected at the NRI CreateContainer hook). Requires VGPUSupport.
// When DevicePluginClientMode is ALSO enabled, the NRI cache is shared with
// the register server to drive its pod-uid resolution; NRISupport does not
// require DevicePluginClientMode.
NRISupport featuregate.Feature = util.NRISupport
// ComputeDomainCliques enables using ComputeDomainClique CRD objects instead of
// storing daemon info directly in ComputeDomainStatus.Nodes.
//ComputeDomainCliques featuregate.Feature = "ComputeDomainCliques"
// CrashOnNVLinkFabricErrors causes the kubelet plugin to crash instead of
// falling back to non-fabric mode when NVLink fabric errors are detected.
//CrashOnNVLinkFabricErrors featuregate.Feature = "CrashOnNVLinkFabricErrors"
)
// Feature gate Version fields use driver SemVer major.minor.
// Former calendar-based release lines map to SemVer minors for reference when
// adding new VersionedSpecs or backport notes:
// ~25.3 -> 0.1, ~25.8 -> 0.2, ~25.12 -> 0.3, ~26.4 -> 0.4
//
// defaultFeatureGates contains the default settings for all project-specific feature gates.
// These will be registered with the standard Kubernetes feature gate system.
var defaultFeatureGates = map[featuregate.Feature]featuregate.VersionedSpecs{
VGPUSupport: {
{
Default: true,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 3),
},
},
TimeSlicingSettings: {
{
Default: false,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 2),
},
},
MPSSupport: {
{
Default: false,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 2),
},
},
IMEXDaemonsWithDNSNames: {
{
Default: true,
PreRelease: featuregate.Beta,
Version: version.MajorMinor(0, 2),
},
},
PassthroughSupport: {
{
Default: false,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 3),
},
},
DynamicMIG: {
{
Default: false,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 3),
},
},
NVMLDeviceHealthCheck: {
{
Default: true,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 3),
},
},
SharedSMUtilizationWatcher: {
{
Default: false,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 3),
},
},
DevicePluginClientMode: {
{
Default: false,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 4),
},
},
DeviceMetadata: {
{
Default: false,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 4),
},
},
NRISupport: {
{
Default: false,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 4),
},
},
FabricManagerPartitioning: {
{
Default: false,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 5),
},
},
DRAListTypeAttributes: {
{
Default: false,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 4),
},
},
ConsumableShares: {
{
Default: false,
PreRelease: featuregate.Alpha,
Version: version.MajorMinor(0, 5),
},
},
//ComputeDomainCliques: {
// {
// Default: true,
// PreRelease: featuregate.Beta,
// Version: version.MajorMinor(0, 3),
// },
//},
//CrashOnNVLinkFabricErrors: {
// {
// Default: true,
// PreRelease: featuregate.Beta,
// Version: version.MajorMinor(0, 3),
// },
//},
}
var (
featureGatesOnce sync.Once
//go:linkname featureGates sigs.k8s.io/dra-driver-nvidia-gpu/pkg/featuregates.featureGates
featureGates featuregate.MutableVersionedFeatureGate
)
// FeatureGates instantiates and returns the package-level singleton representing
// the set of all feature gates and their values.
// It contains both project-specific feature gates and standard Kubernetes logging feature gates.
func FeatureGates() featuregate.MutableVersionedFeatureGate {
if featureGates == nil {
featureGatesOnce.Do(func() {
featureGates = newFeatureGates(featureGateEmulationVersion)
})
}
return featureGates
}
// newFeatureGates instantiates a new set of feature gates with both standard Kubernetes
// logging feature gates and project-specific feature gates, along with appropriate default values.
// Mostly used for testing.
func newFeatureGates(version *version.Version) featuregate.MutableVersionedFeatureGate {
// Create a versioned feature gate with the specified version
// This ensures proper version handling for our feature gates
fg := featuregate.NewVersionedFeatureGate(version)
// Add standard Kubernetes logging feature gates
utilruntime.Must(logsapi.AddFeatureGates(fg))
// Add project-specific feature gates
utilruntime.Must(fg.AddVersioned(defaultFeatureGates))
// Override default logging feature gate values
loggingOverrides := map[string]bool{
string(logsapi.ContextualLogging): true,
}
utilruntime.Must(fg.SetFromMap(loggingOverrides))
return fg
}
// ValidateFeatureGates validates feature gate dependencies and returns an error if
// any dependencies are not satisfied.
func ValidateFeatureGates() error {
if Enabled(VGPUSupport) {
//if Enabled(TimeSlicingSettings) {
// return fmt.Errorf("feature gate %s is currently mutually exclusive with %s", VGPUSupport, TimeSlicingSettings)
//}
if Enabled(MPSSupport) {
return fmt.Errorf("feature gate %s is currently mutually exclusive with %s", VGPUSupport, MPSSupport)
}
if Enabled(PassthroughSupport) {
return fmt.Errorf("feature gate %s is currently mutually exclusive with %s", VGPUSupport, PassthroughSupport)
}
//if Enabled(DynamicMIG) {
// return fmt.Errorf("feature gate %s is currently mutually exclusive with %s", VGPUSupport, DynamicMIG)
//}
//if Enabled(ComputeDomainCliques) {
// return fmt.Errorf("feature gate %s is currently mutually exclusive with %s", VGPUSupport, ComputeDomainCliques)
//}
if Enabled(ConsumableShares) {
return fmt.Errorf("feature gate %s is currently mutually exclusive with %s", VGPUSupport, ConsumableShares)
}
}
// ComputeDomainCliques requires IMEXDaemonsWithDNSNames
//if Enabled(ComputeDomainCliques) && !Enabled(IMEXDaemonsWithDNSNames) {
// return fmt.Errorf("feature gate %s requires %s to also be enabled", ComputeDomainCliques, IMEXDaemonsWithDNSNames)
//}
if Enabled(SharedSMUtilizationWatcher) && !Enabled(VGPUSupport) {
return fmt.Errorf("feature gate %s requires %s to also be enabled", SharedSMUtilizationWatcher, VGPUSupport)
}
if Enabled(DevicePluginClientMode) && !Enabled(VGPUSupport) {
return fmt.Errorf("feature gate %s requires %s to also be enabled", DevicePluginClientMode, VGPUSupport)
}
if Enabled(NRISupport) && !Enabled(VGPUSupport) {
return fmt.Errorf("feature gate %s requires %s to also be enabled", NRISupport, VGPUSupport)
}
if Enabled(DynamicMIG) && Enabled(PassthroughSupport) {
return fmt.Errorf("feature gate %s is currently mutually exclusive with %s", DynamicMIG, PassthroughSupport)
}
if Enabled(DynamicMIG) && Enabled(MPSSupport) {
return fmt.Errorf("feature gate %s is currently mutually exclusive with %s", DynamicMIG, MPSSupport)
}
if Enabled(PassthroughSupport) && Enabled(NVMLDeviceHealthCheck) {
return fmt.Errorf("feature gate %s is currently mutually exclusive with %s", PassthroughSupport, NVMLDeviceHealthCheck)
}
if Enabled(DeviceMetadata) && !Enabled(PassthroughSupport) {
return fmt.Errorf("feature gate %s requires %s to also be enabled", DeviceMetadata, PassthroughSupport)
}
return nil
}
// Enabled returns true if the specified feature gate is enabled in the global FeatureGates singleton.
// This is a convenience function that uses the global feature gate registry.
func Enabled(feature featuregate.Feature) bool {
return FeatureGates().Enabled(feature)
}
// KnownFeatures returns a list of known feature gates with their descriptions.
func KnownFeatures() []string {
return FeatureGates().KnownFeatures()
}
// ToMap returns all known feature gates as a map[string]bool suitable for
// template rendering (e.g., {"FeatureA": true, "FeatureB": false}).
// Returns an empty map if no feature gates are configured.
func ToMap(featureGate featuregate.MutableFeatureGate) map[string]bool {
result := make(map[string]bool)
for feature := range featureGate.GetAll() {
result[string(feature)] = featureGate.Enabled(feature)
}
return result
}