Skip to content

Commit

Permalink
Merge pull request #917 from shajmakh/hugepages-machineconfig
Browse files Browse the repository at this point in the history
tools: generate machine config with hugepages settings only
  • Loading branch information
openshift-ci[bot] committed Jun 29, 2022
2 parents 17661cf + 4d83a04 commit c8a7151
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 16 deletions.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ dist-gather-sysinfo: build-output-dir
echo "Using pre-built gather-sysinfo helper";\
fi

.PHONY: dist-hugepages-mc-genarator
dist-hugepages-mc-genarator: build-output-dir
echo "Building hugepages machineconfig genarator tool";\
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

.PHONY: dist-csv-processor
dist-csv-processor: build-output-dir
@if [ ! -x $(TOOLS_BIN_DIR)/csv-processor ]; then\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,12 @@ func getIgnitionConfig(profile *performancev2.PerformanceProfile) (*igntypes.Con
// add script files under the node /usr/local/bin directory
mode := 0700
for _, script := range []string{hugepagesAllocation, ociHooks, setRPSMask} {
dst := getBashScriptPath(script)
dst := GetBashScriptPath(script)
content, err := assets.Scripts.ReadFile(fmt.Sprintf("scripts/%s.sh", script))
if err != nil {
return nil, err
}
addContent(ignitionConfig, content, dst, &mode)
AddContent(ignitionConfig, content, dst, &mode)
}

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

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

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

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

hugepagesService, err := getSystemdContent(getHugepagesAllocationUnitOptions(
hugepagesService, err := GetSystemdContent(GetHugepagesAllocationUnitOptions(
hugepagesSize,
page.Count,
*page.Node,
Expand All @@ -199,7 +199,7 @@ func getIgnitionConfig(profile *performancev2.PerformanceProfile) (*igntypes.Con
ignitionConfig.Systemd.Units = append(ignitionConfig.Systemd.Units, igntypes.Unit{
Contents: &hugepagesService,
Enabled: pointer.BoolPtr(true),
Name: getSystemdService(fmt.Sprintf("%s-%skB-NUMA%d", hugepagesAllocation, hugepagesSize, *page.Node)),
Name: GetSystemdService(fmt.Sprintf("%s-%skB-NUMA%d", hugepagesAllocation, hugepagesSize, *page.Node)),
})
}
}
Expand All @@ -210,33 +210,36 @@ func getIgnitionConfig(profile *performancev2.PerformanceProfile) (*igntypes.Con
return nil, err
}

rpsService, err := getSystemdContent(getRPSUnitOptions(rpsMask))
rpsService, err := GetSystemdContent(getRPSUnitOptions(rpsMask))
if err != nil {
return nil, err
}

ignitionConfig.Systemd.Units = append(ignitionConfig.Systemd.Units, igntypes.Unit{
Contents: &rpsService,
Name: getSystemdService("update-rps@"),
Name: GetSystemdService("update-rps@"),
})
}

return ignitionConfig, nil
}

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

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

func getSystemdService(serviceName string) string {
//GetSystemdService returns the service name in systemd
func GetSystemdService(serviceName string) string {
return fmt.Sprintf("%s.service", serviceName)
}

func getSystemdContent(options []*unit.UnitOption) (string, error) {
//GetSystemdContent get systemd content from list of unit options
func GetSystemdContent(options []*unit.UnitOption) (string, error) {
outReader := unit.Serialize(options)
outBytes, err := ioutil.ReadAll(outReader)
if err != nil {
Expand Down Expand Up @@ -281,7 +284,8 @@ func GetHugepagesSizeKilobytes(hugepagesSize performancev2.HugePageSize) (string
}
}

func getHugepagesAllocationUnitOptions(hugepagesSize string, hugepagesCount int32, numaNode int32) []*unit.UnitOption {
//GetHugepagesAllocationUnitOptions returns list of unit options based on the settings of the hugepage
func GetHugepagesAllocationUnitOptions(hugepagesSize string, hugepagesCount int32, numaNode int32) []*unit.UnitOption {
return []*unit.UnitOption{
// [Unit]
// Description
Expand All @@ -298,15 +302,15 @@ func getHugepagesAllocationUnitOptions(hugepagesSize string, hugepagesCount int3
// RemainAfterExit
unit.NewUnitOption(systemdSectionService, systemdRemainAfterExit, systemdTrue),
// ExecStart
unit.NewUnitOption(systemdSectionService, systemdExecStart, getBashScriptPath(hugepagesAllocation)),
unit.NewUnitOption(systemdSectionService, systemdExecStart, GetBashScriptPath(hugepagesAllocation)),
// [Install]
// WantedBy
unit.NewUnitOption(systemdSectionInstall, systemdWantedBy, systemdTargetMultiUser),
}
}

func getRPSUnitOptions(rpsMask string) []*unit.UnitOption {
cmd := fmt.Sprintf("%s %%i %s", getBashScriptPath(setRPSMask), rpsMask)
cmd := fmt.Sprintf("%s %%i %s", GetBashScriptPath(setRPSMask), rpsMask)
return []*unit.UnitOption{
// [Unit]
// Description
Expand All @@ -319,7 +323,8 @@ func getRPSUnitOptions(rpsMask string) []*unit.UnitOption {
}
}

func addContent(ignitionConfig *igntypes.Config, content []byte, dst string, mode *int) {
//AddContent appends more content to the ignition configuration
func AddContent(ignitionConfig *igntypes.Config, content []byte, dst string, mode *int) {
contentBase64 := base64.StdEncoding.EncodeToString(content)
ignitionConfig.Storage.Files = append(ignitionConfig.Storage.Files, igntypes.File{
Node: igntypes.Node{
Expand Down
101 changes: 101 additions & 0 deletions pkg/utils/hugepages/machineconfig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package hugepages

import (
"encoding/json"
"fmt"

igntypes "github.com/coreos/ignition/v2/config/v3_2/types"
machineconfigv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/pointer"

performancev2 "github.com/openshift-kni/performance-addon-operators/api/v2"
"github.com/openshift-kni/performance-addon-operators/build/assets"
comps "github.com/openshift-kni/performance-addon-operators/pkg/controller/performanceprofile/components"
"github.com/openshift-kni/performance-addon-operators/pkg/controller/performanceprofile/components/machineconfig"
)

const (
defaultIgnitionVersion = "3.2.0"
defaultIgnitionContentSource = "data:text/plain;charset=utf-8;base64"
bashScriptsDir = "/usr/local/bin"
hugepagesAllocation = "hugepages-allocation" //script name
)

//MakeMachineConfig returns machineconfig object based on the hugepages configuration
func MakeMachineConfig(hugepages *performancev2.HugePages, nodeRole string) (*machineconfigv1.MachineConfig, error) {
labels := make(map[string]string)
labels[comps.MachineConfigRoleLabelKey] = nodeRole

mc := &machineconfigv1.MachineConfig{
TypeMeta: metav1.TypeMeta{
APIVersion: machineconfigv1.GroupVersion.String(),
Kind: "MachineConfig",
},
ObjectMeta: metav1.ObjectMeta{
Name: "hugepages-config",
Labels: labels,
},
Spec: machineconfigv1.MachineConfigSpec{},
}

ignitionConfig, err := getIgnitionConfig(hugepages)
if err != nil {
return nil, err
}

rawIgnition, err := json.Marshal(ignitionConfig)
if err != nil {
return nil, err
}
mc.Spec.Config = runtime.RawExtension{Raw: rawIgnition}

return mc, nil
}

func getIgnitionConfig(hugepages *performancev2.HugePages) (*igntypes.Config, error) {
ignitionConfig := &igntypes.Config{
Ignition: igntypes.Ignition{
Version: defaultIgnitionVersion,
},
Storage: igntypes.Storage{
Files: []igntypes.File{},
},
}

// add hugepages allocation script file under the node /usr/local/bin directory
mode := 0700
dst := machineconfig.GetBashScriptPath(hugepagesAllocation)
content, err := assets.Scripts.ReadFile(fmt.Sprintf("scripts/%s.sh", hugepagesAllocation))
if err != nil {
return nil, err
}
machineconfig.AddContent(ignitionConfig, content, dst, &mode)

// add hugepages units under systemd
for _, page := range hugepages.Pages {
hugepagesSize, err := machineconfig.GetHugepagesSizeKilobytes(page.Size)
if err != nil {
return nil, err
}

hugepagesService, err := machineconfig.GetSystemdContent(machineconfig.GetHugepagesAllocationUnitOptions(
hugepagesSize,
page.Count,
*page.Node,
))
if err != nil {
return nil, err
}

ignitionConfig.Systemd.Units = append(ignitionConfig.Systemd.Units, igntypes.Unit{
Contents: &hugepagesService,
Enabled: pointer.BoolPtr(true),
Name: machineconfig.GetSystemdService(fmt.Sprintf("%s-%skB-NUMA%d", hugepagesAllocation, hugepagesSize, *page.Node)),
})
}

return ignitionConfig, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package main

import (
"flag"
"io"
"io/ioutil"
"log"
"os"

"github.com/ghodss/yaml"

machineconfigv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"

performancev2 "github.com/openshift-kni/performance-addon-operators/api/v2"
"github.com/openshift-kni/performance-addon-operators/pkg/utils/hugepages"
)

var (
nodeRole = flag.String("n", "worker", "node role of the machine config object")
inputFile = flag.String("i", "", "performance profile yaml file")
outputFile = flag.String("o", "", "performance profile yaml file")
)

func main() {
flag.Parse()

var err error
var bytes []byte
if inputFile == nil || *inputFile == "" {
// reads the full content of stdin - possibly a large block of data
bytes, err = ioutil.ReadAll(os.Stdin)
} else {
//reads the full content of the input file
bytes, err = ioutil.ReadFile(*inputFile)
}
if err != nil {
log.Fatalf("failed to read the input: %v", err)
}
profile := &performancev2.PerformanceProfile{}
err = yaml.Unmarshal(bytes, profile)
if err != nil {
log.Fatalf("failed to unmarshal the input into performance profile: %v", err)
}

mc, err := createMachineConfig(profile, nodeRole)
if err != nil {
log.Fatalf("failed to generate a machine config with hugepages settings: %v", err)
}

y, err := yaml.Marshal(mc)
if err != nil {
log.Fatalf("failed to get the machine config as yaml file: %v", err)
}

manifest := string(y)
var sink io.Writer = os.Stdout
if outputFile != nil && *outputFile != "" {
f, err := os.Create(*outputFile)
if err != nil {
log.Fatalf("error opening %s: %v\n", *outputFile, err)
}
defer f.Close()
sink = f
}
// writes all the content to the destination file in one go
_, err = io.WriteString(sink, manifest)
if err != nil {
log.Fatalf("unable to write the output: %v", err)
}

}

func createMachineConfig(profile *performancev2.PerformanceProfile, noderole *string) (*machineconfigv1.MachineConfig, error) {
defer func() {
if rec := recover(); rec != nil {
log.Fatalf("missing page.Node: %v", rec)
}
}()
return hugepages.MakeMachineConfig(profile.Spec.HugePages, *nodeRole)
}

0 comments on commit c8a7151

Please sign in to comment.