Browse Source

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 năm trước cách đây
mục cha
commit
3c25465855
2 tập tin đã thay đổi với 29 bổ sung6 xóa
  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.