mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 12:18:16 +00:00 
			
		
		
		
	Revert "Gracefully delete pods from the Kubelet"
This commit is contained in:
		@@ -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:
 | 
				
			|||||||
      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,25 +878,19 @@ 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: '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.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.")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "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"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,42 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "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 (
 | 
				
			|||||||
	"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"
 | 
				
			||||||
@@ -54,7 +52,6 @@ var (
 | 
				
			|||||||
	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() {
 | 
				
			|||||||
		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)
 | 
				
			|||||||
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
 | 
				
			|||||||
  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
 | 
				
			|||||||
  # 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
 | 
				
			|||||||
  # 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
 | 
				
			|||||||
  # 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
 | 
				
			|||||||
  # 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
 | 
				
			|||||||
  # 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
 | 
				
			|||||||
  # 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
 | 
				
			|||||||
  # 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
 | 
				
			|||||||
  # 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
 | 
				
			|||||||
	} 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
 | 
				
			|||||||
	} 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
 | 
				
			|||||||
	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) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
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
 | 
				
			|||||||
	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
 | 
				
			|||||||
		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) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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) {
 | 
				
			|||||||
		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 {
 | 
				
			|||||||
			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 {
 | 
				
			|||||||
	// 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
 | 
				
			|||||||
	} 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
 | 
				
			|||||||
	} 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
 | 
				
			|||||||
	} 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() {
 | 
				
			|||||||
			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 {
 | 
				
			|||||||
	// 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 (
 | 
				
			|||||||
	// 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 {
 | 
				
			|||||||
	// 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
 | 
				
			|||||||
	} 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
 | 
				
			|||||||
	} 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
 | 
				
			|||||||
	} 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() {
 | 
				
			|||||||
			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 {
 | 
				
			|||||||
	// 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 (
 | 
				
			|||||||
	// 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 {
 | 
				
			|||||||
	// 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
 | 
				
			|||||||
	} 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 {
 | 
				
			|||||||
	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
 | 
				
			|||||||
// 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{}) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	// 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 (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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",
 | 
				
			||||||
@@ -49,7 +48,6 @@ func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList)
 | 
				
			|||||||
				Spec: api.PodSpec{
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
					RestartPolicy: api.RestartPolicyAlways,
 | 
										RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
					DNSPolicy:     api.DNSClusterFirst,
 | 
										DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
					TerminationGracePeriodSeconds: &grace,
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@@ -57,7 +55,6 @@ func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList)
 | 
				
			|||||||
				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) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
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{
 | 
				
			||||||
@@ -517,7 +513,6 @@ func watchTestData() ([]api.Pod, []watch.Event) {
 | 
				
			|||||||
			Spec: api.PodSpec{
 | 
								Spec: api.PodSpec{
 | 
				
			||||||
				RestartPolicy: api.RestartPolicyAlways,
 | 
									RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
				DNSPolicy:     api.DNSClusterFirst,
 | 
									DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
				TerminationGracePeriodSeconds: &grace,
 | 
					 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -533,7 +528,6 @@ func watchTestData() ([]api.Pod, []watch.Event) {
 | 
				
			|||||||
				Spec: api.PodSpec{
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
					RestartPolicy: api.RestartPolicyAlways,
 | 
										RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
					DNSPolicy:     api.DNSClusterFirst,
 | 
										DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
					TerminationGracePeriodSeconds: &grace,
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -548,7 +542,6 @@ func watchTestData() ([]api.Pod, []watch.Event) {
 | 
				
			|||||||
				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 (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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
 | 
				
			||||||
@@ -52,7 +51,6 @@ func TestMerge(t *testing.T) {
 | 
				
			|||||||
				Spec: api.PodSpec{
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
					RestartPolicy: api.RestartPolicyAlways,
 | 
										RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
					DNSPolicy:     api.DNSClusterFirst,
 | 
										DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
					TerminationGracePeriodSeconds: &grace,
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -121,7 +119,6 @@ func TestMerge(t *testing.T) {
 | 
				
			|||||||
					},
 | 
										},
 | 
				
			||||||
					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
 | 
				
			|||||||
		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:\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, "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
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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",
 | 
				
			||||||
@@ -94,7 +93,6 @@ func testData() (*api.PodList, *api.ServiceList) {
 | 
				
			|||||||
				Spec: api.PodSpec{
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
					RestartPolicy: api.RestartPolicyAlways,
 | 
										RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
					DNSPolicy:     api.DNSClusterFirst,
 | 
										DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
					TerminationGracePeriodSeconds: &grace,
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@@ -102,7 +100,6 @@ func testData() (*api.PodList, *api.ServiceList) {
 | 
				
			|||||||
				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) {
 | 
				
			|||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	grace := int64(30)
 | 
					 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		Resp     *http.Response
 | 
							Resp     *http.Response
 | 
				
			||||||
		RespFunc client.HTTPClientFunc
 | 
							RespFunc client.HTTPClientFunc
 | 
				
			||||||
@@ -175,7 +174,6 @@ func TestHelperCreate(t *testing.T) {
 | 
				
			|||||||
				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) {
 | 
				
			|||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	grace := int64(30)
 | 
					 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		Resp      *http.Response
 | 
							Resp      *http.Response
 | 
				
			||||||
		RespFunc  client.HTTPClientFunc
 | 
							RespFunc  client.HTTPClientFunc
 | 
				
			||||||
@@ -423,7 +420,6 @@ func TestHelperUpdate(t *testing.T) {
 | 
				
			|||||||
				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 {
 | 
				
			|||||||
		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) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
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{
 | 
				
			||||||
@@ -648,7 +647,6 @@ 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 (
 | 
				
			|||||||
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: "",
 | 
				
			||||||
@@ -43,7 +42,6 @@ func TestDecodeSinglePod(t *testing.T) {
 | 
				
			|||||||
		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) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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: "",
 | 
				
			||||||
@@ -108,7 +105,6 @@ func TestDecodePodList(t *testing.T) {
 | 
				
			|||||||
		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
 | 
				
			|||||||
		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
 | 
				
			|||||||
			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
 | 
				
			|||||||
	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) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
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
 | 
				
			||||||
@@ -196,7 +195,6 @@ func TestReadPodsFromFile(t *testing.T) {
 | 
				
			|||||||
					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",
 | 
				
			||||||
@@ -232,7 +230,6 @@ func TestReadPodsFromFile(t *testing.T) {
 | 
				
			|||||||
					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) {
 | 
				
			|||||||
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
 | 
				
			||||||
@@ -157,8 +156,6 @@ func TestExtractPodsFromHTTP(t *testing.T) {
 | 
				
			|||||||
						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",
 | 
				
			||||||
@@ -212,8 +209,6 @@ func TestExtractPodsFromHTTP(t *testing.T) {
 | 
				
			|||||||
						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",
 | 
				
			||||||
@@ -234,8 +229,6 @@ func TestExtractPodsFromHTTP(t *testing.T) {
 | 
				
			|||||||
						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
 | 
				
			|||||||
	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 {
 | 
				
			|||||||
	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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,16 +54,7 @@ const (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	maxReasonCacheEntries = 200
 | 
						maxReasonCacheEntries = 200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// In order to avoid unnecessary SIGKILLs, give every container a minimum grace
 | 
					 | 
				
			||||||
	// period after SIGTERM. Docker will guarantee the termination, but SIGTERM is
 | 
					 | 
				
			||||||
	// potentially dangerous.
 | 
					 | 
				
			||||||
	// TODO: evaluate whether there are scenarios in which SIGKILL is preferable to
 | 
					 | 
				
			||||||
	// SIGTERM for certain process types, which may justify setting this to 0.
 | 
					 | 
				
			||||||
	minimumGracePeriodInSeconds = 2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	kubernetesNameLabel                   = "io.kubernetes.pod.name"
 | 
					 | 
				
			||||||
	kubernetesPodLabel       = "io.kubernetes.pod.data"
 | 
						kubernetesPodLabel       = "io.kubernetes.pod.data"
 | 
				
			||||||
	kubernetesTerminationGracePeriodLabel = "io.kubernetes.pod.terminationGracePeriod"
 | 
					 | 
				
			||||||
	kubernetesContainerLabel = "io.kubernetes.container.name"
 | 
						kubernetesContainerLabel = "io.kubernetes.container.name"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -573,19 +564,12 @@ func (dm *DockerManager) runContainer(
 | 
				
			|||||||
	if len(containerHostname) > hostnameMaxLen {
 | 
						if len(containerHostname) > hostnameMaxLen {
 | 
				
			||||||
		containerHostname = containerHostname[:hostnameMaxLen]
 | 
							containerHostname = containerHostname[:hostnameMaxLen]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Pod information is recorded on the container as labels to preserve it in the event the pod is deleted
 | 
					 | 
				
			||||||
	// while the Kubelet is down and there is no information available to recover the pod. This includes
 | 
					 | 
				
			||||||
	// termination information like the termination grace period and the pre stop hooks.
 | 
					 | 
				
			||||||
	// TODO: keep these labels up to date if the pod changes
 | 
					 | 
				
			||||||
	namespacedName := types.NamespacedName{pod.Namespace, pod.Name}
 | 
						namespacedName := types.NamespacedName{pod.Namespace, pod.Name}
 | 
				
			||||||
	labels := map[string]string{
 | 
						labels := map[string]string{
 | 
				
			||||||
		kubernetesNameLabel: namespacedName.String(),
 | 
							"io.kubernetes.pod.name": namespacedName.String(),
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if pod.Spec.TerminationGracePeriodSeconds != nil {
 | 
					 | 
				
			||||||
		labels[kubernetesTerminationGracePeriodLabel] = strconv.FormatInt(*pod.Spec.TerminationGracePeriodSeconds, 10)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if container.Lifecycle != nil && container.Lifecycle.PreStop != nil {
 | 
						if container.Lifecycle != nil && container.Lifecycle.PreStop != nil {
 | 
				
			||||||
 | 
							glog.V(1).Infof("Setting preStop hook")
 | 
				
			||||||
		// TODO: This is kind of hacky, we should really just encode the bits we need.
 | 
							// TODO: This is kind of hacky, we should really just encode the bits we need.
 | 
				
			||||||
		data, err := latest.Codec.Encode(pod)
 | 
							data, err := latest.Codec.Encode(pod)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -1048,12 +1032,12 @@ func (dm *DockerManager) PortForward(pod *kubecontainer.Pod, port uint16, stream
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Kills all containers in the specified pod
 | 
					// Kills all containers in the specified pod
 | 
				
			||||||
func (dm *DockerManager) KillPod(pod *api.Pod, runningPod kubecontainer.Pod) error {
 | 
					func (dm *DockerManager) KillPod(pod kubecontainer.Pod) error {
 | 
				
			||||||
	// Send the kills in parallel since they may take a long time. Len + 1 since there
 | 
						// Send the kills in parallel since they may take a long time. Len + 1 since there
 | 
				
			||||||
	// can be Len errors + the networkPlugin teardown error.
 | 
						// can be Len errors + the networkPlugin teardown error.
 | 
				
			||||||
	errs := make(chan error, len(runningPod.Containers)+1)
 | 
						errs := make(chan error, len(pod.Containers)+1)
 | 
				
			||||||
	wg := sync.WaitGroup{}
 | 
						wg := sync.WaitGroup{}
 | 
				
			||||||
	for _, container := range runningPod.Containers {
 | 
						for _, container := range pod.Containers {
 | 
				
			||||||
		wg.Add(1)
 | 
							wg.Add(1)
 | 
				
			||||||
		go func(container *kubecontainer.Container) {
 | 
							go func(container *kubecontainer.Container) {
 | 
				
			||||||
			defer util.HandleCrash()
 | 
								defer util.HandleCrash()
 | 
				
			||||||
@@ -1061,24 +1045,15 @@ func (dm *DockerManager) KillPod(pod *api.Pod, runningPod kubecontainer.Pod) err
 | 
				
			|||||||
			// TODO: Handle this without signaling the pod infra container to
 | 
								// TODO: Handle this without signaling the pod infra container to
 | 
				
			||||||
			// adapt to the generic container runtime.
 | 
								// adapt to the generic container runtime.
 | 
				
			||||||
			if container.Name == PodInfraContainerName {
 | 
								if container.Name == PodInfraContainerName {
 | 
				
			||||||
				err := dm.networkPlugin.TearDownPod(runningPod.Namespace, runningPod.Name, kubeletTypes.DockerID(container.ID))
 | 
									err := dm.networkPlugin.TearDownPod(pod.Namespace, pod.Name, kubeletTypes.DockerID(container.ID))
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					glog.Errorf("Failed tearing down the infra container: %v", err)
 | 
										glog.Errorf("Failed tearing down the infra container: %v", err)
 | 
				
			||||||
					errs <- err
 | 
										errs <- err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			var containerSpec *api.Container
 | 
								err := dm.killContainer(container.ID)
 | 
				
			||||||
			if pod != nil {
 | 
					 | 
				
			||||||
				for i, c := range pod.Spec.Containers {
 | 
					 | 
				
			||||||
					if c.Name == container.Name {
 | 
					 | 
				
			||||||
						containerSpec = &pod.Spec.Containers[i]
 | 
					 | 
				
			||||||
						break
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			err := dm.killContainer(container.ID, containerSpec, pod)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				glog.Errorf("Failed to delete container: %v; Skipping pod %q", err, runningPod.ID)
 | 
									glog.Errorf("Failed to delete container: %v; Skipping pod %q", err, pod.ID)
 | 
				
			||||||
				errs <- err
 | 
									errs <- err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			wg.Done()
 | 
								wg.Done()
 | 
				
			||||||
@@ -1096,11 +1071,8 @@ func (dm *DockerManager) KillPod(pod *api.Pod, runningPod kubecontainer.Pod) err
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// KillContainerInPod kills a container in the pod. It must be passed either a container ID or a container and pod,
 | 
					// KillContainerInPod kills a container in the pod.
 | 
				
			||||||
// and will attempt to lookup the other information if missing.
 | 
					func (dm *DockerManager) KillContainerInPod(container api.Container, pod *api.Pod) error {
 | 
				
			||||||
func (dm *DockerManager) KillContainerInPod(containerID types.UID, container *api.Container, pod *api.Pod) error {
 | 
					 | 
				
			||||||
	switch {
 | 
					 | 
				
			||||||
	case len(containerID) == 0:
 | 
					 | 
				
			||||||
	// Locate the container.
 | 
						// Locate the container.
 | 
				
			||||||
	pods, err := dm.GetPods(false)
 | 
						pods, err := dm.GetPods(false)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -1111,113 +1083,63 @@ func (dm *DockerManager) KillContainerInPod(containerID types.UID, container *ap
 | 
				
			|||||||
	if targetContainer == nil {
 | 
						if targetContainer == nil {
 | 
				
			||||||
		return fmt.Errorf("unable to find container %q in pod %q", container.Name, targetPod.Name)
 | 
							return fmt.Errorf("unable to find container %q in pod %q", container.Name, targetPod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		containerID = targetContainer.ID
 | 
						return dm.killContainer(targetContainer.ID)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case container == nil || pod == nil:
 | 
					// TODO(vmarmol): Unexport this as it is no longer used externally.
 | 
				
			||||||
		// Read information about the container from labels
 | 
					// KillContainer kills a container identified by containerID.
 | 
				
			||||||
		inspect, err := dm.client.InspectContainer(string(containerID))
 | 
					// Internally, it invokes docker's StopContainer API with a timeout of 10s.
 | 
				
			||||||
 | 
					// TODO: Deprecate this function in favor of KillContainerInPod.
 | 
				
			||||||
 | 
					func (dm *DockerManager) KillContainer(containerID types.UID) error {
 | 
				
			||||||
 | 
						return dm.killContainer(containerID)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (dm *DockerManager) killContainer(containerID types.UID) error {
 | 
				
			||||||
 | 
						ID := string(containerID)
 | 
				
			||||||
 | 
						glog.V(2).Infof("Killing container with id %q", ID)
 | 
				
			||||||
 | 
						inspect, err := dm.client.InspectContainer(ID)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		storedPod, storedContainer, cerr := containerAndPodFromLabels(inspect)
 | 
						var found bool
 | 
				
			||||||
		if cerr != nil {
 | 
						var preStop string
 | 
				
			||||||
			glog.Errorf("unable to access pod data from container: %v", err)
 | 
						if inspect != nil && inspect.Config != nil && inspect.Config.Labels != nil {
 | 
				
			||||||
 | 
							preStop, found = inspect.Config.Labels[kubernetesPodLabel]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		if container == nil {
 | 
						if found {
 | 
				
			||||||
			container = storedContainer
 | 
							var pod api.Pod
 | 
				
			||||||
		}
 | 
							err := latest.Codec.DecodeInto([]byte(preStop), &pod)
 | 
				
			||||||
		if pod == nil {
 | 
							if err != nil {
 | 
				
			||||||
			pod = storedPod
 | 
								glog.Errorf("Failed to decode prestop: %s, %s", preStop, ID)
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return dm.killContainer(containerID, container, pod)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// killContainer accepts a containerID and an optional container or pod containing shutdown policies. Invoke
 | 
					 | 
				
			||||||
// KillContainerInPod if information must be retrieved first.
 | 
					 | 
				
			||||||
func (dm *DockerManager) killContainer(containerID types.UID, container *api.Container, pod *api.Pod) error {
 | 
					 | 
				
			||||||
	ID := string(containerID)
 | 
					 | 
				
			||||||
	name := ID
 | 
					 | 
				
			||||||
	if container != nil {
 | 
					 | 
				
			||||||
		name = fmt.Sprintf("%s %s", name, container.Name)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if pod != nil {
 | 
					 | 
				
			||||||
		name = fmt.Sprintf("%s %s/%s", name, pod.Namespace, pod.Name)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	gracePeriod := int64(minimumGracePeriodInSeconds)
 | 
					 | 
				
			||||||
	if pod != nil && pod.DeletionGracePeriodSeconds != nil {
 | 
					 | 
				
			||||||
		gracePeriod = *pod.DeletionGracePeriodSeconds
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	glog.V(2).Infof("Killing container %q with %d second grace period", name, gracePeriod)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if pod != nil && container != nil && container.Lifecycle != nil && container.Lifecycle.PreStop != nil {
 | 
					 | 
				
			||||||
		glog.V(4).Infof("Running preStop hook for container %q", name)
 | 
					 | 
				
			||||||
		start := util.Now()
 | 
					 | 
				
			||||||
		// TODO: timebox PreStop execution to at most gracePeriod
 | 
					 | 
				
			||||||
		if err := dm.runner.Run(ID, pod, container, container.Lifecycle.PreStop); err != nil {
 | 
					 | 
				
			||||||
			glog.Errorf("preStop hook for container %q failed: %v", name, err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		gracePeriod -= int64(util.Now().Sub(start.Time).Seconds())
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dm.readinessManager.RemoveReadiness(ID)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// always give containers a minimal shutdown window to avoid unnecessary SIGKILLs
 | 
					 | 
				
			||||||
	if gracePeriod < minimumGracePeriodInSeconds {
 | 
					 | 
				
			||||||
		gracePeriod = minimumGracePeriodInSeconds
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	err := dm.client.StopContainer(ID, uint(gracePeriod))
 | 
					 | 
				
			||||||
	ref, ok := dm.containerRefManager.GetRef(ID)
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		glog.Warningf("No ref for pod '%q'", name)
 | 
					 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
		// TODO: pass reason down here, and state, or move this call up the stack.
 | 
								name := inspect.Config.Labels[kubernetesContainerLabel]
 | 
				
			||||||
		dm.recorder.Eventf(ref, "killing", "Killing %v", ID)
 | 
								var container *api.Container
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var errNoPodOnContainer = fmt.Errorf("no pod information labels on Docker container")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// containerAndPodFromLabels tries to load the appropriate container info off of a Docker container's labels
 | 
					 | 
				
			||||||
func containerAndPodFromLabels(inspect *docker.Container) (pod *api.Pod, container *api.Container, err error) {
 | 
					 | 
				
			||||||
	if inspect == nil && inspect.Config == nil && inspect.Config.Labels == nil {
 | 
					 | 
				
			||||||
		return nil, nil, errNoPodOnContainer
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	labels := inspect.Config.Labels
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// the pod data may not be set
 | 
					 | 
				
			||||||
	if body, found := labels[kubernetesPodLabel]; found {
 | 
					 | 
				
			||||||
		pod = &api.Pod{}
 | 
					 | 
				
			||||||
		if err = latest.Codec.DecodeInto([]byte(body), pod); err == nil {
 | 
					 | 
				
			||||||
			name := labels[kubernetesContainerLabel]
 | 
					 | 
				
			||||||
			for ix := range pod.Spec.Containers {
 | 
								for ix := range pod.Spec.Containers {
 | 
				
			||||||
				if pod.Spec.Containers[ix].Name == name {
 | 
									if pod.Spec.Containers[ix].Name == name {
 | 
				
			||||||
					container = &pod.Spec.Containers[ix]
 | 
										container = &pod.Spec.Containers[ix]
 | 
				
			||||||
					break
 | 
										break
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if container == nil {
 | 
								if container != nil {
 | 
				
			||||||
				err = fmt.Errorf("unable to find container %s in pod %v", name, pod)
 | 
									glog.V(1).Infof("Running preStop hook")
 | 
				
			||||||
 | 
									if err := dm.runner.Run(ID, &pod, container, container.Lifecycle.PreStop); err != nil {
 | 
				
			||||||
 | 
										glog.Errorf("failed to run preStop hook: %v", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
			pod = nil
 | 
									glog.Errorf("unable to find container %v, %s", pod, name)
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// attempt to find the default grace period if we didn't commit a pod, but set the generic metadata
 | 
					 | 
				
			||||||
	// field (the one used by kill)
 | 
					 | 
				
			||||||
	if pod == nil {
 | 
					 | 
				
			||||||
		if period, ok := labels[kubernetesTerminationGracePeriodLabel]; ok {
 | 
					 | 
				
			||||||
			if seconds, err := strconv.ParseInt(period, 10, 64); err == nil {
 | 
					 | 
				
			||||||
				pod = &api.Pod{}
 | 
					 | 
				
			||||||
				pod.DeletionGracePeriodSeconds = &seconds
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						dm.readinessManager.RemoveReadiness(ID)
 | 
				
			||||||
	return
 | 
						err = dm.client.StopContainer(ID, 10)
 | 
				
			||||||
 | 
						ref, ok := dm.containerRefManager.GetRef(ID)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							glog.Warningf("No ref for pod '%v'", ID)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							// TODO: pass reason down here, and state, or move this call up the stack.
 | 
				
			||||||
 | 
							dm.recorder.Eventf(ref, "killing", "Killing %v", ID)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Run a single container from a pod. Returns the docker container ID
 | 
					// Run a single container from a pod. Returns the docker container ID
 | 
				
			||||||
@@ -1245,7 +1167,7 @@ func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Containe
 | 
				
			|||||||
	if container.Lifecycle != nil && container.Lifecycle.PostStart != nil {
 | 
						if container.Lifecycle != nil && container.Lifecycle.PostStart != nil {
 | 
				
			||||||
		handlerErr := dm.runner.Run(id, pod, container, container.Lifecycle.PostStart)
 | 
							handlerErr := dm.runner.Run(id, pod, container, container.Lifecycle.PostStart)
 | 
				
			||||||
		if handlerErr != nil {
 | 
							if handlerErr != nil {
 | 
				
			||||||
			dm.killContainer(types.UID(id), container, pod)
 | 
								dm.killContainer(types.UID(id))
 | 
				
			||||||
			return kubeletTypes.DockerID(""), fmt.Errorf("failed to call event handler: %v", handlerErr)
 | 
								return kubeletTypes.DockerID(""), fmt.Errorf("failed to call event handler: %v", handlerErr)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1358,11 +1280,6 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kub
 | 
				
			|||||||
	containersToKeep := make(map[kubeletTypes.DockerID]int)
 | 
						containersToKeep := make(map[kubeletTypes.DockerID]int)
 | 
				
			||||||
	createPodInfraContainer := false
 | 
						createPodInfraContainer := false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if pod.DeletionTimestamp != nil {
 | 
					 | 
				
			||||||
		glog.V(4).Infof("Pod is terminating %q", podFullName)
 | 
					 | 
				
			||||||
		return PodContainerChangesSpec{}, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	var podInfraContainerID kubeletTypes.DockerID
 | 
						var podInfraContainerID kubeletTypes.DockerID
 | 
				
			||||||
	var changed bool
 | 
						var changed bool
 | 
				
			||||||
@@ -1516,7 +1433,7 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, pod
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Killing phase: if we want to start new infra container, or nothing is running kill everything (including infra container)
 | 
							// Killing phase: if we want to start new infra container, or nothing is running kill everything (including infra container)
 | 
				
			||||||
		err = dm.KillPod(pod, runningPod)
 | 
							err = dm.KillPod(runningPod)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -1526,15 +1443,7 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, pod
 | 
				
			|||||||
			_, keep := containerChanges.ContainersToKeep[kubeletTypes.DockerID(container.ID)]
 | 
								_, keep := containerChanges.ContainersToKeep[kubeletTypes.DockerID(container.ID)]
 | 
				
			||||||
			if !keep {
 | 
								if !keep {
 | 
				
			||||||
				glog.V(3).Infof("Killing unwanted container %+v", container)
 | 
									glog.V(3).Infof("Killing unwanted container %+v", container)
 | 
				
			||||||
				// attempt to find the appropriate container policy
 | 
									err = dm.KillContainer(container.ID)
 | 
				
			||||||
				var podContainer *api.Container
 | 
					 | 
				
			||||||
				for i, c := range pod.Spec.Containers {
 | 
					 | 
				
			||||||
					if c.Name == container.Name {
 | 
					 | 
				
			||||||
						podContainer = &pod.Spec.Containers[i]
 | 
					 | 
				
			||||||
						break
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				err = dm.KillContainerInPod(container.ID, podContainer, pod)
 | 
					 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					glog.Errorf("Error killing container: %v", err)
 | 
										glog.Errorf("Error killing container: %v", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
				
			|||||||
		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) {
 | 
				
			|||||||
		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) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	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) {
 | 
				
			|||||||
		// 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) {
 | 
				
			|||||||
		// 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) {
 | 
				
			|||||||
		// 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) {
 | 
				
			|||||||
				// 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,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 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
 | 
				
			|||||||
	// 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,
 | 
				
			|||||||
			}()
 | 
								}()
 | 
				
			||||||
			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) {
 | 
				
			|||||||
		// 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) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 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
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	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 (
 | 
				
			|||||||
	"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,25 +135,14 @@ 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)
 | 
				
			||||||
 | 
					 | 
				
			||||||
			if statusPod.DeletionTimestamp == nil || !allTerminated(statusPod.Status.ContainerStatuses) {
 | 
					 | 
				
			||||||
			return nil
 | 
								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
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// We failed to update status. In order to make sure we retry next time
 | 
						// We failed to update status. In order to make sure we retry next time
 | 
				
			||||||
@@ -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.
 | 
				
			|||||||
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)
 | 
				
			|||||||
	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)
 | 
				
			|||||||
	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
 | 
				
			|||||||
	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) {
 | 
				
			|||||||
		// 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
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
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) {
 | 
				
			|||||||
	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) {
 | 
				
			|||||||
	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
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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 {
 | 
				
			|||||||
		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) {
 | 
				
			|||||||
		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) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}), 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) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			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) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	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) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	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,27 +81,10 @@ 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 {
 | 
				
			||||||
	podStrategy
 | 
						podStrategy
 | 
				
			||||||
@@ -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) {
 | 
				
			|||||||
	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) {
 | 
				
			|||||||
				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
 | 
				
			|||||||
		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,7 +117,6 @@ 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{
 | 
				
			||||||
@@ -126,7 +125,6 @@ func TestExtractToList(t *testing.T) {
 | 
				
			|||||||
				Spec: api.PodSpec{
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
					RestartPolicy: api.RestartPolicyAlways,
 | 
										RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
					DNSPolicy:     api.DNSClusterFirst,
 | 
										DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
					TerminationGracePeriodSeconds: &grace,
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@@ -134,7 +132,6 @@ func TestExtractToList(t *testing.T) {
 | 
				
			|||||||
				Spec: api.PodSpec{
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
					RestartPolicy: api.RestartPolicyAlways,
 | 
										RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
					DNSPolicy:     api.DNSClusterFirst,
 | 
										DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
					TerminationGracePeriodSeconds: &grace,
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@@ -142,7 +139,6 @@ func TestExtractToList(t *testing.T) {
 | 
				
			|||||||
				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) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	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{
 | 
				
			||||||
@@ -214,7 +209,6 @@ func TestExtractToListAcrossDirectories(t *testing.T) {
 | 
				
			|||||||
				Spec: api.PodSpec{
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
					RestartPolicy: api.RestartPolicyAlways,
 | 
										RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
					DNSPolicy:     api.DNSClusterFirst,
 | 
										DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
					TerminationGracePeriodSeconds: &grace,
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@@ -222,7 +216,6 @@ func TestExtractToListAcrossDirectories(t *testing.T) {
 | 
				
			|||||||
				Spec: api.PodSpec{
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
					RestartPolicy: api.RestartPolicyAlways,
 | 
										RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
					DNSPolicy:     api.DNSClusterFirst,
 | 
										DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
					TerminationGracePeriodSeconds: &grace,
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@@ -230,7 +223,6 @@ func TestExtractToListAcrossDirectories(t *testing.T) {
 | 
				
			|||||||
				Spec: api.PodSpec{
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
					RestartPolicy: api.RestartPolicyAlways,
 | 
										RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
					DNSPolicy:     api.DNSClusterFirst,
 | 
										DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
					TerminationGracePeriodSeconds: &grace,
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -280,7 +272,6 @@ 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{
 | 
				
			||||||
@@ -289,7 +280,6 @@ func TestExtractToListExcludesDirectories(t *testing.T) {
 | 
				
			|||||||
				Spec: api.PodSpec{
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
					RestartPolicy: api.RestartPolicyAlways,
 | 
										RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
					DNSPolicy:     api.DNSClusterFirst,
 | 
										DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
					TerminationGracePeriodSeconds: &grace,
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@@ -297,7 +287,6 @@ func TestExtractToListExcludesDirectories(t *testing.T) {
 | 
				
			|||||||
				Spec: api.PodSpec{
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
					RestartPolicy: api.RestartPolicyAlways,
 | 
										RestartPolicy: api.RestartPolicyAlways,
 | 
				
			||||||
					DNSPolicy:     api.DNSClusterFirst,
 | 
										DNSPolicy:     api.DNSClusterFirst,
 | 
				
			||||||
					TerminationGracePeriodSeconds: &grace,
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@@ -305,7 +294,6 @@ func TestExtractToListExcludesDirectories(t *testing.T) {
 | 
				
			|||||||
				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) {
 | 
				
			|||||||
	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 (
 | 
				
			|||||||
	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) {
 | 
				
			|||||||
		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 (
 | 
				
			|||||||
	"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 {
 | 
				
			|||||||
	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
 | 
				
			|||||||
		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
 | 
				
			|||||||
					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
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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
 | 
				
			|||||||
		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() {
 | 
				
			|||||||
			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() {
 | 
				
			|||||||
		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() {
 | 
				
			|||||||
		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() {
 | 
				
			|||||||
			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() {
 | 
				
			|||||||
		_, 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() {
 | 
				
			|||||||
		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) {
 | 
				
			|||||||
	// 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) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	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() {
 | 
				
			|||||||
		// 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() {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		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() {
 | 
				
			|||||||
			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() {
 | 
				
			|||||||
		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() {
 | 
				
			|||||||
		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() {
 | 
				
			|||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		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() {
 | 
				
			|||||||
				// 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() {
 | 
				
			|||||||
				// 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{}) {
 | 
				
			|||||||
	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 = `
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "kind": "DeleteOptions",
 | 
					  "kind": "DeleteOptions",
 | 
				
			||||||
  "apiVersion": "v1beta3",
 | 
					  "apiVersion": "v1beta3",
 | 
				
			||||||
  "gracePeriodSeconds": 0%s
 | 
					  "gracePeriodSeconds": null%s
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			|||||||
			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)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user