Skip to content

Commit

Permalink
nrt: expose TM config as attributes
Browse files Browse the repository at this point in the history
expose TM configuration as attributes of a special Zone.
This is in addition to TopologyPolicies field, which is
being deprecated. See:
- k8stopologyawareschedwg/noderesourcetopology-api#24
- k8stopologyawareschedwg/noderesourcetopology-api#25

Signed-off-by: Francesco Romani <[email protected]>
  • Loading branch information
ffromani committed Jan 30, 2023
1 parent 3da2725 commit b3ba217
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 11 deletions.
39 changes: 37 additions & 2 deletions pkg/nrtupdater/nrtupdater.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const (
RTEUpdatePeriodic = "periodic"
RTEUpdateReactive = "reactive"
)
const (
ZoneConfigType = "TopologyManager"
)

// Command line arguments
type Args struct {
Expand All @@ -32,9 +35,19 @@ type Args struct {
Hostname string
}

type TMConfig struct {
Policy string
Scope string
}

func (conf TMConfig) IsValid() bool {
return conf.Policy != "" && conf.Scope != ""
}

type NRTUpdater struct {
args Args
tmPolicy string
tmConfig TMConfig
stopChan chan struct{}
}

Expand All @@ -51,10 +64,11 @@ func (mi MonitorInfo) UpdateReason() string {
return RTEUpdateReactive
}

func NewNRTUpdater(args Args, policy string) *NRTUpdater {
func NewNRTUpdater(args Args, policy string, tmconf TMConfig) *NRTUpdater {
return &NRTUpdater{
args: args,
tmPolicy: policy,
tmConfig: tmconf,
stopChan: make(chan struct{}),
}
}
Expand Down Expand Up @@ -117,7 +131,28 @@ func (te *NRTUpdater) updateNRTInfo(nrt *v1alpha1.NodeResourceTopology, info Mon
nrt.Annotations = mergeAnnotations(nrt.Annotations, info.Annotations)
nrt.Annotations[k8sannotations.RTEUpdate] = info.UpdateReason()
nrt.TopologyPolicies = []string{te.tmPolicy}
nrt.Zones = info.Zones
nrt.Zones = v1alpha1.ZoneList{}
if te.tmConfig.IsValid() {
nrt.Zones = append(nrt.Zones, te.makeTMConfigZone())
}
nrt.Zones = append(nrt.Zones, info.Zones...)
}

func (te *NRTUpdater) makeTMConfigZone() v1alpha1.Zone {
return v1alpha1.Zone{
Name: ZoneConfigType,
Type: ZoneConfigType,
Attributes: v1alpha1.AttributeList{
{
Name: "scope",
Value: te.tmConfig.Scope,
},
{
Name: "policy",
Value: te.tmConfig.Policy,
},
},
}
}

func (te *NRTUpdater) Stop() {
Expand Down
54 changes: 49 additions & 5 deletions pkg/nrtupdater/nrtupdater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package nrtupdater

import (
"reflect"
"testing"

corev1 "k8s.io/api/core/v1"
Expand All @@ -40,8 +41,17 @@ func TestUpdateTMPolicy(t *testing.T) {
policyInitial := "policy-initial"
policyUpdated := "policy-updated"

tmConfInitial := TMConfig{
Scope: "scope-initial",
Policy: "policy-initial",
}
tmConfUpdated := TMConfig{
Scope: "scope-updated",
Policy: "polcy-updated",
}

var err error
nrtUpd = NewNRTUpdater(args, policyInitial)
nrtUpd = NewNRTUpdater(args, policyInitial, tmConfInitial)
err = nrtUpd.UpdateWithClient(
cli,
MonitorInfo{
Expand Down Expand Up @@ -76,9 +86,9 @@ func TestUpdateTMPolicy(t *testing.T) {
if err != nil {
t.Fatalf("failed to get the NRT object from tracker: %v", err)
}
checkTMPolicy(t, obj, policyInitial)
checkTMPolicy(t, obj, policyInitial, tmConfInitial)

nrtUpd = NewNRTUpdater(args, policyUpdated)
nrtUpd = NewNRTUpdater(args, policyUpdated, tmConfUpdated)
err = nrtUpd.UpdateWithClient(
cli,
MonitorInfo{
Expand Down Expand Up @@ -112,10 +122,10 @@ func TestUpdateTMPolicy(t *testing.T) {
if err != nil {
t.Fatalf("failed to get the NRT object from tracker: %v", err)
}
checkTMPolicy(t, obj, policyUpdated)
checkTMPolicy(t, obj, policyUpdated, tmConfUpdated)
}

func checkTMPolicy(t *testing.T, obj runtime.Object, expectedPolicy string) {
func checkTMPolicy(t *testing.T, obj runtime.Object, expectedPolicy string, expectedConf TMConfig) {
t.Helper()

nrtObj, ok := obj.(*v1alpha1.NodeResourceTopology)
Expand All @@ -128,4 +138,38 @@ func checkTMPolicy(t *testing.T, obj runtime.Object, expectedPolicy string) {
if nrtObj.TopologyPolicies[0] != expectedPolicy {
t.Fatalf("topology policy mismatch: expected %q got %q", expectedPolicy, nrtObj.TopologyPolicies[0])
}
zone := findTMConfigZone(nrtObj)
if zone == nil {
t.Fatalf("topology manager configuration zone not found")
}
gotConf := tmConfigFromAttributes(zone.Attributes)
if !reflect.DeepEqual(gotConf, expectedConf) {
t.Fatalf("config got=%+#v expected=%+#v", gotConf, expectedConf)
}
}

func findTMConfigZone(nodeTopology *v1alpha1.NodeResourceTopology) *v1alpha1.Zone {
for idx := range nodeTopology.Zones {
zone := &nodeTopology.Zones[idx]
if zone.Type != ZoneConfigType {
continue
}
return zone
}
return nil
}

func tmConfigFromAttributes(attrs v1alpha1.AttributeList) TMConfig {
conf := TMConfig{}
for _, attr := range attrs {
if attr.Name == "scope" {
conf.Scope = attr.Value
continue
}
if attr.Name == "policy" {
conf.Policy = attr.Value
continue
}
}
return conf
}
10 changes: 7 additions & 3 deletions pkg/resourcetopologyexporter/resourcetopologyexporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,14 @@ type Args struct {
}

func Execute(cli podresourcesapi.PodResourcesListerClient, nrtupdaterArgs nrtupdater.Args, resourcemonitorArgs resourcemonitor.Args, rteArgs Args) error {
tmPolicy, err := getTopologyManagerPolicy(resourcemonitorArgs, rteArgs)
tmPolicy, err := getTopologyManagerPolicy(rteArgs)
if err != nil {
return err
}
tmConf := nrtupdater.TMConfig{
Policy: rteArgs.TopologyManagerPolicy,
Scope: rteArgs.TopologyManagerScope,
}

var condChan chan v1.PodCondition
if rteArgs.PodReadinessEnable {
Expand All @@ -62,7 +66,7 @@ func Execute(cli podresourcesapi.PodResourcesListerClient, nrtupdaterArgs nrtupd
}
go resObs.Run(eventSource.Events(), condChan)

upd := nrtupdater.NewNRTUpdater(nrtupdaterArgs, string(tmPolicy))
upd := nrtupdater.NewNRTUpdater(nrtupdaterArgs, string(tmPolicy), tmConf)
go upd.Run(resObs.Infos, condChan)

go eventSource.Run()
Expand Down Expand Up @@ -108,7 +112,7 @@ func createEventSource(rteArgs *Args) (notification.EventSource, error) {
return es, nil
}

func getTopologyManagerPolicy(resourcemonitorArgs resourcemonitor.Args, rteArgs Args) (v1alpha1.TopologyManagerPolicy, error) {
func getTopologyManagerPolicy(rteArgs Args) (v1alpha1.TopologyManagerPolicy, error) {
if rteArgs.TopologyManagerPolicy != "" && rteArgs.TopologyManagerScope != "" {
klog.Infof("using given Topology Manager policy %q scope %q", rteArgs.TopologyManagerPolicy, rteArgs.TopologyManagerScope)
return topologypolicy.DetectTopologyPolicy(rteArgs.TopologyManagerPolicy, rteArgs.TopologyManagerScope), nil
Expand Down
8 changes: 7 additions & 1 deletion tools/nrtstress/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ import (
func main() {
var hostname string
var tmPolicy string
var tmScope string
var interval time.Duration
var seed int
var dryRun bool
flag.StringVar(&hostname, "hosthame", "fake-host-0", "fake host name (not validated)")
flag.StringVar(&tmPolicy, "tm-policy", "single-numa-node", "topology manager policy (not validated)")
flag.StringVar(&tmScope, "tm-scope", "pod", "topology manager scope (not validated)")
flag.DurationVar(&interval, "interval", 10*time.Second, "periodic update interval")
flag.IntVar(&seed, "random-seed", 0, "random seed (use time)")
flag.BoolVar(&dryRun, "dry-run", false, "don't send data")
Expand Down Expand Up @@ -47,6 +49,10 @@ func main() {

klog.Infof("using NRT Updater args: %+#v", nrtupdaterArgs)

upd := nrtupdater.NewNRTUpdater(nrtupdaterArgs, tmPolicy)
tmConf := nrtupdater.TMConfig{
Policy: tmPolicy,
Scope: tmScope,
}
upd := nrtupdater.NewNRTUpdater(nrtupdaterArgs, tmPolicy, tmConf)
upd.Run(gen.Infos, nil)
}

0 comments on commit b3ba217

Please sign in to comment.