Add command "kubectl replace". "kubectl update" is still supported as an alias.

"kubectl replace --patch" is NOT supported. It's moved to "kubectl patch" as a separate command in another commit.
This commit is contained in:
Chao Xu 2015-06-26 21:25:08 -07:00
parent ad12c98e6d
commit 9b3d42c090
16 changed files with 101 additions and 189 deletions

View File

@ -321,9 +321,9 @@ _kubectl_create()
must_have_one_noun=()
}
_kubectl_update()
_kubectl_replace()
{
last_command="kubectl_update"
last_command="kubectl_replace"
commands=()
flags=()
@ -342,13 +342,11 @@ _kubectl_update()
flags+=("--grace-period=")
flags+=("--help")
flags+=("-h")
flags+=("--patch=")
flags+=("--timeout=")
must_have_one_flag=()
must_have_one_flag+=("--filename=")
must_have_one_flag+=("-f")
must_have_one_flag+=("--patch=")
must_have_one_noun=()
}
@ -906,7 +904,7 @@ _kubectl()
commands+=("get")
commands+=("describe")
commands+=("create")
commands+=("update")
commands+=("replace")
commands+=("delete")
commands+=("namespace")
commands+=("logs")

View File

@ -20,9 +20,9 @@ kubectl_logs.md
kubectl_namespace.md
kubectl_port-forward.md
kubectl_proxy.md
kubectl_replace.md
kubectl_rolling-update.md
kubectl_run.md
kubectl_scale.md
kubectl_stop.md
kubectl_update.md
kubectl_version.md

View File

@ -44,7 +44,7 @@ pods are replicated, upgrades can be done without special coordination.
If you want more control over the upgrading process, you may use the following workflow:
1. Mark the node to be rebooted as unschedulable:
`kubectl update nodes $NODENAME --patch='{"apiVersion": "v1", "spec": {"unschedulable": true}}'`.
`kubectl replace nodes $NODENAME --patch='{"apiVersion": "v1", "spec": {"unschedulable": true}}'`.
This keeps new pods from landing on the node while you are trying to get them off.
1. Get the pods off the machine, via any of the following strategies:
1. wait for finite-duration pods to complete
@ -53,7 +53,7 @@ If you want more control over the upgrading process, you may use the following w
1. for pods with no replication controller, you need to bring up a new copy of the pod, and assuming it is not part of a service, redirect clients to it.
1. Work on the node
1. Make the node schedulable again:
`kubectl update nodes $NODENAME --patch='{"apiVersion": "v1", "spec": {"unschedulable": false}}'`.
`kubectl replace nodes $NODENAME --patch='{"apiVersion": "v1", "spec": {"unschedulable": false}}'`.
If you deleted the node's VM instance and created a new one, then a new schedulable node resource will
be created automatically when you create a new VM instance (if you're using a cloud provider that supports
node discovery; currently this is only Google Compute Engine, not including CoreOS on Google Compute Engine using kube-register). See [Node](node.md).

View File

@ -58,13 +58,13 @@ kubectl
* [kubectl namespace](kubectl_namespace.md) - SUPERCEDED: Set and view the current Kubernetes namespace
* [kubectl port-forward](kubectl_port-forward.md) - Forward one or more local ports to a pod.
* [kubectl proxy](kubectl_proxy.md) - Run a proxy to the Kubernetes API server
* [kubectl replace](kubectl_replace.md) - Replace a resource by filename or stdin.
* [kubectl rolling-update](kubectl_rolling-update.md) - Perform a rolling update of the given ReplicationController.
* [kubectl run](kubectl_run.md) - Run a particular image on the cluster.
* [kubectl scale](kubectl_scale.md) - Set a new size for a Replication Controller.
* [kubectl stop](kubectl_stop.md) - Gracefully shut down a resource by id or filename.
* [kubectl update](kubectl_update.md) - Update a resource by filename or stdin.
* [kubectl version](kubectl_version.md) - Print the client and server version information.
###### Auto generated by spf13/cobra at 2015-05-22 14:24:30.1784975 +0000 UTC
###### Auto generated by spf13/cobra at 2015-06-29 00:10:06.115525904 +0000 UTC
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/kubectl.md?pixel)]()

View File

@ -1,44 +1,40 @@
## kubectl update
## kubectl replace
Update a resource by filename or stdin.
Replace a resource by filename or stdin.
### Synopsis
Update a resource by filename or stdin.
Replace a resource by filename or stdin.
JSON and YAML formats are accepted.
```
kubectl update -f FILENAME
kubectl replace -f FILENAME
```
### Examples
```
// Update a pod using the data in pod.json.
$ kubectl update -f pod.json
// Replace a pod using the data in pod.json.
$ kubectl replace -f pod.json
// Update a pod based on the JSON passed into stdin.
$ cat pod.json | kubectl update -f -
// Replace a pod based on the JSON passed into stdin.
$ cat pod.json | kubectl replace -f -
// Partially update a node using strategic merge patch
kubectl --api-version=v1 update node k8s-node-1 --patch='{"spec":{"unschedulable":true}}'
// Force update, delete and then re-create the resource
kubectl update --force -f pod.json
// Force replace, delete and then re-create the resource
kubectl replace --force -f pod.json
```
### Options
```
--cascade=false: Only relevant during a force update. If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.
-f, --filename=[]: Filename, directory, or URL to file to use to update the resource.
--cascade=false: Only relevant during a force replace. If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.
-f, --filename=[]: Filename, directory, or URL to file to use to replace the resource.
--force=false: Delete and re-create the specified resource
--grace-period=-1: Only relevant during a force update. Period of time in seconds given to the old resource to terminate gracefully. Ignored if negative.
-h, --help=false: help for update
--patch="": A JSON document to override the existing resource. The resource is downloaded, patched with the JSON, then updated.
--timeout=0: Only relevant during a force update. The length of time to wait before giving up on a delete of the old resource, zero means determine a timeout from the size of the object
--grace-period=-1: Only relevant during a force replace. Period of time in seconds given to the old resource to terminate gracefully. Ignored if negative.
-h, --help=false: help for replace
--timeout=0: Only relevant during a force replace. The length of time to wait before giving up on a delete of the old resource, zero means determine a timeout from the size of the object
```
### Options inherited from parent commands
@ -73,6 +69,6 @@ kubectl update --force -f pod.json
### SEE ALSO
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-06-26 00:15:55.835055081 +0000 UTC
###### Auto generated by spf13/cobra at 2015-06-29 00:11:27.040756424 +0000 UTC
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/kubectl_update.md?pixel)]()
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/kubectl_replace.md?pixel)]()

View File

@ -19,10 +19,10 @@ kubectl-logs.1
kubectl-namespace.1
kubectl-port-forward.1
kubectl-proxy.1
kubectl-replace.1
kubectl-rolling-update.1
kubectl-run.1
kubectl-scale.1
kubectl-stop.1
kubectl-update.1
kubectl-version.1
kubectl.1

View File

