Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 33 additions & 14 deletions hack/render-sync.sh
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
#!/usr/bin/env bash

WORKDIR=$(dirname "$(realpath "$0")")/..
ARTIFACT_DIR=$(mktemp -d)

cd "${WORKDIR}" || { echo "failed to change dir to ${WORKDIR}"; exit; }
_output/cluster-node-tuning-operator render \
--asset-input-dir "${WORKDIR}"/test/e2e/performanceprofile/cluster-setup/manual-cluster/performance,"${WORKDIR}"/test/e2e/performanceprofile/cluster-setup/base/performance \
--asset-output-dir "${ARTIFACT_DIR}"

cp "${ARTIFACT_DIR}"/* "${WORKDIR}"/test/e2e/performanceprofile/testdata/render-expected-output/default
for f in "${WORKDIR}"/test/e2e/performanceprofile/testdata/render-expected-output/default/*
do
sed -i "s/uid:.*/uid: \"\"/" "${f}"
done
rm -r "${ARTIFACT_DIR}"

function join_by { local IFS="$1"; shift; echo "$*"; }

function rendersync() {
INPUT_DIRS=()
while (( $# > 1 )); do
INPUT_DIRS+=("${WORKDIR}/test/e2e/performanceprofile/cluster-setup/$1")
shift
done
INPUT_DIRS=$(join_by , ${INPUT_DIRS[@]})

OUTPUT_DIR=$1

echo "== Rendering ${INPUT_DIRS} into ${OUTPUT_DIR}"

ARTIFACT_DIR=$(mktemp -d)

cd "${WORKDIR}" || { echo "failed to change dir to ${WORKDIR}"; exit; }
_output/cluster-node-tuning-operator render \
--asset-input-dir "${INPUT_DIRS}" \
--asset-output-dir "${ARTIFACT_DIR}"

cp "${ARTIFACT_DIR}"/* "${WORKDIR}"/test/e2e/performanceprofile/testdata/render-expected-output/${OUTPUT_DIR}
for f in "${WORKDIR}"/test/e2e/performanceprofile/testdata/render-expected-output/${OUTPUT_DIR}/*
do
sed -i "s/uid:.*/uid: \"\"/" "${f}"
done
rm -r "${ARTIFACT_DIR}"
}

rendersync manual-cluster/performance base/performance default
rendersync bootstrap-cluster/performance pinned-cluster/default bootstrap/no-mcp
rendersync bootstrap-cluster/performance pinned-cluster/default bootstrap-cluster/extra-mcp bootstrap/extra-mcp
68 changes: 68 additions & 0 deletions pkg/performanceprofile/cmd/render/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import (
"path/filepath"
"strings"

"github.com/openshift/cluster-node-tuning-operator/pkg/performanceprofile/controller/performanceprofile/components"
mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
yamlutil "k8s.io/apimachinery/pkg/util/yaml"
)

Expand Down Expand Up @@ -93,3 +96,68 @@ func listFiles(dirPaths string) ([]string, error) {
}
return results, nil
}

// AppendMissingDefaultMCPManifests When default MCPs are missing, it is desirable to still generate the relevant
// files based off of the standard MCP labels and node selectors.
//
// Here we create the default `master` and `worker` MCP if they are missing with their respective base Labels and NodeSelector Labels,
// this allows any resource such as PAO to utilize the default during bootstrap rendering.
func AppendMissingDefaultMCPManifests(currentMCPs []*mcfgv1.MachineConfigPool) []*mcfgv1.MachineConfigPool {
const (
master = "master"
worker = "worker"
labelPrefix = "pools.operator.machineconfiguration.openshift.io/"
masterLabels = labelPrefix + master
workerLabels = labelPrefix + worker
masterNodeSelector = components.NodeRoleLabelPrefix + master
workerNodeSelector = components.NodeRoleLabelPrefix + worker
)
var (
finalMCPList = []*mcfgv1.MachineConfigPool{}
defaultMCPs = []*mcfgv1.MachineConfigPool{
{
ObjectMeta: v1.ObjectMeta{
Labels: map[string]string{
masterLabels: "",
},
Name: master,
},
Spec: mcfgv1.MachineConfigPoolSpec{
NodeSelector: v1.AddLabelToSelector(&v1.LabelSelector{}, masterNodeSelector, ""),
},
},
{
ObjectMeta: v1.ObjectMeta{
Labels: map[string]string{
workerLabels: "",
},
Name: worker,
},
Spec: mcfgv1.MachineConfigPoolSpec{
NodeSelector: v1.AddLabelToSelector(&v1.LabelSelector{}, workerNodeSelector, ""),
},
},
}
)

if len(currentMCPs) == 0 {
return defaultMCPs
}

for _, defaultMCP := range defaultMCPs {
missing := true
for _, mcp := range currentMCPs {
// Since users can supply MCP files and these will be raw files with out going through the API
// server validation, we normalize the file name so as to not mask any configuration errors.
if strings.ToLower(mcp.Name) == defaultMCP.Name {
missing = false
break
}
}
if missing {
finalMCPList = append(finalMCPList, defaultMCP)
}
}

return append(finalMCPList, currentMCPs...)
}
3 changes: 3 additions & 0 deletions pkg/performanceprofile/cmd/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ func render(inputDir, outputDir string) error {
}
}

// Append any missing default manifests (i.e. `master`/`worker`)
mcPools = util.AppendMissingDefaultMCPManifests(mcPools)

for _, pp := range perfProfiles {
mcp, err := selectMachineConfigPool(mcPools, pp.Spec.NodeSelector)
if err != nil {
Expand Down
90 changes: 90 additions & 0 deletions pkg/tuned/cmd/render/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*

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

http://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 render

import (
"flag"
"fmt"

"github.com/openshift/cluster-node-tuning-operator/pkg/performanceprofile/controller/performanceprofile/components"

"github.com/spf13/cobra"
"github.com/spf13/pflag"

"k8s.io/klog"
)

type renderOpts struct {
assetsInDir []string
assetsOutDir string
mcpName string
}

func NewRenderBootCmdMCCommand() *cobra.Command {
renderOpts := renderOpts{}

cmd := &cobra.Command{
Use: "render-bootcmd-mc",
Short: "Render MC with kernel args",
Run: func(cmd *cobra.Command, args []string) {
if err := renderOpts.Validate(); err != nil {
klog.Fatal(err)
}

if err := renderOpts.Run(); err != nil {
klog.Fatal(err)
}
},
}

addKlogFlags(cmd)
renderOpts.AddFlags(cmd.Flags())
return cmd
}

func (r *renderOpts) AddFlags(fs *pflag.FlagSet) {
fs.StringArrayVar(&r.assetsInDir, "asset-input-dir", []string{components.AssetsDir}, "Input path for the assets directory. (Can use it more than one to define multiple directories)")
fs.StringVar(&r.assetsOutDir, "asset-output-dir", r.assetsOutDir, "Output path for the rendered manifests.")
fs.StringVar(&r.mcpName, "mcp-name", r.mcpName, "MachineConfigPool name for the current node.")
}

func (r *renderOpts) Validate() error {
var err string
if len(r.assetsInDir) == 0 {
err += "asset-input-dir must be specified. "
}
if len(r.assetsOutDir) == 0 {
err += "asset-output-dir must be specified. "
}
if len(r.mcpName) == 0 {
err += "mcp-name must be specified. "
}

if len(err) == 0 {
return nil
}
return fmt.Errorf(err)
}

func (r *renderOpts) Run() error {
return render(r.assetsInDir, r.assetsOutDir, r.mcpName)
}

func addKlogFlags(cmd *cobra.Command) {
fs := flag.NewFlagSet("", flag.PanicOnError)
klog.InitFlags(fs)
cmd.Flags().AddGoFlagSet(fs)
}
Loading