mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Fix up usage and tests, split into multiple files.
Doing this in multiple commits in an attempt to preserve the file movement history.
This commit is contained in:
		@@ -25,6 +25,7 @@ import (
 | 
				
			|||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/registry"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/registry"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
				
			||||||
	"github.com/coreos/go-etcd/etcd"
 | 
						"github.com/coreos/go-etcd/etcd"
 | 
				
			||||||
	"github.com/golang/glog"
 | 
						"github.com/golang/glog"
 | 
				
			||||||
@@ -37,6 +38,7 @@ type Master struct {
 | 
				
			|||||||
	serviceRegistry    registry.ServiceRegistry
 | 
						serviceRegistry    registry.ServiceRegistry
 | 
				
			||||||
	minionRegistry     registry.MinionRegistry
 | 
						minionRegistry     registry.MinionRegistry
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: don't reuse non-threadsafe objects.
 | 
				
			||||||
	random  *rand.Rand
 | 
						random  *rand.Rand
 | 
				
			||||||
	storage map[string]apiserver.RESTStorage
 | 
						storage map[string]apiserver.RESTStorage
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -86,8 +88,9 @@ func (m *Master) init(cloud cloudprovider.Interface) {
 | 
				
			|||||||
	m.random = rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
 | 
						m.random = rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
 | 
				
			||||||
	podCache := NewPodCache(containerInfo, m.podRegistry, time.Second*30)
 | 
						podCache := NewPodCache(containerInfo, m.podRegistry, time.Second*30)
 | 
				
			||||||
	go podCache.Loop()
 | 
						go podCache.Loop()
 | 
				
			||||||
 | 
						s := scheduler.MakeFirstFitScheduler(m.podRegistry, m.random)
 | 
				
			||||||
	m.storage = map[string]apiserver.RESTStorage{
 | 
						m.storage = map[string]apiserver.RESTStorage{
 | 
				
			||||||
		"pods": registry.MakePodRegistryStorage(m.podRegistry, containerInfo, registry.MakeFirstFitScheduler(m.minionRegistry, m.podRegistry, m.random), cloud, podCache),
 | 
							"pods": registry.MakePodRegistryStorage(m.podRegistry, containerInfo, s, m.minionRegistry, cloud, podCache),
 | 
				
			||||||
		"replicationControllers": registry.MakeControllerRegistryStorage(m.controllerRegistry, m.podRegistry),
 | 
							"replicationControllers": registry.MakeControllerRegistryStorage(m.controllerRegistry, m.podRegistry),
 | 
				
			||||||
		"services":               registry.MakeServiceRegistryStorage(m.serviceRegistry, cloud, m.minionRegistry),
 | 
							"services":               registry.MakeServiceRegistryStorage(m.serviceRegistry, cloud, m.minionRegistry),
 | 
				
			||||||
		"minions":                registry.MakeMinionRegistryStorage(m.minionRegistry),
 | 
							"minions":                registry.MakeMinionRegistryStorage(m.minionRegistry),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,6 +25,7 @@ import (
 | 
				
			|||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler"
 | 
				
			||||||
	"github.com/golang/glog"
 | 
						"github.com/golang/glog"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -33,22 +34,30 @@ type PodRegistryStorage struct {
 | 
				
			|||||||
	registry      PodRegistry
 | 
						registry      PodRegistry
 | 
				
			||||||
	containerInfo client.ContainerInfo
 | 
						containerInfo client.ContainerInfo
 | 
				
			||||||
	podCache      client.ContainerInfo
 | 
						podCache      client.ContainerInfo
 | 
				
			||||||
	scheduler     Scheduler
 | 
						scheduler     scheduler.Scheduler
 | 
				
			||||||
 | 
						minionLister  scheduler.MinionLister
 | 
				
			||||||
	cloud         cloudprovider.Interface
 | 
						cloud         cloudprovider.Interface
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MakePodRegistryStorage makes a RESTStorage object for a pod registry.
 | 
					// MakePodRegistryStorage makes a RESTStorage object for a pod registry.
 | 
				
			||||||
// Parameters:
 | 
					// Parameters:
 | 
				
			||||||
//   registry The pod registry
 | 
					//   registry:      The pod registry
 | 
				
			||||||
//   containerInfo Source of fresh container info
 | 
					//   containerInfo: Source of fresh container info
 | 
				
			||||||
//   scheduler The scheduler for assigning pods to machines
 | 
					//   scheduler:     The scheduler for assigning pods to machines
 | 
				
			||||||
//   cloud Interface to a cloud provider (may be null)
 | 
					//   minionLister:  Object which can list available minions for the scheduler
 | 
				
			||||||
//   podCache Source of cached container info
 | 
					//   cloud:         Interface to a cloud provider (may be null)
 | 
				
			||||||
func MakePodRegistryStorage(registry PodRegistry, containerInfo client.ContainerInfo, scheduler Scheduler, cloud cloudprovider.Interface, podCache client.ContainerInfo) apiserver.RESTStorage {
 | 
					//   podCache:      Source of cached container info
 | 
				
			||||||
 | 
					func MakePodRegistryStorage(registry PodRegistry,
 | 
				
			||||||
 | 
						containerInfo client.ContainerInfo,
 | 
				
			||||||
 | 
						scheduler scheduler.Scheduler,
 | 
				
			||||||
 | 
						minionLister scheduler.MinionLister,
 | 
				
			||||||
 | 
						cloud cloudprovider.Interface,
 | 
				
			||||||
 | 
						podCache client.ContainerInfo) apiserver.RESTStorage {
 | 
				
			||||||
	return &PodRegistryStorage{
 | 
						return &PodRegistryStorage{
 | 
				
			||||||
		registry:      registry,
 | 
							registry:      registry,
 | 
				
			||||||
		containerInfo: containerInfo,
 | 
							containerInfo: containerInfo,
 | 
				
			||||||
		scheduler:     scheduler,
 | 
							scheduler:     scheduler,
 | 
				
			||||||
 | 
							minionLister:  minionLister,
 | 
				
			||||||
		cloud:         cloud,
 | 
							cloud:         cloud,
 | 
				
			||||||
		podCache:      podCache,
 | 
							podCache:      podCache,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -150,7 +159,7 @@ func (storage *PodRegistryStorage) Create(obj interface{}) (<-chan interface{},
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return apiserver.MakeAsync(func() (interface{}, error) {
 | 
						return apiserver.MakeAsync(func() (interface{}, error) {
 | 
				
			||||||
		// TODO(lavalamp): Separate scheduler more cleanly.
 | 
							// TODO(lavalamp): Separate scheduler more cleanly.
 | 
				
			||||||
		machine, err := storage.scheduler.Schedule(pod)
 | 
							machine, err := storage.scheduler.Schedule(pod, storage.minionLister)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								pkg/scheduler/doc.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								pkg/scheduler/doc.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Package scheduler contains a generic Scheduler interface and several
 | 
				
			||||||
 | 
					// implementations.
 | 
				
			||||||
 | 
					package scheduler
 | 
				
			||||||
							
								
								
									
										86
									
								
								pkg/scheduler/firstfit.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								pkg/scheduler/firstfit.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package scheduler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"math/rand"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type FirstFitScheduler struct {
 | 
				
			||||||
 | 
						podLister PodLister
 | 
				
			||||||
 | 
						// TODO: *rand.Rand is *not* threadsafe
 | 
				
			||||||
 | 
						random *rand.Rand
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func MakeFirstFitScheduler(podLister PodLister, random *rand.Rand) Scheduler {
 | 
				
			||||||
 | 
						return &FirstFitScheduler{
 | 
				
			||||||
 | 
							podLister: podLister,
 | 
				
			||||||
 | 
							random:    random,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *FirstFitScheduler) containsPort(pod api.Pod, port api.Port) bool {
 | 
				
			||||||
 | 
						for _, container := range pod.DesiredState.Manifest.Containers {
 | 
				
			||||||
 | 
							for _, podPort := range container.Ports {
 | 
				
			||||||
 | 
								if podPort.HostPort == port.HostPort {
 | 
				
			||||||
 | 
									return true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *FirstFitScheduler) Schedule(pod api.Pod, minionLister MinionLister) (string, error) {
 | 
				
			||||||
 | 
						machines, err := minionLister.List()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						machineToPods := map[string][]api.Pod{}
 | 
				
			||||||
 | 
						pods, err := s.podLister.ListPods(labels.Everything())
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, scheduledPod := range pods {
 | 
				
			||||||
 | 
							host := scheduledPod.CurrentState.Host
 | 
				
			||||||
 | 
							machineToPods[host] = append(machineToPods[host], scheduledPod)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var machineOptions []string
 | 
				
			||||||
 | 
						for _, machine := range machines {
 | 
				
			||||||
 | 
							podFits := true
 | 
				
			||||||
 | 
							for _, scheduledPod := range machineToPods[machine] {
 | 
				
			||||||
 | 
								for _, container := range pod.DesiredState.Manifest.Containers {
 | 
				
			||||||
 | 
									for _, port := range container.Ports {
 | 
				
			||||||
 | 
										if s.containsPort(scheduledPod, port) {
 | 
				
			||||||
 | 
											podFits = false
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if podFits {
 | 
				
			||||||
 | 
								machineOptions = append(machineOptions, machine)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(machineOptions) == 0 {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("failed to find fit for %#v", pod)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return machineOptions[s.random.Int()%len(machineOptions)], nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										78
									
								
								pkg/scheduler/firstfit_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								pkg/scheduler/firstfit_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package scheduler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"math/rand"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestFirstFitSchedulerNothingScheduled(t *testing.T) {
 | 
				
			||||||
 | 
						fakeRegistry := FakePodLister{}
 | 
				
			||||||
 | 
						r := rand.New(rand.NewSource(0))
 | 
				
			||||||
 | 
						st := schedulerTester{
 | 
				
			||||||
 | 
							t:            t,
 | 
				
			||||||
 | 
							scheduler:    MakeFirstFitScheduler(&fakeRegistry, r),
 | 
				
			||||||
 | 
							minionLister: FakeMinionLister{"m1", "m2", "m3"},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						st.expectSchedule(api.Pod{}, "m3")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestFirstFitSchedulerFirstScheduled(t *testing.T) {
 | 
				
			||||||
 | 
						fakeRegistry := FakePodLister{
 | 
				
			||||||
 | 
							makePod("m1", 8080),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						r := rand.New(rand.NewSource(0))
 | 
				
			||||||
 | 
						st := schedulerTester{
 | 
				
			||||||
 | 
							t:            t,
 | 
				
			||||||
 | 
							scheduler:    MakeFirstFitScheduler(fakeRegistry, r),
 | 
				
			||||||
 | 
							minionLister: FakeMinionLister{"m1", "m2", "m3"},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						st.expectSchedule(makePod("", 8080), "m3")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestFirstFitSchedulerFirstScheduledComplicated(t *testing.T) {
 | 
				
			||||||
 | 
						fakeRegistry := FakePodLister{
 | 
				
			||||||
 | 
							makePod("m1", 80, 8080),
 | 
				
			||||||
 | 
							makePod("m2", 8081, 8082, 8083),
 | 
				
			||||||
 | 
							makePod("m3", 80, 443, 8085),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						r := rand.New(rand.NewSource(0))
 | 
				
			||||||
 | 
						st := schedulerTester{
 | 
				
			||||||
 | 
							t:            t,
 | 
				
			||||||
 | 
							scheduler:    MakeFirstFitScheduler(fakeRegistry, r),
 | 
				
			||||||
 | 
							minionLister: FakeMinionLister{"m1", "m2", "m3"},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						st.expectSchedule(makePod("", 8080, 8081), "m3")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestFirstFitSchedulerFirstScheduledImpossible(t *testing.T) {
 | 
				
			||||||
 | 
						fakeRegistry := FakePodLister{
 | 
				
			||||||
 | 
							makePod("m1", 8080),
 | 
				
			||||||
 | 
							makePod("m2", 8081),
 | 
				
			||||||
 | 
							makePod("m3", 8080),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						r := rand.New(rand.NewSource(0))
 | 
				
			||||||
 | 
						st := schedulerTester{
 | 
				
			||||||
 | 
							t:            t,
 | 
				
			||||||
 | 
							scheduler:    MakeFirstFitScheduler(fakeRegistry, r),
 | 
				
			||||||
 | 
							minionLister: FakeMinionLister{"m1", "m2", "m3"},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						st.expectFailure(makePod("", 8080, 8081))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										52
									
								
								pkg/scheduler/listers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								pkg/scheduler/listers.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package scheduler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Anything that can list minions for a scheduler.
 | 
				
			||||||
 | 
					type MinionLister interface {
 | 
				
			||||||
 | 
						List() (machines []string, err error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Make a MinionLister from a []string
 | 
				
			||||||
 | 
					type FakeMinionLister []string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Returns minions as a []string
 | 
				
			||||||
 | 
					func (f FakeMinionLister) List() ([]string, error) {
 | 
				
			||||||
 | 
						return []string(f), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Anything that can list pods for a scheduler
 | 
				
			||||||
 | 
					type PodLister interface {
 | 
				
			||||||
 | 
						ListPods(labels.Selector) ([]api.Pod, error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Make a MinionLister from an []api.Pods
 | 
				
			||||||
 | 
					type FakePodLister []api.Pod
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (f FakePodLister) ListPods(s labels.Selector) (selected []api.Pod, err error) {
 | 
				
			||||||
 | 
						for _, pod := range f {
 | 
				
			||||||
 | 
							if s.Matches(labels.Set(pod.Labels)) {
 | 
				
			||||||
 | 
								selected = append(selected, pod)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return selected, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										43
									
								
								pkg/scheduler/random.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								pkg/scheduler/random.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package scheduler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"math/rand"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RandomScheduler choses machines uniformly at random.
 | 
				
			||||||
 | 
					type RandomScheduler struct {
 | 
				
			||||||
 | 
						// TODO: rand.Rand is *NOT* thread safe.
 | 
				
			||||||
 | 
						random *rand.Rand
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func MakeRandomScheduler(random *rand.Rand) Scheduler {
 | 
				
			||||||
 | 
						return &RandomScheduler{
 | 
				
			||||||
 | 
							random: random,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *RandomScheduler) Schedule(pod api.Pod, minionLister MinionLister) (string, error) {
 | 
				
			||||||
 | 
						machines, err := minionLister.List()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return machines[s.random.Int()%len(machines)], nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										34
									
								
								pkg/scheduler/random_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								pkg/scheduler/random_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package scheduler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"math/rand"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestRandomScheduler(t *testing.T) {
 | 
				
			||||||
 | 
						random := rand.New(rand.NewSource(0))
 | 
				
			||||||
 | 
						st := schedulerTester{
 | 
				
			||||||
 | 
							t:            t,
 | 
				
			||||||
 | 
							scheduler:    MakeRandomScheduler(random),
 | 
				
			||||||
 | 
							minionLister: FakeMinionLister{"m1", "m2", "m3", "m4"},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						st.expectSuccess(api.Pod{})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										42
									
								
								pkg/scheduler/roundrobin.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								pkg/scheduler/roundrobin.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package scheduler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RoundRobinScheduler chooses machines in order.
 | 
				
			||||||
 | 
					type RoundRobinScheduler struct {
 | 
				
			||||||
 | 
						currentIndex int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func MakeRoundRobinScheduler() Scheduler {
 | 
				
			||||||
 | 
						return &RoundRobinScheduler{
 | 
				
			||||||
 | 
							currentIndex: -1,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *RoundRobinScheduler) Schedule(pod api.Pod, minionLister MinionLister) (string, error) {
 | 
				
			||||||
 | 
						machines, err := minionLister.List()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s.currentIndex = (s.currentIndex + 1) % len(machines)
 | 
				
			||||||
 | 
						result := machines[s.currentIndex]
 | 
				
			||||||
 | 
						return result, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								pkg/scheduler/roundrobin_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								pkg/scheduler/roundrobin_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package scheduler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestRoundRobinScheduler(t *testing.T) {
 | 
				
			||||||
 | 
						st := schedulerTester{
 | 
				
			||||||
 | 
							t:            t,
 | 
				
			||||||
 | 
							scheduler:    MakeRoundRobinScheduler(),
 | 
				
			||||||
 | 
							minionLister: FakeMinionLister{"m1", "m2", "m3", "m4"},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						st.expectSchedule(api.Pod{}, "m1")
 | 
				
			||||||
 | 
						st.expectSchedule(api.Pod{}, "m2")
 | 
				
			||||||
 | 
						st.expectSchedule(api.Pod{}, "m3")
 | 
				
			||||||
 | 
						st.expectSchedule(api.Pod{}, "m4")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -14,129 +14,14 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package registry
 | 
					package scheduler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"math/rand"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Anything that can list minions for a scheduler.
 | 
					// Scheduler is an interface implemented by things that know how to schedule pods
 | 
				
			||||||
type MinionLister interface {
 | 
					// onto machines.
 | 
				
			||||||
	List() (machines []string, err error)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Make a MinionLister from a []string
 | 
					 | 
				
			||||||
type StringMinionLister []string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s StringMinionLister) List() ([]string, error) {
 | 
					 | 
				
			||||||
	return []string(s), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Scheduler is an interface implemented by things that know how to schedule pods onto machines.
 | 
					 | 
				
			||||||
type Scheduler interface {
 | 
					type Scheduler interface {
 | 
				
			||||||
	Schedule(api.Pod, MinionLister) (string, error)
 | 
						Schedule(api.Pod, MinionLister) (selectedMachine string, err error)
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RandomScheduler choses machines uniformly at random.
 | 
					 | 
				
			||||||
type RandomScheduler struct {
 | 
					 | 
				
			||||||
	random rand.Rand
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func MakeRandomScheduler(random rand.Rand) Scheduler {
 | 
					 | 
				
			||||||
	return &RandomScheduler{
 | 
					 | 
				
			||||||
		random: random,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *RandomScheduler) Schedule(pod api.Pod, minionLister MinionLister) (string, error) {
 | 
					 | 
				
			||||||
	machines, err := minionLister.List()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return machines[s.random.Int()%len(machines)], nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RoundRobinScheduler chooses machines in order.
 | 
					 | 
				
			||||||
type RoundRobinScheduler struct {
 | 
					 | 
				
			||||||
	currentIndex int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func MakeRoundRobinScheduler() Scheduler {
 | 
					 | 
				
			||||||
	return &RoundRobinScheduler{
 | 
					 | 
				
			||||||
		currentIndex: -1,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *RoundRobinScheduler) Schedule(pod api.Pod, minionLister MinionLister) (string, error) {
 | 
					 | 
				
			||||||
	machines, err := minionLister.List()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.currentIndex = (s.currentIndex + 1) % len(machines)
 | 
					 | 
				
			||||||
	result := machines[s.currentIndex]
 | 
					 | 
				
			||||||
	return result, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type FirstFitScheduler struct {
 | 
					 | 
				
			||||||
	registry PodRegistry
 | 
					 | 
				
			||||||
	random   *rand.Rand
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func MakeFirstFitScheduler(registry PodRegistry, random *rand.Rand) Scheduler {
 | 
					 | 
				
			||||||
	return &FirstFitScheduler{
 | 
					 | 
				
			||||||
		registry: registry,
 | 
					 | 
				
			||||||
		random:   random,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *FirstFitScheduler) containsPort(pod api.Pod, port api.Port) bool {
 | 
					 | 
				
			||||||
	for _, container := range pod.DesiredState.Manifest.Containers {
 | 
					 | 
				
			||||||
		for _, podPort := range container.Ports {
 | 
					 | 
				
			||||||
			if podPort.HostPort == port.HostPort {
 | 
					 | 
				
			||||||
				return true
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *FirstFitScheduler) Schedule(pod api.Pod, minionLister MinionLister) (string, error) {
 | 
					 | 
				
			||||||
	machines, err := minionLister.List()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	machineToPods := map[string][]api.Pod{}
 | 
					 | 
				
			||||||
	pods, err := s.registry.ListPods(labels.Everything())
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, scheduledPod := range pods {
 | 
					 | 
				
			||||||
		host := scheduledPod.CurrentState.Host
 | 
					 | 
				
			||||||
		machineToPods[host] = append(machineToPods[host], scheduledPod)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var machineOptions []string
 | 
					 | 
				
			||||||
	for _, machine := range machines {
 | 
					 | 
				
			||||||
		podFits := true
 | 
					 | 
				
			||||||
		for _, scheduledPod := range machineToPods[machine] {
 | 
					 | 
				
			||||||
			for _, container := range pod.DesiredState.Manifest.Containers {
 | 
					 | 
				
			||||||
				for _, port := range container.Ports {
 | 
					 | 
				
			||||||
					if s.containsPort(scheduledPod, port) {
 | 
					 | 
				
			||||||
						podFits = false
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if podFits {
 | 
					 | 
				
			||||||
			machineOptions = append(machineOptions, machine)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(machineOptions) == 0 {
 | 
					 | 
				
			||||||
		return "", fmt.Errorf("failed to find fit for %#v", pod)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		return machineOptions[s.random.Int()%len(machineOptions)], nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,43 +14,49 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package registry
 | 
					package scheduler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"math/rand"
 | 
					 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func expectSchedule(scheduler Scheduler, pod api.Pod, expected string, t *testing.T) {
 | 
					// Some functions used by multiple scheduler tests.
 | 
				
			||||||
	actual, err := scheduler.Schedule(pod)
 | 
					
 | 
				
			||||||
	expectNoError(t, err)
 | 
					type schedulerTester struct {
 | 
				
			||||||
 | 
						t            *testing.T
 | 
				
			||||||
 | 
						scheduler    Scheduler
 | 
				
			||||||
 | 
						minionLister MinionLister
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Call if you know exactly where pod should get scheduled.
 | 
				
			||||||
 | 
					func (st *schedulerTester) expectSchedule(pod api.Pod, expected string) {
 | 
				
			||||||
 | 
						actual, err := st.scheduler.Schedule(pod, st.minionLister)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							st.t.Errorf("Unexpected error %v\nTried to scheduler: %#v", err, pod)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if actual != expected {
 | 
						if actual != expected {
 | 
				
			||||||
		t.Errorf("Unexpected scheduling value: %v, expected %v", actual, expected)
 | 
							st.t.Errorf("Unexpected scheduling value: %v, expected %v", actual, expected)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestRoundRobinScheduler(t *testing.T) {
 | 
					// Call if you can't predict where pod will be scheduled.
 | 
				
			||||||
	scheduler := MakeRoundRobinScheduler(MakeMinionRegistry([]string{"m1", "m2", "m3", "m4"}))
 | 
					func (st *schedulerTester) expectSuccess(pod api.Pod) {
 | 
				
			||||||
	expectSchedule(scheduler, api.Pod{}, "m1", t)
 | 
						_, err := st.scheduler.Schedule(pod, st.minionLister)
 | 
				
			||||||
	expectSchedule(scheduler, api.Pod{}, "m2", t)
 | 
						if err != nil {
 | 
				
			||||||
	expectSchedule(scheduler, api.Pod{}, "m3", t)
 | 
							st.t.Errorf("Unexpected error %v\nTried to scheduler: %#v", err, pod)
 | 
				
			||||||
	expectSchedule(scheduler, api.Pod{}, "m4", t)
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestRandomScheduler(t *testing.T) {
 | 
					// Call if pod should *not* schedule.
 | 
				
			||||||
	random := rand.New(rand.NewSource(0))
 | 
					func (st *schedulerTester) expectFailure(pod api.Pod) {
 | 
				
			||||||
	scheduler := MakeRandomScheduler(MakeMinionRegistry([]string{"m1", "m2", "m3", "m4"}), *random)
 | 
						_, err := st.scheduler.Schedule(pod, st.minionLister)
 | 
				
			||||||
	_, err := scheduler.Schedule(api.Pod{})
 | 
						if err == nil {
 | 
				
			||||||
	expectNoError(t, err)
 | 
							st.t.Error("Unexpected non-error")
 | 
				
			||||||
}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestFirstFitSchedulerNothingScheduled(t *testing.T) {
 | 
					 | 
				
			||||||
	mockRegistry := MockPodRegistry{}
 | 
					 | 
				
			||||||
	r := rand.New(rand.NewSource(0))
 | 
					 | 
				
			||||||
	scheduler := MakeFirstFitScheduler(MakeMinionRegistry([]string{"m1", "m2", "m3"}), &mockRegistry, r)
 | 
					 | 
				
			||||||
	expectSchedule(scheduler, api.Pod{}, "m3", t)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func makePod(host string, hostPorts ...int) api.Pod {
 | 
					func makePod(host string, hostPorts ...int) api.Pod {
 | 
				
			||||||
@@ -73,43 +79,3 @@ func makePod(host string, hostPorts ...int) api.Pod {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestFirstFitSchedulerFirstScheduled(t *testing.T) {
 | 
					 | 
				
			||||||
	mockRegistry := MockPodRegistry{
 | 
					 | 
				
			||||||
		pods: []api.Pod{
 | 
					 | 
				
			||||||
			makePod("m1", 8080),
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	r := rand.New(rand.NewSource(0))
 | 
					 | 
				
			||||||
	scheduler := MakeFirstFitScheduler(MakeMinionRegistry([]string{"m1", "m2", "m3"}), &mockRegistry, r)
 | 
					 | 
				
			||||||
	expectSchedule(scheduler, makePod("", 8080), "m3", t)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestFirstFitSchedulerFirstScheduledComplicated(t *testing.T) {
 | 
					 | 
				
			||||||
	mockRegistry := MockPodRegistry{
 | 
					 | 
				
			||||||
		pods: []api.Pod{
 | 
					 | 
				
			||||||
			makePod("m1", 80, 8080),
 | 
					 | 
				
			||||||
			makePod("m2", 8081, 8082, 8083),
 | 
					 | 
				
			||||||
			makePod("m3", 80, 443, 8085),
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	r := rand.New(rand.NewSource(0))
 | 
					 | 
				
			||||||
	scheduler := MakeFirstFitScheduler(MakeMinionRegistry([]string{"m1", "m2", "m3"}), &mockRegistry, r)
 | 
					 | 
				
			||||||
	expectSchedule(scheduler, makePod("", 8080, 8081), "m3", t)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestFirstFitSchedulerFirstScheduledImpossible(t *testing.T) {
 | 
					 | 
				
			||||||
	mockRegistry := MockPodRegistry{
 | 
					 | 
				
			||||||
		pods: []api.Pod{
 | 
					 | 
				
			||||||
			makePod("m1", 8080),
 | 
					 | 
				
			||||||
			makePod("m2", 8081),
 | 
					 | 
				
			||||||
			makePod("m3", 8080),
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	r := rand.New(rand.NewSource(0))
 | 
					 | 
				
			||||||
	scheduler := MakeFirstFitScheduler(MakeMinionRegistry([]string{"m1", "m2", "m3"}), &mockRegistry, r)
 | 
					 | 
				
			||||||
	_, err := scheduler.Schedule(makePod("", 8080, 8081))
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		t.Error("Unexpected non-error.")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user