Fix CAS operations for put

This commit is contained in:
Seth Vargo 2016-09-26 16:06:32 -07:00
parent 9cd78ea4d4
commit 70fd7efde9
No known key found for this signature in database
GPG key ID: 905A90C2949E8787
3 changed files with 14 additions and 60 deletions

View file

@ -92,7 +92,6 @@ func (c *KVPutCommand) Run(args []string) int {
httpAddr := HTTPAddrFlag(cmdFlags)
datacenter := cmdFlags.String("datacenter", "", "")
token := cmdFlags.String("token", "", "")
stale := cmdFlags.Bool("stale", false, "")
cas := cmdFlags.Bool("cas", false, "")
flags := cmdFlags.Uint64("flags", 0, "")
modifyIndex := cmdFlags.Uint64("modify-index", 0, "")
@ -111,11 +110,18 @@ func (c *KVPutCommand) Run(args []string) int {
return 1
}
// Session is reauired for release or acquire
if (*release || *acquire) && *session == "" {
c.Ui.Error("Error! Missing -session (required with -acquire and -release)")
return 1
}
// ModifyIndex is required for CAS
if *cas && *modifyIndex == 0 {
c.Ui.Error("Must specify -modify-index with -cas!")
return 1
}
// Create and test the HTTP client
conf := api.DefaultConfig()
conf.Address = *httpAddr
@ -141,23 +147,6 @@ func (c *KVPutCommand) Run(args []string) int {
switch {
case *cas:
// If the user did not supply a -modify-index, but wants a check-and-set,
// grab the current modify index and store that on the key.
if pair.ModifyIndex == 0 {
currentPair, _, err := client.KV().Get(key, &api.QueryOptions{
Datacenter: *datacenter,
Token: *token,
AllowStale: *stale,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Error! Could not get current key: %s", err))
return 1
}
if currentPair != nil {
pair.ModifyIndex = currentPair.ModifyIndex
}
}
ok, _, err := client.KV().CAS(pair, wo)
if err != nil {
c.Ui.Error(fmt.Sprintf("Error! Did not write to %s: %s", key, err))

View file

@ -37,6 +37,10 @@ func TestKVPutCommand_Validation(t *testing.T) {
[]string{"-release", "foo"},
"Missing -session",
},
"-cas no -modify-index": {
[]string{"-cas", "foo"},
"Must specify -modify-index",
},
"no key": {
[]string{},
"Missing KEY argument",
@ -224,35 +228,6 @@ func TestKVPutCommand_CAS(t *testing.T) {
defer srv.Shutdown()
waitForLeader(t, srv.httpAddr)
ui := new(cli.MockUi)
c := &KVPutCommand{Ui: ui}
args := []string{
"-http-addr=" + srv.httpAddr,
"-cas",
"foo", "a",
}
code := c.Run(args)
if code != 0 {
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
}
data, _, err := client.KV().Get("foo", nil)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(data.Value, []byte("a")) {
t.Errorf("bad: %#v", data.Value)
}
}
func TestKVPutCommand_CASModifyIndex(t *testing.T) {
srv, client := testAgentWithAPIClient(t)
defer srv.Shutdown()
waitForLeader(t, srv.httpAddr)
// Create the initial pair so it has a ModifyIndex.
pair := &api.KVPair{
Key: "foo",

View file

@ -10,8 +10,8 @@ Command: `consul kv put`
The `kv put` command writes the data to the given path in the key-value store.
The data can be of any type, but it will be transported as a base64-encoded
string for safe transport. The client will transparently handle the encoding
and decoding of these values.
string for safe transport during reads. The client will transparently handle the
encoding and decoding of these values.
## Usage
@ -36,8 +36,7 @@ Usage: `consul kv put [options] KEY [DATA]`
for their use case. The default value is 0 (no flags).
* `-modify-index=<int>` - Unsigned integer representing the ModifyIndex of the
key. This is often combined with the -cas flag, but it can be specified for
any key. The default value is 0.
key. This is used in combination with the -cas flag.
* `-release` - Forfeit the lock on the key at the givne path. This requires the
-session flag to be set. The key must be held by the session in order to be
@ -107,15 +106,6 @@ $ consul kv put -cas -modify-index=456 redis/config/connections 10
Success! Data written to: redis/config/connections
```
It is also possible to have Consul fetch the current ModifyIndex before making
the query, by omitting the `-modify-index` flag. If the data is changed between
the initial read and the write, the operation will fail.
```
$ consul kv put -cas redis/config/connections 10
Success! Data written to: redis/config/connections
```
To specify flags on the key, use the `-flags` option. These flags are completely
controlled by the user: