Skip to content

Commit

Permalink
etcdserver: Fix v2v3api set to create parent directly if not exists
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Iwasaki Yudai committed Apr 26, 2018
1 parent 3da4c8a commit 3c25465
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 6 deletions.
18 changes: 14 additions & 4 deletions etcdserver/api/v2v3/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
17 changes: 15 additions & 2 deletions etcdserver/v2store/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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.
Expand Down

0 comments on commit 3c25465

Please sign in to comment.