Change:
Currently RC emits an event when it's creating a pod: But nothing is emitted when a pod is deleted. We should create event for scaling both ways. cc

Discussion:
// CreatePodsOnNode creates a new pod accorting to the spec on the specified node. CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error // DeletePod deletes the pod identified by podID. <del> DeletePod(namespace string, podID string) error </del> <ins> DeletePod(namespace string, podID string, object runtime.Object) error </ins> } // RealPodControl is the default implementation of PodControlInterface.

return nil } <del> func (r RealPodControl) DeletePod(namespace, podID string) error { return r.KubeClient.Pods(namespace).Delete(podID, nil) </del> <ins> func (r RealPodControl) DeletePod(namespace string, podID string, object runtime.Object) error { meta, err := api.ObjectMetaFor(object) if err != nil { return fmt.Errorf("object does not have ObjectMeta, %v", err) } if err := r.KubeClient.Pods(namespace).Delete(podID, nil); err != nil { r.Recorder.Eventf(object, api.EventTypeWarning, "FailedDelete", "Error deleting: %v", err) return fmt.Errorf("unable to delete pods: %v", err) } else { glog.V(4).Infof("Controller %v deleted pod %v", meta.Name, podID) r.Recorder.Eventf(object, api.EventTypeNormal, "SuccessfulDelete", "Deleted pod: %v", podID) } return nil </ins> } type FakePodControl struct {

return nil } <del> func (f *FakePodControl) DeletePod(namespace string, podName string) error { </del> <ins> func (f *FakePodControl) DeletePod(namespace string, podID string, object runtime.Object) error { </ins> f.Lock() defer f.Unlock() if f.Err != nil { return f.Err } <del> f.DeletePodName = append(f.DeletePodName, podName) </del> <ins> f.DeletePodName = append(f.DeletePodName, podID) </ins> return nil }

glog.V(4).Infof("Pods to delete for daemon set %s: %+v", ds.Name, podsToDelete) for i := range podsToDelete { <del> if err := dsc.podControl.DeletePod(ds.Namespace, podsToDelete[i]); err != nil { </del> <ins> if err := dsc.podControl.DeletePod(ds.Namespace, podsToDelete[i], ds); err != nil { </ins> glog.V(2).Infof("Failed deletion, decrementing expectations for set %q/%q", ds.Namespace, ds.Name) dsc.expectations.DeletionObserved(dsKey) util.HandleError(err)

for i := 0; i < active; i++ { go func(ix int) { defer wait.Done() <del> if err := jm.podControl.DeletePod(job.Namespace, activePods[ix].Name); err != nil { </del> <ins> if err := jm.podControl.DeletePod(job.Namespace, activePods[ix].Name, &job); err != nil { </ins> defer util.HandleError(err) } }(i)

for i := 0; i < diff; i++ { go func(ix int) { defer wait.Done() <del> if err := jm.podControl.DeletePod(job.Namespace, activePods[ix].Name); err != nil { </del> <ins> if err := jm.podControl.DeletePod(job.Namespace, activePods[ix].Name, job); err != nil { </ins> defer util.HandleError(err) // Decrement the expected number of deletes because the informer won't observe this deletion jm.expectations.DeletionObserved(jobKey)

for i := 0; i < diff; i++ { go func(ix int) { defer wait.Done() <del> if err := rm.podControl.DeletePod(rc.Namespace, filteredPods[ix].Name); err != nil { </del> <ins> if err := rm.podControl.DeletePod(rc.Namespace, filteredPods[ix].Name, rc); err != nil { </ins> // Decrement the expected number of deletes because the informer won't observe this deletion glog.V(2).Infof("Failed deletion, decrementing expectations for controller %q/%q", rc.Namespace, rc.Name) rm.expectations.DeletionObserved(rcKey)