Added TerminationGracePeriod field to PodSpec and grace-period flag to kubectl stop

Those are changes which touch users required by Termination Notice

Addresses #6804
This commit is contained in:
Piotr Szczesniak 2015-04-28 14:21:57 +02:00
parent dd976a27fb
commit 11a2dc496f
39 changed files with 164 additions and 58 deletions

View File

@ -395,7 +395,7 @@ containers:
glog.Fatalf("%s FAILED: mirror pod has not been created or is not running: %v", desc, err)
}
// Delete the mirror pod, and wait for it to be recreated.
c.Pods(namespace).Delete(podName)
c.Pods(namespace).Delete(podName, nil)
if err = wait.Poll(time.Second, time.Minute*1,
podRunning(c, namespace, podName)); err != nil {
glog.Fatalf("%s FAILED: mirror pod has not been re-created or is not running: %v", desc, err)
@ -928,7 +928,7 @@ func runSchedulerNoPhantomPodsTest(client *client.Client) {
// Delete a pod to free up room.
glog.Infof("Deleting pod %v", bar.Name)
err = client.Pods(api.NamespaceDefault).Delete(bar.Name)
err = client.Pods(api.NamespaceDefault).Delete(bar.Name, nil)
if err != nil {
glog.Fatalf("FAILED: couldn't delete pod %q: %v", bar.Name, err)
}

View File

@ -350,6 +350,7 @@ _kubectl_delete()
two_word_flags+=("-f")
flags_with_completion+=("-f")
flags_completion+=("_filedir '@(json|yaml|yml)'")
flags+=("--grace-period=")
flags+=("--help")
flags+=("-h")
flags+=("--selector=")
@ -564,6 +565,7 @@ _kubectl_stop()
two_word_flags+=("-f")
flags_with_completion+=("-f")
flags_completion+=("_filedir '@(json|yaml|yml)'")
flags+=("--grace-period=")
flags+=("--help")
flags+=("-h")
flags+=("--selector=")

View File

@ -45,6 +45,7 @@ $ kubectl delete pods --all
--all=false: [-all] to select all the specified resources
--cascade=true: If true, cascade the delete resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.
-f, --filename=[]: Filename, directory, or URL to a file containing the resource to delete
--grace-period=-1: Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.
-h, --help=false: help for delete
-l, --selector="": Selector (label query) to filter on
```
@ -82,4 +83,4 @@ $ kubectl delete pods --all
### SEE ALSO
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.031169223 +0000 UTC
###### Auto generated by spf13/cobra at 2015-04-30 14:53:47.856200003 +0000 UTC

View File

@ -35,6 +35,7 @@ $ kubectl stop -f path/to/resources
```
--all=false: [-all] to select all the specified resources
-f, --filename=[]: Filename, directory, or URL to file of resource(s) to be stopped
--grace-period=-1: Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.
-h, --help=false: help for stop
-l, --selector="": Selector (label query) to filter on
```
@ -72,4 +73,4 @@ $ kubectl stop -f path/to/resources
### SEE ALSO
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.033329682 +0000 UTC
###### Auto generated by spf13/cobra at 2015-04-30 14:53:47.85772498 +0000 UTC

View File

@ -41,6 +41,10 @@ will be lost along with the rest of the resource.
\fB\-f\fP, \fB\-\-filename\fP=[]
Filename, directory, or URL to a file containing the resource to delete
.PP
\fB\-\-grace\-period\fP=\-1
Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.
.PP
\fB\-h\fP, \fB\-\-help\fP=false
help for delete

View File

@ -29,6 +29,10 @@ If the resource is resizable it will be resized to 0 before deletion.
\fB\-f\fP, \fB\-\-filename\fP=[]
Filename, directory, or URL to file of resource(s) to be stopped
.PP
\fB\-\-grace\-period\fP=\-1
Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.
.PP
\fB\-h\fP, \fB\-\-help\fP=false
help for stop

View File

@ -137,6 +137,10 @@ func init() {
if err := s.Convert(&in.RestartPolicy, &out.RestartPolicy, 0); err != nil {
return err
}
if in.TerminationGracePeriodSeconds != nil {
out.TerminationGracePeriodSeconds = new(int64)
*out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds
}
out.DNSPolicy = in.DNSPolicy
out.Version = "v1beta2"
return nil
@ -151,6 +155,10 @@ func init() {
if err := s.Convert(&in.RestartPolicy, &out.RestartPolicy, 0); err != nil {
return err
}
if in.TerminationGracePeriodSeconds != nil {
out.TerminationGracePeriodSeconds = new(int64)
*out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds
}
out.DNSPolicy = in.DNSPolicy
return nil
},

View File

@ -799,6 +799,13 @@ type PodSpec struct {
// Required: there must be at least one container in a pod.
Containers []Container `json:"containers"`
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty"`
// 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 nil, 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.
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
// Required: Set DNS policy.
DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty"`
// NodeSelector is a selector which must be true for the pod to fit on a node
@ -1647,6 +1654,7 @@ type ContainerManifest struct {
Volumes []Volume `json:"volumes"`
Containers []Container `json:"containers"`
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty"`
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
// Required: Set DNS policy.
DNSPolicy DNSPolicy `json:"dnsPolicy"`
HostNetwork bool `json:"hostNetwork,omitempty"`

View File

@ -1829,6 +1829,10 @@ func init() {
}
}
out.RestartPolicy = newer.RestartPolicy(in.RestartPolicy)
if in.TerminationGracePeriodSeconds != nil {
out.TerminationGracePeriodSeconds = new(int64)
*out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds
}
out.DNSPolicy = newer.DNSPolicy(in.DNSPolicy)
if in.NodeSelector != nil {
out.NodeSelector = make(map[string]string)
@ -1858,6 +1862,10 @@ func init() {
}
}
out.RestartPolicy = RestartPolicy(in.RestartPolicy)
if in.TerminationGracePeriodSeconds != nil {
out.TerminationGracePeriodSeconds = new(int64)
*out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds
}
out.DNSPolicy = DNSPolicy(in.DNSPolicy)
if in.NodeSelector != nil {
out.NodeSelector = make(map[string]string)

View File

@ -797,6 +797,13 @@ type PodSpec struct {
// Required: there must be at least one container in a pod.
Containers []Container `json:"containers" description:"list of containers belonging to the pod; cannot be updated; containers cannot currently be added or removed; there must be at least one container in a Pod" patchStrategy:"merge" patchMergeKey:"name"`
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
// 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 nil, 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.
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"`
// 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'"`
// NodeSelector is a selector which must be true for the pod to fit on a node

View File

@ -686,6 +686,10 @@ func init() {
if err := s.Convert(&in.RestartPolicy, &out.RestartPolicy, 0); err != nil {
return err
}
if in.TerminationGracePeriodSeconds != nil {
out.TerminationGracePeriodSeconds = new(int64)
*out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds
}
out.DNSPolicy = DNSPolicy(in.DNSPolicy)
out.Version = "v1beta2"
out.HostNetwork = in.HostNetwork
@ -701,6 +705,10 @@ func init() {
if err := s.Convert(&in.RestartPolicy, &out.RestartPolicy, 0); err != nil {
return err
}
if in.TerminationGracePeriodSeconds != nil {
out.TerminationGracePeriodSeconds = new(int64)
*out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds
}
out.DNSPolicy = newer.DNSPolicy(in.DNSPolicy)
out.HostNetwork = in.HostNetwork
return nil

View File

@ -61,6 +61,13 @@ type ContainerManifest struct {
Volumes []Volume `json:"volumes" description:"list of volumes that can be mounted by containers belonging to the pod"`
Containers []Container `json:"containers" description:"list of containers belonging to the pod; containers cannot currently be added or removed"`
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
// 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 nil, 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.
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"`
// 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'"`
// Uses the host's network namespace. If this option is set, the ports that will be
@ -1447,6 +1454,7 @@ type PodSpec struct {
// Required: there must be at least one container in a pod.
Containers []Container `json:"containers" description:"list of containers belonging to the pod; containers cannot currently be added or removed; there must be at least one container in a Pod"`
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
// TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
// 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'"`
// NodeSelector is a selector which must be true for the pod to fit on a node

View File

@ -466,6 +466,10 @@ func init() {
if err := s.Convert(&in.RestartPolicy, &out.RestartPolicy, 0); err != nil {
return err
}
if in.TerminationGracePeriodSeconds != nil {
out.TerminationGracePeriodSeconds = new(int64)
*out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds
}
out.DNSPolicy = DNSPolicy(in.DNSPolicy)
out.Version = "v1beta2"
out.HostNetwork = in.HostNetwork
@ -481,6 +485,10 @@ func init() {
if err := s.Convert(&in.RestartPolicy, &out.RestartPolicy, 0); err != nil {
return err
}
if in.TerminationGracePeriodSeconds != nil {
out.TerminationGracePeriodSeconds = new(int64)
*out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds
}
out.DNSPolicy = newer.DNSPolicy(in.DNSPolicy)
out.HostNetwork = in.HostNetwork
return nil

View File

@ -1485,6 +1485,13 @@ type ContainerManifest struct {
Volumes []Volume `json:"volumes" description:"list of volumes that can be mounted by containers belonging to the pod"`
Containers []Container `json:"containers" description:"list of containers belonging to the pod; cannot be updated; containers cannot currently be added or removed"`
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
// 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 nil, 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.
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"`
// 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'"`
// Uses the host's network namespace. If this option is set, the ports that will be

View File

@ -1955,6 +1955,10 @@ func convert_v1beta3_PodSpec_To_api_PodSpec(in *PodSpec, out *newer.PodSpec, s c
}
}
out.RestartPolicy = newer.RestartPolicy(in.RestartPolicy)
if in.TerminationGracePeriodSeconds != nil {
out.TerminationGracePeriodSeconds = new(int64)
*out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds
}
out.DNSPolicy = newer.DNSPolicy(in.DNSPolicy)
if in.NodeSelector != nil {
out.NodeSelector = make(map[string]string)
@ -1985,6 +1989,10 @@ func convert_api_PodSpec_To_v1beta3_PodSpec(in *newer.PodSpec, out *PodSpec, s c
}
}
out.RestartPolicy = RestartPolicy(in.RestartPolicy)
if in.TerminationGracePeriodSeconds != nil {
out.TerminationGracePeriodSeconds = new(int64)
*out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds
}
out.DNSPolicy = DNSPolicy(in.DNSPolicy)
if in.NodeSelector != nil {
out.NodeSelector = make(map[string]string)

View File

@ -797,6 +797,13 @@ type PodSpec struct {
// Required: there must be at least one container in a pod.
Containers []Container `json:"containers" description:"list of containers belonging to the pod; cannot be updated; containers cannot currently be added or removed; there must be at least one container in a Pod" patchStrategy:"merge" patchMergeKey:"name"`
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
// 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 nil, 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.
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"`
// 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'"`
// NodeSelector is a selector which must be true for the pod to fit on a node

View File

@ -32,7 +32,7 @@ type PodsNamespacer interface {
type PodInterface interface {
List(label labels.Selector, field fields.Selector) (*api.PodList, error)
Get(name string) (*api.Pod, error)
Delete(name string) error
Delete(name string, options *api.DeleteOptions) error
Create(pod *api.Pod) (*api.Pod, error)
Update(pod *api.Pod) (*api.Pod, error)
Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
@ -69,9 +69,17 @@ func (c *pods) Get(name string) (result *api.Pod, err error) {
}
// Delete takes the name of the pod, and returns an error if one occurs
func (c *pods) Delete(name string) error {
func (c *pods) Delete(name string, options *api.DeleteOptions) error {
// TODO: to make this reusable in other client libraries
if options == nil {
return c.r.Delete().Namespace(c.ns).Resource("pods").Name(name).Do().Error()
}
body, err := api.Scheme.EncodeToVersion(options, c.r.APIVersion())
if err != nil {
return err
}
return c.r.Delete().Namespace(c.ns).Resource("pods").Name(name).Body(body).Do().Error()
}
// Create takes the representation of a pod. Returns the server's representation of the pod, and an error, if it occurs.
func (c *pods) Create(pod *api.Pod) (result *api.Pod, err error) {

View File

@ -136,7 +136,7 @@ func TestDeletePod(t *testing.T) {
Request: testRequest{Method: "DELETE", Path: testapi.ResourcePath("pods", ns, "foo"), Query: buildQueryValues(ns, nil)},
Response: Response{StatusCode: 200},
}
err := c.Setup().Pods(ns).Delete("foo")
err := c.Setup().Pods(ns).Delete("foo", nil)
c.Validate(t, nil, err)
}

View File

@ -40,7 +40,7 @@ func (c *FakePods) Get(name string) (*api.Pod, error) {
return obj.(*api.Pod), err
}
func (c *FakePods) Delete(name string) error {
func (c *FakePods) Delete(name string, options *api.DeleteOptions) error {
_, err := c.Fake.Invokes(FakeAction{Action: "delete-pod", Value: name}, &api.Pod{})
return err
}

View File

@ -593,7 +593,7 @@ func (nc *NodeController) deletePods(nodeID string) error {
continue
}
glog.V(2).Infof("Delete pod %v", pod.Name)
if err := nc.kubeClient.Pods(pod.Namespace).Delete(pod.Name); err != nil {
if err := nc.kubeClient.Pods(pod.Namespace).Delete(pod.Name, nil); err != nil {
glog.Errorf("Error deleting pod %v: %v", pod.Name, err)
}
}

View File

@ -233,7 +233,7 @@ func (r RealPodControl) createReplica(namespace string, controller *api.Replicat
}
func (r RealPodControl) deletePod(namespace, podID string) error {
return r.kubeClient.Pods(namespace).Delete(podID)
return r.kubeClient.Pods(namespace).Delete(podID, nil)
}
// activePods type allows custom sorting of pods so an rc can pick the best ones to delete.

View File

@ -22,6 +22,7 @@ import (
"github.com/spf13/cobra"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
@ -73,6 +74,7 @@ func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command {
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on")
cmd.Flags().Bool("all", false, "[-all] to select all the specified resources")
cmd.Flags().Bool("cascade", true, "If true, cascade the delete resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.")
cmd.Flags().Int("grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.")
return cmd
}
@ -98,12 +100,12 @@ func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
// By default use a reaper to delete all related resources.
if cmdutil.GetFlagBool(cmd, "cascade") {
return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"))
return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), cmdutil.GetFlagInt(cmd, "grace-period"))
}
return DeleteResult(r, out)
}
func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefaultDelete bool) error {
func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefaultDelete bool, gracePeriod int) error {
found := 0
err := r.IgnoreErrors(errors.IsNotFound).Visit(func(info *resource.Info) error {
found++
@ -115,7 +117,11 @@ func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefault
}
return err
}
if _, err := reaper.Stop(info.Namespace, info.Name); err != nil {
var options *api.DeleteOptions
if gracePeriod >= 0 {
options = api.NewDeleteOptions(int64(gracePeriod))
}
if _, err := reaper.Stop(info.Namespace, info.Name, options); err != nil {
return err
}
fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name)

View File

@ -345,7 +345,7 @@ func addDeploymentKeyToReplicationController(oldRc *api.ReplicationController, c
for ix := range podList.Items {
pod := &podList.Items[ix]
if value, found := pod.Labels[deploymentKey]; !found || value != oldHash {
if err := client.Pods(namespace).Delete(pod.Name); err != nil {
if err := client.Pods(namespace).Delete(pod.Name, nil); err != nil {
return err
}
}

View File

@ -61,6 +61,7 @@ func NewCmdStop(f *cmdutil.Factory, out io.Writer) *cobra.Command {
kubectl.AddJsonFilenameFlag(cmd, &flags.Filenames, usage)
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on")
cmd.Flags().Bool("all", false, "[-all] to select all the specified resources")
cmd.Flags().Int("grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.")
return cmd
}
@ -82,5 +83,5 @@ func RunStop(f *cmdutil.Factory, cmd *cobra.Command, args []string, filenames ut
if r.Err() != nil {
return r.Err()
}
return ReapResult(r, f, out, false)
return ReapResult(r, f, out, false, cmdutil.GetFlagInt(cmd, "grace-period"))
}

View File

@ -20,6 +20,7 @@ import (
"fmt"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
)
@ -32,7 +33,7 @@ const (
// A Reaper handles terminating an object as gracefully as possible.
type Reaper interface {
Stop(namespace, name string) (string, error)
Stop(namespace, name string, gracePeriod *api.DeleteOptions) (string, error)
}
type NoSuchReaperError struct {
@ -76,7 +77,7 @@ type objInterface interface {
Get(name string) (meta.Interface, error)
}
func (reaper *ReplicationControllerReaper) Stop(namespace, name string) (string, error) {
func (reaper *ReplicationControllerReaper) Stop(namespace, name string, gracePeriod *api.DeleteOptions) (string, error) {
rc := reaper.ReplicationControllers(namespace)
resizer, err := ResizerFor("ReplicationController", NewResizerClient(*reaper))
if err != nil {
@ -91,19 +92,20 @@ func (reaper *ReplicationControllerReaper) Stop(namespace, name string) (string,
return fmt.Sprintf("%s stopped", name), nil
}
func (reaper *PodReaper) Stop(namespace, name string) (string, error) {
func (reaper *PodReaper) Stop(namespace, name string, gracePeriod *api.DeleteOptions) (string, error) {
pods := reaper.Pods(namespace)
_, err := pods.Get(name)
if err != nil {
return "", err
}
if err := pods.Delete(name); err != nil {
if err := pods.Delete(name, gracePeriod); err != nil {
return "", err
}
return fmt.Sprintf("%s stopped", name), nil
}
func (reaper *ServiceReaper) Stop(namespace, name string) (string, error) {
func (reaper *ServiceReaper) Stop(namespace, name string, gracePeriod *api.DeleteOptions) (string, error) {
services := reaper.Services(namespace)
_, err := services.Get(name)
if err != nil {

View File

@ -34,7 +34,7 @@ func TestReplicationControllerStop(t *testing.T) {
})
reaper := ReplicationControllerReaper{fake, time.Millisecond, time.Millisecond}
name := "foo"
s, err := reaper.Stop("default", name)
s, err := reaper.Stop("default", name, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -142,7 +142,7 @@ func TestSimpleStop(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v (%s)", err, test.test)
}
s, err := reaper.Stop("default", "foo")
s, err := reaper.Stop("default", "foo", nil)
if err != nil && !test.expectError {
t.Errorf("unexpected error: %v (%s)", err, test.test)
}

View File

@ -64,7 +64,7 @@ func (mc *basicMirrorClient) DeleteMirrorPod(podFullName string) error {
return err
}
glog.V(4).Infof("Deleting a mirror pod %q", podFullName)
if err := mc.apiserverClient.Pods(namespace).Delete(name); err != nil {
if err := mc.apiserverClient.Pods(namespace).Delete(name, nil); err != nil {
glog.Errorf("Failed deleting a mirror pod %q: %v", podFullName, err)
}
return nil

View File

@ -251,7 +251,7 @@ func deletePods(kubeClient client.Interface, ns string) error {
return err
}
for i := range items.Items {
err := kubeClient.Pods(ns).Delete(items.Items[i].Name)
err := kubeClient.Pods(ns).Delete(items.Items[i].Name, nil)
if err != nil {
return err
}

View File

@ -213,7 +213,7 @@ func ClusterLevelLoggingWithElasticsearch(c *client.Client) {
// Cleanup the pods when we are done.
defer func() {
for _, pod := range podNames {
if err = c.Pods(ns).Delete(pod); err != nil {
if err = c.Pods(ns).Delete(pod, nil); err != nil {
Logf("Failed to delete pod %s: %v", pod, err)
}
}

View File

@ -69,7 +69,7 @@ var _ = Describe("Events", func() {
By("submitting the pod to kubernetes")
defer func() {
By("deleting the pod")
podClient.Delete(pod.Name)
podClient.Delete(pod.Name, nil)
}()
if _, err := podClient.Create(pod); err != nil {
Failf("Failed to create pod: %v", err)

View File

@ -188,7 +188,7 @@ var _ = Describe("Networking", func() {
defer GinkgoRecover()
By("Cleaning up the webserver pods")
for _, podName := range podNames {
if err = c.Pods(namespace.Name).Delete(podName); err != nil {
if err = c.Pods(namespace.Name).Delete(podName, nil); err != nil {
Logf("Failed to delete pod %s: %v", podName, err)
}
}

View File

@ -82,8 +82,8 @@ var _ = Describe("PD", func() {
By("cleaning up PD-RW test environment")
// Teardown pods, PD. Ignore errors.
// Teardown should do nothing unless test failed.
podClient.Delete(host0Pod.Name)
podClient.Delete(host1Pod.Name)
podClient.Delete(host0Pod.Name, nil)
podClient.Delete(host1Pod.Name, nil)
detachPD(host0Name, diskName)
detachPD(host1Name, diskName)
deletePD(diskName)
@ -96,7 +96,7 @@ var _ = Describe("PD", func() {
expectNoError(waitForPodRunning(c, host0Pod.Name))
By("deleting host0Pod")
expectNoError(podClient.Delete(host0Pod.Name), "Failed to delete host0Pod")
expectNoError(podClient.Delete(host0Pod.Name, nil), "Failed to delete host0Pod")
By("submitting host1Pod to kubernetes")
_, err = podClient.Create(host1Pod)
@ -105,7 +105,7 @@ var _ = Describe("PD", func() {
expectNoError(waitForPodRunning(c, host1Pod.Name))
By("deleting host1Pod")
expectNoError(podClient.Delete(host1Pod.Name), "Failed to delete host1Pod")
expectNoError(podClient.Delete(host1Pod.Name, nil), "Failed to delete host1Pod")
By(fmt.Sprintf("deleting PD %q", diskName))
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")
// Teardown pods, PD. Ignore errors.
// Teardown should do nothing unless test failed.
podClient.Delete(rwPod.Name)
podClient.Delete(host0ROPod.Name)
podClient.Delete(host1ROPod.Name)
podClient.Delete(rwPod.Name, nil)
podClient.Delete(host0ROPod.Name, nil)
podClient.Delete(host1ROPod.Name, nil)
detachPD(host0Name, diskName)
detachPD(host1Name, diskName)
@ -155,7 +155,7 @@ var _ = Describe("PD", func() {
_, err = podClient.Create(rwPod)
expectNoError(err, "Failed to create rwPod")
expectNoError(waitForPodRunning(c, rwPod.Name))
expectNoError(podClient.Delete(rwPod.Name), "Failed to delete host0Pod")
expectNoError(podClient.Delete(rwPod.Name, nil), "Failed to delete host0Pod")
By("submitting host0ROPod to kubernetes")
_, err = podClient.Create(host0ROPod)
@ -170,10 +170,10 @@ var _ = Describe("PD", func() {
expectNoError(waitForPodRunning(c, host1ROPod.Name))
By("deleting host0ROPod")
expectNoError(podClient.Delete(host0ROPod.Name), "Failed to delete host0ROPod")
expectNoError(podClient.Delete(host0ROPod.Name, nil), "Failed to delete host0ROPod")
By("deleting host1ROPod")
expectNoError(podClient.Delete(host1ROPod.Name), "Failed to delete host1ROPod")
expectNoError(podClient.Delete(host1ROPod.Name, nil), "Failed to delete host1ROPod")
By(fmt.Sprintf("deleting PD %q", diskName))
for start := time.Now(); time.Since(start) < 180*time.Second; time.Sleep(5 * time.Second) {

View File

@ -44,7 +44,7 @@ func runLivenessTest(c *client.Client, podDescr *api.Pod) {
// At the end of the test, clean up by removing the pod.
defer func() {
By("deleting the pod")
c.Pods(ns).Delete(podDescr.Name)
c.Pods(ns).Delete(podDescr.Name, nil)
}()
// Wait until the pod is not pending. (Here we need to check for something other than
@ -87,7 +87,7 @@ func testHostIP(c *client.Client, pod *api.Pod) {
ns := "e2e-test-" + string(util.NewUUID())
podClient := c.Pods(ns)
By("creating pod")
defer podClient.Delete(pod.Name)
defer podClient.Delete(pod.Name, nil)
_, err := podClient.Create(pod)
if err != nil {
Fail(fmt.Sprintf("Failed to create pod: %v", err))
@ -191,7 +191,7 @@ var _ = Describe("Pods", func() {
// We call defer here in case there is a problem with
// the test so we can ensure that we clean up after
// ourselves
defer podClient.Delete(pod.Name)
defer podClient.Delete(pod.Name, nil)
_, err = podClient.Create(pod)
if err != nil {
Fail(fmt.Sprintf("Failed to create pod: %v", err))
@ -215,7 +215,7 @@ var _ = Describe("Pods", func() {
}
By("deleting the pod")
podClient.Delete(pod.Name)
podClient.Delete(pod.Name, nil)
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))
@ -278,7 +278,7 @@ var _ = Describe("Pods", func() {
By("submitting the pod to kubernetes")
defer func() {
By("deleting the pod")
podClient.Delete(pod.Name)
podClient.Delete(pod.Name, nil)
}()
pod, err := podClient.Create(pod)
if err != nil {
@ -342,7 +342,7 @@ var _ = Describe("Pods", func() {
},
},
}
defer c.Pods(api.NamespaceDefault).Delete(serverPod.Name)
defer c.Pods(api.NamespaceDefault).Delete(serverPod.Name, nil)
_, err := c.Pods(api.NamespaceDefault).Create(serverPod)
if err != nil {
Fail(fmt.Sprintf("Failed to create serverPod: %v", err))

View File

@ -103,7 +103,7 @@ func ServeImageOrFail(c *client.Client, test string, image string) {
if err != nil {
Logf("Failed to cleanup replication controller %v: %v.", controller.Name, err)
}
if _, err = rcReaper.Stop(ns, controller.Name); err != nil {
if _, err = rcReaper.Stop(ns, controller.Name, nil); err != nil {
Logf("Failed to stop replication controller %v: %v.", controller.Name, err)
}
}()

View File

@ -119,7 +119,7 @@ var _ = Describe("Services", func() {
defer func() {
By("deleting the pod")
defer GinkgoRecover()
podClient.Delete(pod.Name)
podClient.Delete(pod.Name, nil)
}()
if _, err := podClient.Create(pod); err != nil {
Failf("Failed to create %s pod: %v", pod.Name, err)
@ -220,7 +220,7 @@ var _ = Describe("Services", func() {
var names []string
defer func() {
for _, name := range names {
err := c.Pods(ns).Delete(name)
err := c.Pods(ns).Delete(name, nil)
Expect(err).NotTo(HaveOccurred())
}
}()
@ -237,13 +237,13 @@ var _ = Describe("Services", func() {
validateEndpointsOrFail(c, ns, serviceName, expectedPort, names)
err = c.Pods(ns).Delete(name1)
err = c.Pods(ns).Delete(name1, nil)
Expect(err).NotTo(HaveOccurred())
names = []string{name2}
validateEndpointsOrFail(c, ns, serviceName, expectedPort, names)
err = c.Pods(ns).Delete(name2)
err = c.Pods(ns).Delete(name2, nil)
Expect(err).NotTo(HaveOccurred())
names = []string{}
@ -323,7 +323,7 @@ var _ = Describe("Services", func() {
defer func() {
By("deleting pod " + pod.Name)
defer GinkgoRecover()
podClient.Delete(pod.Name)
podClient.Delete(pod.Name, nil)
}()
if _, err := podClient.Create(pod); err != nil {
Failf("Failed to create pod %s: %v", pod.Name, err)

View File

@ -363,7 +363,7 @@ func testContainerOutput(scenarioName string, c *client.Client, pod *api.Pod, ex
func testContainerOutputInNamespace(scenarioName string, c *client.Client, pod *api.Pod, expectedOutput []string, ns string) {
By(fmt.Sprintf("Creating a pod to test %v", scenarioName))
defer c.Pods(ns).Delete(pod.Name)
defer c.Pods(ns).Delete(pod.Name, nil)
if _, err := c.Pods(ns).Create(pod); err != nil {
Failf("Failed to create pod: %v", err)
}

View File

@ -145,7 +145,7 @@ func DoTestUnschedulableNodes(t *testing.T, client *client.Client) {
t.Errorf("Failed to schedule a pod: %v", err)
}
err = client.Pods(api.NamespaceDefault).Delete(myPod.Name)
err = client.Pods(api.NamespaceDefault).Delete(myPod.Name, nil)
if err != nil {
t.Errorf("Failed to delete pod: %v", err)
}

View File

@ -39,7 +39,7 @@ func init() {
}
func deletePodOrErrorf(t *testing.T, c *client.Client, ns, name string) {
if err := c.Pods(ns).Delete(name); err != nil {
if err := c.Pods(ns).Delete(name, nil); err != nil {
t.Errorf("unable to delete pod %v: %v", name, err)
}
}

View File

@ -206,7 +206,7 @@ func main() {
// Make several attempts to delete the pods.
for _, podName := range podNames {
for start := time.Now(); time.Since(start) < deleteTimeout; time.Sleep(1 * time.Second) {
if err = c.Pods(ns).Delete(podName); err == nil {
if err = c.Pods(ns).Delete(podName, nil); err == nil {
break
}
glog.Warningf("After %v failed to delete pod %s/%s: %v", time.Since(start), ns, podName, err)