@ -3,17 +3,17 @@
.SH NAME
.PP
kubectl update \- Update a resource by filename or stdin.
kubectl replace \- Replace a resource by filename or stdin.
.SH SYNOPSIS
.PP
\fBkubectl update\fP [OPTIONS]
\fBkubectl replace\fP [OPTIONS]
.SH DESCRIPTION
.PP
Update a resource by filename or stdin.
Replace a resource by filename or stdin.
.PP
JSON and YAML formats are accepted.
@ -22,11 +22,11 @@ JSON and YAML formats are accepted.
.SH OPTIONS
.PP
\fB\-\-cascade\fP=false
Only relevant during a force update. If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.
Only relevant during a force replace. If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.
.PP
\fB\-f\fP, \fB\-\-filename\fP=[]
Filename, directory, or URL to file to use to update the resource.
Filename, directory, or URL to file to use to replace the resource.
.PP
\fB\-\-force\fP=false
@ -34,19 +34,15 @@ JSON and YAML formats are accepted.
.PP
\fB\-\-grace\-period\fP=\-1
Only relevant during a force update. Period of time in seconds given to the old resource to terminate gracefully. Ignored if negative.
Only relevant during a force replace. Period of time in seconds given to the old resource to terminate gracefully. Ignored if negative.
.PP
\fB\-h\fP, \fB\-\-help\fP=false
help for update
.PP
\fB\-\-patch\fP=""
A JSON document to override the existing resource. The resource is downloaded, patched with the JSON, then updated.
help for replace
.PP
\fB\-\-timeout\fP=0
Only relevant during a force update. The length of time to wait before giving up on a delete of the old resource, zero means determine a timeout from the size of the object
Only relevant during a force replace. The length of time to wait before giving up on a delete of the old resource, zero means determine a timeout from the size of the object
.SH OPTIONS INHERITED FROM PARENT COMMANDS
@ -152,17 +148,14 @@ JSON and YAML formats are accepted.
.RS
.nf
// Update a pod using the data in pod.json.
$ kubectl update \-f pod.json
// Replace a pod using the data in pod.json.
$ kubectl replace \-f pod.json
// Update a pod based on the JSON passed into stdin.
$ cat pod.json | kubectl update \-f \-
// Replace a pod based on the JSON passed into stdin.
$ cat pod.json | kubectl replace \-f \-
// Partially update a node using strategic merge patch
kubectl \-\-api\-version=v1 update node k8s\-node\-1 \-\-patch='\{"spec":\{"unschedulable":true\}\}'
// Force update, delete and then re\-create the resource
kubectl update \-\-force \-f pod.json
// Force replace, delete and then re\-create the resource
kubectl replace \-\-force \-f pod.json
.fi
.RE

View File

@ -124,7 +124,7 @@ Find more information at
.SH SEE ALSO
.PP
\fBkubectl\-get(1)\fP, \fBkubectl\-describe(1)\fP, \fBkubectl\-create(1)\fP, \fBkubectl\-update(1)\fP, \fBkubectl\-delete(1)\fP, \fBkubectl\-namespace(1)\fP, \fBkubectl\-logs(1)\fP, \fBkubectl\-rolling\-update(1)\fP, \fBkubectl\-scale(1)\fP, \fBkubectl\-exec(1)\fP, \fBkubectl\-port\-forward(1)\fP, \fBkubectl\-proxy(1)\fP, \fBkubectl\-run(1)\fP, \fBkubectl\-stop(1)\fP, \fBkubectl\-expose(1)\fP, \fBkubectl\-label(1)\fP, \fBkubectl\-config(1)\fP, \fBkubectl\-cluster\-info(1)\fP, \fBkubectl\-api\-versions(1)\fP, \fBkubectl\-version(1)\fP,
\fBkubectl\-get(1)\fP, \fBkubectl\-describe(1)\fP, \fBkubectl\-create(1)\fP, \fBkubectl\-replace(1)\fP, \fBkubectl\-delete(1)\fP, \fBkubectl\-namespace(1)\fP, \fBkubectl\-logs(1)\fP, \fBkubectl\-rolling\-update(1)\fP, \fBkubectl\-scale(1)\fP, \fBkubectl\-exec(1)\fP, \fBkubectl\-port\-forward(1)\fP, \fBkubectl\-proxy(1)\fP, \fBkubectl\-run(1)\fP, \fBkubectl\-stop(1)\fP, \fBkubectl\-expose(1)\fP, \fBkubectl\-label(1)\fP, \fBkubectl\-config(1)\fP, \fBkubectl\-cluster\-info(1)\fP, \fBkubectl\-api\-versions(1)\fP, \fBkubectl\-version(1)\fP,
.SH HISTORY

View File

@ -146,7 +146,7 @@ node, but will not affect any existing pods on the node. This is useful as a
preparatory step before a node reboot, etc. For example, to mark a node
unschedulable, run this command:
```
kubectl update nodes 10.1.2.3 --patch='{"apiVersion": "v1", "unschedulable": true}'
kubectl replace nodes 10.1.2.3 --patch='{"apiVersion": "v1", "unschedulable": true}'
```
### Node capacity

