Commit 98115fac authored by Filip Grzadkowski's avatar Filip Grzadkowski

Revert "Gracefully delete pods from the Kubelet"

parent 52e5df7e
...@@ -17,7 +17,6 @@ spec: ...@@ -17,7 +17,6 @@ spec:
mountPath: /varlog mountPath: /varlog
- name: containers - name: containers
mountPath: /var/lib/docker/containers mountPath: /var/lib/docker/containers
terminationGracePeriodSeconds: 30
volumes: volumes:
- name: varlog - name: varlog
hostPath: hostPath:
......
...@@ -17,7 +17,6 @@ spec: ...@@ -17,7 +17,6 @@ spec:
mountPath: /varlog mountPath: /varlog
- name: containers - name: containers
mountPath: /var/lib/docker/containers mountPath: /var/lib/docker/containers
terminationGracePeriodSeconds: 30
volumes: volumes:
- name: varlog - name: varlog
hostPath: hostPath:
......
...@@ -878,24 +878,18 @@ func runSchedulerNoPhantomPodsTest(client *client.Client) { ...@@ -878,24 +878,18 @@ func runSchedulerNoPhantomPodsTest(client *client.Client) {
// Delete a pod to free up room. // Delete a pod to free up room.
glog.Infof("Deleting pod %v", bar.Name) glog.Infof("Deleting pod %v", bar.Name)
err = client.Pods(api.NamespaceDefault).Delete(bar.Name, api.NewDeleteOptions(1)) err = client.Pods(api.NamespaceDefault).Delete(bar.Name, nil)
if err != nil { if err != nil {
glog.Fatalf("FAILED: couldn't delete pod %q: %v", bar.Name, err) glog.Fatalf("FAILED: couldn't delete pod %q: %v", bar.Name, err)
} }
time.Sleep(2 * time.Second)
pod.ObjectMeta.Name = "phantom.baz" pod.ObjectMeta.Name = "phantom.baz"
baz, err := client.Pods(api.NamespaceDefault).Create(pod) baz, err := client.Pods(api.NamespaceDefault).Create(pod)
if err != nil { if err != nil {
glog.Fatalf("Failed to create pod: %v, %v", pod, err) glog.Fatalf("Failed to create pod: %v, %v", pod, err)
} }
if err := wait.Poll(time.Second, time.Second*60, podRunning(client, baz.Namespace, baz.Name)); err != nil { if err := wait.Poll(time.Second, time.Second*60, podRunning(client, baz.Namespace, baz.Name)); err != nil {
if pod, perr := client.Pods(api.NamespaceDefault).Get("phantom.bar"); perr == nil { glog.Fatalf("FAILED: (Scheduler probably didn't process deletion of 'phantom.bar') Pod never started running: %v", err)
glog.Fatalf("FAILED: 'phantom.bar' was never deleted: %#v", pod)
} else {
glog.Fatalf("FAILED: (Scheduler probably didn't process deletion of 'phantom.bar') Pod never started running: %v", err)
}
} }
glog.Info("Scheduler doesn't make phantom pods: test passed.") glog.Info("Scheduler doesn't make phantom pods: test passed.")
......
{
"kind": "Pod",
"apiVersion": "v1beta3",
"metadata": {
"name": "slow-pod",
"labels": {
"name": "nettest"
}
},
"spec": {
"containers": [
{
"name": "webserver",
"image": "gcr.io/google_containers/nettest:1.5",
"args": [
"-service=nettest",
"-delay-shutdown=10"
],
"ports": [
{
"containerPort": 8080,
"protocol": "TCP"
}
]
}
]
}
}
{
"kind": "ReplicationController",
"apiVersion": "v1beta3",
"metadata": {
"name": "slow-rc",
"labels": {
"name": "nettest"
}
},
"spec": {
"replicas": 8,
"selector": {
"name": "nettest"
},
"template": {
"metadata": {
"labels": {
"name": "nettest"
}
},
"spec": {
"terminationGracePeriodSeconds": 5,
"containers": [
{
"name": "webserver",
"image": "gcr.io/google_containers/nettest:1.5",
"args": [
"-service=nettest",
"-delay-shutdown=10"
],
"ports": [
{
"containerPort": 8080,
"protocol": "TCP"
}
]
}
]
}
}
}
}
...@@ -40,9 +40,7 @@ import ( ...@@ -40,9 +40,7 @@ import (
"net" "net"
"net/http" "net/http"
"os" "os"
"os/signal"
"sync" "sync"
"syscall"
"time" "time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
...@@ -50,11 +48,10 @@ import ( ...@@ -50,11 +48,10 @@ import (
) )
var ( var (
port = flag.Int("port", 8080, "Port number to serve at.") port = flag.Int("port", 8080, "Port number to serve at.")
peerCount = flag.Int("peers", 8, "Must find at least this many peers for the test to pass.") peerCount = flag.Int("peers", 8, "Must find at least this many peers for the test to pass.")
service = flag.String("service", "nettest", "Service to find other network test pods in.") service = flag.String("service", "nettest", "Service to find other network test pods in.")
namespace = flag.String("namespace", "default", "Namespace of this pod. TODO: kubernetes should make this discoverable.") namespace = flag.String("namespace", "default", "Namespace of this pod. TODO: kubernetes should make this discoverable.")
delayShutdown = flag.Int("delay-shutdown", 0, "Number of seconds to delay shutdown when receiving SIGTERM.")
) )
// State tracks the internal state of our little http server. // State tracks the internal state of our little http server.
...@@ -182,17 +179,6 @@ func main() { ...@@ -182,17 +179,6 @@ func main() {
log.Fatalf("Error getting hostname: %v", err) log.Fatalf("Error getting hostname: %v", err)
} }
if *delayShutdown > 0 {
termCh := make(chan os.Signal)
signal.Notify(termCh, syscall.SIGTERM)
go func() {
<-termCh
log.Printf("Sleeping %d seconds before exit ...", *delayShutdown)
time.Sleep(time.Duration(*delayShutdown) * time.Second)
os.Exit(0)
}()
}
state := State{ state := State{
Hostname: hostname, Hostname: hostname,
StillContactingPeers: true, StillContactingPeers: true,
......
...@@ -23,7 +23,7 @@ readonly red=$(tput setaf 1) ...@@ -23,7 +23,7 @@ readonly red=$(tput setaf 1)
readonly green=$(tput setaf 2) readonly green=$(tput setaf 2)
kube::test::clear_all() { kube::test::clear_all() {
kubectl delete "${kube_flags[@]}" rc,pods --all --grace-period=0 kubectl delete "${kube_flags[@]}" rc,pods --all
} }
kube::test::get_object_assert() { kube::test::get_object_assert() {
......
...@@ -179,11 +179,6 @@ for version in "${kube_api_versions[@]}"; do ...@@ -179,11 +179,6 @@ for version in "${kube_api_versions[@]}"; do
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
# Command # Command
kubectl delete pod valid-pod "${kube_flags[@]}" kubectl delete pod valid-pod "${kube_flags[@]}"
# Post-condition: pod is still there, in terminating
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
[[ "$(kubectl get pods "${kube_flags[@]}" | grep Terminating)" ]]
# Command
kubectl delete pod valid-pod "${kube_flags[@]}" --grace-period=0
# Post-condition: no POD is running # Post-condition: no POD is running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" '' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" ''
...@@ -199,7 +194,7 @@ for version in "${kube_api_versions[@]}"; do ...@@ -199,7 +194,7 @@ for version in "${kube_api_versions[@]}"; do
# Pre-condition: valid-pod POD is running # Pre-condition: valid-pod POD is running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
# Command # Command
kubectl delete -f examples/limitrange/valid-pod.json "${kube_flags[@]}" --grace-period=0 kubectl delete -f examples/limitrange/valid-pod.json "${kube_flags[@]}"
# Post-condition: no POD is running # Post-condition: no POD is running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" '' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" ''
...@@ -215,7 +210,7 @@ for version in "${kube_api_versions[@]}"; do ...@@ -215,7 +210,7 @@ for version in "${kube_api_versions[@]}"; do
# Pre-condition: valid-pod POD is running # Pre-condition: valid-pod POD is running
kube::test::get_object_assert "pods -l'name in (valid-pod)'" '{{range.items}}{{$id_field}}:{{end}}' 'valid-pod:' kube::test::get_object_assert "pods -l'name in (valid-pod)'" '{{range.items}}{{$id_field}}:{{end}}' 'valid-pod:'
# Command # Command
kubectl delete pods -l'name in (valid-pod)' "${kube_flags[@]}" --grace-period=0 kubectl delete pods -l'name in (valid-pod)' "${kube_flags[@]}"
# Post-condition: no POD is running # Post-condition: no POD is running
kube::test::get_object_assert "pods -l'name in (valid-pod)'" '{{range.items}}{{$id_field}}:{{end}}' '' kube::test::get_object_assert "pods -l'name in (valid-pod)'" '{{range.items}}{{$id_field}}:{{end}}' ''
...@@ -247,7 +242,7 @@ for version in "${kube_api_versions[@]}"; do ...@@ -247,7 +242,7 @@ for version in "${kube_api_versions[@]}"; do
# Pre-condition: valid-pod POD is running # Pre-condition: valid-pod POD is running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
# Command # Command
kubectl delete --all pods "${kube_flags[@]}" --grace-period=0 # --all remove all the pods kubectl delete --all pods "${kube_flags[@]}" # --all remove all the pods
# Post-condition: no POD is running # Post-condition: no POD is running
kube::test::get_object_assert "pods -l'name in (valid-pod)'" '{{range.items}}{{$id_field}}:{{end}}' '' kube::test::get_object_assert "pods -l'name in (valid-pod)'" '{{range.items}}{{$id_field}}:{{end}}' ''
...@@ -264,7 +259,7 @@ for version in "${kube_api_versions[@]}"; do ...@@ -264,7 +259,7 @@ for version in "${kube_api_versions[@]}"; do
# Pre-condition: valid-pod and redis-proxy PODs are running # Pre-condition: valid-pod and redis-proxy PODs are running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'redis-proxy:valid-pod:' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'redis-proxy:valid-pod:'
# Command # Command
kubectl delete pods valid-pod redis-proxy "${kube_flags[@]}" --grace-period=0 # delete multiple pods at once kubectl delete pods valid-pod redis-proxy "${kube_flags[@]}" # delete multiple pods at once
# Post-condition: no POD is running # Post-condition: no POD is running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" '' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" ''
...@@ -281,7 +276,7 @@ for version in "${kube_api_versions[@]}"; do ...@@ -281,7 +276,7 @@ for version in "${kube_api_versions[@]}"; do
# Pre-condition: valid-pod and redis-proxy PODs are running # Pre-condition: valid-pod and redis-proxy PODs are running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'redis-proxy:valid-pod:' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'redis-proxy:valid-pod:'
# Command # Command
kubectl stop pods valid-pod redis-proxy "${kube_flags[@]}" --grace-period=0 # stop multiple pods at once kubectl stop pods valid-pod redis-proxy "${kube_flags[@]}" # stop multiple pods at once
# Post-condition: no POD is running # Post-condition: no POD is running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" '' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" ''
...@@ -305,7 +300,7 @@ for version in "${kube_api_versions[@]}"; do ...@@ -305,7 +300,7 @@ for version in "${kube_api_versions[@]}"; do
# Pre-condition: valid-pod POD is running # Pre-condition: valid-pod POD is running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
# Command # Command
kubectl delete pods -lnew-name=new-valid-pod --grace-period=0 "${kube_flags[@]}" kubectl delete pods -lnew-name=new-valid-pod "${kube_flags[@]}"
# Post-condition: no POD is running # Post-condition: no POD is running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" '' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" ''
...@@ -337,7 +332,7 @@ for version in "${kube_api_versions[@]}"; do ...@@ -337,7 +332,7 @@ for version in "${kube_api_versions[@]}"; do
# Pre-condition: valid-pod POD is running # Pre-condition: valid-pod POD is running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
# Command # Command
kubectl delete pods -l'name in (valid-pod-super-sayan)' --grace-period=0 "${kube_flags[@]}" kubectl delete pods -l'name in (valid-pod-super-sayan)' "${kube_flags[@]}"
# Post-condition: no POD is running # Post-condition: no POD is running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" '' kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" ''
...@@ -358,7 +353,7 @@ for version in "${kube_api_versions[@]}"; do ...@@ -358,7 +353,7 @@ for version in "${kube_api_versions[@]}"; do
# Pre-condition: valid-pod POD is running # Pre-condition: valid-pod POD is running
kube::test::get_object_assert 'pods --namespace=other' "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:' kube::test::get_object_assert 'pods --namespace=other' "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
# Command # Command
kubectl delete "${kube_flags[@]}" pod --namespace=other valid-pod --grace-period=0 kubectl delete "${kube_flags[@]}" pod --namespace=other valid-pod
# Post-condition: no POD is running # Post-condition: no POD is running
kube::test::get_object_assert 'pods --namespace=other' "{{range.items}}{{$id_field}}:{{end}}" '' kube::test::get_object_assert 'pods --namespace=other' "{{range.items}}{{$id_field}}:{{end}}" ''
......
...@@ -1002,12 +1002,6 @@ func deepCopy_api_ObjectMeta(in ObjectMeta, out *ObjectMeta, c *conversion.Clone ...@@ -1002,12 +1002,6 @@ func deepCopy_api_ObjectMeta(in ObjectMeta, out *ObjectMeta, c *conversion.Clone
} else { } else {
out.DeletionTimestamp = nil out.DeletionTimestamp = nil
} }
if in.DeletionGracePeriodSeconds != nil {
out.DeletionGracePeriodSeconds = new(int64)
*out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds
} else {
out.DeletionGracePeriodSeconds = nil
}
if in.Labels != nil { if in.Labels != nil {
out.Labels = make(map[string]string) out.Labels = make(map[string]string)
for key, val := range in.Labels { for key, val := range in.Labels {
......
...@@ -59,8 +59,6 @@ func BeforeCreate(strategy RESTCreateStrategy, ctx api.Context, obj runtime.Obje ...@@ -59,8 +59,6 @@ func BeforeCreate(strategy RESTCreateStrategy, ctx api.Context, obj runtime.Obje
} else { } else {
objectMeta.Namespace = api.NamespaceNone objectMeta.Namespace = api.NamespaceNone
} }
objectMeta.DeletionTimestamp = nil
objectMeta.DeletionGracePeriodSeconds = nil
strategy.PrepareForCreate(obj) strategy.PrepareForCreate(obj)
api.FillObjectMetaSystemFields(ctx, objectMeta) api.FillObjectMetaSystemFields(ctx, objectMeta)
api.GenerateName(strategy, objectMeta) api.GenerateName(strategy, objectMeta)
......
...@@ -40,37 +40,12 @@ func BeforeDelete(strategy RESTDeleteStrategy, ctx api.Context, obj runtime.Obje ...@@ -40,37 +40,12 @@ func BeforeDelete(strategy RESTDeleteStrategy, ctx api.Context, obj runtime.Obje
if strategy == nil { if strategy == nil {
return false, false, nil return false, false, nil
} }
objectMeta, _, kerr := objectMetaAndKind(strategy, obj) _, _, kerr := objectMetaAndKind(strategy, obj)
if kerr != nil { if kerr != nil {
return false, false, kerr return false, false, kerr
} }
// if the object is already being deleted
if objectMeta.DeletionTimestamp != nil {
// if we are already being deleted, we may only shorten the deletion grace period
// this means the object was gracefully deleted previously but deletionGracePeriodSeconds was not set,
// so we force deletion immediately
if objectMeta.DeletionGracePeriodSeconds == nil {
return false, false, nil
}
// only a shorter grace period may be provided by a user
if options.GracePeriodSeconds != nil {
period := int64(*options.GracePeriodSeconds)
if period > *objectMeta.DeletionGracePeriodSeconds {
return false, true, nil
}
objectMeta.DeletionGracePeriodSeconds = &period
options.GracePeriodSeconds = &period
return true, false, nil
}
// graceful deletion is pending, do nothing
options.GracePeriodSeconds = objectMeta.DeletionGracePeriodSeconds
return false, true, nil
}
if !strategy.CheckGracefulDelete(obj, options) { if !strategy.CheckGracefulDelete(obj, options) {
return false, false, nil return false, false, nil
} }
objectMeta.DeletionGracePeriodSeconds = options.GracePeriodSeconds
return true, false, nil return true, false, nil
} }
...@@ -329,9 +329,7 @@ func (t *Tester) TestDeleteNonExist(createFn func() runtime.Object) { ...@@ -329,9 +329,7 @@ func (t *Tester) TestDeleteNonExist(createFn func() runtime.Object) {
func (t *Tester) TestDeleteGraceful(createFn func() runtime.Object, expectedGrace int64, wasGracefulFn func() bool) { func (t *Tester) TestDeleteGraceful(createFn func() runtime.Object, expectedGrace int64, wasGracefulFn func() bool) {
t.TestDeleteGracefulHasDefault(createFn(), expectedGrace, wasGracefulFn) t.TestDeleteGracefulHasDefault(createFn(), expectedGrace, wasGracefulFn)
t.TestDeleteGracefulWithValue(createFn(), expectedGrace, wasGracefulFn)
t.TestDeleteGracefulUsesZeroOnNil(createFn(), 0) t.TestDeleteGracefulUsesZeroOnNil(createFn(), 0)
t.TestDeleteGracefulExtend(createFn(), expectedGrace, wasGracefulFn)
} }
func (t *Tester) TestDeleteNoGraceful(createFn func() runtime.Object, wasGracefulFn func() bool) { func (t *Tester) TestDeleteNoGraceful(createFn func() runtime.Object, wasGracefulFn func() bool) {
...@@ -364,99 +362,12 @@ func (t *Tester) TestDeleteGracefulHasDefault(existing runtime.Object, expectedG ...@@ -364,99 +362,12 @@ func (t *Tester) TestDeleteGracefulHasDefault(existing runtime.Object, expectedG
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if !wasGracefulFn() { if _, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name); err != nil {
t.Errorf("did not gracefully delete resource")
return
}
object, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name)
if err != nil {
t.Errorf("unexpected error, object should exist: %v", err) t.Errorf("unexpected error, object should exist: %v", err)
return
}
objectMeta, err = api.ObjectMetaFor(object)
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, object)
}
if objectMeta.DeletionTimestamp == nil {
t.Errorf("did not set deletion timestamp")
}
if objectMeta.DeletionGracePeriodSeconds == nil {
t.Fatalf("did not set deletion grace period seconds")
}
if *objectMeta.DeletionGracePeriodSeconds != expectedGrace {
t.Errorf("actual grace period does not match expected: %d", *objectMeta.DeletionGracePeriodSeconds)
}
}
func (t *Tester) TestDeleteGracefulWithValue(existing runtime.Object, expectedGrace int64, wasGracefulFn func() bool) {
objectMeta, err := api.ObjectMetaFor(existing)
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing)
}
ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace)
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(expectedGrace+2))
if err != nil {
t.Errorf("unexpected error: %v", err)
} }
if !wasGracefulFn() { if !wasGracefulFn() {
t.Errorf("did not gracefully delete resource") t.Errorf("did not gracefully delete resource")
} }
object, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name)
if err != nil {
t.Errorf("unexpected error, object should exist: %v", err)
}
objectMeta, err = api.ObjectMetaFor(object)
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, object)
}
if objectMeta.DeletionTimestamp == nil {
t.Errorf("did not set deletion timestamp")
}
if objectMeta.DeletionGracePeriodSeconds == nil {
t.Fatalf("did not set deletion grace period seconds")
}
if *objectMeta.DeletionGracePeriodSeconds != expectedGrace+2 {
t.Errorf("actual grace period does not match expected: %d", *objectMeta.DeletionGracePeriodSeconds)
}
}
func (t *Tester) TestDeleteGracefulExtend(existing runtime.Object, expectedGrace int64, wasGracefulFn func() bool) {
objectMeta, err := api.ObjectMetaFor(existing)
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing)
}
ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace)
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(expectedGrace))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if !wasGracefulFn() {
t.Errorf("did not gracefully delete resource")
}
// second delete duration is ignored
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(expectedGrace+2))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
object, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name)
if err != nil {
t.Errorf("unexpected error, object should exist: %v", err)
}
objectMeta, err = api.ObjectMetaFor(object)
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, object)
}
if objectMeta.DeletionTimestamp == nil {
t.Errorf("did not set deletion timestamp")
}
if objectMeta.DeletionGracePeriodSeconds == nil {
t.Fatalf("did not set deletion grace period seconds")
}
if *objectMeta.DeletionGracePeriodSeconds != expectedGrace {
t.Errorf("actual grace period does not match expected: %d", *objectMeta.DeletionGracePeriodSeconds)
}
} }
func (t *Tester) TestDeleteGracefulUsesZeroOnNil(existing runtime.Object, expectedGrace int64) { func (t *Tester) TestDeleteGracefulUsesZeroOnNil(existing runtime.Object, expectedGrace int64) {
...@@ -471,6 +382,6 @@ func (t *Tester) TestDeleteGracefulUsesZeroOnNil(existing runtime.Object, expect ...@@ -471,6 +382,6 @@ func (t *Tester) TestDeleteGracefulUsesZeroOnNil(existing runtime.Object, expect
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if _, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name); !errors.IsNotFound(err) { if _, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name); !errors.IsNotFound(err) {
t.Errorf("unexpected error, object should not exist: %v", err) t.Errorf("unexpected error, object should exist: %v", err)
} }
} }
...@@ -155,7 +155,6 @@ func TestRoundTripTypes(t *testing.T) { ...@@ -155,7 +155,6 @@ func TestRoundTripTypes(t *testing.T) {
} }
func TestEncode_Ptr(t *testing.T) { func TestEncode_Ptr(t *testing.T) {
grace := int64(30)
pod := &api.Pod{ pod := &api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Labels: map[string]string{"name": "foo"}, Labels: map[string]string{"name": "foo"},
...@@ -163,8 +162,6 @@ func TestEncode_Ptr(t *testing.T) { ...@@ -163,8 +162,6 @@ func TestEncode_Ptr(t *testing.T) {
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
} }
obj := runtime.Object(pod) obj := runtime.Object(pod)
......
...@@ -88,15 +88,6 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { ...@@ -88,15 +88,6 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
j.LabelSelector, _ = labels.Parse("a=b") j.LabelSelector, _ = labels.Parse("a=b")
j.FieldSelector, _ = fields.ParseSelector("a=b") j.FieldSelector, _ = fields.ParseSelector("a=b")
}, },
func(j *api.PodSpec, c fuzz.Continue) {
c.FuzzNoCustom(j)
// has a default value
ttl := int64(30)
if c.RandBool() {
ttl = int64(c.Uint32())
}
j.TerminationGracePeriodSeconds = &ttl
},
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}
*j = statuses[c.Rand.Intn(len(statuses))] *j = statuses[c.Rand.Intn(len(statuses))]
......
...@@ -133,10 +133,6 @@ type ObjectMeta struct { ...@@ -133,10 +133,6 @@ type ObjectMeta struct {
// will send a hard termination signal to the container. // will send a hard termination signal to the container.
DeletionTimestamp *util.Time `json:"deletionTimestamp,omitempty"` DeletionTimestamp *util.Time `json:"deletionTimestamp,omitempty"`
// DeletionGracePeriodSeconds records the graceful deletion value set when graceful deletion
// was requested. Represents the most recent grace period, and may only be shortened once set.
DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty"`
// Labels are key value pairs that may be used to scope and select individual resources. // Labels are key value pairs that may be used to scope and select individual resources.
// Label keys are of the form: // Label keys are of the form:
// label-key ::= prefixed-name | name // label-key ::= prefixed-name | name
......
...@@ -1087,12 +1087,6 @@ func convert_api_ObjectMeta_To_v1_ObjectMeta(in *api.ObjectMeta, out *ObjectMeta ...@@ -1087,12 +1087,6 @@ func convert_api_ObjectMeta_To_v1_ObjectMeta(in *api.ObjectMeta, out *ObjectMeta
} else { } else {
out.DeletionTimestamp = nil out.DeletionTimestamp = nil
} }
if in.DeletionGracePeriodSeconds != nil {
out.DeletionGracePeriodSeconds = new(int64)
*out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds
} else {
out.DeletionGracePeriodSeconds = nil
}
if in.Labels != nil { if in.Labels != nil {
out.Labels = make(map[string]string) out.Labels = make(map[string]string)
for key, val := range in.Labels { for key, val := range in.Labels {
...@@ -3368,12 +3362,6 @@ func convert_v1_ObjectMeta_To_api_ObjectMeta(in *ObjectMeta, out *api.ObjectMeta ...@@ -3368,12 +3362,6 @@ func convert_v1_ObjectMeta_To_api_ObjectMeta(in *ObjectMeta, out *api.ObjectMeta
} else { } else {
out.DeletionTimestamp = nil out.DeletionTimestamp = nil
} }
if in.DeletionGracePeriodSeconds != nil {
out.DeletionGracePeriodSeconds = new(int64)
*out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds
} else {
out.DeletionGracePeriodSeconds = nil
}
if in.Labels != nil { if in.Labels != nil {
out.Labels = make(map[string]string) out.Labels = make(map[string]string)
for key, val := range in.Labels { for key, val := range in.Labels {
......
...@@ -933,12 +933,6 @@ func deepCopy_v1_ObjectMeta(in ObjectMeta, out *ObjectMeta, c *conversion.Cloner ...@@ -933,12 +933,6 @@ func deepCopy_v1_ObjectMeta(in ObjectMeta, out *ObjectMeta, c *conversion.Cloner
} else { } else {
out.DeletionTimestamp = nil out.DeletionTimestamp = nil
} }
if in.DeletionGracePeriodSeconds != nil {
out.DeletionGracePeriodSeconds = new(int64)
*out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds
} else {
out.DeletionGracePeriodSeconds = nil
}
if in.Labels != nil { if in.Labels != nil {
out.Labels = make(map[string]string) out.Labels = make(map[string]string)
for key, val := range in.Labels { for key, val := range in.Labels {
......
...@@ -98,10 +98,6 @@ func addDefaultingFuncs() { ...@@ -98,10 +98,6 @@ func addDefaultingFuncs() {
if obj.HostNetwork { if obj.HostNetwork {
defaultHostNetworkPorts(&obj.Containers) defaultHostNetworkPorts(&obj.Containers)
} }
if obj.TerminationGracePeriodSeconds == nil {
period := int64(DefaultTerminationGracePeriodSeconds)
obj.TerminationGracePeriodSeconds = &period
}
}, },
func(obj *Probe) { func(obj *Probe) {
if obj.TimeoutSeconds == 0 { if obj.TimeoutSeconds == 0 {
......
...@@ -131,10 +131,6 @@ type ObjectMeta struct { ...@@ -131,10 +131,6 @@ type ObjectMeta struct {
// will send a hard termination signal to the container. // will send a hard termination signal to the container.
DeletionTimestamp *util.Time `json:"deletionTimestamp,omitempty" description:"RFC 3339 date and time at which the object will be deleted; populated by the system when a graceful deletion is requested, read-only; if not set, graceful deletion of the object has not been requested"` DeletionTimestamp *util.Time `json:"deletionTimestamp,omitempty" description:"RFC 3339 date and time at which the object will be deleted; populated by the system when a graceful deletion is requested, read-only; if not set, graceful deletion of the object has not been requested"`
// DeletionGracePeriodSeconds records the graceful deletion value set when graceful deletion
// was requested. Represents the most recent grace period, and may only be shortened once set.
DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty" description:"number of seconds allowed for this object to gracefully terminate before it will be removed from the system; only set when deletionTimestamp is also set, read-only; may only be shortened"`
// Labels are key value pairs that may be used to scope and select individual resources. // Labels are key value pairs that may be used to scope and select individual resources.
// TODO: replace map[string]string with labels.LabelSet type // TODO: replace map[string]string with labels.LabelSet type
Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize objects; may match selectors of replication controllers and services"` Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize objects; may match selectors of replication controllers and services"`
...@@ -842,8 +838,6 @@ const ( ...@@ -842,8 +838,6 @@ const (
// DNSDefault indicates that the pod should use the default (as // DNSDefault indicates that the pod should use the default (as
// determined by kubelet) DNS settings. // determined by kubelet) DNS settings.
DNSDefault DNSPolicy = "Default" DNSDefault DNSPolicy = "Default"
DefaultTerminationGracePeriodSeconds = 30
) )
// PodSpec is a description of a pod // PodSpec is a description of a pod
...@@ -858,7 +852,7 @@ type PodSpec struct { ...@@ -858,7 +852,7 @@ type PodSpec struct {
// The grace period is the duration in seconds after the processes running in the pod are sent // The grace period is the duration in seconds after the processes running in the pod are sent
// a termination signal and the time when the processes are forcibly halted with a kill signal. // a termination signal and the time when the processes are forcibly halted with a kill signal.
// Set this value longer than the expected cleanup time for your process. // Set this value longer than the expected cleanup time for your process.
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" description:"optional duration in seconds the pod needs to terminate gracefully; may be decreased in delete request; value must be non-negative integer; the value zero indicates delete immediately; if this value is not set, the default grace period will be used instead; the grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal; set this value longer than the expected cleanup time for your process; defaults to 30 seconds"` TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" description:"optional duration in seconds the pod needs to terminate gracefully; may be decreased in delete request; value must be non-negative integer; the value zero indicates delete immediately; if this value is not set, the default grace period will be used instead; the grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal; set this value longer than the expected cleanup time for your process"`
ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" description:"optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers; value must be a positive integer` ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" description:"optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers; value must be a positive integer`
// Optional: Set DNS policy. Defaults to "ClusterFirst" // Optional: Set DNS policy. Defaults to "ClusterFirst"
DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty" description:"DNS policy for containers within the pod; one of 'ClusterFirst' or 'Default'"` DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty" description:"DNS policy for containers within the pod; one of 'ClusterFirst' or 'Default'"`
......
...@@ -945,12 +945,6 @@ func convert_api_ObjectMeta_To_v1beta3_ObjectMeta(in *api.ObjectMeta, out *Objec ...@@ -945,12 +945,6 @@ func convert_api_ObjectMeta_To_v1beta3_ObjectMeta(in *api.ObjectMeta, out *Objec
} else { } else {
out.DeletionTimestamp = nil out.DeletionTimestamp = nil
} }
if in.DeletionGracePeriodSeconds != nil {
out.DeletionGracePeriodSeconds = new(int64)
*out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds
} else {
out.DeletionGracePeriodSeconds = nil
}
if in.Labels != nil { if in.Labels != nil {
out.Labels = make(map[string]string) out.Labels = make(map[string]string)
for key, val := range in.Labels { for key, val := range in.Labels {
...@@ -3040,12 +3034,6 @@ func convert_v1beta3_ObjectMeta_To_api_ObjectMeta(in *ObjectMeta, out *api.Objec ...@@ -3040,12 +3034,6 @@ func convert_v1beta3_ObjectMeta_To_api_ObjectMeta(in *ObjectMeta, out *api.Objec
} else { } else {
out.DeletionTimestamp = nil out.DeletionTimestamp = nil
} }
if in.DeletionGracePeriodSeconds != nil {
out.DeletionGracePeriodSeconds = new(int64)
*out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds
} else {
out.DeletionGracePeriodSeconds = nil
}
if in.Labels != nil { if in.Labels != nil {
out.Labels = make(map[string]string) out.Labels = make(map[string]string)
for key, val := range in.Labels { for key, val := range in.Labels {
......
...@@ -937,12 +937,6 @@ func deepCopy_v1beta3_ObjectMeta(in ObjectMeta, out *ObjectMeta, c *conversion.C ...@@ -937,12 +937,6 @@ func deepCopy_v1beta3_ObjectMeta(in ObjectMeta, out *ObjectMeta, c *conversion.C
} else { } else {
out.DeletionTimestamp = nil out.DeletionTimestamp = nil
} }
if in.DeletionGracePeriodSeconds != nil {
out.DeletionGracePeriodSeconds = new(int64)
*out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds
} else {
out.DeletionGracePeriodSeconds = nil
}
if in.Labels != nil { if in.Labels != nil {
out.Labels = make(map[string]string) out.Labels = make(map[string]string)
for key, val := range in.Labels { for key, val := range in.Labels {
......
...@@ -102,10 +102,6 @@ func addDefaultingFuncs() { ...@@ -102,10 +102,6 @@ func addDefaultingFuncs() {
if obj.HostNetwork { if obj.HostNetwork {
defaultHostNetworkPorts(&obj.Containers) defaultHostNetworkPorts(&obj.Containers)
} }
if obj.TerminationGracePeriodSeconds == nil {
period := int64(DefaultTerminationGracePeriodSeconds)
obj.TerminationGracePeriodSeconds = &period
}
}, },
func(obj *Probe) { func(obj *Probe) {
if obj.TimeoutSeconds == 0 { if obj.TimeoutSeconds == 0 {
......
...@@ -131,10 +131,6 @@ type ObjectMeta struct { ...@@ -131,10 +131,6 @@ type ObjectMeta struct {
// will send a hard termination signal to the container. // will send a hard termination signal to the container.
DeletionTimestamp *util.Time `json:"deletionTimestamp,omitempty" description:"RFC 3339 date and time at which the object will be deleted; populated by the system when a graceful deletion is requested, read-only; if not set, graceful deletion of the object has not been requested"` DeletionTimestamp *util.Time `json:"deletionTimestamp,omitempty" description:"RFC 3339 date and time at which the object will be deleted; populated by the system when a graceful deletion is requested, read-only; if not set, graceful deletion of the object has not been requested"`
// DeletionGracePeriodSeconds records the graceful deletion value set when graceful deletion
// was requested. Represents the most recent grace period, and may only be shortened once set.
DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty" description:"number of seconds allowed for this object to gracefully terminate before it will be removed from the system; only set when deletionTimestamp is also set, read-only; may only be shortened"`
// Labels are key value pairs that may be used to scope and select individual resources. // Labels are key value pairs that may be used to scope and select individual resources.
// TODO: replace map[string]string with labels.LabelSet type // TODO: replace map[string]string with labels.LabelSet type
Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize objects; may match selectors of replication controllers and services"` Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize objects; may match selectors of replication controllers and services"`
...@@ -846,8 +842,6 @@ const ( ...@@ -846,8 +842,6 @@ const (
// DNSDefault indicates that the pod should use the default (as // DNSDefault indicates that the pod should use the default (as
// determined by kubelet) DNS settings. // determined by kubelet) DNS settings.
DNSDefault DNSPolicy = "Default" DNSDefault DNSPolicy = "Default"
DefaultTerminationGracePeriodSeconds = 30
) )
// PodSpec is a description of a pod // PodSpec is a description of a pod
...@@ -862,7 +856,7 @@ type PodSpec struct { ...@@ -862,7 +856,7 @@ type PodSpec struct {
// The grace period is the duration in seconds after the processes running in the pod are sent // The grace period is the duration in seconds after the processes running in the pod are sent
// a termination signal and the time when the processes are forcibly halted with a kill signal. // a termination signal and the time when the processes are forcibly halted with a kill signal.
// Set this value longer than the expected cleanup time for your process. // Set this value longer than the expected cleanup time for your process.
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" description:"optional duration in seconds the pod needs to terminate gracefully; may be decreased in delete request; value must be non-negative integer; the value zero indicates delete immediately; if this value is not set, the default grace period will be used instead; the grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal; set this value longer than the expected cleanup time for your process; defaults to 30 seconds"` TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" description:"optional duration in seconds the pod needs to terminate gracefully; may be decreased in delete request; value must be non-negative integer; the value zero indicates delete immediately; if this value is not set, the default grace period will be used instead; the grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal; set this value longer than the expected cleanup time for your process"`
ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" description:"optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers; value must be a positive integer` ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" description:"optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers; value must be a positive integer`
// Optional: Set DNS policy. Defaults to "ClusterFirst" // Optional: Set DNS policy. Defaults to "ClusterFirst"
DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty" description:"DNS policy for containers within the pod; one of 'ClusterFirst' or 'Default'"` DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty" description:"DNS policy for containers within the pod; one of 'ClusterFirst' or 'Default'"`
......
...@@ -252,16 +252,6 @@ func ValidateObjectMetaUpdate(old, meta *api.ObjectMeta) errs.ValidationErrorLis ...@@ -252,16 +252,6 @@ func ValidateObjectMetaUpdate(old, meta *api.ObjectMeta) errs.ValidationErrorLis
} else { } else {
meta.CreationTimestamp = old.CreationTimestamp meta.CreationTimestamp = old.CreationTimestamp
} }
// an object can never remove a deletion timestamp or clear/change grace period seconds
if !old.DeletionTimestamp.IsZero() {
meta.DeletionTimestamp = old.DeletionTimestamp
}
if old.DeletionGracePeriodSeconds != nil && meta.DeletionGracePeriodSeconds == nil {
meta.DeletionGracePeriodSeconds = old.DeletionGracePeriodSeconds
}
if meta.DeletionGracePeriodSeconds != nil && *meta.DeletionGracePeriodSeconds != *old.DeletionGracePeriodSeconds {
allErrs = append(allErrs, errs.NewFieldInvalid("deletionGracePeriodSeconds", meta.DeletionGracePeriodSeconds, "field is immutable; may only be changed via deletion"))
}
// Reject updates that don't specify a resource version // Reject updates that don't specify a resource version
if meta.ResourceVersion == "" { if meta.ResourceVersion == "" {
......
...@@ -294,8 +294,7 @@ func filterActivePods(pods []api.Pod) []*api.Pod { ...@@ -294,8 +294,7 @@ func filterActivePods(pods []api.Pod) []*api.Pod {
var result []*api.Pod var result []*api.Pod
for i := range pods { for i := range pods {
if api.PodSucceeded != pods[i].Status.Phase && if api.PodSucceeded != pods[i].Status.Phase &&
api.PodFailed != pods[i].Status.Phase && api.PodFailed != pods[i].Status.Phase {
pods[i].DeletionTimestamp == nil {
result = append(result, &pods[i]) result = append(result, &pods[i])
} }
} }
......
...@@ -204,12 +204,6 @@ func (rm *ReplicationManager) getPodControllers(pod *api.Pod) *api.ReplicationCo ...@@ -204,12 +204,6 @@ func (rm *ReplicationManager) getPodControllers(pod *api.Pod) *api.ReplicationCo
// When a pod is created, enqueue the controller that manages it and update it's expectations. // When a pod is created, enqueue the controller that manages it and update it's expectations.
func (rm *ReplicationManager) addPod(obj interface{}) { func (rm *ReplicationManager) addPod(obj interface{}) {
pod := obj.(*api.Pod) pod := obj.(*api.Pod)
if pod.DeletionTimestamp != nil {
// on a restart of the controller manager, it's possible a new pod shows up in a state that
// is already pending deletion. Prevent the pod from being a creation observation.
rm.deletePod(pod)
return
}
if rc := rm.getPodControllers(pod); rc != nil { if rc := rm.getPodControllers(pod); rc != nil {
rm.expectations.CreationObserved(rc) rm.expectations.CreationObserved(rc)
rm.enqueueController(rc) rm.enqueueController(rc)
...@@ -226,15 +220,6 @@ func (rm *ReplicationManager) updatePod(old, cur interface{}) { ...@@ -226,15 +220,6 @@ func (rm *ReplicationManager) updatePod(old, cur interface{}) {
} }
// TODO: Write a unittest for this case // TODO: Write a unittest for this case
curPod := cur.(*api.Pod) curPod := cur.(*api.Pod)
if curPod.DeletionTimestamp != nil {
// when a pod is deleted gracefully it's deletion timestamp is first modified to reflect a grace period,
// and after such time has passed, the kubelet actually deletes it from the store. We receive an update
// for modification of the deletion timestamp and expect an rc to create more replicas asap, not wait
// until the kubelet actually deletes the pod. This is different from the Phase of a pod changing, because
// an rc never initiates a phase change, and so is never asleep waiting for the same.
rm.deletePod(curPod)
return
}
if rc := rm.getPodControllers(curPod); rc != nil { if rc := rm.getPodControllers(curPod); rc != nil {
rm.enqueueController(rc) rm.enqueueController(rc)
} }
......
...@@ -38,7 +38,6 @@ import ( ...@@ -38,7 +38,6 @@ import (
) )
func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList) { func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList) {
grace := int64(30)
pods := &api.PodList{ pods := &api.PodList{
ListMeta: api.ListMeta{ ListMeta: api.ListMeta{
ResourceVersion: "15", ResourceVersion: "15",
...@@ -47,17 +46,15 @@ func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList) ...@@ -47,17 +46,15 @@ func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList)
{ {
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"}, ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"}, ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
}, },
...@@ -506,7 +503,6 @@ func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) { ...@@ -506,7 +503,6 @@ func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) {
} }
} }
func watchTestData() ([]api.Pod, []watch.Event) { func watchTestData() ([]api.Pod, []watch.Event) {
grace := int64(30)
pods := []api.Pod{ pods := []api.Pod{
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
...@@ -515,9 +511,8 @@ func watchTestData() ([]api.Pod, []watch.Event) { ...@@ -515,9 +511,8 @@ func watchTestData() ([]api.Pod, []watch.Event) {
ResourceVersion: "10", ResourceVersion: "10",
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
} }
...@@ -531,9 +526,8 @@ func watchTestData() ([]api.Pod, []watch.Event) { ...@@ -531,9 +526,8 @@ func watchTestData() ([]api.Pod, []watch.Event) {
ResourceVersion: "11", ResourceVersion: "11",
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
}, },
...@@ -546,9 +540,8 @@ func watchTestData() ([]api.Pod, []watch.Event) { ...@@ -546,9 +540,8 @@ func watchTestData() ([]api.Pod, []watch.Event) {
ResourceVersion: "12", ResourceVersion: "12",
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
}, },
......
...@@ -29,7 +29,6 @@ import ( ...@@ -29,7 +29,6 @@ import (
) )
func TestMerge(t *testing.T) { func TestMerge(t *testing.T) {
grace := int64(30)
tests := []struct { tests := []struct {
obj runtime.Object obj runtime.Object
fragment string fragment string
...@@ -50,9 +49,8 @@ func TestMerge(t *testing.T) { ...@@ -50,9 +49,8 @@ func TestMerge(t *testing.T) {
Name: "foo", Name: "foo",
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
}, },
...@@ -119,9 +117,8 @@ func TestMerge(t *testing.T) { ...@@ -119,9 +117,8 @@ func TestMerge(t *testing.T) {
VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}, VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}},
}, },
}, },
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
}, },
......
...@@ -271,12 +271,7 @@ func describePod(pod *api.Pod, rcs []api.ReplicationController, events *api.Even ...@@ -271,12 +271,7 @@ func describePod(pod *api.Pod, rcs []api.ReplicationController, events *api.Even
fmt.Fprintf(out, "Image(s):\t%s\n", makeImageList(&pod.Spec)) fmt.Fprintf(out, "Image(s):\t%s\n", makeImageList(&pod.Spec))
fmt.Fprintf(out, "Node:\t%s\n", pod.Spec.NodeName+"/"+pod.Status.HostIP) fmt.Fprintf(out, "Node:\t%s\n", pod.Spec.NodeName+"/"+pod.Status.HostIP)
fmt.Fprintf(out, "Labels:\t%s\n", formatLabels(pod.Labels)) fmt.Fprintf(out, "Labels:\t%s\n", formatLabels(pod.Labels))
if pod.DeletionTimestamp != nil { fmt.Fprintf(out, "Status:\t%s\n", string(pod.Status.Phase))
fmt.Fprintf(out, "Status:\tTerminating (expires %s)\n", pod.DeletionTimestamp.Time.Format(time.RFC1123Z))
fmt.Fprintf(out, "Termination Grace Period:\t%ss\n", pod.DeletionGracePeriodSeconds)
} else {
fmt.Fprintf(out, "Status:\t%s\n", string(pod.Status.Phase))
}
fmt.Fprintf(out, "Replication Controllers:\t%s\n", printReplicationControllersByLabels(rcs)) fmt.Fprintf(out, "Replication Controllers:\t%s\n", printReplicationControllersByLabels(rcs))
fmt.Fprintf(out, "Containers:\n") fmt.Fprintf(out, "Containers:\n")
describeContainers(pod.Status.ContainerStatuses, out) describeContainers(pod.Status.ContainerStatuses, out)
......
...@@ -83,7 +83,6 @@ func fakeClientWith(testName string, t *testing.T, data map[string]string) Clien ...@@ -83,7 +83,6 @@ func fakeClientWith(testName string, t *testing.T, data map[string]string) Clien
} }
func testData() (*api.PodList, *api.ServiceList) { func testData() (*api.PodList, *api.ServiceList) {
grace := int64(30)
pods := &api.PodList{ pods := &api.PodList{
ListMeta: api.ListMeta{ ListMeta: api.ListMeta{
ResourceVersion: "15", ResourceVersion: "15",
...@@ -92,17 +91,15 @@ func testData() (*api.PodList, *api.ServiceList) { ...@@ -92,17 +91,15 @@ func testData() (*api.PodList, *api.ServiceList) {
{ {
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"}, ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"}, ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
}, },
......
...@@ -128,7 +128,6 @@ func TestHelperCreate(t *testing.T) { ...@@ -128,7 +128,6 @@ func TestHelperCreate(t *testing.T) {
return true return true
} }
grace := int64(30)
tests := []struct { tests := []struct {
Resp *http.Response Resp *http.Response
RespFunc client.HTTPClientFunc RespFunc client.HTTPClientFunc
...@@ -173,9 +172,8 @@ func TestHelperCreate(t *testing.T) { ...@@ -173,9 +172,8 @@ func TestHelperCreate(t *testing.T) {
ExpectObject: &api.Pod{ ExpectObject: &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
Resp: &http.Response{StatusCode: http.StatusOK, Body: objBody(&api.Status{Status: api.StatusSuccess})}, Resp: &http.Response{StatusCode: http.StatusOK, Body: objBody(&api.Status{Status: api.StatusSuccess})},
...@@ -383,7 +381,6 @@ func TestHelperUpdate(t *testing.T) { ...@@ -383,7 +381,6 @@ func TestHelperUpdate(t *testing.T) {
return true return true
} }
grace := int64(30)
tests := []struct { tests := []struct {
Resp *http.Response Resp *http.Response
RespFunc client.HTTPClientFunc RespFunc client.HTTPClientFunc
...@@ -421,9 +418,8 @@ func TestHelperUpdate(t *testing.T) { ...@@ -421,9 +418,8 @@ func TestHelperUpdate(t *testing.T) {
ExpectObject: &api.Pod{ ExpectObject: &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}, ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
Overwrite: true, Overwrite: true,
......
...@@ -404,17 +404,13 @@ func printPod(pod *api.Pod, w io.Writer, withNamespace bool) error { ...@@ -404,17 +404,13 @@ func printPod(pod *api.Pod, w io.Writer, withNamespace bool) error {
name = pod.Name name = pod.Name
} }
phase := string(pod.Status.Phase)
if pod.DeletionTimestamp != nil {
phase = "Terminating"
}
_, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
name, name,
pod.Status.PodIP, pod.Status.PodIP,
"", "", "", "",
podHostString(pod.Spec.NodeName, pod.Status.HostIP), podHostString(pod.Spec.NodeName, pod.Status.HostIP),
formatLabels(pod.Labels), formatLabels(pod.Labels),
phase, pod.Status.Phase,
translateTimestamp(pod.CreationTimestamp), translateTimestamp(pod.CreationTimestamp),
pod.Status.Message, pod.Status.Message,
) )
......
...@@ -628,7 +628,6 @@ func TestUpdateExistingReplicationController(t *testing.T) { ...@@ -628,7 +628,6 @@ func TestUpdateExistingReplicationController(t *testing.T) {
func TestUpdateWithRetries(t *testing.T) { func TestUpdateWithRetries(t *testing.T) {
codec := testapi.Codec() codec := testapi.Codec()
grace := int64(30)
rc := &api.ReplicationController{ rc := &api.ReplicationController{
ObjectMeta: api.ObjectMeta{Name: "rc", ObjectMeta: api.ObjectMeta{Name: "rc",
Labels: map[string]string{ Labels: map[string]string{
...@@ -646,9 +645,8 @@ func TestUpdateWithRetries(t *testing.T) { ...@@ -646,9 +645,8 @@ func TestUpdateWithRetries(t *testing.T) {
}, },
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
}, },
......
...@@ -30,7 +30,6 @@ import ( ...@@ -30,7 +30,6 @@ import (
func noDefault(*api.Pod) error { return nil } func noDefault(*api.Pod) error { return nil }
func TestDecodeSinglePod(t *testing.T) { func TestDecodeSinglePod(t *testing.T) {
grace := int64(30)
pod := &api.Pod{ pod := &api.Pod{
TypeMeta: api.TypeMeta{ TypeMeta: api.TypeMeta{
APIVersion: "", APIVersion: "",
...@@ -41,9 +40,8 @@ func TestDecodeSinglePod(t *testing.T) { ...@@ -41,9 +40,8 @@ func TestDecodeSinglePod(t *testing.T) {
Namespace: "mynamespace", Namespace: "mynamespace",
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
Containers: []api.Container{{ Containers: []api.Container{{
Name: "image", Name: "image",
Image: "test/image", Image: "test/image",
...@@ -95,7 +93,6 @@ func TestDecodeSinglePod(t *testing.T) { ...@@ -95,7 +93,6 @@ func TestDecodeSinglePod(t *testing.T) {
} }
func TestDecodePodList(t *testing.T) { func TestDecodePodList(t *testing.T) {
grace := int64(30)
pod := &api.Pod{ pod := &api.Pod{
TypeMeta: api.TypeMeta{ TypeMeta: api.TypeMeta{
APIVersion: "", APIVersion: "",
...@@ -106,9 +103,8 @@ func TestDecodePodList(t *testing.T) { ...@@ -106,9 +103,8 @@ func TestDecodePodList(t *testing.T) {
Namespace: "mynamespace", Namespace: "mynamespace",
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
Containers: []api.Container{{ Containers: []api.Container{{
Name: "image", Name: "image",
Image: "test/image", Image: "test/image",
......
...@@ -209,8 +209,9 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de ...@@ -209,8 +209,9 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de
for _, ref := range filtered { for _, ref := range filtered {
name := kubecontainer.GetPodFullName(ref) name := kubecontainer.GetPodFullName(ref)
if existing, found := pods[name]; found { if existing, found := pods[name]; found {
if checkAndUpdatePod(existing, ref) { if !reflect.DeepEqual(existing.Spec, ref.Spec) {
// this is an update // this is an update
existing.Spec = ref.Spec
updates.Pods = append(updates.Pods, existing) updates.Pods = append(updates.Pods, existing)
continue continue
} }
...@@ -251,8 +252,9 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de ...@@ -251,8 +252,9 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de
name := kubecontainer.GetPodFullName(ref) name := kubecontainer.GetPodFullName(ref)
if existing, found := oldPods[name]; found { if existing, found := oldPods[name]; found {
pods[name] = existing pods[name] = existing
if checkAndUpdatePod(existing, ref) { if !reflect.DeepEqual(existing.Spec, ref.Spec) {
// this is an update // this is an update
existing.Spec = ref.Spec
updates.Pods = append(updates.Pods, existing) updates.Pods = append(updates.Pods, existing)
continue continue
} }
...@@ -323,23 +325,6 @@ func filterInvalidPods(pods []*api.Pod, source string, recorder record.EventReco ...@@ -323,23 +325,6 @@ func filterInvalidPods(pods []*api.Pod, source string, recorder record.EventReco
return return
} }
// checkAndUpdatePod updates existing if ref makes a meaningful change and returns true, or
// returns false if there was no update.
func checkAndUpdatePod(existing, ref *api.Pod) bool {
// TODO: it would be better to update the whole object and only preserve certain things
// like the source annotation or the UID (to ensure safety)
if reflect.DeepEqual(existing.Spec, ref.Spec) &&
reflect.DeepEqual(existing.DeletionTimestamp, ref.DeletionTimestamp) &&
reflect.DeepEqual(existing.DeletionGracePeriodSeconds, ref.DeletionGracePeriodSeconds) {
return false
}
// this is an update
existing.Spec = ref.Spec
existing.DeletionTimestamp = ref.DeletionTimestamp
existing.DeletionGracePeriodSeconds = ref.DeletionGracePeriodSeconds
return true
}
// Sync sends a copy of the current state through the update channel. // Sync sends a copy of the current state through the update channel.
func (s *podStorage) Sync() { func (s *podStorage) Sync() {
s.updateLock.Lock() s.updateLock.Lock()
......
...@@ -163,7 +163,6 @@ func TestReadContainerManifestFromFile(t *testing.T) { ...@@ -163,7 +163,6 @@ func TestReadContainerManifestFromFile(t *testing.T) {
func TestReadPodsFromFile(t *testing.T) { func TestReadPodsFromFile(t *testing.T) {
hostname := "random-test-hostname" hostname := "random-test-hostname"
grace := int64(30)
var testCases = []struct { var testCases = []struct {
desc string desc string
pod runtime.Object pod runtime.Object
...@@ -193,10 +192,9 @@ func TestReadPodsFromFile(t *testing.T) { ...@@ -193,10 +192,9 @@ func TestReadPodsFromFile(t *testing.T) {
SelfLink: getSelfLink("test-"+hostname, "mynamespace"), SelfLink: getSelfLink("test-"+hostname, "mynamespace"),
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
NodeName: hostname, NodeName: hostname,
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
Containers: []api.Container{{ Containers: []api.Container{{
Name: "image", Name: "image",
Image: "test/image", Image: "test/image",
...@@ -229,10 +227,9 @@ func TestReadPodsFromFile(t *testing.T) { ...@@ -229,10 +227,9 @@ func TestReadPodsFromFile(t *testing.T) {
SelfLink: getSelfLink("12345-"+hostname, kubelet.NamespaceDefault), SelfLink: getSelfLink("12345-"+hostname, kubelet.NamespaceDefault),
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
NodeName: hostname, NodeName: hostname,
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
Containers: []api.Container{{ Containers: []api.Container{{
Name: "image", Name: "image",
Image: "test/image", Image: "test/image",
......
...@@ -120,7 +120,6 @@ func TestExtractInvalidManifest(t *testing.T) { ...@@ -120,7 +120,6 @@ func TestExtractInvalidManifest(t *testing.T) {
func TestExtractPodsFromHTTP(t *testing.T) { func TestExtractPodsFromHTTP(t *testing.T) {
hostname := "different-value" hostname := "different-value"
grace := int64(30)
var testCases = []struct { var testCases = []struct {
desc string desc string
pods runtime.Object pods runtime.Object
...@@ -154,11 +153,9 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -154,11 +153,9 @@ func TestExtractPodsFromHTTP(t *testing.T) {
SelfLink: getSelfLink("foo-"+hostname, "mynamespace"), SelfLink: getSelfLink("foo-"+hostname, "mynamespace"),
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
NodeName: hostname, NodeName: hostname,
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
Containers: []api.Container{{ Containers: []api.Container{{
Name: "1", Name: "1",
Image: "foo", Image: "foo",
...@@ -209,11 +206,9 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -209,11 +206,9 @@ func TestExtractPodsFromHTTP(t *testing.T) {
SelfLink: getSelfLink("foo-"+hostname, kubelet.NamespaceDefault), SelfLink: getSelfLink("foo-"+hostname, kubelet.NamespaceDefault),
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
NodeName: hostname, NodeName: hostname,
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
Containers: []api.Container{{ Containers: []api.Container{{
Name: "1", Name: "1",
Image: "foo", Image: "foo",
...@@ -231,11 +226,9 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -231,11 +226,9 @@ func TestExtractPodsFromHTTP(t *testing.T) {
SelfLink: getSelfLink("bar-"+hostname, kubelet.NamespaceDefault), SelfLink: getSelfLink("bar-"+hostname, kubelet.NamespaceDefault),
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
NodeName: hostname, NodeName: hostname,
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
Containers: []api.Container{{ Containers: []api.Container{{
Name: "2", Name: "2",
Image: "bar", Image: "bar",
......
...@@ -163,13 +163,13 @@ func (f *FakeRuntime) SyncPod(pod *api.Pod, _ Pod, _ api.PodStatus, _ []api.Secr ...@@ -163,13 +163,13 @@ func (f *FakeRuntime) SyncPod(pod *api.Pod, _ Pod, _ api.PodStatus, _ []api.Secr
return f.Err return f.Err
} }
func (f *FakeRuntime) KillPod(pod *api.Pod, runningPod Pod) error { func (f *FakeRuntime) KillPod(pod Pod) error {
f.Lock() f.Lock()
defer f.Unlock() defer f.Unlock()
f.CalledFunctions = append(f.CalledFunctions, "KillPod") f.CalledFunctions = append(f.CalledFunctions, "KillPod")
f.KilledPods = append(f.KilledPods, string(runningPod.ID)) f.KilledPods = append(f.KilledPods, string(pod.ID))
for _, c := range runningPod.Containers { for _, c := range pod.Containers {
f.KilledContainers = append(f.KilledContainers, c.Name) f.KilledContainers = append(f.KilledContainers, c.Name)
} }
return f.Err return f.Err
......
...@@ -53,8 +53,8 @@ type Runtime interface { ...@@ -53,8 +53,8 @@ type Runtime interface {
GetPods(all bool) ([]*Pod, error) GetPods(all bool) ([]*Pod, error)
// Syncs the running pod into the desired pod. // Syncs the running pod into the desired pod.
SyncPod(pod *api.Pod, runningPod Pod, podStatus api.PodStatus, pullSecrets []api.Secret) error SyncPod(pod *api.Pod, runningPod Pod, podStatus api.PodStatus, pullSecrets []api.Secret) error
// KillPod kills all the containers of a pod. Pod may be nil, running pod must not be. // KillPod kills all the containers of a pod.
KillPod(pod *api.Pod, runningPod Pod) error KillPod(pod Pod) error
// GetPodStatus retrieves the status of the pod, including the information of // GetPodStatus retrieves the status of the pod, including the information of
// all containers in the pod. // all containers in the pod.
GetPodStatus(*api.Pod) (*api.PodStatus, error) GetPodStatus(*api.Pod) (*api.PodStatus, error)
......
...@@ -417,7 +417,7 @@ func TestKillContainerInPod(t *testing.T) { ...@@ -417,7 +417,7 @@ func TestKillContainerInPod(t *testing.T) {
manager.readinessManager.SetReadiness(c.ID, true) manager.readinessManager.SetReadiness(c.ID, true)
} }
if err := manager.KillContainerInPod("", &pod.Spec.Containers[0], pod); err != nil { if err := manager.KillContainerInPod(pod.Spec.Containers[0], pod); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
// Assert the container has been stopped. // Assert the container has been stopped.
...@@ -490,14 +490,14 @@ func TestKillContainerInPodWithPreStop(t *testing.T) { ...@@ -490,14 +490,14 @@ func TestKillContainerInPodWithPreStop(t *testing.T) {
manager.readinessManager.SetReadiness(c.ID, true) manager.readinessManager.SetReadiness(c.ID, true)
} }
if err := manager.KillContainerInPod("", &pod.Spec.Containers[0], pod); err != nil { if err := manager.KillContainerInPod(pod.Spec.Containers[0], pod); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
// Assert the container has been stopped. // Assert the container has been stopped.
if err := fakeDocker.AssertStopped([]string{containerToKill.ID}); err != nil { if err := fakeDocker.AssertStopped([]string{containerToKill.ID}); err != nil {
t.Errorf("container was not stopped correctly: %v", err) t.Errorf("container was not stopped correctly: %v", err)
} }
verifyCalls(t, fakeDocker, []string{"list", "create_exec", "start_exec", "stop"}) verifyCalls(t, fakeDocker, []string{"list", "inspect_container", "create_exec", "start_exec", "stop"})
if !reflect.DeepEqual(expectedCmd, fakeDocker.execCmd) { if !reflect.DeepEqual(expectedCmd, fakeDocker.execCmd) {
t.Errorf("expected: %v, got %v", expectedCmd, fakeDocker.execCmd) t.Errorf("expected: %v, got %v", expectedCmd, fakeDocker.execCmd)
} }
...@@ -534,7 +534,7 @@ func TestKillContainerInPodWithError(t *testing.T) { ...@@ -534,7 +534,7 @@ func TestKillContainerInPodWithError(t *testing.T) {
manager.readinessManager.SetReadiness(c.ID, true) manager.readinessManager.SetReadiness(c.ID, true)
} }
if err := manager.KillContainerInPod("", &pod.Spec.Containers[0], pod); err == nil { if err := manager.KillContainerInPod(pod.Spec.Containers[0], pod); err == nil {
t.Errorf("expected error, found nil") t.Errorf("expected error, found nil")
} }
...@@ -1030,7 +1030,7 @@ func TestSyncPodDeletesWithNoPodInfraContainer(t *testing.T) { ...@@ -1030,7 +1030,7 @@ func TestSyncPodDeletesWithNoPodInfraContainer(t *testing.T) {
verifyCalls(t, fakeDocker, []string{ verifyCalls(t, fakeDocker, []string{
// Kill the container since pod infra container is not running. // Kill the container since pod infra container is not running.
"stop", "inspect_container", "stop",
// Create pod infra container. // Create pod infra container.
"create", "start", "inspect_container", "create", "start", "inspect_container",
// Create container. // Create container.
...@@ -1105,7 +1105,7 @@ func TestSyncPodDeletesDuplicate(t *testing.T) { ...@@ -1105,7 +1105,7 @@ func TestSyncPodDeletesDuplicate(t *testing.T) {
// Check the pod infra container. // Check the pod infra container.
"inspect_container", "inspect_container",
// Kill the duplicated container. // Kill the duplicated container.
"stop", "inspect_container", "stop",
}) })
// Expect one of the duplicates to be killed. // Expect one of the duplicates to be killed.
if len(fakeDocker.Stopped) != 1 || (fakeDocker.Stopped[0] != "1234" && fakeDocker.Stopped[0] != "4567") { if len(fakeDocker.Stopped) != 1 || (fakeDocker.Stopped[0] != "1234" && fakeDocker.Stopped[0] != "4567") {
...@@ -1159,7 +1159,7 @@ func TestSyncPodBadHash(t *testing.T) { ...@@ -1159,7 +1159,7 @@ func TestSyncPodBadHash(t *testing.T) {
// Check the pod infra container. // Check the pod infra container.
"inspect_container", "inspect_container",
// Kill and restart the bad hash container. // Kill and restart the bad hash container.
"stop", "create", "start", "inspect_container", "stop", "create", "start",
}) })
if err := fakeDocker.AssertStopped([]string{"1234"}); err != nil { if err := fakeDocker.AssertStopped([]string{"1234"}); err != nil {
...@@ -1217,7 +1217,7 @@ func TestSyncPodsUnhealthy(t *testing.T) { ...@@ -1217,7 +1217,7 @@ func TestSyncPodsUnhealthy(t *testing.T) {
// Check the pod infra container. // Check the pod infra container.
"inspect_container", "inspect_container",
// Kill the unhealthy container. // Kill the unhealthy container.
"stop", "inspect_container", "stop",
// Restart the unhealthy container. // Restart the unhealthy container.
"create", "start", "create", "start",
}) })
...@@ -1426,7 +1426,7 @@ func TestSyncPodWithRestartPolicy(t *testing.T) { ...@@ -1426,7 +1426,7 @@ func TestSyncPodWithRestartPolicy(t *testing.T) {
// Check the pod infra container. // Check the pod infra container.
"inspect_container", "inspect_container",
// Stop the last pod infra container. // Stop the last pod infra container.
"stop", "inspect_container", "stop",
}, },
[]string{}, []string{},
[]string{"9876"}, []string{"9876"},
......
...@@ -1056,8 +1056,8 @@ func parseResolvConf(reader io.Reader) (nameservers []string, searches []string, ...@@ -1056,8 +1056,8 @@ func parseResolvConf(reader io.Reader) (nameservers []string, searches []string,
} }
// Kill all running containers in a pod (includes the pod infra container). // Kill all running containers in a pod (includes the pod infra container).
func (kl *Kubelet) killPod(pod *api.Pod, runningPod kubecontainer.Pod) error { func (kl *Kubelet) killPod(pod kubecontainer.Pod) error {
return kl.containerRuntime.KillPod(pod, runningPod) return kl.containerRuntime.KillPod(pod)
} }
type empty struct{} type empty struct{}
...@@ -1103,7 +1103,7 @@ func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecont ...@@ -1103,7 +1103,7 @@ func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecont
// Kill pods we can't run. // Kill pods we can't run.
err := canRunPod(pod) err := canRunPod(pod)
if err != nil { if err != nil {
kl.killPod(pod, runningPod) kl.killPod(runningPod)
return err return err
} }
...@@ -1418,7 +1418,7 @@ func (kl *Kubelet) killUnwantedPods(desiredPods map[types.UID]empty, ...@@ -1418,7 +1418,7 @@ func (kl *Kubelet) killUnwantedPods(desiredPods map[types.UID]empty,
}() }()
glog.V(1).Infof("Killing unwanted pod %q", pod.Name) glog.V(1).Infof("Killing unwanted pod %q", pod.Name)
// Stop the containers. // Stop the containers.
err = kl.killPod(nil, *pod) err = kl.killPod(*pod)
if err != nil { if err != nil {
glog.Errorf("Failed killing the pod %q: %v", pod.Name, err) glog.Errorf("Failed killing the pod %q: %v", pod.Name, err)
return return
......
...@@ -1155,7 +1155,7 @@ func TestSyncPodEventHandlerFails(t *testing.T) { ...@@ -1155,7 +1155,7 @@ func TestSyncPodEventHandlerFails(t *testing.T) {
// Create the container. // Create the container.
"create", "start", "create", "start",
// Kill the container since event handler fails. // Kill the container since event handler fails.
"stop", "inspect_container", "stop",
// Get pod status. // Get pod status.
"list", "inspect_container", "inspect_container", "list", "inspect_container", "inspect_container",
// Get pods for deleting orphaned volumes. // Get pods for deleting orphaned volumes.
......
...@@ -671,11 +671,11 @@ func (r *runtime) GetPods(all bool) ([]*kubecontainer.Pod, error) { ...@@ -671,11 +671,11 @@ func (r *runtime) GetPods(all bool) ([]*kubecontainer.Pod, error) {
} }
// KillPod invokes 'systemctl kill' to kill the unit that runs the pod. // KillPod invokes 'systemctl kill' to kill the unit that runs the pod.
func (r *runtime) KillPod(pod *api.Pod, runningPod kubecontainer.Pod) error { func (r *runtime) KillPod(pod kubecontainer.Pod) error {
glog.V(4).Infof("Rkt is killing pod: name %q.", runningPod.Name) glog.V(4).Infof("Rkt is killing pod: name %q.", pod.Name)
// TODO(yifan): More graceful stop. Replace with StopUnit and wait for a timeout. // TODO(yifan): More graceful stop. Replace with StopUnit and wait for a timeout.
r.systemd.KillUnit(makePodServiceFileName(runningPod.ID), int32(syscall.SIGKILL)) r.systemd.KillUnit(makePodServiceFileName(pod.ID), int32(syscall.SIGKILL))
return r.systemd.Reload() return r.systemd.Reload()
} }
...@@ -880,7 +880,7 @@ func (r *runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus ...@@ -880,7 +880,7 @@ func (r *runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus
if restartPod { if restartPod {
// TODO(yifan): Handle network plugin. // TODO(yifan): Handle network plugin.
if err := r.KillPod(pod, runningPod); err != nil { if err := r.KillPod(runningPod); err != nil {
return err return err
} }
if err := r.RunPod(pod); err != nil { if err := r.RunPod(pod); err != nil {
......
...@@ -22,7 +22,6 @@ import ( ...@@ -22,7 +22,6 @@ import (
"sync" "sync"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
kubecontainer "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/container" kubecontainer "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/container"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
...@@ -136,24 +135,13 @@ func (s *statusManager) syncBatch() error { ...@@ -136,24 +135,13 @@ func (s *statusManager) syncBatch() error {
} }
// TODO: make me easier to express from client code // TODO: make me easier to express from client code
statusPod, err = s.kubeClient.Pods(statusPod.Namespace).Get(statusPod.Name) statusPod, err = s.kubeClient.Pods(statusPod.Namespace).Get(statusPod.Name)
if errors.IsNotFound(err) {
glog.V(3).Infof("Pod %q was deleted on the server", pod.Name)
return nil
}
if err == nil { if err == nil {
statusPod.Status = status statusPod.Status = status
_, err = s.kubeClient.Pods(pod.Namespace).UpdateStatus(statusPod)
// TODO: handle conflict as a retry, make that easier too. // TODO: handle conflict as a retry, make that easier too.
statusPod, err = s.kubeClient.Pods(pod.Namespace).UpdateStatus(statusPod)
if err == nil { if err == nil {
glog.V(3).Infof("Status for pod %q updated successfully", pod.Name) glog.V(3).Infof("Status for pod %q updated successfully", pod.Name)
return nil
if statusPod.DeletionTimestamp == nil || !allTerminated(statusPod.Status.ContainerStatuses) {
return nil
}
if err := s.kubeClient.Pods(statusPod.Namespace).Delete(statusPod.Name, api.NewDeleteOptions(0)); err == nil {
glog.V(3).Infof("Pod %q fully terminated and removed from etcd", statusPod.Name)
return nil
}
} }
} }
...@@ -163,14 +151,3 @@ func (s *statusManager) syncBatch() error { ...@@ -163,14 +151,3 @@ func (s *statusManager) syncBatch() error {
s.DeletePodStatus(podFullName) s.DeletePodStatus(podFullName)
return fmt.Errorf("error updating status for pod %q: %v", pod.Name, err) return fmt.Errorf("error updating status for pod %q: %v", pod.Name, err)
} }
// allTerminated returns true if every status is terminated, or the status list
// is empty.
func allTerminated(statuses []api.ContainerStatus) bool {
for _, status := range statuses {
if status.State.Terminated == nil {
return false
}
}
return true
}
...@@ -17,7 +17,6 @@ limitations under the License. ...@@ -17,7 +17,6 @@ limitations under the License.
package namespace package namespace
import ( import (
"fmt"
"time" "time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
...@@ -120,7 +119,7 @@ func deleteAllContent(kubeClient client.Interface, namespace string) (err error) ...@@ -120,7 +119,7 @@ func deleteAllContent(kubeClient client.Interface, namespace string) (err error)
if err != nil { if err != nil {
return err return err
} }
estimate, err := deletePods(kubeClient, namespace) err = deletePods(kubeClient, namespace)
if err != nil { if err != nil {
return err return err
} }
...@@ -144,10 +143,6 @@ func deleteAllContent(kubeClient client.Interface, namespace string) (err error) ...@@ -144,10 +143,6 @@ func deleteAllContent(kubeClient client.Interface, namespace string) (err error)
if err != nil { if err != nil {
return err return err
} }
if estimate > 0 {
return fmt.Errorf("some resources are being gracefully deleted, estimate %d seconds", estimate)
}
return nil return nil
} }
...@@ -268,25 +263,18 @@ func deleteReplicationControllers(kubeClient client.Interface, ns string) error ...@@ -268,25 +263,18 @@ func deleteReplicationControllers(kubeClient client.Interface, ns string) error
return nil return nil
} }
func deletePods(kubeClient client.Interface, ns string) (int64, error) { func deletePods(kubeClient client.Interface, ns string) error {
items, err := kubeClient.Pods(ns).List(labels.Everything(), fields.Everything()) items, err := kubeClient.Pods(ns).List(labels.Everything(), fields.Everything())
if err != nil { if err != nil {
return 0, err return err
} }
estimate := int64(0)
for i := range items.Items { for i := range items.Items {
if items.Items[i].Spec.TerminationGracePeriodSeconds != nil {
grace := *items.Items[i].Spec.TerminationGracePeriodSeconds
if grace > estimate {
estimate = grace
}
}
err := kubeClient.Pods(ns).Delete(items.Items[i].Name, nil) err := kubeClient.Pods(ns).Delete(items.Items[i].Name, nil)
if err != nil { if err != nil {
return 0, err return err
} }
} }
return estimate, nil return nil
} }
func deleteEvents(kubeClient client.Interface, ns string) error { func deleteEvents(kubeClient client.Interface, ns string) error {
......
...@@ -722,7 +722,7 @@ func TestDelete(t *testing.T) { ...@@ -722,7 +722,7 @@ func TestDelete(t *testing.T) {
// If the controller is still around after trying to delete either the delete // If the controller is still around after trying to delete either the delete
// failed, or we're deleting it gracefully. // failed, or we're deleting it gracefully.
if fakeClient.Data[key].R.Node != nil { if fakeClient.Data[key].R.Node != nil {
return fakeClient.Data[key].R.Node.TTL != 0 return true
} }
return false return false
} }
......
...@@ -37,7 +37,6 @@ var testTTL uint64 = 60 ...@@ -37,7 +37,6 @@ var testTTL uint64 = 60
func NewTestEventEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) { func NewTestEventEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) {
f := tools.NewFakeEtcdClient(t) f := tools.NewFakeEtcdClient(t)
f.HideExpires = true
f.TestIndex = true f.TestIndex = true
h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix()) h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix())
......
...@@ -324,7 +324,7 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -324,7 +324,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
key, _ := storage.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
pvStart := validNewPersistentVolume("foo") pvStart := validNewPersistentVolume("foo")
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, pvStart), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, pvStart), 1)
pvIn := &api.PersistentVolume{ pvIn := &api.PersistentVolume{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
......
...@@ -325,7 +325,7 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -325,7 +325,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
key, _ := storage.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
pvcStart := validNewPersistentVolumeClaim("foo", api.NamespaceDefault) pvcStart := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, pvcStart), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, pvcStart), 1)
pvc := &api.PersistentVolumeClaim{ pvc := &api.PersistentVolumeClaim{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
......
...@@ -54,7 +54,6 @@ func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *tools.FakeEtcd ...@@ -54,7 +54,6 @@ func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *tools.FakeEtcd
} }
func validNewPod() *api.Pod { func validNewPod() *api.Pod {
grace := int64(30)
return &api.Pod{ return &api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
...@@ -63,8 +62,6 @@ func validNewPod() *api.Pod { ...@@ -63,8 +62,6 @@ func validNewPod() *api.Pod {
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
Containers: []api.Container{ Containers: []api.Container{
{ {
Name: "foo", Name: "foo",
...@@ -135,9 +132,9 @@ func TestDelete(t *testing.T) { ...@@ -135,9 +132,9 @@ func TestDelete(t *testing.T) {
if fakeEtcdClient.Data[key].R.Node == nil { if fakeEtcdClient.Data[key].R.Node == nil {
return false return false
} }
return fakeEtcdClient.Data[key].R.Node.TTL != 0 return fakeEtcdClient.Data[key].R.Node.TTL == 30
} }
test.TestDeleteGraceful(createFn, 30, gracefulSetFn) test.TestDelete(createFn, gracefulSetFn)
} }
func expectPod(t *testing.T, out runtime.Object) (*api.Pod, bool) { func expectPod(t *testing.T, out runtime.Object) (*api.Pod, bool) {
...@@ -1121,7 +1118,6 @@ func TestEtcdUpdateScheduled(t *testing.T) { ...@@ -1121,7 +1118,6 @@ func TestEtcdUpdateScheduled(t *testing.T) {
}, },
}), 1) }), 1)
grace := int64(30)
podIn := api.Pod{ podIn := api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
...@@ -1143,8 +1139,6 @@ func TestEtcdUpdateScheduled(t *testing.T) { ...@@ -1143,8 +1139,6 @@ func TestEtcdUpdateScheduled(t *testing.T) {
}, },
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
} }
_, _, err := registry.Update(ctx, &podIn) _, _, err := registry.Update(ctx, &podIn)
...@@ -1185,7 +1179,7 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -1185,7 +1179,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
}, },
}, },
} }
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &podStart), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &podStart), 1)
podIn := api.Pod{ podIn := api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
...@@ -1214,8 +1208,6 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -1214,8 +1208,6 @@ func TestEtcdUpdateStatus(t *testing.T) {
expected := podStart expected := podStart
expected.ResourceVersion = "2" expected.ResourceVersion = "2"
grace := int64(30)
expected.Spec.TerminationGracePeriodSeconds = &grace
expected.Spec.RestartPolicy = api.RestartPolicyAlways expected.Spec.RestartPolicy = api.RestartPolicyAlways
expected.Spec.DNSPolicy = api.DNSClusterFirst expected.Spec.DNSPolicy = api.DNSClusterFirst
expected.Spec.Containers[0].ImagePullPolicy = api.PullIfNotPresent expected.Spec.Containers[0].ImagePullPolicy = api.PullIfNotPresent
......
...@@ -81,26 +81,9 @@ func (podStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fiel ...@@ -81,26 +81,9 @@ func (podStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fiel
return append(errorList, validation.ValidatePodUpdate(obj.(*api.Pod), old.(*api.Pod))...) return append(errorList, validation.ValidatePodUpdate(obj.(*api.Pod), old.(*api.Pod))...)
} }
// CheckGracefulDelete allows a pod to be gracefully deleted. It updates the DeleteOptions to // CheckGracefulDelete allows a pod to be gracefully deleted.
// reflect the desired grace value.
func (podStrategy) CheckGracefulDelete(obj runtime.Object, options *api.DeleteOptions) bool { func (podStrategy) CheckGracefulDelete(obj runtime.Object, options *api.DeleteOptions) bool {
if options == nil { return false
return false
}
period := int64(0)
// user has specified a value
if options.GracePeriodSeconds != nil {
period = *options.GracePeriodSeconds
} else {
// use the default value if set, or deletes the pod immediately (0)
pod := obj.(*api.Pod)
if pod.Spec.TerminationGracePeriodSeconds != nil {
period = *pod.Spec.TerminationGracePeriodSeconds
}
}
// ensure the options and the pod are in sync
options.GracePeriodSeconds = &period
return true
} }
type podStatusStrategy struct { type podStatusStrategy struct {
...@@ -113,7 +96,6 @@ func (podStatusStrategy) PrepareForUpdate(obj, old runtime.Object) { ...@@ -113,7 +96,6 @@ func (podStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
newPod := obj.(*api.Pod) newPod := obj.(*api.Pod)
oldPod := old.(*api.Pod) oldPod := old.(*api.Pod)
newPod.Spec = oldPod.Spec newPod.Spec = oldPod.Spec
newPod.DeletionTimestamp = nil
} }
func (podStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList { func (podStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
......
...@@ -477,7 +477,7 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -477,7 +477,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
key, _ := registry.KeyFunc(ctx, "foo") key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
resourcequotaStart := validNewResourceQuota() resourcequotaStart := validNewResourceQuota()
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, resourcequotaStart), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, resourcequotaStart), 1)
resourcequotaIn := &api.ResourceQuota{ resourcequotaIn := &api.ResourceQuota{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
......
...@@ -308,11 +308,7 @@ func (e *EndpointController) syncService(key string) { ...@@ -308,11 +308,7 @@ func (e *EndpointController) syncService(key string) {
continue continue
} }
if len(pod.Status.PodIP) == 0 { if len(pod.Status.PodIP) == 0 {
glog.V(5).Infof("Failed to find an IP for pod %s/%s", pod.Namespace, pod.Name) glog.V(4).Infof("Failed to find an IP for pod %s/%s", pod.Namespace, pod.Name)
continue
}
if pod.DeletionTimestamp != nil {
glog.V(5).Infof("Pod is being deleted %s/%s", pod.Namespace, pod.Name)
continue continue
} }
......
...@@ -556,21 +556,14 @@ func (h *EtcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno ...@@ -556,21 +556,14 @@ func (h *EtcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno
ttl := uint64(0) ttl := uint64(0)
if node != nil { if node != nil {
index = node.ModifiedIndex index = node.ModifiedIndex
if node.TTL != 0 { if node.TTL > 0 {
ttl = uint64(node.TTL) ttl = uint64(node.TTL)
} }
if node.Expiration != nil && ttl == 0 {
ttl = 1
}
} else if res != nil { } else if res != nil {
index = res.EtcdIndex index = res.EtcdIndex
} }
if newTTL != nil { if newTTL != nil {
if ttl != 0 && *newTTL == 0 {
// TODO: remove this after we have verified this is no longer an issue
glog.V(4).Infof("GuaranteedUpdate is clearing TTL for %q, may not be intentional", key)
}
ttl = *newTTL ttl = *newTTL
} }
......
...@@ -117,32 +117,28 @@ func TestExtractToList(t *testing.T) { ...@@ -117,32 +117,28 @@ func TestExtractToList(t *testing.T) {
}, },
}, },
} }
grace := int64(30)
expect := api.PodList{ expect := api.PodList{
ListMeta: api.ListMeta{ResourceVersion: "10"}, ListMeta: api.ListMeta{ResourceVersion: "10"},
Items: []api.Pod{ Items: []api.Pod{
{ {
ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"}, ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"}, ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
}, },
...@@ -204,7 +200,6 @@ func TestExtractToListAcrossDirectories(t *testing.T) { ...@@ -204,7 +200,6 @@ func TestExtractToListAcrossDirectories(t *testing.T) {
}, },
}, },
} }
grace := int64(30)
expect := api.PodList{ expect := api.PodList{
ListMeta: api.ListMeta{ResourceVersion: "10"}, ListMeta: api.ListMeta{ResourceVersion: "10"},
Items: []api.Pod{ Items: []api.Pod{
...@@ -212,25 +207,22 @@ func TestExtractToListAcrossDirectories(t *testing.T) { ...@@ -212,25 +207,22 @@ func TestExtractToListAcrossDirectories(t *testing.T) {
{ {
ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"}, ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"}, ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
}, },
...@@ -280,32 +272,28 @@ func TestExtractToListExcludesDirectories(t *testing.T) { ...@@ -280,32 +272,28 @@ func TestExtractToListExcludesDirectories(t *testing.T) {
}, },
}, },
} }
grace := int64(30)
expect := api.PodList{ expect := api.PodList{
ListMeta: api.ListMeta{ResourceVersion: "10"}, ListMeta: api.ListMeta{ResourceVersion: "10"},
Items: []api.Pod{ Items: []api.Pod{
{ {
ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"}, ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"}, ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
}, },
}, },
...@@ -325,13 +313,11 @@ func TestExtractObj(t *testing.T) { ...@@ -325,13 +313,11 @@ func TestExtractObj(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
grace := int64(30)
expect := api.Pod{ expect := api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
} }
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &expect), 0) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &expect), 0)
......
...@@ -39,7 +39,6 @@ const ( ...@@ -39,7 +39,6 @@ const (
EtcdSet = "set" EtcdSet = "set"
EtcdCAS = "compareAndSwap" EtcdCAS = "compareAndSwap"
EtcdDelete = "delete" EtcdDelete = "delete"
EtcdExpire = "expire"
) )
// FilterFunc is a predicate which takes an API object and returns true // FilterFunc is a predicate which takes an API object and returns true
...@@ -406,7 +405,7 @@ func (w *etcdWatcher) sendResult(res *etcd.Response) { ...@@ -406,7 +405,7 @@ func (w *etcdWatcher) sendResult(res *etcd.Response) {
w.sendAdd(res) w.sendAdd(res)
case EtcdSet, EtcdCAS: case EtcdSet, EtcdCAS:
w.sendModify(res) w.sendModify(res)
case EtcdDelete, EtcdExpire: case EtcdDelete:
w.sendDelete(res) w.sendDelete(res)
default: default:
glog.Errorf("unknown action: %v", res.Action) glog.Errorf("unknown action: %v", res.Action)
......
...@@ -21,7 +21,6 @@ import ( ...@@ -21,7 +21,6 @@ import (
"fmt" "fmt"
"sort" "sort"
"sync" "sync"
"time"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
...@@ -54,8 +53,6 @@ type FakeEtcdClient struct { ...@@ -54,8 +53,6 @@ type FakeEtcdClient struct {
TestIndex bool TestIndex bool
ChangeIndex uint64 ChangeIndex uint64
LastSetTTL uint64 LastSetTTL uint64
// Will avoid setting the expires header on objects to make comparison easier
HideExpires bool
Machines []string Machines []string
// Will become valid after Watch is called; tester may write to it. Tester may // Will become valid after Watch is called; tester may write to it. Tester may
...@@ -187,11 +184,6 @@ func (f *FakeEtcdClient) setLocked(key, value string, ttl uint64) (*etcd.Respons ...@@ -187,11 +184,6 @@ func (f *FakeEtcdClient) setLocked(key, value string, ttl uint64) (*etcd.Respons
prevResult := f.Data[key] prevResult := f.Data[key]
createdIndex := prevResult.R.Node.CreatedIndex createdIndex := prevResult.R.Node.CreatedIndex
f.t.Logf("updating %v, index %v -> %v (ttl: %d)", key, createdIndex, i, ttl) f.t.Logf("updating %v, index %v -> %v (ttl: %d)", key, createdIndex, i, ttl)
var expires *time.Time
if !f.HideExpires && ttl > 0 {
now := time.Now()
expires = &now
}
result := EtcdResponseWithError{ result := EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
...@@ -199,7 +191,6 @@ func (f *FakeEtcdClient) setLocked(key, value string, ttl uint64) (*etcd.Respons ...@@ -199,7 +191,6 @@ func (f *FakeEtcdClient) setLocked(key, value string, ttl uint64) (*etcd.Respons
CreatedIndex: createdIndex, CreatedIndex: createdIndex,
ModifiedIndex: i, ModifiedIndex: i,
TTL: int64(ttl), TTL: int64(ttl),
Expiration: expires,
}, },
}, },
} }
......
...@@ -132,13 +132,11 @@ func PriorityTwo(pod *api.Pod, podLister algorithm.PodLister, minionLister algor ...@@ -132,13 +132,11 @@ func PriorityTwo(pod *api.Pod, podLister algorithm.PodLister, minionLister algor
} }
func TestDefaultErrorFunc(t *testing.T) { func TestDefaultErrorFunc(t *testing.T) {
grace := int64(30)
testPod := &api.Pod{ testPod := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "bar"}, ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "bar"},
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
}, },
} }
handler := util.FakeHandler{ handler := util.FakeHandler{
......
...@@ -205,7 +205,7 @@ func getUDData(jpgExpected string, ns string) func(*client.Client, string) error ...@@ -205,7 +205,7 @@ func getUDData(jpgExpected string, ns string) func(*client.Client, string) error
if strings.Contains(data.Image, jpgExpected) { if strings.Contains(data.Image, jpgExpected) {
return nil return nil
} else { } else {
return errors.New(fmt.Sprintf("data served up in container is inaccurate, %s didn't contain %s", data, jpgExpected)) return errors.New(fmt.Sprintf("data served up in container is innaccurate, %s didn't contain %s", data, jpgExpected))
} }
} }
} }
...@@ -82,8 +82,8 @@ var _ = Describe("PD", func() { ...@@ -82,8 +82,8 @@ var _ = Describe("PD", func() {
By("cleaning up PD-RW test environment") By("cleaning up PD-RW test environment")
// Teardown pods, PD. Ignore errors. // Teardown pods, PD. Ignore errors.
// Teardown should do nothing unless test failed. // Teardown should do nothing unless test failed.
podClient.Delete(host0Pod.Name, api.NewDeleteOptions(0)) podClient.Delete(host0Pod.Name, nil)
podClient.Delete(host1Pod.Name, api.NewDeleteOptions(0)) podClient.Delete(host1Pod.Name, nil)
detachPD(host0Name, diskName) detachPD(host0Name, diskName)
detachPD(host1Name, diskName) detachPD(host1Name, diskName)
deletePD(diskName) deletePD(diskName)
...@@ -96,7 +96,7 @@ var _ = Describe("PD", func() { ...@@ -96,7 +96,7 @@ var _ = Describe("PD", func() {
expectNoError(waitForPodRunning(c, host0Pod.Name)) expectNoError(waitForPodRunning(c, host0Pod.Name))
By("deleting host0Pod") By("deleting host0Pod")
expectNoError(podClient.Delete(host0Pod.Name, api.NewDeleteOptions(0)), "Failed to delete host0Pod") expectNoError(podClient.Delete(host0Pod.Name, nil), "Failed to delete host0Pod")
By("submitting host1Pod to kubernetes") By("submitting host1Pod to kubernetes")
_, err = podClient.Create(host1Pod) _, err = podClient.Create(host1Pod)
...@@ -105,7 +105,7 @@ var _ = Describe("PD", func() { ...@@ -105,7 +105,7 @@ var _ = Describe("PD", func() {
expectNoError(waitForPodRunning(c, host1Pod.Name)) expectNoError(waitForPodRunning(c, host1Pod.Name))
By("deleting host1Pod") By("deleting host1Pod")
expectNoError(podClient.Delete(host1Pod.Name, api.NewDeleteOptions(0)), "Failed to delete host1Pod") expectNoError(podClient.Delete(host1Pod.Name, nil), "Failed to delete host1Pod")
By(fmt.Sprintf("deleting PD %q", diskName)) By(fmt.Sprintf("deleting PD %q", diskName))
for start := time.Now(); time.Since(start) < 180*time.Second; time.Sleep(5 * time.Second) { for start := time.Now(); time.Since(start) < 180*time.Second; time.Sleep(5 * time.Second) {
...@@ -142,9 +142,9 @@ var _ = Describe("PD", func() { ...@@ -142,9 +142,9 @@ var _ = Describe("PD", func() {
By("cleaning up PD-RO test environment") By("cleaning up PD-RO test environment")
// Teardown pods, PD. Ignore errors. // Teardown pods, PD. Ignore errors.
// Teardown should do nothing unless test failed. // Teardown should do nothing unless test failed.
podClient.Delete(rwPod.Name, api.NewDeleteOptions(0)) podClient.Delete(rwPod.Name, nil)
podClient.Delete(host0ROPod.Name, api.NewDeleteOptions(0)) podClient.Delete(host0ROPod.Name, nil)
podClient.Delete(host1ROPod.Name, api.NewDeleteOptions(0)) podClient.Delete(host1ROPod.Name, nil)
detachPD(host0Name, diskName) detachPD(host0Name, diskName)
detachPD(host1Name, diskName) detachPD(host1Name, diskName)
...@@ -155,7 +155,7 @@ var _ = Describe("PD", func() { ...@@ -155,7 +155,7 @@ var _ = Describe("PD", func() {
_, err = podClient.Create(rwPod) _, err = podClient.Create(rwPod)
expectNoError(err, "Failed to create rwPod") expectNoError(err, "Failed to create rwPod")
expectNoError(waitForPodRunning(c, rwPod.Name)) expectNoError(waitForPodRunning(c, rwPod.Name))
expectNoError(podClient.Delete(rwPod.Name, api.NewDeleteOptions(0)), "Failed to delete host0Pod") expectNoError(podClient.Delete(rwPod.Name, nil), "Failed to delete host0Pod")
By("submitting host0ROPod to kubernetes") By("submitting host0ROPod to kubernetes")
_, err = podClient.Create(host0ROPod) _, err = podClient.Create(host0ROPod)
...@@ -170,10 +170,10 @@ var _ = Describe("PD", func() { ...@@ -170,10 +170,10 @@ var _ = Describe("PD", func() {
expectNoError(waitForPodRunning(c, host1ROPod.Name)) expectNoError(waitForPodRunning(c, host1ROPod.Name))
By("deleting host0ROPod") By("deleting host0ROPod")
expectNoError(podClient.Delete(host0ROPod.Name, api.NewDeleteOptions(0)), "Failed to delete host0ROPod") expectNoError(podClient.Delete(host0ROPod.Name, nil), "Failed to delete host0ROPod")
By("deleting host1ROPod") By("deleting host1ROPod")
expectNoError(podClient.Delete(host1ROPod.Name, api.NewDeleteOptions(0)), "Failed to delete host1ROPod") expectNoError(podClient.Delete(host1ROPod.Name, nil), "Failed to delete host1ROPod")
By(fmt.Sprintf("deleting PD %q", diskName)) By(fmt.Sprintf("deleting PD %q", diskName))
for start := time.Now(); time.Since(start) < 180*time.Second; time.Sleep(5 * time.Second) { for start := time.Now(); time.Since(start) < 180*time.Second; time.Sleep(5 * time.Second) {
......
...@@ -55,7 +55,7 @@ func runLivenessTest(c *client.Client, podDescr *api.Pod, expectRestart bool) { ...@@ -55,7 +55,7 @@ func runLivenessTest(c *client.Client, podDescr *api.Pod, expectRestart bool) {
// At the end of the test, clean up by removing the pod. // At the end of the test, clean up by removing the pod.
defer func() { defer func() {
By("deleting the pod") By("deleting the pod")
c.Pods(ns).Delete(podDescr.Name, api.NewDeleteOptions(0)) c.Pods(ns).Delete(podDescr.Name, nil)
}() }()
// Wait until the pod is not pending. (Here we need to check for something other than // Wait until the pod is not pending. (Here we need to check for something other than
...@@ -101,7 +101,7 @@ func testHostIP(c *client.Client, pod *api.Pod) { ...@@ -101,7 +101,7 @@ func testHostIP(c *client.Client, pod *api.Pod) {
podClient := c.Pods(ns) podClient := c.Pods(ns)
By("creating pod") By("creating pod")
defer podClient.Delete(pod.Name, api.NewDeleteOptions(0)) defer podClient.Delete(pod.Name, nil)
_, err = podClient.Create(pod) _, err = podClient.Create(pod)
if err != nil { if err != nil {
Fail(fmt.Sprintf("Failed to create pod: %v", err)) Fail(fmt.Sprintf("Failed to create pod: %v", err))
...@@ -205,7 +205,7 @@ var _ = Describe("Pods", func() { ...@@ -205,7 +205,7 @@ var _ = Describe("Pods", func() {
// We call defer here in case there is a problem with // We call defer here in case there is a problem with
// the test so we can ensure that we clean up after // the test so we can ensure that we clean up after
// ourselves // ourselves
defer podClient.Delete(pod.Name, api.NewDeleteOptions(0)) defer podClient.Delete(pod.Name, nil)
_, err = podClient.Create(pod) _, err = podClient.Create(pod)
if err != nil { if err != nil {
Fail(fmt.Sprintf("Failed to create pod: %v", err)) Fail(fmt.Sprintf("Failed to create pod: %v", err))
...@@ -218,7 +218,7 @@ var _ = Describe("Pods", func() { ...@@ -218,7 +218,7 @@ var _ = Describe("Pods", func() {
} }
Expect(len(pods.Items)).To(Equal(1)) Expect(len(pods.Items)).To(Equal(1))
By("verifying pod creation was observed") By("veryfying pod creation was observed")
select { select {
case event, _ := <-w.ResultChan(): case event, _ := <-w.ResultChan():
if event.Type != watch.Added { if event.Type != watch.Added {
...@@ -228,21 +228,22 @@ var _ = Describe("Pods", func() { ...@@ -228,21 +228,22 @@ var _ = Describe("Pods", func() {
Fail("Timeout while waiting for pod creation") Fail("Timeout while waiting for pod creation")
} }
By("deleting the pod gracefully") By("deleting the pod")
if err := podClient.Delete(pod.Name, nil); err != nil { podClient.Delete(pod.Name, nil)
Fail(fmt.Sprintf("Failed to observe pod deletion: %v", err)) pods, err = podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})), fields.Everything())
if err != nil {
Fail(fmt.Sprintf("Failed to delete pod: %v", err))
} }
Expect(len(pods.Items)).To(Equal(0))
By("verifying pod deletion was observed") By("veryfying pod deletion was observed")
deleted := false deleted := false
timeout := false timeout := false
var lastPod *api.Pod
timer := time.After(podStartTimeout) timer := time.After(podStartTimeout)
for !deleted && !timeout { for !deleted && !timeout {
select { select {
case event, _ := <-w.ResultChan(): case event, _ := <-w.ResultChan():
if event.Type == watch.Deleted { if event.Type == watch.Deleted {
lastPod = event.Object.(*api.Pod)
deleted = true deleted = true
} }
case <-timer: case <-timer:
...@@ -252,14 +253,6 @@ var _ = Describe("Pods", func() { ...@@ -252,14 +253,6 @@ var _ = Describe("Pods", func() {
if !deleted { if !deleted {
Fail("Failed to observe pod deletion") Fail("Failed to observe pod deletion")
} }
Expect(lastPod.DeletionTimestamp).ToNot(BeNil())
Expect(lastPod.Spec.TerminationGracePeriodSeconds).ToNot(BeZero())
pods, err = podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})), fields.Everything())
if err != nil {
Fail(fmt.Sprintf("Failed to delete pod: %v", err))
}
Expect(len(pods.Items)).To(Equal(0))
}) })
It("should be updated", func() { It("should be updated", func() {
...@@ -299,7 +292,7 @@ var _ = Describe("Pods", func() { ...@@ -299,7 +292,7 @@ var _ = Describe("Pods", func() {
By("submitting the pod to kubernetes") By("submitting the pod to kubernetes")
defer func() { defer func() {
By("deleting the pod") By("deleting the pod")
podClient.Delete(pod.Name, api.NewDeleteOptions(0)) podClient.Delete(pod.Name, nil)
}() }()
pod, err := podClient.Create(pod) pod, err := podClient.Create(pod)
if err != nil { if err != nil {
...@@ -363,7 +356,7 @@ var _ = Describe("Pods", func() { ...@@ -363,7 +356,7 @@ var _ = Describe("Pods", func() {
}, },
}, },
} }
defer c.Pods(api.NamespaceDefault).Delete(serverPod.Name, api.NewDeleteOptions(0)) defer c.Pods(api.NamespaceDefault).Delete(serverPod.Name, nil)
_, err := c.Pods(api.NamespaceDefault).Create(serverPod) _, err := c.Pods(api.NamespaceDefault).Create(serverPod)
if err != nil { if err != nil {
Fail(fmt.Sprintf("Failed to create serverPod: %v", err)) Fail(fmt.Sprintf("Failed to create serverPod: %v", err))
...@@ -554,7 +547,7 @@ var _ = Describe("Pods", func() { ...@@ -554,7 +547,7 @@ var _ = Describe("Pods", func() {
// We call defer here in case there is a problem with // We call defer here in case there is a problem with
// the test so we can ensure that we clean up after // the test so we can ensure that we clean up after
// ourselves // ourselves
podClient.Delete(pod.Name, api.NewDeleteOptions(0)) podClient.Delete(pod.Name)
}() }()
By("waiting for the pod to start running") By("waiting for the pod to start running")
...@@ -627,7 +620,7 @@ var _ = Describe("Pods", func() { ...@@ -627,7 +620,7 @@ var _ = Describe("Pods", func() {
// We call defer here in case there is a problem with // We call defer here in case there is a problem with
// the test so we can ensure that we clean up after // the test so we can ensure that we clean up after
// ourselves // ourselves
podClient.Delete(pod.Name, api.NewDeleteOptions(0)) podClient.Delete(pod.Name)
}() }()
By("waiting for the pod to start running") By("waiting for the pod to start running")
......
...@@ -495,24 +495,20 @@ func expectNoError(err error, explain ...interface{}) { ...@@ -495,24 +495,20 @@ func expectNoError(err error, explain ...interface{}) {
ExpectWithOffset(1, err).NotTo(HaveOccurred(), explain...) ExpectWithOffset(1, err).NotTo(HaveOccurred(), explain...)
} }
// Stops everything from filePath from namespace ns and checks if everything matching selectors from the given namespace is correctly stopped. // Stops everything from filePath from namespace ns and checks if everything maching selectors from the given namespace is correctly stopped.
func cleanup(filePath string, ns string, selectors ...string) { func cleanup(filePath string, ns string, selectors ...string) {
By("using delete to clean up resources") By("using stop to clean up resources")
var nsArg string var nsArg string
if ns != "" { if ns != "" {
nsArg = fmt.Sprintf("--namespace=%s", ns) nsArg = fmt.Sprintf("--namespace=%s", ns)
} }
runKubectl("stop", "--grace-period=0", "-f", filePath, nsArg) runKubectl("stop", "-f", filePath, nsArg)
for _, selector := range selectors { for _, selector := range selectors {
resources := runKubectl("get", "rc,se", "-l", selector, "--no-headers", nsArg) resources := runKubectl("get", "pods,rc,se", "-l", selector, "--no-headers", nsArg)
if resources != "" { if resources != "" {
Failf("Resources left running after stop:\n%s", resources) Failf("Resources left running after stop:\n%s", resources)
} }
pods := runKubectl("get", "pods", "-l", selector, nsArg, "-t", "{{ range .items }}{{ if not .metadata.deletionTimestamp }}{{ .metadata.name }}{{ \"\\n\" }}{{ end }}{{ end }}")
if pods != "" {
Failf("Pods left unterminated after stop:\n%s", pods)
}
} }
} }
......
...@@ -240,7 +240,7 @@ var deleteNow string = ` ...@@ -240,7 +240,7 @@ var deleteNow string = `
{ {
"kind": "DeleteOptions", "kind": "DeleteOptions",
"apiVersion": "v1beta3", "apiVersion": "v1beta3",
"gracePeriodSeconds": 0%s "gracePeriodSeconds": null%s
} }
` `
......
...@@ -88,58 +88,6 @@ func TestExtractObj(t *testing.T) { ...@@ -88,58 +88,6 @@ func TestExtractObj(t *testing.T) {
}) })
} }
func TestWriteTTL(t *testing.T) {
client := framework.NewEtcdClient()
helper := tools.EtcdHelper{Client: client, Codec: stringCodec{}}
framework.WithEtcdKey(func(key string) {
_, err := client.Set(key, "object", 0)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
s := fakeAPIObject("")
err = helper.GuaranteedUpdate(key, &s, false, func(obj runtime.Object, res tools.ResponseMeta) (runtime.Object, *uint64, error) {
if *(obj.(*fakeAPIObject)) != "object" {
t.Fatalf("unexpected existing object: %v", obj)
}
if res.TTL != 0 {
t.Fatalf("unexpected TTL: %#v", res)
}
ttl := uint64(10)
out := fakeAPIObject("test")
return &out, &ttl, nil
})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if s != "test" {
t.Errorf("unexpected response: %#v", s)
}
if res, err := client.Get(key, false, false); err != nil || res == nil || res.Node.TTL != 10 {
t.Fatalf("unexpected get: %v %#v", err, res)
}
err = helper.GuaranteedUpdate(key, &s, false, func(obj runtime.Object, res tools.ResponseMeta) (runtime.Object, *uint64, error) {
if *(obj.(*fakeAPIObject)) != "test" {
t.Fatalf("unexpected existing object: %v", obj)
}
if res.TTL <= 1 {
t.Fatalf("unexpected TTL: %#v", res)
}
out := fakeAPIObject("test2")
return &out, nil, nil
})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if s != "test2" {
t.Errorf("unexpected response: %#v", s)
}
if res, err := client.Get(key, false, false); err != nil || res == nil || res.Node.TTL <= 1 {
t.Fatalf("unexpected get: %v %#v", err, res)
}
})
}
func TestWatch(t *testing.T) { func TestWatch(t *testing.T) {
client := framework.NewEtcdClient() client := framework.NewEtcdClient()
helper := tools.NewEtcdHelper(client, testapi.Codec(), etcdtest.PathPrefix()) helper := tools.NewEtcdHelper(client, testapi.Codec(), etcdtest.PathPrefix())
......
...@@ -277,7 +277,7 @@ func DoTestUnschedulableNodes(t *testing.T, restClient *client.Client, nodeStore ...@@ -277,7 +277,7 @@ func DoTestUnschedulableNodes(t *testing.T, restClient *client.Client, nodeStore
t.Logf("Test %d: Pod got scheduled on a schedulable node", i) t.Logf("Test %d: Pod got scheduled on a schedulable node", i)
} }
err = restClient.Pods(api.NamespaceDefault).Delete(myPod.Name, api.NewDeleteOptions(0)) err = restClient.Pods(api.NamespaceDefault).Delete(myPod.Name, nil)
if err != nil { if err != nil {
t.Errorf("Failed to delete pod: %v", err) t.Errorf("Failed to delete pod: %v", err)
} }
......
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