@@ -43,6 +43,10 @@ const (
4343	cdiDeviceKey  =  "cdi-devices.noderesource.dev" 
4444	// Deprecated: Prefix of the key used for CDI device annotations. 
4545	oldCDIDeviceKey  =  "cdi-devices.nri.io" 
46+ 	// Prefix of the key used for scheduler attribute adjustment. 
47+ 	schedulerKey  =  "scheduling-policy.noderesource.dev" 
48+ 	// Deprecated: Prefix of the key used for scheduler attribute adjustment. 
49+ 	oldSchedulerKey  =  "scheduling-policy.nri.io" 
4650)
4751
4852var  (
@@ -69,6 +73,17 @@ type mount struct {
6973	Options      []string  `json:"options"` 
7074}
7175
76+ // scheduler attribute adjustment 
77+ type  scheduler  struct  {
78+ 	Policy    string    `json:"policy"` 
79+ 	Nice      int32     `json:"nice"` 
80+ 	Priority  int32     `json:"priority"` 
81+ 	Flags     []string  `json:"flags"` 
82+ 	Runtime   uint64    `json:"runtime"` 
83+ 	Deadline  uint64    `json:"deadline"` 
84+ 	Period    uint64    `json:"period"` 
85+ }
86+ 
7287// our injector plugin 
7388type  plugin  struct  {
7489	stub  stub.Stub 
@@ -94,6 +109,10 @@ func (p *plugin) CreateContainer(_ context.Context, pod *api.PodSandbox, ctr *ap
94109		return  nil , nil , err 
95110	}
96111
112+ 	if  err  :=  adjustScheduler (pod , ctr , adjust ); err  !=  nil  {
113+ 		return  nil , nil , err 
114+ 	}
115+ 
97116	if  verbose  {
98117		dump (containerName (pod , ctr ), "ContainerAdjustment" , adjust )
99118	}
@@ -232,6 +251,46 @@ func parseMounts(ctr string, annotations map[string]string) ([]mount, error) {
232251	return  mounts , nil 
233252}
234253
254+ func  adjustScheduler (pod  * api.PodSandbox , ctr  * api.Container , a  * api.ContainerAdjustment ) error  {
255+ 	sch , err  :=  parseScheduler (ctr .Name , pod .Annotations )
256+ 	if  err  !=  nil  {
257+ 		return  err 
258+ 	}
259+ 
260+ 	if  sch  ==  nil  {
261+ 		log .Debugf ("%s: no scheduling attributes annotated..." , containerName (pod , ctr ))
262+ 		return  nil 
263+ 	}
264+ 
265+ 	if  verbose  {
266+ 		dump (containerName (pod , ctr ), "annotated scheduling attributes" , sch )
267+ 	}
268+ 
269+ 	a .SetLinuxScheduler (sch .ToNRI ())
270+ 	if  ! verbose  {
271+ 		log .Infof ("%s: adjusted scheduling attributes to %s..." , containerName (pod , ctr ), sch )
272+ 	}
273+ 
274+ 	return  nil 
275+ }
276+ 
277+ func  parseScheduler (ctr  string , annotations  map [string ]string ) (* scheduler , error ) {
278+ 	var  (
279+ 		sch  =  & scheduler {}
280+ 	)
281+ 
282+ 	annotation  :=  getAnnotation (annotations , schedulerKey , oldSchedulerKey , ctr )
283+ 	if  annotation  ==  nil  {
284+ 		return  nil , nil 
285+ 	}
286+ 
287+ 	if  err  :=  yaml .Unmarshal (annotation , sch ); err  !=  nil  {
288+ 		return  nil , fmt .Errorf ("invalid scheduler annotation %q: %w" , string (annotation ), err )
289+ 	}
290+ 
291+ 	return  sch , nil 
292+ }
293+ 
235294func  getAnnotation (annotations  map [string ]string , mainKey , oldKey , ctr  string ) []byte  {
236295	for  _ , key  :=  range  []string {
237296		mainKey  +  "/container."  +  ctr ,
@@ -280,6 +339,47 @@ func (m *mount) toNRI() *api.Mount {
280339	return  apiMnt 
281340}
282341
342+ // Convert scheduling attributes to the NRI API representation. 
343+ func  (sch  * scheduler ) ToNRI () * api.LinuxScheduler  {
344+ 	apiSch  :=  & api.LinuxScheduler {
345+ 		Policy :   api .LinuxSchedulerPolicy (api .LinuxSchedulerPolicy_value [sch .Policy ]),
346+ 		Nice :     sch .Nice ,
347+ 		Priority : sch .Priority ,
348+ 		Runtime :  sch .Runtime ,
349+ 		Deadline : sch .Deadline ,
350+ 		Period :   sch .Period ,
351+ 	}
352+ 
353+ 	for  _ , f  :=  range  sch .Flags  {
354+ 		apiSch .Flags  =  append (apiSch .Flags , api .LinuxSchedulerFlag (api .LinuxSchedulerFlag_value [f ]))
355+ 	}
356+ 
357+ 	return  apiSch 
358+ }
359+ 
360+ func  (sc  * scheduler ) String () string  {
361+ 	if  sc  ==  nil  {
362+ 		return  "<no scheduling attributes>" 
363+ 	}
364+ 
365+ 	s  :=  fmt .Sprintf ("<scheduler policy=%s" , sc .Policy )
366+ 	if  sc .Nice  !=  0  {
367+ 		s  +=  fmt .Sprintf (", nice=%d" , sc .Nice )
368+ 	}
369+ 	if  sc .Priority  !=  0  {
370+ 		s  +=  fmt .Sprintf (", priority=%d" , sc .Priority )
371+ 	}
372+ 	if  sc .Runtime  !=  0  {
373+ 		s  +=  fmt .Sprintf (", runtime=%d, deadline=%d, period=%d" , sc .Runtime , sc .Deadline , sc .Period )
374+ 	}
375+ 	if  len (sc .Flags ) >  0  {
376+ 		s  +=  fmt .Sprintf (", flags=%v" , sc .Flags )
377+ 	}
378+ 	s  +=  ">" 
379+ 
380+ 	return  s 
381+ }
382+ 
283383// Construct a container name for log messages. 
284384func  containerName (pod  * api.PodSandbox , container  * api.Container ) string  {
285385	if  pod  !=  nil  {
0 commit comments