@@ -47,6 +47,10 @@ const (
4747 ioPrioKey = "io-priority.noderesource.dev"
4848 // Deprecated: Prefix of the key used for I/O priority adjustment.
4949 oldIoPrioKey = "io-priority.nri.io"
50+ // Prefix of the key used for scheduler attribute adjustment.
51+ schedulerKey = "scheduling-policy.noderesource.dev"
52+ // Deprecated: Prefix of the key used for scheduler attribute adjustment.
53+ oldSchedulerKey = "scheduling-policy.nri.io"
5054)
5155
5256var (
@@ -79,6 +83,17 @@ type ioPrio struct {
7983 Priority int32 `json:"priority"`
8084}
8185
86+ // scheduler attribute adjustment
87+ type scheduler struct {
88+ Policy string `json:"policy"`
89+ Nice int32 `json:"nice"`
90+ Priority int32 `json:"priority"`
91+ Flags []string `json:"flags"`
92+ Runtime uint64 `json:"runtime"`
93+ Deadline uint64 `json:"deadline"`
94+ Period uint64 `json:"period"`
95+ }
96+
8297// our injector plugin
8398type plugin struct {
8499 stub stub.Stub
@@ -107,6 +122,9 @@ func (p *plugin) CreateContainer(_ context.Context, pod *api.PodSandbox, ctr *ap
107122 if err := setIOPriority (pod , ctr , adjust ); err != nil {
108123 return nil , nil , err
109124 }
125+ if err := adjustScheduler (pod , ctr , adjust ); err != nil {
126+ return nil , nil , err
127+ }
110128
111129 if verbose {
112130 dump (containerName (pod , ctr ), "ContainerAdjustment" , adjust )
@@ -269,6 +287,29 @@ func setIOPriority(pod *api.PodSandbox, ctr *api.Container, a *api.ContainerAdju
269287 return nil
270288}
271289
290+ func adjustScheduler (pod * api.PodSandbox , ctr * api.Container , a * api.ContainerAdjustment ) error {
291+ sch , err := parseScheduler (ctr .Name , pod .Annotations )
292+ if err != nil {
293+ return err
294+ }
295+
296+ if sch == nil {
297+ log .Debugf ("%s: no scheduling attributes annotated..." , containerName (pod , ctr ))
298+ return nil
299+ }
300+
301+ if verbose {
302+ dump (containerName (pod , ctr ), "annotated scheduling attributes" , sch )
303+ }
304+
305+ a .SetLinuxScheduler (sch .ToNRI ())
306+ if ! verbose {
307+ log .Infof ("%s: adjusted scheduling attributes to %s..." , containerName (pod , ctr ), sch )
308+ }
309+
310+ return nil
311+ }
312+
272313func parseIOPriority (ctr string , annotations map [string ]string ) (* ioPrio , error ) {
273314 var (
274315 priority = & ioPrio {}
@@ -286,6 +327,23 @@ func parseIOPriority(ctr string, annotations map[string]string) (*ioPrio, error)
286327 return priority , nil
287328}
288329
330+ func parseScheduler (ctr string , annotations map [string ]string ) (* scheduler , error ) {
331+ var (
332+ sch = & scheduler {}
333+ )
334+
335+ annotation := getAnnotation (annotations , schedulerKey , oldSchedulerKey , ctr )
336+ if annotation == nil {
337+ return nil , nil
338+ }
339+
340+ if err := yaml .Unmarshal (annotation , sch ); err != nil {
341+ return nil , fmt .Errorf ("invalid scheduler annotation %q: %w" , string (annotation ), err )
342+ }
343+
344+ return sch , nil
345+ }
346+
289347func getAnnotation (annotations map [string ]string , mainKey , oldKey , ctr string ) []byte {
290348 for _ , key := range []string {
291349 mainKey + "/container." + ctr ,
@@ -369,6 +427,47 @@ func (p *ioPrio) String() string {
369427 return fmt .Sprintf ("<I/O priority class %s:%d>" , p .Class , p .Priority )
370428}
371429
430+ // Convert scheduling attributes to the NRI API representation.
431+ func (sch * scheduler ) ToNRI () * api.LinuxScheduler {
432+ apiSch := & api.LinuxScheduler {
433+ Policy : api .LinuxSchedulerPolicy (api .LinuxSchedulerPolicy_value [sch .Policy ]),
434+ Nice : sch .Nice ,
435+ Priority : sch .Priority ,
436+ Runtime : sch .Runtime ,
437+ Deadline : sch .Deadline ,
438+ Period : sch .Period ,
439+ }
440+
441+ for _ , f := range sch .Flags {
442+ apiSch .Flags = append (apiSch .Flags , api .LinuxSchedulerFlag (api .LinuxSchedulerFlag_value [f ]))
443+ }
444+
445+ return apiSch
446+ }
447+
448+ func (sc * scheduler ) String () string {
449+ if sc == nil {
450+ return "<no scheduling attributes>"
451+ }
452+
453+ s := fmt .Sprintf ("<scheduler policy=%s" , sc .Policy )
454+ if sc .Nice != 0 {
455+ s += fmt .Sprintf (", nice=%d" , sc .Nice )
456+ }
457+ if sc .Priority != 0 {
458+ s += fmt .Sprintf (", priority=%d" , sc .Priority )
459+ }
460+ if sc .Runtime != 0 {
461+ s += fmt .Sprintf (", runtime=%d, deadline=%d, period=%d" , sc .Runtime , sc .Deadline , sc .Period )
462+ }
463+ if len (sc .Flags ) > 0 {
464+ s += fmt .Sprintf (", flags=%v" , sc .Flags )
465+ }
466+ s += ">"
467+
468+ return s
469+ }
470+
372471// Construct a container name for log messages.
373472func containerName (pod * api.PodSandbox , container * api.Container ) string {
374473 if pod != nil {
0 commit comments