Skip to content

Commit 56ccd81

Browse files
committed
UPSTREAM: <carry>: require configuration file enablement
similarly to what we do for the managed CPU (aka workload partitioning) feature, introduce a master configuration file `/etc/kubernetes/openshift-llc-alignment` which needs to be present for the LLC alignment feature to be activated, in addition to the policy option being required. Note this replace the standard upstream feature gate check. This can be dropped when the feature per KEP kubernetes/enhancements#4800 goes beta. Signed-off-by: Francesco Romani <[email protected]>
1 parent 10bf2a2 commit 56ccd81

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed

pkg/kubelet/cm/cpumanager/policy_options.go

+20
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ import (
2222

2323
"k8s.io/apimachinery/pkg/util/sets"
2424
utilfeature "k8s.io/apiserver/pkg/util/feature"
25+
"k8s.io/klog/v2"
2526
kubefeatures "k8s.io/kubernetes/pkg/features"
2627
"k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology"
2728
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
29+
"k8s.io/kubernetes/pkg/kubelet/llcalign"
2830
)
2931

3032
// Names of the options, as part of the user interface.
@@ -54,6 +56,14 @@ func CheckPolicyOptionAvailable(option string) error {
5456
return fmt.Errorf("unknown CPU Manager Policy option: %q", option)
5557
}
5658

59+
// must override the base feature gate check. Relevant only for alpha (disabled by default).
60+
// for beta options are enabled by default and we totally want to keep the possibility to
61+
// disable them explicitly.
62+
if alphaOptions.Has(option) && checkPolicyOptionHasEnablementFile(option) {
63+
// note that we override the decision and shortcut exit with success
64+
// all other cases exit early with failure.
65+
return nil
66+
}
5767
if alphaOptions.Has(option) && !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUManagerPolicyAlphaOptions) {
5868
return fmt.Errorf("CPU Manager Policy Alpha-level Options not enabled, but option %q provided", option)
5969
}
@@ -148,3 +158,13 @@ func ValidateStaticPolicyOptions(opts StaticPolicyOptions, topology *topology.CP
148158
}
149159
return nil
150160
}
161+
162+
func checkPolicyOptionHasEnablementFile(option string) bool {
163+
switch option {
164+
case PreferAlignByUnCoreCacheOption:
165+
val := llcalign.IsEnabled()
166+
klog.InfoS("policy option enablement file check", "option", option, "enablementFile", val)
167+
return val
168+
}
169+
return false
170+
}

pkg/kubelet/cm/cpumanager/policy_options_test.go

+63
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
pkgfeatures "k8s.io/kubernetes/pkg/features"
2626
"k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology"
2727
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
28+
"k8s.io/kubernetes/pkg/kubelet/llcalign"
2829
)
2930

3031
type optionAvailTest struct {
@@ -177,3 +178,65 @@ func TestValidateStaticPolicyOptions(t *testing.T) {
177178
})
178179
}
179180
}
181+
182+
func TestPolicyOptionsAvailableWithEnablement(t *testing.T) {
183+
184+
type optionAvailEnabTest struct {
185+
name string
186+
option string
187+
featureGate featuregate.Feature
188+
featureGateEnable bool
189+
featureEnablementFlag bool
190+
expectedAvailable bool
191+
}
192+
193+
testCases := []optionAvailEnabTest{
194+
{
195+
name: "all disabled",
196+
option: PreferAlignByUnCoreCacheOption,
197+
featureGate: pkgfeatures.CPUManagerPolicyAlphaOptions,
198+
featureGateEnable: false, // expected standard case
199+
featureEnablementFlag: false,
200+
expectedAvailable: false,
201+
},
202+
{
203+
name: "all enabled",
204+
option: PreferAlignByUnCoreCacheOption,
205+
featureGate: pkgfeatures.CPUManagerPolicyAlphaOptions,
206+
featureGateEnable: true, // this should not be allowed by OCP profiles
207+
featureEnablementFlag: true,
208+
expectedAvailable: true,
209+
},
210+
{
211+
name: "enabled by feature gate",
212+
option: PreferAlignByUnCoreCacheOption,
213+
featureGate: pkgfeatures.CPUManagerPolicyAlphaOptions,
214+
featureGateEnable: true, // this should not be allowed by OCP profiles, makes no sense either
215+
featureEnablementFlag: false,
216+
expectedAvailable: true,
217+
},
218+
{
219+
name: "enabled by enablement file",
220+
option: PreferAlignByUnCoreCacheOption,
221+
featureGate: pkgfeatures.CPUManagerPolicyAlphaOptions,
222+
featureGateEnable: false,
223+
featureEnablementFlag: true,
224+
expectedAvailable: true,
225+
},
226+
}
227+
for _, testCase := range testCases {
228+
t.Run(testCase.name, func(t *testing.T) {
229+
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, testCase.featureGate, testCase.featureGateEnable)
230+
oldEnablementFlag := llcalign.TestOnlySetEnabled(testCase.featureEnablementFlag)
231+
232+
err := CheckPolicyOptionAvailable(testCase.option)
233+
234+
_ = llcalign.TestOnlySetEnabled(oldEnablementFlag)
235+
236+
isEnabled := (err == nil)
237+
if isEnabled != testCase.expectedAvailable {
238+
t.Errorf("option %q available got=%v expected=%v", testCase.option, isEnabled, testCase.expectedAvailable)
239+
}
240+
})
241+
}
242+
}

pkg/kubelet/llcalign/llcalign.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
Copyright 2024 The Kubernetes 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 llcalign
18+
19+
import (
20+
"os"
21+
)
22+
23+
var (
24+
llcAlignmentEnabled bool
25+
llcAlignmentFilename = "/etc/kubernetes/openshift-llc-alignment"
26+
)
27+
28+
func init() {
29+
readEnablementFile()
30+
}
31+
32+
func readEnablementFile() {
33+
if _, err := os.Stat(llcAlignmentFilename); err == nil {
34+
llcAlignmentEnabled = true
35+
}
36+
}
37+
38+
func IsEnabled() bool {
39+
return llcAlignmentEnabled
40+
}
41+
42+
func TestOnlySetEnabled(enabled bool) bool {
43+
oldEnabled := llcAlignmentEnabled
44+
llcAlignmentEnabled = enabled
45+
return oldEnabled
46+
}

0 commit comments

Comments
 (0)