From 6b0db76e85f4f8b3752a24b6095a5358340da6ec Mon Sep 17 00:00:00 2001 From: Victor Marmol Date: Mon, 27 Apr 2015 15:34:01 -0700 Subject: [PATCH] Move killPod() logic to DockerManager KillPod(). This moved Docker specific logic there and allows it to align with the runtime API. There is still a pod infra container reference in the function due to network plugins. We can handle this in the Kubelet since we'll need to be explicit in stating that the network plugin will not work in a non-Docker runtime. --- pkg/kubelet/dockertools/manager.go | 38 +++++++++++++++++++++++ pkg/kubelet/kubelet.go | 49 +++++++++++------------------- 2 files changed, 55 insertions(+), 32 deletions(-) diff --git a/pkg/kubelet/dockertools/manager.go b/pkg/kubelet/dockertools/manager.go index 0aee6c01ea3..a00cf7b2581 100644 --- a/pkg/kubelet/dockertools/manager.go +++ b/pkg/kubelet/dockertools/manager.go @@ -391,6 +391,15 @@ func (dm *DockerManager) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) { return &podStatus, nil } +func (dm *DockerManager) GetPodInfraContainer(pod kubecontainer.Pod) (kubecontainer.Container, error) { + for _, container := range pod.Containers { + if container.Name == PodInfraContainerName { + return *container, nil + } + } + return kubecontainer.Container{}, fmt.Errorf("unable to find pod infra container for pod %v", pod.ID) +} + func (dm *DockerManager) GetRunningContainers(ids []string) ([]*docker.Container, error) { var result []*docker.Container if dm.client == nil { @@ -888,6 +897,35 @@ func (dm *DockerManager) PortForward(pod *kubecontainer.Pod, port uint16, stream return command.Run() } +// Kills all containers in the specified pod +func (dm *DockerManager) KillPod(pod kubecontainer.Pod) error { + // Send the kills in parallel since they may take a long time. + errs := make(chan error, len(pod.Containers)) + wg := sync.WaitGroup{} + for _, container := range pod.Containers { + wg.Add(1) + go func(container *kubecontainer.Container) { + defer util.HandleCrash() + err := dm.KillContainer(container.ID) + if err != nil { + glog.Errorf("Failed to delete container: %v; Skipping pod %q", err, pod.ID) + errs <- err + } + wg.Done() + }(container) + } + wg.Wait() + close(errs) + if len(errs) > 0 { + errList := []error{} + for err := range errs { + errList = append(errList, err) + } + return fmt.Errorf("failed to delete containers (%v)", errList) + } + return nil +} + // KillContainer kills a container identified by containerID. // Internally, it invokes docker's StopContainer API with a timeout of 10s. // TODO(yifan): Use new ContainerID type. diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 23931cec9f6..19aa3f5ccf7 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -27,7 +27,6 @@ import ( "path" "sort" "strings" - "sync" "time" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" @@ -927,39 +926,25 @@ func (kl *Kubelet) pullImage(img string, ref *api.ObjectReference) error { // Kill all running containers in a pod (includes the pod infra container). func (kl *Kubelet) killPod(pod kubecontainer.Pod) error { - // Send the kills in parallel since they may take a long time. - errs := make(chan error, len(pod.Containers)) - wg := sync.WaitGroup{} - for _, container := range pod.Containers { - wg.Add(1) - go func(container *kubecontainer.Container) { - defer util.HandleCrash() - // Call the networking plugin for teardown. - // TODO: Handle this without signaling the pod infra container to - // adapt to the generic container runtime. - if container.Name == dockertools.PodInfraContainerName { - err := kl.networkPlugin.TearDownPod(pod.Namespace, pod.Name, dockertools.DockerID(container.ID)) - if err != nil { - glog.Errorf("Failed tearing down the infra container: %v", err) - errs <- err - } - } - err := kl.containerManager.KillContainer(container.ID) - if err != nil { - glog.Errorf("Failed to delete container: %v; Skipping pod %q", err, pod.ID) - errs <- err - } - wg.Done() - }(container) - } - wg.Wait() - close(errs) - if len(errs) > 0 { - errList := []error{} - for err := range errs { + // TODO(vmarmol): Consider handling non-Docker runtimes, the plugins are not friendly to it today. + container, err := kl.containerManager.GetPodInfraContainer(pod) + errList := []error{} + if err == nil { + // Call the networking plugin for teardown. + err = kl.networkPlugin.TearDownPod(pod.Namespace, pod.Name, dockertools.DockerID(container.ID)) + if err != nil { + glog.Errorf("Failed tearing down the network plugin for pod %q: %v", pod.ID, err) errList = append(errList, err) } - return fmt.Errorf("failed to delete containers (%v)", errList) + } + + err = kl.containerManager.KillPod(pod) + if err != nil { + errList = append(errList, err) + } + + if len(errList) > 0 { + return utilErrors.NewAggregate(errList) } return nil }