etcdserver: Fix v2v3api set to create parent directly if not exists

When a new file is created under an non existent directly,
the v2 API automatically create the parent directly.
This commit aligns the behaviour of v2v3 emulation to comply with the v2
API.
This commit is contained in:
Iwasaki Yudai 2018-04-24 18:47:30 -07:00
parent 3da4c8a585
commit 3c25465855
2 changed files with 29 additions and 6 deletions

View File

@ -143,10 +143,20 @@ func (s *v2v3Store) Set(
ecode := 0
applyf := func(stm concurrency.STM) error {
parent := path.Dir(nodePath)
if !isRoot(parent) && stm.Rev(s.mkPath(parent)+"/") == 0 {
ecode = v2error.EcodeKeyNotFound
return nil
// build path if any directories in path do not exist
dirs := []string{}
for p := path.Dir(nodePath); !isRoot(p); p = path.Dir(p) {
pp := s.mkPath(p)
if stm.Rev(pp) > 0 {
ecode = v2error.EcodeNotDir
return nil
}
if stm.Rev(pp+"/") == 0 {
dirs = append(dirs, pp+"/")
}
}
for _, d := range dirs {
stm.Put(d, "")
}
key := s.mkPath(nodePath)

View File

@ -145,8 +145,21 @@ func TestSet(t *testing.T) {
testutil.AssertEqual(t, *e.PrevNode.Value, "bar")
testutil.AssertEqual(t, e.PrevNode.ModifiedIndex, uint64(2))
// Set /dir as a directory
// Set /a/b/c/d="efg"
eidx = 4
e, err = s.Set("/a/b/c/d", false, "efg", v2store.TTLOptionSet{ExpireTime: v2store.Permanent})
testutil.AssertNil(t, err)
testutil.AssertEqual(t, e.EtcdIndex, eidx)
testutil.AssertEqual(t, e.Node.Key, "/a/b/c/d")
testutil.AssertFalse(t, e.Node.Dir)
testutil.AssertEqual(t, *e.Node.Value, "efg")
testutil.AssertNil(t, e.Node.Nodes)
testutil.AssertNil(t, e.Node.Expiration)
testutil.AssertEqual(t, e.Node.TTL, int64(0))
testutil.AssertEqual(t, e.Node.ModifiedIndex, uint64(4))
// Set /dir as a directory
eidx = 5
e, err = s.Set("/dir", true, "", v2store.TTLOptionSet{ExpireTime: v2store.Permanent})
testutil.AssertNil(t, err)
testutil.AssertEqual(t, e.EtcdIndex, eidx)
@ -157,7 +170,7 @@ func TestSet(t *testing.T) {
testutil.AssertNil(t, e.Node.Nodes)
testutil.AssertNil(t, e.Node.Expiration)
testutil.AssertEqual(t, e.Node.TTL, int64(0))
testutil.AssertEqual(t, e.Node.ModifiedIndex, uint64(4))
testutil.AssertEqual(t, e.Node.ModifiedIndex, uint64(5))
}
// Ensure that the store can create a new key if it doesn't already exist.