View File

@ -377,21 +377,13 @@ for version in "${kube_api_versions[@]}"; do
kubectl create -f examples/limitrange/valid-pod.json "${kube_flags[@]}"
# Post-condition: valid-pod POD is running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
## --patch update pod can change image
# Pre-condition: valid-pod POD is running
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
## --force replace pod can change other field, e.g., spec.container.name
# Command
kubectl update "${kube_flags[@]}" pod valid-pod --patch='{"spec":{"containers":[{"name": "kubernetes-serve-hostname", "image": "nginx"}]}}'
# Post-condition: valid-pod POD has image nginx
kube::test::get_object_assert pods "{{range.items}}{{$image_field}}:{{end}}" 'nginx:'
## --force update pod can change other field, e.g., spec.container.name
# Command
kubectl get "${kube_flags[@]}" pod valid-pod -o json | sed 's/"kubernetes-serve-hostname"/"update-k8s-serve-hostname"/g' > tmp-valid-pod.json
kubectl update "${kube_flags[@]}" --force -f tmp-valid-pod.json
# Post-condition: spec.container.name = "update-k8s-serve-hostname"
kube::test::get_object_assert 'pod valid-pod' "{{(index .spec.containers 0).name}}" 'update-k8s-serve-hostname'
kubectl get "${kube_flags[@]}" pod valid-pod -o json | sed 's/"kubernetes-serve-hostname"/"replaced-k8s-serve-hostname"/g' > tmp-valid-pod.json
kubectl replace "${kube_flags[@]}" --force -f tmp-valid-pod.json
# Post-condition: spec.container.name = "replaced-k8s-serve-hostname"
kube::test::get_object_assert 'pod valid-pod' "{{(index .spec.containers 0).name}}" 'replaced-k8s-serve-hostname'
### Overwriting an existing label is not permitted
# Pre-condition: name is valid-pod
@ -528,7 +520,7 @@ __EOF__
kube::test::get_object_assert services "{{range.items}}{{$id_field}}:{{end}}" 'kubernetes:redis-master:service-.*-test:'
### Identity
kubectl get service "${kube_flags[@]}" service-${version}-test -o json | kubectl update "${kube_flags[@]}" -f -
kubectl get service "${kube_flags[@]}" service-${version}-test -o json | kubectl replace "${kube_flags[@]}" -f -
### Delete services by id
# Pre-condition: redis-master-service service is running
@ -711,16 +703,6 @@ __EOF__
kube::test::describe_object_assert nodes "127.0.0.1" "Name:" "Labels:" "CreationTimestamp:" "Conditions:" "Addresses:" "Capacity:" "Pods:"
### --patch update can mark node unschedulable
# Pre-condition: node is schedulable
kube::test::get_object_assert "nodes 127.0.0.1" "{{.spec.unschedulable}}" '<no value>'
kubectl update "${kube_flags[@]}" nodes "127.0.0.1" --patch='{"spec":{"unschedulable":true}}'
# Post-condition: node is unschedulable
kube::test::get_object_assert "nodes 127.0.0.1" "{{.spec.unschedulable}}" 'true'
kubectl update "${kube_flags[@]}" nodes "127.0.0.1" --patch='{"spec":{"unschedulable":null}}'
# Post-condition: node is schedulable
kube::test::get_object_assert "nodes 127.0.0.1" "{{.spec.unschedulable}}" '<no value>'
###########
# Nodes #
###########

View File

@ -114,7 +114,7 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
cmds.AddCommand(NewCmdGet(f, out))
cmds.AddCommand(NewCmdDescribe(f, out))
cmds.AddCommand(NewCmdCreate(f, out))
cmds.AddCommand(NewCmdUpdate(f, out))
cmds.AddCommand(NewCmdReplace(f, out))
cmds.AddCommand(NewCmdDelete(f, out))
cmds.AddCommand(NewCmdNamespace(out))

View File

