diff --git a/pkg/api/testapi/testapi.go b/pkg/api/testapi/testapi.go index 23a5b25391b..f9ef1816176 100644 --- a/pkg/api/testapi/testapi.go +++ b/pkg/api/testapi/testapi.go @@ -18,6 +18,7 @@ limitations under the License. package testapi import ( + "fmt" "os" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" @@ -52,3 +53,13 @@ func ResourceVersioner() runtime.ResourceVersioner { } return interfaces.ResourceVersioner } + +// SelfLink returns a self link that will appear to be for the version Version(). +// 'resource' should be the resource path, e.g. "pods" for the Pod type. 'name' should be +// empty for lists. +func SelfLink(resource, name string) string { + if name == "" { + return fmt.Sprintf("/api/%s/%s", Version(), resource) + } + return fmt.Sprintf("/api/%s/%s/%s", Version(), resource, name) +} diff --git a/plugin/cmd/scheduler/scheduler.go b/plugin/cmd/scheduler/scheduler.go index ca872ef0437..ead41b7e166 100644 --- a/plugin/cmd/scheduler/scheduler.go +++ b/plugin/cmd/scheduler/scheduler.go @@ -23,6 +23,7 @@ import ( "strconv" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client/record" _ "github.com/GoogleCloudPlatform/kubernetes/pkg/healthz" masterPkg "github.com/GoogleCloudPlatform/kubernetes/pkg/master" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -55,6 +56,8 @@ func main() { glog.Fatalf("Invalid API configuration: %v", err) } + record.StartRecording(kubeClient, "scheduler") + go http.ListenAndServe(net.JoinHostPort(address.String(), strconv.Itoa(*port)), nil) configFactory := &factory.ConfigFactory{Client: kubeClient} diff --git a/plugin/pkg/scheduler/scheduler.go b/plugin/pkg/scheduler/scheduler.go index 2c6f81483e2..c1527600e13 100644 --- a/plugin/pkg/scheduler/scheduler.go +++ b/plugin/pkg/scheduler/scheduler.go @@ -18,6 +18,7 @@ package scheduler import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client/record" // TODO: move everything from pkg/scheduler into this package. Remove references from registry. "github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -67,6 +68,7 @@ func (s *Scheduler) scheduleOne() { pod := s.config.NextPod() dest, err := s.config.Algorithm.Schedule(*pod, s.config.MinionLister) if err != nil { + record.Eventf(pod, "", string(api.PodWaiting), "failedScheduling", "Error scheduling: %v", err) s.config.Error(pod, err) return } @@ -75,6 +77,9 @@ func (s *Scheduler) scheduleOne() { Host: dest, } if err := s.config.Binder.Bind(b); err != nil { + record.Eventf(pod, "", string(api.PodWaiting), "failedScheduling", "Binding rejected: %v", err) s.config.Error(pod, err) + return } + record.Eventf(pod, "", string(api.PodWaiting), "scheduled", "Successfully assigned %v to %v", pod.ID, dest) } diff --git a/plugin/pkg/scheduler/scheduler_test.go b/plugin/pkg/scheduler/scheduler_test.go index 5d0df3722d3..421e4267789 100644 --- a/plugin/pkg/scheduler/scheduler_test.go +++ b/plugin/pkg/scheduler/scheduler_test.go @@ -22,6 +22,8 @@ import ( "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client/record" "github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler" ) @@ -32,7 +34,7 @@ type fakeBinder struct { func (fb fakeBinder) Bind(binding *api.Binding) error { return fb.b(binding) } func podWithID(id string) *api.Pod { - return &api.Pod{TypeMeta: api.TypeMeta{ID: "foo"}} + return &api.Pod{TypeMeta: api.TypeMeta{ID: id, SelfLink: testapi.SelfLink("pods", id)}} } type mockScheduler struct { @@ -45,7 +47,7 @@ func (es mockScheduler) Schedule(pod api.Pod, ml scheduler.MinionLister) (string } func TestScheduler(t *testing.T) { - + defer record.StartLogging(t.Logf).Stop() errS := errors.New("scheduler") errB := errors.New("binder") @@ -56,16 +58,19 @@ func TestScheduler(t *testing.T) { expectErrorPod *api.Pod expectError error expectBind *api.Binding + eventReason string }{ { - sendPod: podWithID("foo"), - algo: mockScheduler{"machine1", nil}, - expectBind: &api.Binding{PodID: "foo", Host: "machine1"}, + sendPod: podWithID("foo"), + algo: mockScheduler{"machine1", nil}, + expectBind: &api.Binding{PodID: "foo", Host: "machine1"}, + eventReason: "scheduled", }, { sendPod: podWithID("foo"), algo: mockScheduler{"machine1", errS}, expectError: errS, expectErrorPod: podWithID("foo"), + eventReason: "failedScheduling", }, { sendPod: podWithID("foo"), algo: mockScheduler{"machine1", nil}, @@ -73,6 +78,7 @@ func TestScheduler(t *testing.T) { injectBindError: errB, expectError: errB, expectErrorPod: podWithID("foo"), + eventReason: "failedScheduling", }, } @@ -98,6 +104,13 @@ func TestScheduler(t *testing.T) { }, } s := New(c) + called := make(chan struct{}) + events := record.GetEvents(func(e *api.Event) { + if e, a := item.eventReason, e.Reason; e != a { + t.Errorf("%v: expected %v, got %v", i, e, a) + } + close(called) + }) s.scheduleOne() if e, a := item.expectErrorPod, gotPod; !reflect.DeepEqual(e, a) { t.Errorf("%v: error pod: wanted %v, got %v", i, e, a) @@ -108,5 +121,7 @@ func TestScheduler(t *testing.T) { if e, a := item.expectBind, gotBinding; !reflect.DeepEqual(e, a) { t.Errorf("%v: error: wanted %v, got %v", i, e, a) } + <-called + events.Stop() } }