Skip to content

Commit db346c5

Browse files
authored
Merge pull request #5491 from ngopalak-redhat/ngopalak/mco_auto_node_master_disable
OCPNODE-3973: Default CPU/Memory changes to Workers - AutoSizingReserved
2 parents 9333c5a + e97d1a0 commit db346c5

8 files changed

Lines changed: 238 additions & 2 deletions

File tree

pkg/controller/common/constants.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ const (
152152
// Stub Ignition upgrade related annotation keys
153153
StubIgnitionVersionAnnotation = "machineconfiguration.openshift.io/stub-ignition-upgraded-to"
154154
StubIgnitionTimestampAnnotation = "machineconfiguration.openshift.io/stub-ignition-upgraded-at"
155+
156+
// NodeSizingEnabledEnvPath is the file path for the node sizing enabled environment file
157+
NodeSizingEnabledEnvPath = "/etc/node-sizing-enabled.env"
155158
)
156159

157160
// Commonly-used MCO ConfigMap names

pkg/controller/kubelet-config/helpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func createNewKubeletDynamicSystemReservedIgnition(autoSystemReserved *bool, use
6868
config := fmt.Sprintf("NODE_SIZING_ENABLED=%s\nSYSTEM_RESERVED_MEMORY=%s\nSYSTEM_RESERVED_CPU=%s\nSYSTEM_RESERVED_ES=%s\n",
6969
autoNodeSizing, systemReservedMemory, systemReservedCPU, systemReservedEphemeralStorage)
7070

71-
r := ctrlcommon.NewIgnFileBytesOverwriting("/etc/node-sizing-enabled.env", []byte(config))
71+
r := ctrlcommon.NewIgnFileBytesOverwriting(ctrlcommon.NodeSizingEnabledEnvPath, []byte(config))
7272
return &r
7373
}
7474