@ -83,7 +83,7 @@ func updateObject(info *resource.Info, updateFn func(runtime.Object) (runtime.Ob
return nil, err
}
_, err = helper.Update(info.Namespace, info.Name, true, data)
_, err = helper.Replace(info.Namespace, info.Name, true, data)
if err != nil {
return nil, err
}

View File

@ -19,10 +19,10 @@ package cmd
import (
"fmt"
"io"
"os"
"github.com/spf13/cobra"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
@ -31,47 +31,47 @@ import (
)
const (
update_long = `Update a resource by filename or stdin.
replace_long = `Replace a resource by filename or stdin.
JSON and YAML formats are accepted.`
update_example = `// Update a pod using the data in pod.json.
$ kubectl update -f pod.json
replace_example = `// Replace a pod using the data in pod.json.
$ kubectl replace -f pod.json
// Update a pod based on the JSON passed into stdin.
$ cat pod.json | kubectl update -f -
// Replace a pod based on the JSON passed into stdin.
$ cat pod.json | kubectl replace -f -
// Partially update a node using strategic merge patch
kubectl --api-version=v1 update node k8s-node-1 --patch='{"spec":{"unschedulable":true}}'
// Force update, delete and then re-create the resource
kubectl update --force -f pod.json`
// Force replace, delete and then re-create the resource
kubectl replace --force -f pod.json`
)
func NewCmdUpdate(f *cmdutil.Factory, out io.Writer) *cobra.Command {
func NewCmdReplace(f *cmdutil.Factory, out io.Writer) *cobra.Command {
var filenames util.StringList
cmd := &cobra.Command{
Use: "update -f FILENAME",
Short: "Update a resource by filename or stdin.",
Long: update_long,
Example: update_example,
Use: "replace -f FILENAME",
// update is deprecated.
Aliases: []string{"update"},
Short: "Replace a resource by filename or stdin.",
Long: replace_long,
Example: replace_example,
Run: func(cmd *cobra.Command, args []string) {
err := RunUpdate(f, out, cmd, args, filenames)
cmdutil.CheckCustomErr("Update failed", err)
err := RunReplace(f, out, cmd, args, filenames)
cmdutil.CheckCustomErr("Replace failed", err)
},
}
usage := "Filename, directory, or URL to file to use to update the resource."
usage := "Filename, directory, or URL to file to use to replace the resource."
kubectl.AddJsonFilenameFlag(cmd, &filenames, usage)
cmd.MarkFlagRequired("filename")
cmd.Flags().String("patch", "", "A JSON document to override the existing resource. The resource is downloaded, patched with the JSON, then updated.")
cmd.MarkFlagRequired("patch")
cmd.Flags().Bool("force", false, "Delete and re-create the specified resource")
cmd.Flags().Bool("cascade", false, "Only relevant during a force update. If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.")
cmd.Flags().Int("grace-period", -1, "Only relevant during a force update. Period of time in seconds given to the old resource to terminate gracefully. Ignored if negative.")
cmd.Flags().Duration("timeout", 0, "Only relevant during a force update. The length of time to wait before giving up on a delete of the old resource, zero means determine a timeout from the size of the object")
cmd.Flags().Bool("cascade", false, "Only relevant during a force replace. If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.")
cmd.Flags().Int("grace-period", -1, "Only relevant during a force replace. Period of time in seconds given to the old resource to terminate gracefully. Ignored if negative.")
cmd.Flags().Duration("timeout", 0, "Only relevant during a force replace. The length of time to wait before giving up on a delete of the old resource, zero means determine a timeout from the size of the object")
return cmd
}
func RunUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error {
func RunReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error {
if os.Args[1] == "update" {
printDeprecationWarning("replace", "update")
}
schema, err := f.Validator()
if err != nil {
return err
@ -83,32 +83,12 @@ func RunUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
}
force := cmdutil.GetFlagBool(cmd, "force")
patch := cmdutil.GetFlagString(cmd, "patch")
if len(filenames) == 0 && len(patch) == 0 {
return cmdutil.UsageError(cmd, "Must specify --filename or --patch to update")
}
if len(filenames) != 0 && len(patch) != 0 {
return cmdutil.UsageError(cmd, "Can not specify both --filename and --patch")
}
if len(filenames) == 0 && force {
return cmdutil.UsageError(cmd, "--force can only be used with --filename")
}
// TODO: Make patching work with -f, updating with patched JSON input files
if len(filenames) == 0 {
name, err := updateWithPatch(cmd, args, f, patch)
if err != nil {
return err
}
fmt.Fprintf(out, "%s\n", name)
return nil
}
if len(filenames) == 0 {
return cmdutil.UsageError(cmd, "Must specify --filename to update")
return cmdutil.UsageError(cmd, "Must specify --filename to replace")
}
if force {
return forceUpdate(f, out, cmd, args, filenames)
return forceReplace(f, out, cmd, args, filenames)
}
mapper, typer := f.Object()
@ -127,11 +107,11 @@ func RunUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
return r.Visit(func(info *resource.Info) error {
data, err := info.Mapping.Codec.Encode(info.Object)
if err != nil {
return cmdutil.AddSourceToErr("updating", info.Source, err)
return cmdutil.AddSourceToErr("replacing", info.Source, err)
}
obj, err := resource.NewHelper(info.Client, info.Mapping).Update(info.Namespace, info.Name, true, data)
obj, err := resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, true, data)
if err != nil {
return cmdutil.AddSourceToErr("updating", info.Source, err)
return cmdutil.AddSourceToErr("replacing", info.Source, err)
}
info.Refresh(obj, true)
printObjectSpecificMessage(obj, out)
@ -140,44 +120,7 @@ func RunUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
})
}
func updateWithPatch(cmd *cobra.Command, args []string, f *cmdutil.Factory, patch string) (string, error) {
cmdNamespace, err := f.DefaultNamespace()
if err != nil {
return "", err
}
mapper, typer := f.Object()
r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()).
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
ResourceTypeOrNameArgs(false, args...).
Flatten().
Do()
err = r.Err()
if err != nil {
return "", err
}
mapping, err := r.ResourceMapping()
if err != nil {
return "", err
}
client, err := f.RESTClient(mapping)
if err != nil {
return "", err
}
infos, err := r.Infos()
if err != nil {
return "", err
}
name, namespace := infos[0].Name, infos[0].Namespace
helper := resource.NewHelper(client, mapping)
_, err = helper.Patch(namespace, name, api.StrategicMergePatchType, []byte(patch))
return name, err
}
func forceUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error {
func forceReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error {
schema, err := f.Validator()
if err != nil {
return err
@ -200,7 +143,7 @@ func forceUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
if err != nil {
return err
}
//Update will create a resource if it doesn't exist already, so ignore not found error
//Replace will create a resource if it doesn't exist already, so ignore not found error
ignoreNotFound := true
// By default use a reaper to delete all related resources.
if cmdutil.GetFlagBool(cmd, "cascade") {
@ -245,7 +188,7 @@ func forceUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
return err
}
if count == 0 {
return fmt.Errorf("no objects passed to update")
return fmt.Errorf("no objects passed to replace")
}
return nil
}

View File

@ -25,7 +25,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
)
func TestUpdateObject(t *testing.T) {
func TestReplaceObject(t *testing.T) {
_, _, rc := testData()
f, tf, codec := NewAPIFactory()
@ -47,7 +47,7 @@ func TestUpdateObject(t *testing.T) {
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdUpdate(f, buf)
cmd := NewCmdReplace(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Run(cmd, []string{})
@ -66,7 +66,7 @@ func TestUpdateObject(t *testing.T) {
}
}
func TestUpdateMultipleObject(t *testing.T) {
func TestReplaceMultipleObject(t *testing.T) {
_, svc, rc := testData()
f, tf, codec := NewAPIFactory()
@ -92,7 +92,7 @@ func TestUpdateMultipleObject(t *testing.T) {
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdUpdate(f, buf)
cmd := NewCmdReplace(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.yaml")
cmd.Run(cmd, []string{})
@ -111,7 +111,7 @@ func TestUpdateMultipleObject(t *testing.T) {
}
}
func TestUpdateDirectory(t *testing.T) {
func TestReplaceDirectory(t *testing.T) {
_, svc, rc := testData()
f, tf, codec := NewAPIFactory()
@ -137,7 +137,7 @@ func TestUpdateDirectory(t *testing.T) {
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdUpdate(f, buf)
cmd := NewCmdReplace(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook")
cmd.Flags().Set("namespace", "test")
cmd.Run(cmd, []string{})
@ -157,7 +157,7 @@ func TestUpdateDirectory(t *testing.T) {
}
}
func TestForceUpdateObjectNotFound(t *testing.T) {
func TestForceReplaceObjectNotFound(t *testing.T) {
_, _, rc := testData()
f, tf, codec := NewAPIFactory()
@ -179,7 +179,7 @@ func TestForceUpdateObjectNotFound(t *testing.T) {
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdUpdate(f, buf)
cmd := NewCmdReplace(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Flags().Set("force", "true")
cmd.Flags().Set("cascade", "false")

View File

@ -143,27 +143,27 @@ func (m *Helper) Patch(namespace, name string, pt api.PatchType, data []byte) (r
Get()
}
func (m *Helper) Update(namespace, name string, overwrite bool, data []byte) (runtime.Object, error) {
func (m *Helper) Replace(namespace, name string, overwrite bool, data []byte) (runtime.Object, error) {
c := m.RESTClient
obj, err := m.Codec.Decode(data)
if err != nil {
// We don't know how to handle this object, but update it anyway
return m.updateResource(c, m.Resource, namespace, name, data)
// We don't know how to handle this object, but replace it anyway
return m.replaceResource(c, m.Resource, namespace, name, data)
}
// Attempt to version the object based on client logic.
version, err := m.Versioner.ResourceVersion(obj)
if err != nil {
// We don't know how to version this object, so send it to the server as is
return m.updateResource(c, m.Resource, namespace, name, data)
return m.replaceResource(c, m.Resource, namespace, name, data)
}
if version == "" && overwrite {
// Retrieve the current version of the object to overwrite the server object
serverObj, err := c.Get().Namespace(namespace).Resource(m.Resource).Name(name).Do().Get()
if err != nil {
// The object does not exist, but we want it to be created
return m.updateResource(c, m.Resource, namespace, name, data)
return m.replaceResource(c, m.Resource, namespace, name, data)
}
serverVersion, err := m.Versioner.ResourceVersion(serverObj)
if err != nil {
@ -179,9 +179,9 @@ func (m *Helper) Update(namespace, name string, overwrite bool, data []byte) (ru
data = newData
}
return m.updateResource(c, m.Resource, namespace, name, data)
return m.replaceResource(c, m.Resource, namespace, name, data)
}
func (m *Helper) updateResource(c RESTClient, resource, namespace, name string, data []byte) (runtime.Object, error) {
func (m *Helper) replaceResource(c RESTClient, resource, namespace, name string, data []byte) (runtime.Object, error) {
return c.Put().NamespaceIfScoped(namespace, m.NamespaceScoped).Resource(resource).Name(name).Body(data).Do().Get()
}

View File

@ -363,7 +363,7 @@ func TestHelperList(t *testing.T) {
}
}
func TestHelperUpdate(t *testing.T) {
func TestHelperReplace(t *testing.T) {
expectPut := func(req *http.Request) bool {
if req.Method != "PUT" {
t.Errorf("unexpected method: %#v", req)
@ -457,7 +457,7 @@ func TestHelperUpdate(t *testing.T) {
if test.Object != nil {
data = []byte(runtime.EncodeOrDie(testapi.Codec(), test.Object))
}
_, err := modifier.Update("bar", "foo", test.Overwrite, data)
_, err := modifier.Replace("bar", "foo", test.Overwrite, data)
if (err != nil) != test.Err {
t.Errorf("%d: unexpected error: %t %v", i, test.Err, err)
}