@@ -37,6 +37,10 @@ type Binder interface {
3737 Bind (binding * api.Binding ) error
3838}
3939
40+ type PodConditionUpdater interface {
41+ Update (pod * api.Pod , podCondition * api.PodCondition ) error
42+ }
43+
4044// Scheduler watches for new unscheduled pods. It attempts to find
4145// nodes that they fit on and writes bindings back to the api server.
4246type Scheduler struct {
@@ -50,6 +54,10 @@ type Config struct {
5054 NodeLister algorithm.NodeLister
5155 Algorithm algorithm.ScheduleAlgorithm
5256 Binder Binder
57+ // PodConditionUpdater is used only in case of scheduling errors. If we succeed
58+ // with scheduling, PodScheduled condition will be updated in apiserver in /bind
59+ // handler so that binding and setting PodCondition it is atomic.
60+ PodConditionUpdater PodConditionUpdater
5361
5462 // NextPod should be a function that blocks until the next pod
5563 // is available. We don't use a channel for this, because scheduling
@@ -92,6 +100,12 @@ func (s *Scheduler) scheduleOne() {
92100 glog .V (1 ).Infof ("Failed to schedule: %+v" , pod )
93101 s .config .Error (pod , err )
94102 s .config .Recorder .Eventf (pod , api .EventTypeWarning , "FailedScheduling" , "%v" , err )
103+ s .config .PodConditionUpdater .Update (pod , & api.PodCondition {
104+ Type : api .PodScheduled ,
105+ Status : api .ConditionFalse ,
106+ Reason : "Unschedulable" ,
107+ Message : err .Error (),
108+ })
95109 return
96110 }
97111 metrics .SchedulingAlgorithmLatency .Observe (metrics .SinceInMicroseconds (start ))
@@ -120,11 +134,19 @@ func (s *Scheduler) scheduleOne() {
120134 }
121135
122136 bindingStart := time .Now ()
137+ // If binding succeded then PodScheduled condition will be updated in apiserver so that
138+ // it's atomic with setting host.
123139 err := s .config .Binder .Bind (b )
124140 if err != nil {
125141 glog .V (1 ).Infof ("Failed to bind pod: %+v" , err )
126142 s .config .Error (pod , err )
127143 s .config .Recorder .Eventf (pod , api .EventTypeNormal , "FailedScheduling" , "Binding rejected: %v" , err )
144+ s .config .PodConditionUpdater .Update (pod , & api.PodCondition {
145+ Type : api .PodScheduled ,
146+ Status : api .ConditionFalse ,
147+ Reason : "BindingRejected" ,
148+ Message : err .Error (),
149+ })
128150 return
129151 }
130152 metrics .BindingLatency .Observe (metrics .SinceInMicroseconds (bindingStart ))
0 commit comments