Skip to content

Commit c8a7151

Browse files
Merge pull request #917 from shajmakh/hugepages-machineconfig
tools: generate machine config with hugepages settings only
2 parents 17661cf + 4d83a04 commit c8a7151

File tree

4 files changed

+207
-16
lines changed

4 files changed

+207
-16
lines changed

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ dist-gather-sysinfo: build-output-dir
7676
echo "Using pre-built gather-sysinfo helper";\
7777
fi
7878

79+
.PHONY: dist-hugepages-mc-genarator
80+
dist-hugepages-mc-genarator: build-output-dir
81+
echo "Building hugepages machineconfig genarator tool";\
82+
env GOOS=$(TARGET_GOOS) GOARCH=$(TARGET_GOARCH) go build -ldflags="-s -w" -mod=vendor -o $(TOOLS_BIN_DIR)/hugepages-machineconfig-generator ./tools/hugepages-machineconfig-generator
83+
7984
.PHONY: dist-csv-processor
8085
dist-csv-processor: build-output-dir
8186
@if [ ! -x $(TOOLS_BIN_DIR)/csv-processor ]; then\

pkg/controller/performanceprofile/components/machineconfig/machineconfig.go

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,12 @@ func getIgnitionConfig(profile *performancev2.PerformanceProfile) (*igntypes.Con
140140
// add script files under the node /usr/local/bin directory
141141
mode := 0700
142142
for _, script := range []string{hugepagesAllocation, ociHooks, setRPSMask} {
143-
dst := getBashScriptPath(script)
143+
dst := GetBashScriptPath(script)
144144
content, err := assets.Scripts.ReadFile(fmt.Sprintf("scripts/%s.sh", script))
145145
if err != nil {
146146
return nil, err
147147
}
148-
addContent(ignitionConfig, content, dst, &mode)
148+
AddContent(ignitionConfig, content, dst, &mode)
149149
}
150150

151151
// add crio config snippet under the node /etc/crio/crio.conf.d/ directory
@@ -155,7 +155,7 @@ func getIgnitionConfig(profile *performancev2.PerformanceProfile) (*igntypes.Con
155155
return nil, err
156156
}
157157
crioConfSnippetDst := filepath.Join(crioConfd, crioRuntimesConfig)
158-
addContent(ignitionConfig, crioConfigSnippetContent, crioConfSnippetDst, &crioConfdRuntimesMode)
158+
AddContent(ignitionConfig, crioConfigSnippetContent, crioConfSnippetDst, &crioConfdRuntimesMode)
159159

160160
// add crio hooks config under the node cri-o hook directory
161161
crioHooksConfigsMode := 0644
@@ -164,7 +164,7 @@ func getIgnitionConfig(profile *performancev2.PerformanceProfile) (*igntypes.Con
164164
return nil, err
165165
}
166166
ociHookConfigDst := filepath.Join(OCIHooksConfigDir, OCIHooksConfig)
167-
addContent(ignitionConfig, ociHooksConfigContent, ociHookConfigDst, &crioHooksConfigsMode)
167+
AddContent(ignitionConfig, ociHooksConfigContent, ociHookConfigDst, &crioHooksConfigsMode)
168168

169169
// add rps udev rule
170170
rpsRulesMode := 0644
@@ -173,7 +173,7 @@ func getIgnitionConfig(profile *performancev2.PerformanceProfile) (*igntypes.Con
173173
return nil, err
174174
}
175175
rpsRulesDst := filepath.Join(udevRulesDir, udevRpsRules)
176-
addContent(ignitionConfig, rpsRulesContent, rpsRulesDst, &rpsRulesMode)
176+
AddContent(ignitionConfig, rpsRulesContent, rpsRulesDst, &rpsRulesMode)
177177

178178
if profile.Spec.HugePages != nil {
179179
for _, page := range profile.Spec.HugePages.Pages {
@@ -187,7 +187,7 @@ func getIgnitionConfig(profile *performancev2.PerformanceProfile) (*igntypes.Con
187187
return nil, err
188188
}
189189

190-
hugepagesService, err := getSystemdContent(getHugepagesAllocationUnitOptions(
190+
hugepagesService, err := GetSystemdContent(GetHugepagesAllocationUnitOptions(
191191
hugepagesSize,
192192
page.Count,
193193
*page.Node,
@@ -199,7 +199,7 @@ func getIgnitionConfig(profile *performancev2.PerformanceProfile) (*igntypes.Con
199199
ignitionConfig.Systemd.Units = append(ignitionConfig.Systemd.Units, igntypes.Unit{
200200
Contents: &hugepagesService,
201201
Enabled: pointer.BoolPtr(true),
202-
Name: getSystemdService(fmt.Sprintf("%s-%skB-NUMA%d", hugepagesAllocation, hugepagesSize, *page.Node)),
202+
Name: GetSystemdService(fmt.Sprintf("%s-%skB-NUMA%d", hugepagesAllocation, hugepagesSize, *page.Node)),
203203
})
204204
}
205205
}
@@ -210,33 +210,36 @@ func getIgnitionConfig(profile *performancev2.PerformanceProfile) (*igntypes.Con
210210
return nil, err
211211
}
212212

213-
rpsService, err := getSystemdContent(getRPSUnitOptions(rpsMask))
213+
rpsService, err := GetSystemdContent(getRPSUnitOptions(rpsMask))
214214
if err != nil {
215215
return nil, err
216216
}
217217

218218
ignitionConfig.Systemd.Units = append(ignitionConfig.Systemd.Units, igntypes.Unit{
219219
Contents: &rpsService,
220-
Name: getSystemdService("update-rps@"),
220+
Name: GetSystemdService("update-rps@"),
221221
})
222222
}
223223

224224
return ignitionConfig, nil
225225
}
226226

227-
func getBashScriptPath(scriptName string) string {
227+
//GetBashScriptPath returns the script path containing teh directory and the script name
228+
func GetBashScriptPath(scriptName string) string {
228229
return fmt.Sprintf("%s/%s.sh", bashScriptsDir, scriptName)
229230
}
230231

231232
func getSystemdEnvironment(key string, value string) string {
232233
return fmt.Sprintf("%s=%s", key, value)
233234
}
234235

235-
func getSystemdService(serviceName string) string {
236+
//GetSystemdService returns the service name in systemd
237+
func GetSystemdService(serviceName string) string {
236238
return fmt.Sprintf("%s.service", serviceName)
237239
}
238240

239-
func getSystemdContent(options []*unit.UnitOption) (string, error) {
241+
//GetSystemdContent get systemd content from list of unit options
242+
func GetSystemdContent(options []*unit.UnitOption) (string, error) {
240243
outReader := unit.Serialize(options)
241244
outBytes, err := ioutil.ReadAll(outReader)
242245
if err != nil {
@@ -281,7 +284,8 @@ func GetHugepagesSizeKilobytes(hugepagesSize performancev2.HugePageSize) (string
281284
}
282285
}
283286

284-
func getHugepagesAllocationUnitOptions(hugepagesSize string, hugepagesCount int32, numaNode int32) []*unit.UnitOption {
287+
//GetHugepagesAllocationUnitOptions returns list of unit options based on the settings of the hugepage
288+
func GetHugepagesAllocationUnitOptions(hugepagesSize string, hugepagesCount int32, numaNode int32) []*unit.UnitOption {
285289
return []*unit.UnitOption{
286290
// [Unit]
287291
// Description
@@ -298,15 +302,15 @@ func getHugepagesAllocationUnitOptions(hugepagesSize string, hugepagesCount int3
298302
// RemainAfterExit
299303
unit.NewUnitOption(systemdSectionService, systemdRemainAfterExit, systemdTrue),
300304
// ExecStart
301-
unit.NewUnitOption(systemdSectionService, systemdExecStart, getBashScriptPath(hugepagesAllocation)),
305+
unit.NewUnitOption(systemdSectionService, systemdExecStart, GetBashScriptPath(hugepagesAllocation)),
302306
// [Install]
303307
// WantedBy
304308
unit.NewUnitOption(systemdSectionInstall, systemdWantedBy, systemdTargetMultiUser),
305309
}
306310
}
307311

308312
func getRPSUnitOptions(rpsMask string) []*unit.UnitOption {
309-
cmd := fmt.Sprintf("%s %%i %s", getBashScriptPath(setRPSMask), rpsMask)
313+
cmd := fmt.Sprintf("%s %%i %s", GetBashScriptPath(setRPSMask), rpsMask)
310314
return []*unit.UnitOption{
311315
// [Unit]
312316
// Description
@@ -319,7 +323,8 @@ func getRPSUnitOptions(rpsMask string) []*unit.UnitOption {
319323
}
320324
}
321325

322-
func addContent(ignitionConfig *igntypes.Config, content []byte, dst string, mode *int) {
326+
//AddContent appends more content to the ignition configuration
327+
func AddContent(ignitionConfig *igntypes.Config, content []byte, dst string, mode *int) {
323328
contentBase64 := base64.StdEncoding.EncodeToString(content)
324329
ignitionConfig.Storage.Files = append(ignitionConfig.Storage.Files, igntypes.File{
325330
Node: igntypes.Node{
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package hugepages
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
7+
igntypes "github.com/coreos/ignition/v2/config/v3_2/types"
8+
machineconfigv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
9+
10+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11+
"k8s.io/apimachinery/pkg/runtime"
12+
"k8s.io/utils/pointer"
13+
14+
performancev2 "github.com/openshift-kni/performance-addon-operators/api/v2"
15+
"github.com/openshift-kni/performance-addon-operators/build/assets"
16+
comps "github.com/openshift-kni/performance-addon-operators/pkg/controller/performanceprofile/components"
17+
"github.com/openshift-kni/performance-addon-operators/pkg/controller/performanceprofile/components/machineconfig"
18+
)
19+
20+
const (
21+
defaultIgnitionVersion = "3.2.0"
22+
defaultIgnitionContentSource = "data:text/plain;charset=utf-8;base64"
23+
bashScriptsDir = "/usr/local/bin"
24+
hugepagesAllocation = "hugepages-allocation" //script name
25+
)
26+
27+
//MakeMachineConfig returns machineconfig object based on the hugepages configuration
28+
func MakeMachineConfig(hugepages *performancev2.HugePages, nodeRole string) (*machineconfigv1.MachineConfig, error) {
29+
labels := make(map[string]string)
30+
labels[comps.MachineConfigRoleLabelKey] = nodeRole
31+
32+
mc := &machineconfigv1.MachineConfig{
33+
TypeMeta: metav1.TypeMeta{
34+
APIVersion: machineconfigv1.GroupVersion.String(),
35+
Kind: "MachineConfig",
36+
},
37+
ObjectMeta: metav1.ObjectMeta{
38+
Name: "hugepages-config",
39+
Labels: labels,
40+
},
41+
Spec: machineconfigv1.MachineConfigSpec{},
42+
}
43+
44+
ignitionConfig, err := getIgnitionConfig(hugepages)
45+
if err != nil {
46+
return nil, err
47+
}
48+
49+
rawIgnition, err := json.Marshal(ignitionConfig)
50+
if err != nil {
51+
return nil, err
52+
}
53+
mc.Spec.Config = runtime.RawExtension{Raw: rawIgnition}
54+
55+
return mc, nil
56+
}
57+
58+
func getIgnitionConfig(hugepages *performancev2.HugePages) (*igntypes.Config, error) {
59+
ignitionConfig := &igntypes.Config{
60+
Ignition: igntypes.Ignition{
61+
Version: defaultIgnitionVersion,
62+
},
63+
Storage: igntypes.Storage{
64+
Files: []igntypes.File{},
65+
},
66+
}
67+
68+
// add hugepages allocation script file under the node /usr/local/bin directory
69+
mode := 0700
70+
dst := machineconfig.GetBashScriptPath(hugepagesAllocation)
71+
content, err := assets.Scripts.ReadFile(fmt.Sprintf("scripts/%s.sh", hugepagesAllocation))
72+
if err != nil {
73+
return nil, err
74+
}
75+
machineconfig.AddContent(ignitionConfig, content, dst, &mode)
76+
77+
// add hugepages units under systemd
78+
for _, page := range hugepages.Pages {
79+
hugepagesSize, err := machineconfig.GetHugepagesSizeKilobytes(page.Size)
80+
if err != nil {
81+
return nil, err
82+
}
83+
84+
hugepagesService, err := machineconfig.GetSystemdContent(machineconfig.GetHugepagesAllocationUnitOptions(
85+
hugepagesSize,
86+
page.Count,
87+
*page.Node,
88+
))
89+
if err != nil {
90+
return nil, err
91+
}
92+
93+
ignitionConfig.Systemd.Units = append(ignitionConfig.Systemd.Units, igntypes.Unit{
94+
Contents: &hugepagesService,
95+
Enabled: pointer.BoolPtr(true),
96+
Name: machineconfig.GetSystemdService(fmt.Sprintf("%s-%skB-NUMA%d", hugepagesAllocation, hugepagesSize, *page.Node)),
97+
})
98+
}
99+
100+
return ignitionConfig, nil
101+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"io"
6+
"io/ioutil"
7+
"log"
8+
"os"
9+
10+
"github.com/ghodss/yaml"
11+
12+
machineconfigv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
13+
14+
performancev2 "github.com/openshift-kni/performance-addon-operators/api/v2"
15+
"github.com/openshift-kni/performance-addon-operators/pkg/utils/hugepages"
16+
)
17+
18+
var (
19+
nodeRole = flag.String("n", "worker", "node role of the machine config object")
20+
inputFile = flag.String("i", "", "performance profile yaml file")
21+
outputFile = flag.String("o", "", "performance profile yaml file")
22+
)
23+
24+
func main() {
25+
flag.Parse()
26+
27+
var err error
28+
var bytes []byte
29+
if inputFile == nil || *inputFile == "" {
30+
// reads the full content of stdin - possibly a large block of data
31+
bytes, err = ioutil.ReadAll(os.Stdin)
32+
} else {
33+
//reads the full content of the input file
34+
bytes, err = ioutil.ReadFile(*inputFile)
35+
}
36+
if err != nil {
37+
log.Fatalf("failed to read the input: %v", err)
38+
}
39+
profile := &performancev2.PerformanceProfile{}
40+
err = yaml.Unmarshal(bytes, profile)
41+
if err != nil {
42+
log.Fatalf("failed to unmarshal the input into performance profile: %v", err)
43+
}
44+
45+
mc, err := createMachineConfig(profile, nodeRole)
46+
if err != nil {
47+
log.Fatalf("failed to generate a machine config with hugepages settings: %v", err)
48+
}
49+
50+
y, err := yaml.Marshal(mc)
51+
if err != nil {
52+
log.Fatalf("failed to get the machine config as yaml file: %v", err)
53+
}
54+
55+
manifest := string(y)
56+
var sink io.Writer = os.Stdout
57+
if outputFile != nil && *outputFile != "" {
58+
f, err := os.Create(*outputFile)
59+
if err != nil {
60+
log.Fatalf("error opening %s: %v\n", *outputFile, err)
61+
}
62+
defer f.Close()
63+
sink = f
64+
}
65+
// writes all the content to the destination file in one go
66+
_, err = io.WriteString(sink, manifest)
67+
if err != nil {
68+
log.Fatalf("unable to write the output: %v", err)
69+
}
70+
71+
}
72+
73+
func createMachineConfig(profile *performancev2.PerformanceProfile, noderole *string) (*machineconfigv1.MachineConfig, error) {
74+
defer func() {
75+
if rec := recover(); rec != nil {
76+
log.Fatalf("missing page.Node: %v", rec)
77+
}
78+
}()
79+
return hugepages.MakeMachineConfig(profile.Spec.HugePages, *nodeRole)
80+
}

0 commit comments

Comments
 (0)