Commit 05c2a082 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #38871 from k82cn/k8s_25318

Automatic merge from submit-queue Made multi-scheduler graduated to Beta and then v1. fixes #25318
parents ac857a5a 604957c1
...@@ -37534,6 +37534,10 @@ ...@@ -37534,6 +37534,10 @@
"description": "Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: http://kubernetes.io/docs/user-guide/pod-states#restartpolicy", "description": "Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: http://kubernetes.io/docs/user-guide/pod-states#restartpolicy",
"type": "string" "type": "string"
}, },
"schedulername": {
"description": "If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler.",
"type": "string"
},
"securityContext": { "securityContext": {
"description": "SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field.", "description": "SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field.",
"$ref": "#/definitions/v1.PodSecurityContext" "$ref": "#/definitions/v1.PodSecurityContext"
...@@ -1353,6 +1353,10 @@ ...@@ -1353,6 +1353,10 @@
"affinity": { "affinity": {
"$ref": "v1.Affinity", "$ref": "v1.Affinity",
"description": "If specified, the pod's scheduling constraints" "description": "If specified, the pod's scheduling constraints"
},
"schedulername": {
"type": "string",
"description": "If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler."
} }
} }
}, },
......
...@@ -1358,6 +1358,10 @@ ...@@ -1358,6 +1358,10 @@
"affinity": { "affinity": {
"$ref": "v1.Affinity", "$ref": "v1.Affinity",
"description": "If specified, the pod's scheduling constraints" "description": "If specified, the pod's scheduling constraints"
},
"schedulername": {
"type": "string",
"description": "If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler."
} }
} }
}, },
......
...@@ -7730,6 +7730,10 @@ ...@@ -7730,6 +7730,10 @@
"affinity": { "affinity": {
"$ref": "v1.Affinity", "$ref": "v1.Affinity",
"description": "If specified, the pod's scheduling constraints" "description": "If specified, the pod's scheduling constraints"
},
"schedulername": {
"type": "string",
"description": "If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler."
} }
} }
}, },
......
...@@ -18272,6 +18272,10 @@ ...@@ -18272,6 +18272,10 @@
"affinity": { "affinity": {
"$ref": "v1.Affinity", "$ref": "v1.Affinity",
"description": "If specified, the pod's scheduling constraints" "description": "If specified, the pod's scheduling constraints"
},
"schedulername": {
"type": "string",
"description": "If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler."
} }
} }
}, },
......
...@@ -4511,6 +4511,13 @@ The StatefulSet guarantees that a given network identity will always map to the ...@@ -4511,6 +4511,13 @@ The StatefulSet guarantees that a given network identity will always map to the
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_affinity">v1.Affinity</a></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_affinity">v1.Affinity</a></p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">schedulername</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>
...@@ -4960,7 +4967,7 @@ Examples:<br> ...@@ -4960,7 +4967,7 @@ Examples:<br>
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2017-01-06 18:13:59 UTC Last updated 2017-01-18 15:32:06 UTC
</div> </div>
</div> </div>
</body> </body>
......
...@@ -4498,6 +4498,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i ...@@ -4498,6 +4498,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_affinity">v1.Affinity</a></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_affinity">v1.Affinity</a></p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">schedulername</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>
...@@ -4892,7 +4899,7 @@ Examples:<br> ...@@ -4892,7 +4899,7 @@ Examples:<br>
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2017-01-06 18:14:24 UTC Last updated 2017-01-18 15:32:28 UTC
</div> </div>
</div> </div>
</body> </body>
......
...@@ -4124,6 +4124,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i ...@@ -4124,6 +4124,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_affinity">v1.Affinity</a></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_affinity">v1.Affinity</a></p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">schedulername</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>
...@@ -7509,7 +7516,7 @@ Both these may change in the future. Incoming requests are matched against the h ...@@ -7509,7 +7516,7 @@ Both these may change in the future. Incoming requests are matched against the h
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2017-01-11 19:09:46 UTC Last updated 2017-01-18 15:32:45 UTC
</div> </div>
</div> </div>
</body> </body>
......
...@@ -4762,6 +4762,13 @@ The resulting set of endpoints can be viewed as:<br> ...@@ -4762,6 +4762,13 @@ The resulting set of endpoints can be viewed as:<br>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_affinity">v1.Affinity</a></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_affinity">v1.Affinity</a></p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">schedulername</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>
...@@ -9136,7 +9143,7 @@ Examples:<br> ...@@ -9136,7 +9143,7 @@ Examples:<br>
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2017-01-06 18:13:51 UTC Last updated 2017-01-18 15:31:58 UTC
</div> </div>
</div> </div>
</body> </body>
......
...@@ -11313,6 +11313,10 @@ ...@@ -11313,6 +11313,10 @@
"description": "Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: http://kubernetes.io/docs/user-guide/pod-states#restartpolicy", "description": "Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: http://kubernetes.io/docs/user-guide/pod-states#restartpolicy",
"type": "string" "type": "string"
}, },
"schedulername": {
"description": "If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler.",
"type": "string"
},
"securityContext": { "securityContext": {
"description": "SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field.", "description": "SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field.",
"$ref": "#/definitions/v1.PodSecurityContext" "$ref": "#/definitions/v1.PodSecurityContext"
......
...@@ -366,6 +366,7 @@ func TestEncodePtr(t *testing.T) { ...@@ -366,6 +366,7 @@ func TestEncodePtr(t *testing.T) {
TerminationGracePeriodSeconds: &grace, TerminationGracePeriodSeconds: &grace,
SecurityContext: &api.PodSecurityContext{}, SecurityContext: &api.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
} }
obj := runtime.Object(pod) obj := runtime.Object(pod)
......
...@@ -134,6 +134,9 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz ...@@ -134,6 +134,9 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz
if s.Affinity == nil { if s.Affinity == nil {
s.Affinity = new(api.Affinity) s.Affinity = new(api.Affinity)
} }
if s.SchedulerName == "" {
s.SchedulerName = api.DefaultSchedulerName
}
}, },
func(j *api.PodPhase, c fuzz.Continue) { func(j *api.PodPhase, c fuzz.Continue) {
statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown} statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown}
......
...@@ -29,6 +29,7 @@ func DeepEqualSafePodSpec() api.PodSpec { ...@@ -29,6 +29,7 @@ func DeepEqualSafePodSpec() api.PodSpec {
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace, TerminationGracePeriodSeconds: &grace,
SecurityContext: &api.PodSecurityContext{}, SecurityContext: &api.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
} }
} }
......
...@@ -1856,6 +1856,10 @@ type PodSpec struct { ...@@ -1856,6 +1856,10 @@ type PodSpec struct {
// If specified, the pod's scheduling constraints // If specified, the pod's scheduling constraints
// +optional // +optional
Affinity *Affinity Affinity *Affinity
// If specified, the pod will be dispatched by specified scheduler.
// If not specified, the pod will be dispatched by default scheduler.
// +optional
SchedulerName string
} }
// Sysctl defines a kernel parameter to be set // Sysctl defines a kernel parameter to be set
......
...@@ -174,6 +174,9 @@ func SetDefaults_PodSpec(obj *PodSpec) { ...@@ -174,6 +174,9 @@ func SetDefaults_PodSpec(obj *PodSpec) {
period := int64(DefaultTerminationGracePeriodSeconds) period := int64(DefaultTerminationGracePeriodSeconds)
obj.TerminationGracePeriodSeconds = &period obj.TerminationGracePeriodSeconds = &period
} }
if obj.SchedulerName == "" {
obj.SchedulerName = DefaultSchedulerName
}
} }
func SetDefaults_Probe(obj *Probe) { func SetDefaults_Probe(obj *Probe) {
if obj.TimeoutSeconds == 0 { if obj.TimeoutSeconds == 0 {
......
...@@ -807,3 +807,12 @@ func TestSetDefaultProbe(t *testing.T) { ...@@ -807,3 +807,12 @@ func TestSetDefaultProbe(t *testing.T) {
t.Errorf("Expected probe: %+v\ngot: %+v\n", expectedProbe, actualProbe) t.Errorf("Expected probe: %+v\ngot: %+v\n", expectedProbe, actualProbe)
} }
} }
func TestSetDefaultSchedulerName(t *testing.T) {
pod := &v1.Pod{}
output := roundTrip(t, runtime.Object(pod)).(*v1.Pod)
if output.Spec.SchedulerName != v1.DefaultSchedulerName {
t.Errorf("Expected scheduler name: %+v\ngot: %+v\n", v1.DefaultSchedulerName, output.Spec.SchedulerName)
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -2553,6 +2553,11 @@ message PodSpec { ...@@ -2553,6 +2553,11 @@ message PodSpec {
// If specified, the pod's scheduling constraints // If specified, the pod's scheduling constraints
// +optional // +optional
optional Affinity affinity = 18; optional Affinity affinity = 18;
// If specified, the pod will be dispatched by specified scheduler.
// If not specified, the pod will be dispatched by default scheduler.
// +optional
optional string schedulername = 19;
} }
// PodStatus represents information about the status of a pod. Status may trail the actual // PodStatus represents information about the status of a pod. Status may trail the actual
......
...@@ -2140,6 +2140,10 @@ type PodSpec struct { ...@@ -2140,6 +2140,10 @@ type PodSpec struct {
// If specified, the pod's scheduling constraints // If specified, the pod's scheduling constraints
// +optional // +optional
Affinity *Affinity `json:"affinity,omitempty" protobuf:"bytes,18,opt,name=affinity"` Affinity *Affinity `json:"affinity,omitempty" protobuf:"bytes,18,opt,name=affinity"`
// If specified, the pod will be dispatched by specified scheduler.
// If not specified, the pod will be dispatched by default scheduler.
// +optional
SchedulerName string `json:"schedulername,omitempty" protobuf:"bytes,19,opt,name=schedulername"`
} }
// PodSecurityContext holds pod-level security attributes and common container settings. // PodSecurityContext holds pod-level security attributes and common container settings.
......
...@@ -1294,6 +1294,7 @@ var map_PodSpec = map[string]string{ ...@@ -1294,6 +1294,7 @@ var map_PodSpec = map[string]string{
"hostname": "Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value.", "hostname": "Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value.",
"subdomain": "If specified, the fully qualified Pod hostname will be \"<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>\". If not specified, the pod will not have a domainname at all.", "subdomain": "If specified, the fully qualified Pod hostname will be \"<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>\". If not specified, the pod will not have a domainname at all.",
"affinity": "If specified, the pod's scheduling constraints", "affinity": "If specified, the pod's scheduling constraints",
"schedulername": "If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler.",
} }
func (PodSpec) SwaggerDoc() map[string]string { func (PodSpec) SwaggerDoc() map[string]string {
......
...@@ -3069,6 +3069,7 @@ func autoConvert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conv ...@@ -3069,6 +3069,7 @@ func autoConvert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conv
out.Hostname = in.Hostname out.Hostname = in.Hostname
out.Subdomain = in.Subdomain out.Subdomain = in.Subdomain
out.Affinity = (*api.Affinity)(unsafe.Pointer(in.Affinity)) out.Affinity = (*api.Affinity)(unsafe.Pointer(in.Affinity))
out.SchedulerName = in.SchedulerName
return nil return nil
} }
...@@ -3106,6 +3107,7 @@ func autoConvert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conv ...@@ -3106,6 +3107,7 @@ func autoConvert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conv
out.Hostname = in.Hostname out.Hostname = in.Hostname
out.Subdomain = in.Subdomain out.Subdomain = in.Subdomain
out.Affinity = (*Affinity)(unsafe.Pointer(in.Affinity)) out.Affinity = (*Affinity)(unsafe.Pointer(in.Affinity))
out.SchedulerName = in.SchedulerName
return nil return nil
} }
......
...@@ -1679,7 +1679,7 @@ func (x codecSelfer1234) decSliceStatefulSet(v *[]StatefulSet, d *codec1978.Deco ...@@ -1679,7 +1679,7 @@ func (x codecSelfer1234) decSliceStatefulSet(v *[]StatefulSet, d *codec1978.Deco
yyrg1 := len(yyv1) > 0 yyrg1 := len(yyv1) > 0
yyv21 := yyv1 yyv21 := yyv1
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 808) yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 824)
if yyrt1 { if yyrt1 {
if yyrl1 <= cap(yyv1) { if yyrl1 <= cap(yyv1) {
yyv1 = yyv1[:yyrl1] yyv1 = yyv1[:yyrl1]
......
...@@ -2481,7 +2481,7 @@ func (x codecSelfer1234) decSliceJob(v *[]Job, d *codec1978.Decoder) { ...@@ -2481,7 +2481,7 @@ func (x codecSelfer1234) decSliceJob(v *[]Job, d *codec1978.Decoder) {
yyrg1 := len(yyv1) > 0 yyrg1 := len(yyv1) > 0
yyv21 := yyv1 yyv21 := yyv1
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 832) yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 848)
if yyrt1 { if yyrt1 {
if yyrl1 <= cap(yyv1) { if yyrl1 <= cap(yyv1) {
yyv1 = yyv1[:yyrl1] yyv1 = yyv1[:yyrl1]
......
...@@ -4534,7 +4534,7 @@ func (x codecSelfer1234) decSliceJob(v *[]Job, d *codec1978.Decoder) { ...@@ -4534,7 +4534,7 @@ func (x codecSelfer1234) decSliceJob(v *[]Job, d *codec1978.Decoder) {
yyrg1 := len(yyv1) > 0 yyrg1 := len(yyv1) > 0
yyv21 := yyv1 yyv21 := yyv1
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 832) yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 848)
if yyrt1 { if yyrt1 {
if yyrl1 <= cap(yyv1) { if yyrl1 <= cap(yyv1) {
yyv1 = yyv1[:yyrl1] yyv1 = yyv1[:yyrl1]
...@@ -4772,7 +4772,7 @@ func (x codecSelfer1234) decSliceCronJob(v *[]CronJob, d *codec1978.Decoder) { ...@@ -4772,7 +4772,7 @@ func (x codecSelfer1234) decSliceCronJob(v *[]CronJob, d *codec1978.Decoder) {
yyrg1 := len(yyv1) > 0 yyrg1 := len(yyv1) > 0
yyv21 := yyv1 yyv21 := yyv1
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 1080) yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 1096)
if yyrt1 { if yyrt1 {
if yyrl1 <= cap(yyv1) { if yyrl1 <= cap(yyv1) {
yyv1 = yyv1[:yyrl1] yyv1 = yyv1[:yyrl1]
......
...@@ -561,8 +561,7 @@ type KubeSchedulerConfiguration struct { ...@@ -561,8 +561,7 @@ type KubeSchedulerConfiguration struct {
// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver. // kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver.
KubeAPIBurst int32 KubeAPIBurst int32
// schedulerName is name of the scheduler, used to select which pods // schedulerName is name of the scheduler, used to select which pods
// will be processed by this scheduler, based on pod's annotation with // will be processed by this scheduler, based on pod's "spec.SchedulerName".
// key 'scheduler.alpha.kubernetes.io/name'.
SchedulerName string SchedulerName string
// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule // RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
// corresponding to every RequiredDuringScheduling affinity rule. // corresponding to every RequiredDuringScheduling affinity rule.
......
...@@ -122,8 +122,7 @@ type KubeSchedulerConfiguration struct { ...@@ -122,8 +122,7 @@ type KubeSchedulerConfiguration struct {
// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver. // kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver.
KubeAPIBurst int `json:"kubeAPIBurst"` KubeAPIBurst int `json:"kubeAPIBurst"`
// schedulerName is name of the scheduler, used to select which pods // schedulerName is name of the scheduler, used to select which pods
// will be processed by this scheduler, based on pod's annotation with // will be processed by this scheduler, based on pod's "spec.SchedulerName".
// key 'scheduler.alpha.kubernetes.io/name'.
SchedulerName string `json:"schedulerName"` SchedulerName string `json:"schedulerName"`
// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule // RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
// corresponding to every RequiredDuringScheduling affinity rule. // corresponding to every RequiredDuringScheduling affinity rule.
......
...@@ -40,6 +40,7 @@ func TestSetDefaultDaemonSet(t *testing.T) { ...@@ -40,6 +40,7 @@ func TestSetDefaultDaemonSet(t *testing.T) {
RestartPolicy: v1.RestartPolicyAlways, RestartPolicy: v1.RestartPolicyAlways,
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
TerminationGracePeriodSeconds: &period, TerminationGracePeriodSeconds: &period,
SchedulerName: api.DefaultSchedulerName,
}, },
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Labels: defaultLabels, Labels: defaultLabels,
...@@ -51,6 +52,7 @@ func TestSetDefaultDaemonSet(t *testing.T) { ...@@ -51,6 +52,7 @@ func TestSetDefaultDaemonSet(t *testing.T) {
RestartPolicy: v1.RestartPolicyAlways, RestartPolicy: v1.RestartPolicyAlways,
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
TerminationGracePeriodSeconds: &period, TerminationGracePeriodSeconds: &period,
SchedulerName: api.DefaultSchedulerName,
}, },
} }
tests := []struct { tests := []struct {
...@@ -155,6 +157,7 @@ func TestSetDefaultDeployment(t *testing.T) { ...@@ -155,6 +157,7 @@ func TestSetDefaultDeployment(t *testing.T) {
RestartPolicy: v1.RestartPolicyAlways, RestartPolicy: v1.RestartPolicyAlways,
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
TerminationGracePeriodSeconds: &period, TerminationGracePeriodSeconds: &period,
SchedulerName: api.DefaultSchedulerName,
}, },
} }
tests := []struct { tests := []struct {
......
...@@ -21093,7 +21093,7 @@ func (x codecSelfer1234) decSliceDeployment(v *[]Deployment, d *codec1978.Decode ...@@ -21093,7 +21093,7 @@ func (x codecSelfer1234) decSliceDeployment(v *[]Deployment, d *codec1978.Decode
yyrg1 := len(yyv1) > 0 yyrg1 := len(yyv1) > 0
yyv21 := yyv1 yyv21 := yyv1
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 872) yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 888)
if yyrt1 { if yyrt1 {
if yyrl1 <= cap(yyv1) { if yyrl1 <= cap(yyv1) {
yyv1 = yyv1[:yyrl1] yyv1 = yyv1[:yyrl1]
...@@ -21212,7 +21212,7 @@ func (x codecSelfer1234) decSliceDaemonSet(v *[]DaemonSet, d *codec1978.Decoder) ...@@ -21212,7 +21212,7 @@ func (x codecSelfer1234) decSliceDaemonSet(v *[]DaemonSet, d *codec1978.Decoder)
yyrg1 := len(yyv1) > 0 yyrg1 := len(yyv1) > 0
yyv21 := yyv1 yyv21 := yyv1
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 768) yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 784)
if yyrt1 { if yyrt1 {
if yyrl1 <= cap(yyv1) { if yyrl1 <= cap(yyv1) {
yyv1 = yyv1[:yyrl1] yyv1 = yyv1[:yyrl1]
...@@ -21926,7 +21926,7 @@ func (x codecSelfer1234) decSliceReplicaSet(v *[]ReplicaSet, d *codec1978.Decode ...@@ -21926,7 +21926,7 @@ func (x codecSelfer1234) decSliceReplicaSet(v *[]ReplicaSet, d *codec1978.Decode
yyrg1 := len(yyv1) > 0 yyrg1 := len(yyv1) > 0
yyv21 := yyv1 yyv21 := yyv1
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 808) yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 824)
if yyrt1 { if yyrt1 {
if yyrl1 <= cap(yyv1) { if yyrl1 <= cap(yyv1) {
yyv1 = yyv1[:yyrl1] yyv1 = yyv1[:yyrl1]
......
...@@ -6131,6 +6131,13 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions ...@@ -6131,6 +6131,13 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions
Ref: spec.MustCreateRef("#/definitions/v1.Affinity"), Ref: spec.MustCreateRef("#/definitions/v1.Affinity"),
}, },
}, },
"schedulername": {
SchemaProps: spec.SchemaProps{
Description: "If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler.",
Type: []string{"string"},
Format: "",
},
},
}, },
Required: []string{"containers"}, Required: []string{"containers"},
}, },
...@@ -9659,7 +9666,7 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions ...@@ -9659,7 +9666,7 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions
}, },
"schedulerName": { "schedulerName": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "schedulerName is name of the scheduler, used to select which pods will be processed by this scheduler, based on pod's annotation with key 'scheduler.alpha.kubernetes.io/name'.", Description: "schedulerName is name of the scheduler, used to select which pods will be processed by this scheduler, based on pod's \"spec.SchedulerName\".",
Type: []string{"string"}, Type: []string{"string"},
Format: "", Format: "",
}, },
......
...@@ -131,6 +131,7 @@ func TestMerge(t *testing.T) { ...@@ -131,6 +131,7 @@ func TestMerge(t *testing.T) {
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace, TerminationGracePeriodSeconds: &grace,
SecurityContext: &api.PodSecurityContext{}, SecurityContext: &api.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
}, },
}, },
......
...@@ -53,6 +53,7 @@ func TestDecodeSinglePod(t *testing.T) { ...@@ -53,6 +53,7 @@ func TestDecodeSinglePod(t *testing.T) {
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
}}, }},
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
} }
json, err := runtime.Encode(testapi.Default.Codec(), pod) json, err := runtime.Encode(testapi.Default.Codec(), pod)
...@@ -113,6 +114,7 @@ func TestDecodePodList(t *testing.T) { ...@@ -113,6 +114,7 @@ func TestDecodePodList(t *testing.T) {
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
}}, }},
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
} }
podList := &v1.PodList{ podList := &v1.PodList{
......
...@@ -188,6 +188,7 @@ func getTestCases(hostname types.NodeName) []*testCase { ...@@ -188,6 +188,7 @@ func getTestCases(hostname types.NodeName) []*testCase {
Spec: v1.PodSpec{ Spec: v1.PodSpec{
Containers: []v1.Container{{Name: "image", Image: "test/image", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}}, Containers: []v1.Container{{Name: "image", Image: "test/image", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}},
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
Status: v1.PodStatus{ Status: v1.PodStatus{
Phase: v1.PodPending, Phase: v1.PodPending,
...@@ -213,6 +214,7 @@ func getTestCases(hostname types.NodeName) []*testCase { ...@@ -213,6 +214,7 @@ func getTestCases(hostname types.NodeName) []*testCase {
ImagePullPolicy: "Always", ImagePullPolicy: "Always",
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}}, SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}},
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
Status: v1.PodStatus{ Status: v1.PodStatus{
Phase: v1.PodPending, Phase: v1.PodPending,
......
...@@ -147,6 +147,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -147,6 +147,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
NodeName: string(nodeName), NodeName: string(nodeName),
Containers: []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways}}, Containers: []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways}},
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
Status: v1.PodStatus{ Status: v1.PodStatus{
Phase: v1.PodPending, Phase: v1.PodPending,
...@@ -168,6 +169,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -168,6 +169,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
DNSPolicy: v1.DNSClusterFirst, DNSPolicy: v1.DNSClusterFirst,
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
TerminationGracePeriodSeconds: &grace, TerminationGracePeriodSeconds: &grace,
SchedulerName: api.DefaultSchedulerName,
Containers: []v1.Container{{ Containers: []v1.Container{{
Name: "1", Name: "1",
...@@ -198,6 +200,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -198,6 +200,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
NodeName: nodeName, NodeName: nodeName,
Containers: []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways}}, Containers: []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways}},
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
Status: v1.PodStatus{ Status: v1.PodStatus{
Phase: v1.PodPending, Phase: v1.PodPending,
...@@ -212,6 +215,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -212,6 +215,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
NodeName: nodeName, NodeName: nodeName,
Containers: []v1.Container{{Name: "2", Image: "bar:bartag", ImagePullPolicy: ""}}, Containers: []v1.Container{{Name: "2", Image: "bar:bartag", ImagePullPolicy: ""}},
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
Status: v1.PodStatus{ Status: v1.PodStatus{
Phase: v1.PodPending, Phase: v1.PodPending,
...@@ -235,6 +239,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -235,6 +239,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
DNSPolicy: v1.DNSClusterFirst, DNSPolicy: v1.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace, TerminationGracePeriodSeconds: &grace,
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
Containers: []v1.Container{{ Containers: []v1.Container{{
Name: "1", Name: "1",
...@@ -261,6 +266,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -261,6 +266,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
DNSPolicy: v1.DNSClusterFirst, DNSPolicy: v1.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace, TerminationGracePeriodSeconds: &grace,
SecurityContext: &v1.PodSecurityContext{}, SecurityContext: &v1.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
Containers: []v1.Container{{ Containers: []v1.Container{{
Name: "2", Name: "2",
......
...@@ -73,6 +73,7 @@ func validNewPod() *api.Pod { ...@@ -73,6 +73,7 @@ func validNewPod() *api.Pod {
}, },
}, },
SecurityContext: &api.PodSecurityContext{}, SecurityContext: &api.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
} }
} }
...@@ -659,6 +660,7 @@ func TestEtcdUpdateScheduled(t *testing.T) { ...@@ -659,6 +660,7 @@ func TestEtcdUpdateScheduled(t *testing.T) {
}, },
}, },
SecurityContext: &api.PodSecurityContext{}, SecurityContext: &api.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
}, nil, 1) }, nil, 1)
if err != nil { if err != nil {
...@@ -687,6 +689,7 @@ func TestEtcdUpdateScheduled(t *testing.T) { ...@@ -687,6 +689,7 @@ func TestEtcdUpdateScheduled(t *testing.T) {
TerminationGracePeriodSeconds: &grace, TerminationGracePeriodSeconds: &grace,
SecurityContext: &api.PodSecurityContext{}, SecurityContext: &api.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
} }
_, _, err = storage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn, api.Scheme)) _, _, err = storage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn, api.Scheme))
...@@ -727,6 +730,7 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -727,6 +730,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
}, },
}, },
SecurityContext: &api.PodSecurityContext{}, SecurityContext: &api.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
} }
err := storage.Storage.Create(ctx, key, &podStart, nil, 0) err := storage.Storage.Create(ctx, key, &podStart, nil, 0)
...@@ -751,6 +755,7 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -751,6 +755,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
}, },
}, },
SecurityContext: &api.PodSecurityContext{}, SecurityContext: &api.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
}, },
Status: api.PodStatus{ Status: api.PodStatus{
Phase: api.PodRunning, Phase: api.PodRunning,
......
...@@ -66,7 +66,7 @@ func (s *SchedulerServer) AddFlags(fs *pflag.FlagSet) { ...@@ -66,7 +66,7 @@ func (s *SchedulerServer) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "Content type of requests sent to apiserver.") fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "Content type of requests sent to apiserver.")
fs.Float32Var(&s.KubeAPIQPS, "kube-api-qps", s.KubeAPIQPS, "QPS to use while talking with kubernetes apiserver") fs.Float32Var(&s.KubeAPIQPS, "kube-api-qps", s.KubeAPIQPS, "QPS to use while talking with kubernetes apiserver")
fs.Int32Var(&s.KubeAPIBurst, "kube-api-burst", s.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver") fs.Int32Var(&s.KubeAPIBurst, "kube-api-burst", s.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver")
fs.StringVar(&s.SchedulerName, "scheduler-name", s.SchedulerName, "Name of the scheduler, used to select which pods will be processed by this scheduler, based on pod's annotation with key 'scheduler.alpha.kubernetes.io/name'") fs.StringVar(&s.SchedulerName, "scheduler-name", s.SchedulerName, "Name of the scheduler, used to select which pods will be processed by this scheduler, based on pod's \"spec.SchedulerName\".")
fs.IntVar(&s.HardPodAffinitySymmetricWeight, "hard-pod-affinity-symmetric-weight", api.DefaultHardPodAffinitySymmetricWeight, fs.IntVar(&s.HardPodAffinitySymmetricWeight, "hard-pod-affinity-symmetric-weight", api.DefaultHardPodAffinitySymmetricWeight,
"RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule corresponding "+ "RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule corresponding "+
"to every RequiredDuringScheduling affinity rule. --hard-pod-affinity-symmetric-weight represents the weight of implicit PreferredDuringScheduling affinity rule.") "to every RequiredDuringScheduling affinity rule. --hard-pod-affinity-symmetric-weight represents the weight of implicit PreferredDuringScheduling affinity rule.")
......
...@@ -48,9 +48,8 @@ import ( ...@@ -48,9 +48,8 @@ import (
) )
const ( const (
SchedulerAnnotationKey = "scheduler.alpha.kubernetes.io/name" initialGetBackoff = 100 * time.Millisecond
initialGetBackoff = 100 * time.Millisecond maximalGetBackoff = time.Minute
maximalGetBackoff = time.Minute
) )
// ConfigFactory is the default implementation of the scheduler.Configurator interface. // ConfigFactory is the default implementation of the scheduler.Configurator interface.
...@@ -90,8 +89,7 @@ type ConfigFactory struct { ...@@ -90,8 +89,7 @@ type ConfigFactory struct {
schedulerCache schedulercache.Cache schedulerCache schedulercache.Cache
// SchedulerName of a scheduler is used to select which pods will be // SchedulerName of a scheduler is used to select which pods will be
// processed by this scheduler, based on pods's annotation key: // processed by this scheduler, based on pods's "spec.SchedulerName".
// 'scheduler.alpha.kubernetes.io/name'
schedulerName string schedulerName string
// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule // RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
...@@ -514,11 +512,7 @@ func (f *ConfigFactory) getNextPod() *v1.Pod { ...@@ -514,11 +512,7 @@ func (f *ConfigFactory) getNextPod() *v1.Pod {
} }
func (f *ConfigFactory) ResponsibleForPod(pod *v1.Pod) bool { func (f *ConfigFactory) ResponsibleForPod(pod *v1.Pod) bool {
if f.schedulerName == v1.DefaultSchedulerName { return f.schedulerName == pod.Spec.SchedulerName
return pod.Annotations[SchedulerAnnotationKey] == f.schedulerName || pod.Annotations[SchedulerAnnotationKey] == ""
} else {
return pod.Annotations[SchedulerAnnotationKey] == f.schedulerName
}
} }
func getNodeConditionPredicate() cache.NodeConditionPredicate { func getNodeConditionPredicate() cache.NodeConditionPredicate {
......
...@@ -251,39 +251,33 @@ func TestResponsibleForPod(t *testing.T) { ...@@ -251,39 +251,33 @@ func TestResponsibleForPod(t *testing.T) {
// factory of "foo-scheduler" // factory of "foo-scheduler"
factoryFooScheduler := NewConfigFactory(client, "foo-scheduler", v1.DefaultHardPodAffinitySymmetricWeight, v1.DefaultFailureDomains) factoryFooScheduler := NewConfigFactory(client, "foo-scheduler", v1.DefaultHardPodAffinitySymmetricWeight, v1.DefaultFailureDomains)
// scheduler annotations to be tested // scheduler annotations to be tested
schedulerAnnotationFitsDefault := map[string]string{"scheduler.alpha.kubernetes.io/name": "default-scheduler"} schedulerFitsDefault := "default-scheduler"
schedulerAnnotationFitsFoo := map[string]string{"scheduler.alpha.kubernetes.io/name": "foo-scheduler"} schedulerFitsFoo := "foo-scheduler"
schedulerAnnotationFitsNone := map[string]string{"scheduler.alpha.kubernetes.io/name": "bar-scheduler"} schedulerFitsNone := "bar-scheduler"
tests := []struct { tests := []struct {
pod *v1.Pod pod *v1.Pod
pickedByDefault bool pickedByDefault bool
pickedByFoo bool pickedByFoo bool
}{ }{
{ {
// pod with no annotation "scheduler.alpha.kubernetes.io/name=<scheduler-name>" should be // pod with "spec.Schedulername=default-scheduler" should be picked
// picked by the default scheduler, NOT by the one of name "foo-scheduler"
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}},
pickedByDefault: true,
pickedByFoo: false,
},
{
// pod with annotation "scheduler.alpha.kubernetes.io/name=default-scheduler" should be picked
// by the scheduler of name "default-scheduler", NOT by the one of name "foo-scheduler" // by the scheduler of name "default-scheduler", NOT by the one of name "foo-scheduler"
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar", Annotations: schedulerAnnotationFitsDefault}}, pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: v1.PodSpec{SchedulerName: schedulerFitsDefault}},
pickedByDefault: true, pickedByDefault: true,
pickedByFoo: false, pickedByFoo: false,
}, },
{ {
// pod with annotataion "scheduler.alpha.kubernetes.io/name=foo-scheduler" should be NOT // pod with "spec.SchedulerName=foo-scheduler" should be NOT
// be picked by the scheduler of name "default-scheduler", but by the one of name "foo-scheduler" // be picked by the scheduler of name "default-scheduler", but by the one of name "foo-scheduler"
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar", Annotations: schedulerAnnotationFitsFoo}}, pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: v1.PodSpec{SchedulerName: schedulerFitsFoo}},
pickedByDefault: false, pickedByDefault: false,
pickedByFoo: true, pickedByFoo: true,
}, },
{ {
// pod with annotataion "scheduler.alpha.kubernetes.io/name=foo-scheduler" should be NOT // pod with "spec.SchedulerName=foo-scheduler" should be NOT
// be picked by niether the scheduler of name "default-scheduler" nor the one of name "foo-scheduler" // be picked by niether the scheduler of name "default-scheduler" nor the one of name "foo-scheduler"
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar", Annotations: schedulerAnnotationFitsNone}}, pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: v1.PodSpec{SchedulerName: schedulerFitsNone}},
pickedByDefault: false, pickedByDefault: false,
pickedByFoo: false, pickedByFoo: false,
}, },
......
...@@ -561,8 +561,7 @@ type KubeSchedulerConfiguration struct { ...@@ -561,8 +561,7 @@ type KubeSchedulerConfiguration struct {
// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver. // kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver.
KubeAPIBurst int32 KubeAPIBurst int32
// schedulerName is name of the scheduler, used to select which pods // schedulerName is name of the scheduler, used to select which pods
// will be processed by this scheduler, based on pod's annotation with // will be processed by this scheduler, based on pod's "spec.SchedulerName".
// key 'scheduler.alpha.kubernetes.io/name'.
SchedulerName string SchedulerName string
// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule // RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
// corresponding to every RequiredDuringScheduling affinity rule. // corresponding to every RequiredDuringScheduling affinity rule.
......
...@@ -122,8 +122,7 @@ type KubeSchedulerConfiguration struct { ...@@ -122,8 +122,7 @@ type KubeSchedulerConfiguration struct {
// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver. // kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver.
KubeAPIBurst int `json:"kubeAPIBurst"` KubeAPIBurst int `json:"kubeAPIBurst"`
// schedulerName is name of the scheduler, used to select which pods // schedulerName is name of the scheduler, used to select which pods
// will be processed by this scheduler, based on pod's annotation with // will be processed by this scheduler, based on pod's "spec.SchedulerName".
// key 'scheduler.alpha.kubernetes.io/name'.
SchedulerName string `json:"schedulerName"` SchedulerName string `json:"schedulerName"`
// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule // RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
// corresponding to every RequiredDuringScheduling affinity rule. // corresponding to every RequiredDuringScheduling affinity rule.
......
...@@ -84,9 +84,6 @@ func createTerminatingPod(f *framework.Framework) (*v1.Pod, error) { ...@@ -84,9 +84,6 @@ func createTerminatingPod(f *framework.Framework) (*v1.Pod, error) {
pod := &v1.Pod{ pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: string(uuid), Name: string(uuid),
Annotations: map[string]string{
"scheduler.alpha.kubernetes.io/name": "please don't schedule my pods",
},
}, },
Spec: v1.PodSpec{ Spec: v1.PodSpec{
Containers: []v1.Container{ Containers: []v1.Container{
...@@ -95,6 +92,7 @@ func createTerminatingPod(f *framework.Framework) (*v1.Pod, error) { ...@@ -95,6 +92,7 @@ func createTerminatingPod(f *framework.Framework) (*v1.Pod, error) {
Image: "gcr.io/google_containers/busybox:1.24", Image: "gcr.io/google_containers/busybox:1.24",
}, },
}, },
SchedulerName: "please don't schedule my pods",
}, },
} }
return f.ClientSet.Core().Pods(f.Namespace.Name).Create(pod) return f.ClientSet.Core().Pods(f.Namespace.Name).Create(pod)
......
...@@ -352,48 +352,48 @@ func TestMultiScheduler(t *testing.T) { ...@@ -352,48 +352,48 @@ func TestMultiScheduler(t *testing.T) {
clientSet.Core().Nodes().Create(node) clientSet.Core().Nodes().Create(node)
// 3. create 3 pods for testing // 3. create 3 pods for testing
podWithNoAnnotation := createPod(clientSet, "pod-with-no-annotation", nil) podWithoutSchedulerName := createPod(clientSet, "pod-without-scheduler-name", "")
testPodNoAnnotation, err := clientSet.Core().Pods(ns.Name).Create(podWithNoAnnotation) testPod, err := clientSet.Core().Pods(ns.Name).Create(podWithoutSchedulerName)
if err != nil { if err != nil {
t.Fatalf("Failed to create pod: %v", err) t.Fatalf("Failed to create pod: %v", err)
} }
schedulerAnnotationFitsDefault := map[string]string{"scheduler.alpha.kubernetes.io/name": "default-scheduler"} schedulerFitsDefault := "default-scheduler"
podWithAnnotationFitsDefault := createPod(clientSet, "pod-with-annotation-fits-default", schedulerAnnotationFitsDefault) podFitsDefault := createPod(clientSet, "pod-fits-default", schedulerFitsDefault)
testPodWithAnnotationFitsDefault, err := clientSet.Core().Pods(ns.Name).Create(podWithAnnotationFitsDefault) testPodFitsDefault, err := clientSet.Core().Pods(ns.Name).Create(podFitsDefault)
if err != nil { if err != nil {
t.Fatalf("Failed to create pod: %v", err) t.Fatalf("Failed to create pod: %v", err)
} }
schedulerAnnotationFitsFoo := map[string]string{"scheduler.alpha.kubernetes.io/name": "foo-scheduler"} schedulerFitsFoo := "foo-scheduler"
podWithAnnotationFitsFoo := createPod(clientSet, "pod-with-annotation-fits-foo", schedulerAnnotationFitsFoo) podFitsFoo := createPod(clientSet, "pod-fits-foo", schedulerFitsFoo)
testPodWithAnnotationFitsFoo, err := clientSet.Core().Pods(ns.Name).Create(podWithAnnotationFitsFoo) testPodFitsFoo, err := clientSet.Core().Pods(ns.Name).Create(podFitsFoo)
if err != nil { if err != nil {
t.Fatalf("Failed to create pod: %v", err) t.Fatalf("Failed to create pod: %v", err)
} }
// 4. **check point-1**: // 4. **check point-1**:
// - testPodNoAnnotation, testPodWithAnnotationFitsDefault should be scheduled // - testPod, testPodFitsDefault should be scheduled
// - testPodWithAnnotationFitsFoo should NOT be scheduled // - testPodFitsFoo should NOT be scheduled
err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodNoAnnotation.Namespace, testPodNoAnnotation.Name)) err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPod.Namespace, testPod.Name))
if err != nil { if err != nil {
t.Errorf("Test MultiScheduler: %s Pod not scheduled: %v", testPodNoAnnotation.Name, err) t.Errorf("Test MultiScheduler: %s Pod not scheduled: %v", testPod.Name, err)
} else { } else {
t.Logf("Test MultiScheduler: %s Pod scheduled", testPodNoAnnotation.Name) t.Logf("Test MultiScheduler: %s Pod scheduled", testPod.Name)
} }
err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodWithAnnotationFitsDefault.Namespace, testPodWithAnnotationFitsDefault.Name)) err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodFitsDefault.Namespace, testPodFitsDefault.Name))
if err != nil { if err != nil {
t.Errorf("Test MultiScheduler: %s Pod not scheduled: %v", testPodWithAnnotationFitsDefault.Name, err) t.Errorf("Test MultiScheduler: %s Pod not scheduled: %v", testPodFitsDefault.Name, err)
} else { } else {
t.Logf("Test MultiScheduler: %s Pod scheduled", testPodWithAnnotationFitsDefault.Name) t.Logf("Test MultiScheduler: %s Pod scheduled", testPodFitsDefault.Name)
} }
err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodWithAnnotationFitsFoo.Namespace, testPodWithAnnotationFitsFoo.Name)) err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodFitsFoo.Namespace, testPodFitsFoo.Name))
if err == nil { if err == nil {
t.Errorf("Test MultiScheduler: %s Pod got scheduled, %v", testPodWithAnnotationFitsFoo.Name, err) t.Errorf("Test MultiScheduler: %s Pod got scheduled, %v", testPodFitsFoo.Name, err)
} else { } else {
t.Logf("Test MultiScheduler: %s Pod not scheduled", testPodWithAnnotationFitsFoo.Name) t.Logf("Test MultiScheduler: %s Pod not scheduled", testPodFitsFoo.Name)
} }
// 5. create and start a scheduler with name "foo-scheduler" // 5. create and start a scheduler with name "foo-scheduler"
...@@ -413,19 +413,19 @@ func TestMultiScheduler(t *testing.T) { ...@@ -413,19 +413,19 @@ func TestMultiScheduler(t *testing.T) {
// 6. **check point-2**: // 6. **check point-2**:
// - testPodWithAnnotationFitsFoo should be scheduled // - testPodWithAnnotationFitsFoo should be scheduled
err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodWithAnnotationFitsFoo.Namespace, testPodWithAnnotationFitsFoo.Name)) err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodFitsFoo.Namespace, testPodFitsFoo.Name))
if err != nil { if err != nil {
t.Errorf("Test MultiScheduler: %s Pod not scheduled, %v", testPodWithAnnotationFitsFoo.Name, err) t.Errorf("Test MultiScheduler: %s Pod not scheduled, %v", testPodFitsFoo.Name, err)
} else { } else {
t.Logf("Test MultiScheduler: %s Pod scheduled", testPodWithAnnotationFitsFoo.Name) t.Logf("Test MultiScheduler: %s Pod scheduled", testPodFitsFoo.Name)
} }
// 7. delete the pods that were scheduled by the default scheduler, and stop the default scheduler // 7. delete the pods that were scheduled by the default scheduler, and stop the default scheduler
err = clientSet.Core().Pods(ns.Name).Delete(testPodNoAnnotation.Name, v1.NewDeleteOptions(0)) err = clientSet.Core().Pods(ns.Name).Delete(testPod.Name, v1.NewDeleteOptions(0))
if err != nil { if err != nil {
t.Errorf("Failed to delete pod: %v", err) t.Errorf("Failed to delete pod: %v", err)
} }
err = clientSet.Core().Pods(ns.Name).Delete(testPodWithAnnotationFitsDefault.Name, v1.NewDeleteOptions(0)) err = clientSet.Core().Pods(ns.Name).Delete(testPodFitsDefault.Name, v1.NewDeleteOptions(0))
if err != nil { if err != nil {
t.Errorf("Failed to delete pod: %v", err) t.Errorf("Failed to delete pod: %v", err)
} }
...@@ -469,11 +469,12 @@ func TestMultiScheduler(t *testing.T) { ...@@ -469,11 +469,12 @@ func TestMultiScheduler(t *testing.T) {
*/ */
} }
func createPod(client clientset.Interface, name string, annotation map[string]string) *v1.Pod { func createPod(client clientset.Interface, name string, scheduler string) *v1.Pod {
return &v1.Pod{ return &v1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: name, Annotations: annotation}, ObjectMeta: metav1.ObjectMeta{Name: name},
Spec: v1.PodSpec{ Spec: v1.PodSpec{
Containers: []v1.Container{{Name: "container", Image: e2e.GetPauseImageName(client)}}, Containers: []v1.Container{{Name: "container", Image: e2e.GetPauseImageName(client)}},
SchedulerName: scheduler,
}, },
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment