git2consul icon indicating copy to clipboard operation
git2consul copied to clipboard

git2consul incorrectly removes key from consul

Open khernyo opened this issue 9 years ago • 2 comments

Steps to reproduce:

  1. Init repo and add foo.txt
$ git init .
$ echo foo >foo.txt
$ git add foo.txt 
$ git commit -m.
  1. Start git2consul and wait for it to insert the data into consul
  2. Copy foo.txt into directory foobar
$ mkdir foobar
$ cp foo.txt foobar/
$ git add foobar/
$ git commit -m.
  1. Wait for git2consul to pick up the changes: It correctly inserts "foo" into the key "foobar/foo" in consul.
  2. Remove foo.txt
$ rm foo.txt 
$ git add foo.txt 
$ git commit -m.
  1. Wait for git2consul to pick up the changes.

It incorrectly removes both "foo" and "foobar/foo" from consul (it should only remove "foo" and leave "foobar/foo" in consul).

I used the following git2consul config (you will need to change the repo url to make it usable):

{
    "version": "1.0",
    "logger": {
        "name": "git2consul",
        "streams": [{
            "level": "trace",
            "stream": "process.stdout"
        }]
    },
    "repos" : [{
        "name" : "config",
        "url" : "git@localhost:user/repo.git",
        "expand_keys": true,
        "include_branch_name": false,
        "ignore_file_extension": true,
        "branches" : ["master"],
        "hooks": [{
            "type" : "polling",
            "interval" : "1"
        }]
    }]
}

khernyo avatar Nov 14 '16 21:11 khernyo

@khernyo I was not able to reproduce your issue. I see you have trace level logging enabled. Can you provide any relevant details from the logs? Also, make sure you are using the most recent version.

davidnewman avatar Nov 18 '16 21:11 davidnewman

I'm using git2consul v0.12.13 and consul v0.7.0 and I can reproduce it. I did some digging and the issue is the following:

Let's put something in config/foobar/foo in the KV store:

$ curl -X PUT -d "foo" consul:8500/v1/kv/config/foobar/foo
true
$ curl consul:8500/v1/kv/config/foobar/foo
[{"LockIndex":0,"Key":"config/foobar/foo","Flags":0,"Value":"Zm9v","CreateIndex":956,"ModifyIndex":956}]
$

Now delete config/foo and check that config/foobar/foo is still there:

$ curl -X DELETE consul:8500/v1/kv/config/foo?recurse=true
true
$ curl consul:8500/v1/kv/config/foobar/foo
$ 

Well, it's gone. The reason is that recurse=true deletes all keys with the specified prefix, but the prefix check is string based and not path segment based. Appending a / to the path excludes config/foobar but it also excludes config/foo, so it seems that two DELETE requests are needed to achieve what we want:

$ curl -X PUT -d "foo" consul:8500/v1/kv/config/foobar/foo
true
$ curl -X PUT -d "foo" consul:8500/v1/kv/config/foo
true
$ curl -X DELETE consul:8500/v1/kv/config/foo/?recurse=true
true
$ curl consul:8500/v1/kv/config/foo
[{"LockIndex":0,"Key":"config/foo","Flags":0,"Value":"Zm9v","CreateIndex":1093,"ModifyIndex":1093}]
$ curl consul:8500/v1/kv/config/foobar/foo
[{"LockIndex":0,"Key":"config/foobar/foo","Flags":0,"Value":"Zm9v","CreateIndex":956,"ModifyIndex":956}]
$ curl -X DELETE consul:8500/v1/kv/config/foo
true
$ curl consul:8500/v1/kv/config/foo
$ curl consul:8500/v1/kv/config/foobar/foo
[{"LockIndex":0,"Key":"config/foobar/foo","Flags":0,"Value":"Zm9v","CreateIndex":956,"ModifyIndex":956}]
$

I have the logs and also a tcpdump if you are interested, but I think it's irrelevant now. Everything seems fine except for the trailing / in the DELETE request.

khernyo avatar Nov 19 '16 14:11 khernyo