mirror of https://github.com/hashicorp/consul
Fix CAS operations for put
parent
85350a4329
commit
39fb70ff67
|
@ -92,7 +92,6 @@ func (c *KVPutCommand) Run(args []string) int {
|
||||||
httpAddr := HTTPAddrFlag(cmdFlags)
|
httpAddr := HTTPAddrFlag(cmdFlags)
|
||||||
datacenter := cmdFlags.String("datacenter", "", "")
|
datacenter := cmdFlags.String("datacenter", "", "")
|
||||||
token := cmdFlags.String("token", "", "")
|
token := cmdFlags.String("token", "", "")
|
||||||
stale := cmdFlags.Bool("stale", false, "")
|
|
||||||
cas := cmdFlags.Bool("cas", false, "")
|
cas := cmdFlags.Bool("cas", false, "")
|
||||||
flags := cmdFlags.Uint64("flags", 0, "")
|
flags := cmdFlags.Uint64("flags", 0, "")
|
||||||
modifyIndex := cmdFlags.Uint64("modify-index", 0, "")
|
modifyIndex := cmdFlags.Uint64("modify-index", 0, "")
|
||||||
|
@ -111,11 +110,18 @@ func (c *KVPutCommand) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Session is reauired for release or acquire
|
||||||
if (*release || *acquire) && *session == "" {
|
if (*release || *acquire) && *session == "" {
|
||||||
c.Ui.Error("Error! Missing -session (required with -acquire and -release)")
|
c.Ui.Error("Error! Missing -session (required with -acquire and -release)")
|
||||||
return 1
|
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
|
// Create and test the HTTP client
|
||||||
conf := api.DefaultConfig()
|
conf := api.DefaultConfig()
|
||||||
conf.Address = *httpAddr
|
conf.Address = *httpAddr
|
||||||
|
@ -141,23 +147,6 @@ func (c *KVPutCommand) Run(args []string) int {
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case *cas:
|
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)
|
ok, _, err := client.KV().CAS(pair, wo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Error! Did not write to %s: %s", key, err))
|
c.Ui.Error(fmt.Sprintf("Error! Did not write to %s: %s", key, err))
|
||||||
|
|
|
@ -37,6 +37,10 @@ func TestKVPutCommand_Validation(t *testing.T) {
|
||||||
[]string{"-release", "foo"},
|
[]string{"-release", "foo"},
|
||||||
"Missing -session",
|
"Missing -session",
|
||||||
},
|
},
|
||||||
|
"-cas no -modify-index": {
|
||||||
|
[]string{"-cas", "foo"},
|
||||||
|
"Must specify -modify-index",
|
||||||
|
},
|
||||||
"no key": {
|
"no key": {
|
||||||
[]string{},
|
[]string{},
|
||||||
"Missing KEY argument",
|
"Missing KEY argument",
|
||||||
|
@ -224,35 +228,6 @@ func TestKVPutCommand_CAS(t *testing.T) {
|
||||||
defer srv.Shutdown()
|
defer srv.Shutdown()
|
||||||
waitForLeader(t, srv.httpAddr)
|
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.
|
// Create the initial pair so it has a ModifyIndex.
|
||||||
pair := &api.KVPair{
|
pair := &api.KVPair{
|
||||||
Key: "foo",
|
Key: "foo",
|
||||||
|
|
|
@ -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 `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
|
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
|
string for safe transport during reads. The client will transparently handle the
|
||||||
and decoding of these values.
|
encoding and decoding of these values.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -36,8 +36,7 @@ Usage: `consul kv put [options] KEY [DATA]`
|
||||||
for their use case. The default value is 0 (no flags).
|
for their use case. The default value is 0 (no flags).
|
||||||
|
|
||||||
* `-modify-index=<int>` - Unsigned integer representing the ModifyIndex of the
|
* `-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
|
key. This is used in combination with the -cas flag.
|
||||||
any key. The default value is 0.
|
|
||||||
|
|
||||||
* `-release` - Forfeit the lock on the key at the givne path. This requires the
|
* `-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
|
-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
|
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
|
To specify flags on the key, use the `-flags` option. These flags are completely
|
||||||
controlled by the user:
|
controlled by the user:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue