瀏覽代碼

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.
Iwasaki Yudai 7 年之前
父節點
當前提交
3c25465855
共有 2 個文件被更改,包括 29 次插入6 次删除
  1. 14 4
      etcdserver/api/v2v3/store.go
  2. 15 2
      etcdserver/v2store/store_test.go

+ 14 - 4
etcdserver/api/v2v3/store.go

@@ -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)

+ 15 - 2
etcdserver/v2store/store_test.go

@@ -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.