Merge pull request #3043 from brendandburns/api

Add Host to PodSpec and add a predicate to make the scheduler work.
pull/6/head
bgrant0607 2014-12-19 13:35:05 -08:00
commit 486e92963b
9 changed files with 87 additions and 0 deletions

View File

@ -452,6 +452,11 @@ type PodSpec struct {
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty"`
// NodeSelector is a selector which must be true for the pod to fit on a node
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
// Host is a request to schedule this pod onto a specific host. If it is non-empty,
// the the scheduler simply schedules this pod onto that host, assuming that it fits
// resource requirements.
Host string `json:"host,omitempty"`
}
// PodStatus represents information about the status of a pod. Status may trail the actual

View File

@ -204,12 +204,14 @@ func init() {
if err := s.Convert(&in, &out.Manifest, 0); err != nil {
return err
}
out.Host = in.Host
return nil
},
func(in *PodState, out *newer.PodSpec, s conversion.Scope) error {
if err := s.Convert(&in.Manifest, &out, 0); err != nil {
return err
}
out.Host = in.Host
return nil
},
@ -265,6 +267,7 @@ func init() {
if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil {
return err
}
out.DesiredState.Host = in.Spec.Host
if err := s.Convert(&in.Status, &out.CurrentState, 0); err != nil {
return err
}
@ -286,6 +289,7 @@ func init() {
if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil {
return err
}
out.Spec.Host = in.DesiredState.Host
if err := s.Convert(&in.CurrentState, &out.Status, 0); err != nil {
return err
}
@ -361,6 +365,7 @@ func init() {
if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil {
return err
}
out.DesiredState.Host = in.Spec.Host
if err := s.Convert(&in.ObjectMeta.Labels, &out.Labels, 0); err != nil {
return err
}
@ -370,6 +375,7 @@ func init() {
if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil {
return err
}
out.Spec.Host = in.DesiredState.Host
if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil {
return err
}

View File

@ -830,6 +830,11 @@ type PodSpec struct {
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
// NodeSelector is a selector which must be true for the pod to fit on a node
NodeSelector map[string]string `json:"nodeSelector,omitempty" description:"selector which must match a node's labels for the pod to be scheduled on that node"`
// Host is a request to schedule this pod onto a specific host. If it is non-empty,
// the the scheduler simply schedules this pod onto that host, assuming that it fits
// resource requirements.
Host string `json:"host,omitempty" description:"host requested for this pod"`
}
// BoundPod is a collection of containers that should be run on a host. A BoundPod

View File

@ -155,6 +155,7 @@ func init() {
if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil {
return err
}
out.DesiredState.Host = in.Spec.Host
if err := s.Convert(&in.Status, &out.CurrentState, 0); err != nil {
return err
}
@ -176,6 +177,7 @@ func init() {
if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil {
return err
}
out.Spec.Host = in.DesiredState.Host
if err := s.Convert(&in.CurrentState, &out.Status, 0); err != nil {
return err
}
@ -251,6 +253,7 @@ func init() {
if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil {
return err
}
out.DesiredState.Host = in.Spec.Host
if err := s.Convert(&in.ObjectMeta.Labels, &out.Labels, 0); err != nil {
return err
}
@ -260,6 +263,7 @@ func init() {
if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil {
return err
}
out.Spec.Host = in.DesiredState.Host
if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil {
return err
}
@ -323,12 +327,14 @@ func init() {
if err := s.Convert(&in, &out.Manifest, 0); err != nil {
return err
}
out.Host = in.Host
return nil
},
func(in *PodState, out *newer.PodSpec, s conversion.Scope) error {
if err := s.Convert(&in.Manifest, &out, 0); err != nil {
return err
}
out.Host = in.Host
return nil
},
func(in *newer.Service, out *Service, s conversion.Scope) error {

View File

@ -831,6 +831,11 @@ type PodSpec struct {
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
// NodeSelector is a selector which must be true for the pod to fit on a node
NodeSelector map[string]string `json:"nodeSelector,omitempty" description:"selector which must match a node's labels for the pod to be scheduled on that node"`
// Host is a request to schedule this pod onto a specific host. If it is non-empty,
// the the scheduler simply schedules this pod onto that host, assuming that it fits
// resource requirements.
Host string `json:"host,omitempty" description:"host requested for this pod"`
}
// BoundPod is a collection of containers that should be run on a host. A BoundPod

View File

@ -461,6 +461,11 @@ type PodSpec struct {
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty"`
// NodeSelector is a selector which must be true for the pod to fit on a node
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
// Host is a request to schedule this pod onto a specific host. If it is non-empty,
// the the scheduler simply schedules this pod onto that host, assuming that it fits
// other requirements.
Host string `json:"host,omitempty" description:"host requested for this pod"`
}
// PodStatus represents information about the status of a pod. Status may trail the actual

View File

@ -162,6 +162,13 @@ func (n *NodeSelector) PodSelectorMatches(pod api.Pod, existingPods []api.Pod, n
return selector.Matches(labels.Set(minion.Labels)), nil
}
func PodFitsHost(pod api.Pod, existingPods []api.Pod, node string) (bool, error) {
if len(pod.Spec.Host) == 0 {
return true, nil
}
return pod.Spec.Host == node, nil
}
func PodFitsPorts(pod api.Pod, existingPods []api.Pod, node string) (bool, error) {
existingPorts := getUsedPorts(existingPods...)
wantPorts := getUsedPorts(pod)

View File

@ -124,6 +124,52 @@ func TestPodFitsResources(t *testing.T) {
}
}
func TestPodFitsHost(t *testing.T) {
tests := []struct {
pod api.Pod
node string
fits bool
test string
}{
{
pod: api.Pod{},
node: "foo",
fits: true,
test: "no host specified",
},
{
pod: api.Pod{
Spec: api.PodSpec{
Host: "foo",
},
},
node: "foo",
fits: true,
test: "host matches",
},
{
pod: api.Pod{
Spec: api.PodSpec{
Host: "bar",
},
},
node: "foo",
fits: false,
test: "host doesn't match",
},
}
for _, test := range tests {
result, err := PodFitsHost(test.pod, []api.Pod{}, test.node)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if result != test.fits {
t.Errorf("unexpected difference for %s: got: %v expected %v", test.test, test.fits, result)
}
}
}
func TestPodFitsPorts(t *testing.T) {
tests := []struct {
pod api.Pod

View File

@ -37,6 +37,8 @@ func defaultPredicates() util.StringSet {
factory.RegisterFitPredicate("NoDiskConflict", algorithm.NoDiskConflict),
// Fit is determined by node selector query
factory.RegisterFitPredicate("MatchNodeSelector", algorithm.NewSelectorMatchPredicate(factory.MinionLister)),
// Fit is determined by the presence of the Host parameter and a string match
factory.RegisterFitPredicate("HostName", algorithm.PodFitsHost),
)
}