pkg/controller/template/template_controller_test.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package template
33
import (
44
"fmt"
55
"reflect"
6+
"strings"
67
"testing"
78
"time"
89

@@ -439,3 +440,127 @@ func getKey(config *mcfgv1.ControllerConfig, t *testing.T) string {
439440
}
440441
return key
441442
}
443+
444+
func TestKubeletAutoNodeSizingEnabled(t *testing.T) {
445+
cc := newControllerConfig("test-cluster")
446+
ps := []byte(`{"dummy": "dummy"}`)
447+
448+
mcs, err := getMachineConfigsForControllerConfig(templateDir, cc, ps, nil)
449+
if err != nil {
450+
t.Fatal(err)
451+
}
452+
453+
// Find machine configs that should contain the auto-node-sizing file
454+
// The file should be in all role-based machine configs (master, worker)
455+
autoSizingFileFound := false
456+
for _, mc := range mcs {
457+
ignCfg, err := ctrlcommon.ParseAndConvertConfig(mc.Spec.Config.Raw)
458+
if err != nil {
459+
t.Fatalf("Failed to parse ignition config for %s: %v", mc.Name, err)
460+
}
461+
462+
// Look for the auto-node-sizing file
463+
for _, file := range ignCfg.Storage.Files {
464+
if file.Path == ctrlcommon.NodeSizingEnabledEnvPath {
465+
autoSizingFileFound = true
466+
467+
// Decode the file contents
468+
contents, err := ctrlcommon.DecodeIgnitionFileContents(file.Contents.Source, file.Contents.Compression)
469+
if err != nil {
470+
t.Fatalf("Failed to decode auto-node-sizing file contents: %v", err)
471+
}
472+
473+
contentsStr := string(contents)
474+
475+
// Verify NODE_SIZING_ENABLED based on node role
476+
// Master nodes should have NODE_SIZING_ENABLED=false
477+
// Other nodes (worker, etc.) should have NODE_SIZING_ENABLED=true
478+
isMasterNode := strings.Contains(mc.Name, "master")
479+
if isMasterNode {
480+
if !strings.Contains(contentsStr, "NODE_SIZING_ENABLED=false") {
481+
t.Errorf("Expected NODE_SIZING_ENABLED=false in %s, got: %s", mc.Name, contentsStr)
482+
}
483+
} else {
484+
if !strings.Contains(contentsStr, "NODE_SIZING_ENABLED=true") {
485+
t.Errorf("Expected NODE_SIZING_ENABLED=true in %s, got: %s", mc.Name, contentsStr)
486+
}
487+
}
488+
489+
// Verify other expected values
490+
if !strings.Contains(contentsStr, "SYSTEM_RESERVED_MEMORY=1Gi") {
491+
t.Errorf("Expected SYSTEM_RESERVED_MEMORY=1Gi in %s, got: %s", mc.Name, contentsStr)
492+
}
493+
494+
if !strings.Contains(contentsStr, "SYSTEM_RESERVED_CPU=500m") {
495+
t.Errorf("Expected SYSTEM_RESERVED_CPU=500m in %s, got: %s", mc.Name, contentsStr)
496+
}
497+
498+
if !strings.Contains(contentsStr, "SYSTEM_RESERVED_ES=1Gi") {
499+
t.Errorf("Expected SYSTEM_RESERVED_ES=1Gi in %s, got: %s", mc.Name, contentsStr)
500+
}
501+
}
502+
}
503+
}
504+
505+
if !autoSizingFileFound {
506+
t.Errorf("Expected to find %s file in at least one machine config", ctrlcommon.NodeSizingEnabledEnvPath)
507+
}
508+
}
509+
510+
func TestKubeletAutoNodeSizingDisabledForHypershift(t *testing.T) {
511+
cc := newControllerConfig("test-cluster")
512+
// Set ControlPlaneTopology to External to simulate Hypershift
513+
cc.Spec.Infra.Status.ControlPlaneTopology = configv1.ExternalTopologyMode
514+
ps := []byte(`{"dummy": "dummy"}`)
515+
516+
mcs, err := getMachineConfigsForControllerConfig(templateDir, cc, ps, nil)
517+
if err != nil {
518+
t.Fatal(err)
519+
}
520+
521+
// Find machine configs that should contain the auto-node-sizing file
522+
autoSizingFileFound := false
523+
for _, mc := range mcs {
524+
ignCfg, err := ctrlcommon.ParseAndConvertConfig(mc.Spec.Config.Raw)
525+
if err != nil {
526+
t.Fatalf("Failed to parse ignition config for %s: %v", mc.Name, err)
527+
}
528+
529+
// Look for the auto-node-sizing file
530+
for _, file := range ignCfg.Storage.Files {
531+
if file.Path == ctrlcommon.NodeSizingEnabledEnvPath {
532+
autoSizingFileFound = true
533+
534+
// Decode the file contents
535+
contents, err := ctrlcommon.DecodeIgnitionFileContents(file.Contents.Source, file.Contents.Compression)
536+
if err != nil {
537+
t.Fatalf("Failed to decode auto-node-sizing file contents: %v", err)
538+
}
539+
540+
contentsStr := string(contents)
541+
542+
// Verify NODE_SIZING_ENABLED=false is present for Hypershift
543+
if !strings.Contains(contentsStr, "NODE_SIZING_ENABLED=false") {
544+
t.Errorf("Expected NODE_SIZING_ENABLED=false for Hypershift in %s, got: %s", mc.Name, contentsStr)
545+
}
546+
547+
// Verify other expected values are still present
548+
if !strings.Contains(contentsStr, "SYSTEM_RESERVED_MEMORY=1Gi") {
549+
t.Errorf("Expected SYSTEM_RESERVED_MEMORY=1Gi in %s, got: %s", mc.Name, contentsStr)
550+
}
551+
552+
if !strings.Contains(contentsStr, "SYSTEM_RESERVED_CPU=500m") {
553+
t.Errorf("Expected SYSTEM_RESERVED_CPU=500m in %s, got: %s", mc.Name, contentsStr)
554+
}
555+
556+
if !strings.Contains(contentsStr, "SYSTEM_RESERVED_ES=1Gi") {
557+
t.Errorf("Expected SYSTEM_RESERVED_ES=1Gi in %s, got: %s", mc.Name, contentsStr)
558+
}
559+
}
560+
}
561+
}
562+
563+
if !autoSizingFileFound {
564+
t.Errorf("Expected to find %s file in at least one machine config", ctrlcommon.NodeSizingEnabledEnvPath)
565+
}
566+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
mode: 0644
2+
path: "/etc/node-sizing-enabled.env"
3+
contents:
4+
inline: |
5+
NODE_SIZING_ENABLED=false
6+
SYSTEM_RESERVED_MEMORY=1Gi
7+
SYSTEM_RESERVED_CPU=500m
8+
SYSTEM_RESERVED_ES=1Gi

templates/common/_base/files/kubelet-auto-node-sizing-enabled.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mode: 0644
22
path: "/etc/node-sizing-enabled.env"
33
contents:
44
inline: |
5-
NODE_SIZING_ENABLED=false
5+
NODE_SIZING_ENABLED={{if eq .Infra.Status.ControlPlaneTopology "External"}}false{{else}}true{{end}}
66
SYSTEM_RESERVED_MEMORY=1Gi
77
SYSTEM_RESERVED_CPU=500m
88
SYSTEM_RESERVED_ES=1Gi
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
mode: 0644
2+
path: "/etc/node-sizing-enabled.env"
3+
contents:
4+
inline: |
5+
NODE_SIZING_ENABLED=false
6+
SYSTEM_RESERVED_MEMORY=1Gi
7+
SYSTEM_RESERVED_CPU=500m
8+
SYSTEM_RESERVED_ES=1Gi

test/e2e-2of2/kubeletcfg_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ func TestKubeletConfigMaxPods(t *testing.T) {
6565
kc2 := &mcfgv1.KubeletConfig{
6666
ObjectMeta: metav1.ObjectMeta{Name: "test-200"},
6767
Spec: mcfgv1.KubeletConfigSpec{
68+
AutoSizingReserved: &autoNodeSizing,
6869
KubeletConfig: &runtime.RawExtension{
6970
Raw: kcRaw2,
7071
},

test/e2e-bootstrap/bootstrap_test.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,97 @@ metadata:
389389
}
390390
}
391391

392+
func TestNodeSizingEnabled(t *testing.T) {
393+
ctx := context.Background()
394+
395+
testEnv := framework.NewTestEnv(t)
396+
397+
configv1.Install(scheme.Scheme)
398+
configv1alpha1.Install(scheme.Scheme)
399+
mcfgv1.Install(scheme.Scheme)
400+
apioperatorsv1alpha1.Install(scheme.Scheme)
401+
402+
baseTestManifests := loadBaseTestManifests(t)
403+
404+
cfg, err := testEnv.Start()
405+
require.NoError(t, err)
406+
defer func() {
407+
assert.NoError(t, testEnv.Stop())
408+
}()
409+
410+
clientSet := framework.NewClientSetFromConfig(cfg)
411+
412+
_, err = clientSet.Namespaces().Create(ctx, &corev1.Namespace{
413+
ObjectMeta: metav1.ObjectMeta{
414+
Name: framework.OpenshiftConfigNamespace,
415+
},
416+
}, metav1.CreateOptions{})
417+
require.NoError(t, err)
418+
419+
_, err = clientSet.Namespaces().Create(ctx, &corev1.Namespace{
420+
ObjectMeta: metav1.ObjectMeta{
421+
Name: bootstrapTestName,
422+
},
423+
}, metav1.CreateOptions{})
424+
require.NoError(t, err)
425+
426+
objs := append([]runtime.Object{}, baseTestManifests...)
427+
428+
// Add node config
429+
nodeConfigManifest := [][]byte{
430+
[]byte(`apiVersion: config.openshift.io/v1
431+
kind: Node
432+
metadata:
433+
name: cluster`),
434+
}
435+
objs = append(objs, loadRawManifests(t, nodeConfigManifest)...)
436+
437+
fixture := newTestFixture(t, cfg, objs)
438+
defer framework.CleanEnvironment(t, clientSet)
439+
defer fixture.stop()
440+
441+
// Fetch the controller rendered configurations
442+
controllerRenderedMasterConfigName, err := helpers.WaitForRenderedConfigs(t, clientSet, "master", []string{"99-master-ssh", "99-master-generated-registries"}...)
443+
require.NoError(t, err)
444+
t.Logf("Controller rendered master config as %q", controllerRenderedMasterConfigName)
445+
446+
controllerRenderedWorkerConfigName, err := helpers.WaitForRenderedConfigs(t, clientSet, "worker", []string{"99-worker-ssh", "99-worker-generated-registries"}...)
447+
require.NoError(t, err)
448+
t.Logf("Controller rendered worker config as %q", controllerRenderedWorkerConfigName)
449+
450+
// Verify node sizing enabled file for master
451+
verifyNodeSizingEnabled(t, clientSet, controllerRenderedMasterConfigName)
452+
453+
// Verify node sizing enabled file for worker
454+
verifyNodeSizingEnabled(t, clientSet, controllerRenderedWorkerConfigName)
455+
}
456+
457+
func verifyNodeSizingEnabled(t *testing.T, clientSet *framework.ClientSet, renderedConfigName string) {
458+
controllerMC, err := clientSet.MachineConfigs().Get(context.Background(), renderedConfigName, metav1.GetOptions{})
459+
require.NoError(t, err)
460+
461+
ignCfg, err := ctrlcommon.ParseAndConvertConfig(controllerMC.Spec.Config.Raw)
462+
require.NoError(t, err)
463+
464+
// Find the node sizing enabled file
465+
var foundFile bool
466+
for _, file := range ignCfg.Storage.Files {
467+
if file.Path == "/etc/node-sizing-enabled.env" {
468+
foundFile = true
469+
470+
// Decode the file contents
471+
contents, err := ctrlcommon.DecodeIgnitionFileContents(file.Contents.Source, file.Contents.Compression)
472+
require.NoError(t, err, "Failed to decode node-sizing-enabled.env file contents")
473+
474+
contentsStr := string(contents)
475+
require.Contains(t, contentsStr, "NODE_SIZING_ENABLED=true", "Expected /etc/node-sizing-enabled.env to contain NODE_SIZING_ENABLED=true in machine config %s", renderedConfigName)
476+
break
477+
}
478+
}
479+
480+
require.True(t, foundFile, "Expected to find /etc/node-sizing-enabled.env in machine config %s", renderedConfigName)
481+
}
482+
392483
func compareRenderedConfigPool(t *testing.T, clientSet *framework.ClientSet, destDir, poolName, controllerRenderedConfigName string) {
393484
paths, err := filepath.Glob(filepath.Join(destDir, "machine-configs", fmt.Sprintf("rendered-%s-*.yaml", poolName)))
394485
require.NoError(t, err)

0 commit comments

Comments
 (0)