@@ -37,6 +37,8 @@ const (
3737	mountKey  =  "mounts.nri.io" 
3838	// Prefix of the key used for CDI device annotations. 
3939	cdiDeviceKey  =  "cdi-devices.nri.io" 
40+ 	// Prefix of the key user for scheduler attribute adjustment. 
41+ 	schedulerKey  =  "scheduling-policy.nri.io" 
4042)
4143
4244var  (
@@ -63,6 +65,17 @@ type mount struct {
6365	Options      []string  `json:"options"` 
6466}
6567
68+ // scheduler attribute adjustment 
69+ type  scheduler  struct  {
70+ 	Policy    string    `json:"policy"` 
71+ 	Nice      int32     `json:"nice"` 
72+ 	Priority  int32     `json:"priority"` 
73+ 	Flags     []string  `json:"flags"` 
74+ 	Runtime   uint64    `json:"runtime"` 
75+ 	Deadline  uint64    `json:"deadline"` 
76+ 	Period    uint64    `json:"period"` 
77+ }
78+ 
6679// our injector plugin 
6780type  plugin  struct  {
6881	stub  stub.Stub 
@@ -88,6 +101,10 @@ func (p *plugin) CreateContainer(_ context.Context, pod *api.PodSandbox, ctr *ap
88101		return  nil , nil , err 
89102	}
90103
104+ 	if  err  :=  adjustScheduler (pod , ctr , adjust ); err  !=  nil  {
105+ 		return  nil , nil , err 
106+ 	}
107+ 
91108	if  verbose  {
92109		dump (containerName (pod , ctr ), "ContainerAdjustment" , adjust )
93110	}
@@ -226,6 +243,46 @@ func parseMounts(ctr string, annotations map[string]string) ([]mount, error) {
226243	return  mounts , nil 
227244}
228245
246+ func  adjustScheduler (pod  * api.PodSandbox , ctr  * api.Container , a  * api.ContainerAdjustment ) error  {
247+ 	sch , err  :=  parseScheduler (ctr .Name , pod .Annotations )
248+ 	if  err  !=  nil  {
249+ 		return  err 
250+ 	}
251+ 
252+ 	if  sch  ==  nil  {
253+ 		log .Debugf ("%s: no scheduling attributes annotated..." , containerName (pod , ctr ))
254+ 		return  nil 
255+ 	}
256+ 
257+ 	if  verbose  {
258+ 		dump (containerName (pod , ctr ), "annotated scheduling attributes" , sch )
259+ 	}
260+ 
261+ 	a .SetLinuxScheduler (sch .ToNRI ())
262+ 	if  ! verbose  {
263+ 		log .Infof ("%s: adjusted scheduling attributes to %s..." , containerName (pod , ctr ), sch )
264+ 	}
265+ 
266+ 	return  nil 
267+ }
268+ 
269+ func  parseScheduler (ctr  string , annotations  map [string ]string ) (* scheduler , error ) {
270+ 	var  (
271+ 		sch  =  & scheduler {}
272+ 	)
273+ 
274+ 	annotation  :=  getAnnotation (annotations , schedulerKey , ctr )
275+ 	if  annotation  ==  nil  {
276+ 		return  nil , nil 
277+ 	}
278+ 
279+ 	if  err  :=  yaml .Unmarshal (annotation , sch ); err  !=  nil  {
280+ 		return  nil , fmt .Errorf ("invalid scheduler annotation %q: %w" , string (annotation ), err )
281+ 	}
282+ 
283+ 	return  sch , nil 
284+ }
285+ 
229286func  getAnnotation (annotations  map [string ]string , mainKey , ctr  string ) []byte  {
230287	for  _ , key  :=  range  []string {
231288		mainKey  +  "/container."  +  ctr ,
@@ -271,6 +328,47 @@ func (m *mount) toNRI() *api.Mount {
271328	return  apiMnt 
272329}
273330
331+ // Convert scheduling attributes to the NRI API representation. 
332+ func  (sch  * scheduler ) ToNRI () * api.LinuxScheduler  {
333+ 	apiSch  :=  & api.LinuxScheduler {
334+ 		Policy :   api .LinuxSchedulerPolicy (api .LinuxSchedulerPolicy_value [sch .Policy ]),
335+ 		Nice :     sch .Nice ,
336+ 		Priority : sch .Priority ,
337+ 		Runtime :  sch .Runtime ,
338+ 		Deadline : sch .Deadline ,
339+ 		Period :   sch .Period ,
340+ 	}
341+ 
342+ 	for  _ , f  :=  range  sch .Flags  {
343+ 		apiSch .Flags  =  append (apiSch .Flags , api .LinuxSchedulerFlag (api .LinuxSchedulerFlag_value [f ]))
344+ 	}
345+ 
346+ 	return  apiSch 
347+ }
348+ 
349+ func  (sc  * scheduler ) String () string  {
350+ 	if  sc  ==  nil  {
351+ 		return  "<no scheduling attributes>" 
352+ 	}
353+ 
354+ 	s  :=  fmt .Sprintf ("<scheduler policy=%s" , sc .Policy )
355+ 	if  sc .Nice  !=  0  {
356+ 		s  +=  fmt .Sprintf (", nice=%d" , sc .Nice )
357+ 	}
358+ 	if  sc .Priority  !=  0  {
359+ 		s  +=  fmt .Sprintf (", priority=%d" , sc .Priority )
360+ 	}
361+ 	if  sc .Runtime  !=  0  {
362+ 		s  +=  fmt .Sprintf (", runtime=%d, deadline=%d, period=%d" , sc .Runtime , sc .Deadline , sc .Period )
363+ 	}
364+ 	if  len (sc .Flags ) >  0  {
365+ 		s  +=  fmt .Sprintf (", flags=%v" , sc .Flags )
366+ 	}
367+ 	s  +=  ">" 
368+ 
369+ 	return  s 
370+ }
371+ 
274372// Construct a container name for log messages. 
275373func  containerName (pod  * api.PodSandbox , container  * api.Container ) string  {
276374	if  pod  !=  nil  {
0 commit comments