consulconsul-kv

Locking a KV with consul


I am trying to acquire a lock on a KV pair on consul while updating it, so no one else can update it.

Initially I have

curl -XGET http://localhost:8500/v1/kv/hosts?raw
{"k1":"v1"}

Now I get a session

curl -XPUT http://localhost:8500/v1/session/create
{"ID":"9ed55585-ddda-4605-a926-d1e0b57a9919"}

I then acquire a lock on KV

curl -XPUT http://localhost:8500/v1/kv/hosts?acquire=9ed55585-ddda-4605-a926-d1e0b57a9919

Now when I release and do a GET, my values are empty

curl -XPUT http://localhost:8500/v1/kv/hosts?release=9ed55585-ddda-4605-a926-d1e0b57a9919

curl -XGET http://localhost:8500/v1/kv/hosts?raw => This returns empty

Am I doing something wrong here.


Solution

  • You get nothing back because you did not send any data to write in your PUT request to the kv store.

    Here is the same commands, with some pretty printing.

    Create a session

     curl --request PUT http://localhost:8500/v1/session/create
     {"ID":"3619d9fd-8b8f-0b89-acdf-8d752b38a754"}
    

    Write a value

    Using a Linux "here file", I will write the value "Hello, World" under the host key. Remeber to use the session ID you got back from the previous command. Copy/Paste the 3 lines as a single unit.

    curl --request PUT http://localhost:8500/v1/kv/host?acquire=3619d9fd-8b8f-0b89-acdf-8d752b38a754 --data @- << EOF
    Hello, World
    EOF
    

    Read the value back

    Reading is just a GET, that I piped to a pretty printer.

    curl -s http://localhost:8500/v1/kv/host| python -m json.tool
    [
        {
            "CreateIndex": 3832257,
            "Flags": 0,
            "Key": "host",
            "LockIndex": 1,
            "ModifyIndex": 3832260,
            "Session": "3619d9fd-8b8f-0b89-acdf-8d752b38a754",
            "Value": "SGVsbG8sIFdvcmxk"
        }
    ]
    

    That base64 blob is the data we wrote the first time

    echo "SGVsbG8sIFdvcmxk" | openssl base64 -d -A
    Hello, World
    

    Try to write the value whithout the lock

    This does not work like you think. The K/V documentation says this

    an update that does not include the acquire parameter will proceed normally even if another session has locked the key

    Delete the session

    You could set a TTL to your session and wait for it to expire, but let's delete it.

    curl --request PUT http://localhost:8500/v1/session/destroy/3619d9fd-8b8f-0b89-acdf-8d752b38a754
    

    The value is still there, but not associated with a session anymore:

    curl -s http://localhost:8500/v1/kv/host| python -m json.tool
    [
        {
            "CreateIndex": 3832257,
            "Flags": 0,
            "Key": "host",
            "LockIndex": 0,
            "ModifyIndex": 3832331,
            "Value": "SGVsbG8sIFdvcmxk"
        }
    ]
    

    If you want keys to be deleted when the session expires or is deleted, specify "Behavior": "delete" when you create the session

    curl --request PUT http://localhost:8500/v1/session/create --data @- << EOF
    {
        "Name": "Helps with debugging",
        "Behavior": "delete",
        "TTL": "2m"
    }
    EOF
    {"ID":"45c17b06-b632-d17f-b0af-b2bee8f82511"}