Browse Source

Merge pull request #2232 from yichengq/319

fix the problem of StoreKeysPrefix key in store
Yicheng Qin 11 years ago
parent
commit
a387e2a989
3 changed files with 37 additions and 19 deletions
  1. 1 1
      etcdserver/server.go
  2. 14 7
      store/store.go
  3. 22 11
      store/store_test.go

+ 1 - 1
etcdserver/server.go

@@ -141,7 +141,7 @@ type EtcdServer struct {
 // NewServer creates a new EtcdServer from the supplied configuration. The
 // configuration is considered static for the lifetime of the EtcdServer.
 func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
-	st := store.New()
+	st := store.New(StoreAdminPrefix, StoreKeysPrefix)
 	var w *wal.WAL
 	var n raft.Node
 	var s *raft.MemoryStorage

+ 14 - 7
store/store.go

@@ -25,6 +25,7 @@ import (
 
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/jonboulle/clockwork"
 	etcdErr "github.com/coreos/etcd/error"
+	"github.com/coreos/etcd/pkg/types"
 )
 
 // The default version to set when the store is first initialized.
@@ -68,21 +69,27 @@ type store struct {
 	ttlKeyHeap     *ttlKeyHeap  // need to recovery manually
 	worldLock      sync.RWMutex // stop the world lock
 	clock          clockwork.Clock
+	readonlySet    types.Set
 }
 
-func New() Store {
-	s := newStore()
+// The given namespaces will be created as initial directories in the returned store.
+func New(namespaces ...string) Store {
+	s := newStore(namespaces...)
 	s.clock = clockwork.NewRealClock()
 	return s
 }
 
-func newStore() *store {
+func newStore(namespaces ...string) *store {
 	s := new(store)
 	s.CurrentVersion = defaultVersion
 	s.Root = newDir(s, "/", s.CurrentIndex, nil, "", Permanent)
+	for _, namespace := range namespaces {
+		s.Root.Add(newDir(s, namespace, s.CurrentIndex, s.Root, "", Permanent))
+	}
 	s.Stats = newStats()
 	s.WatcherHub = newWatchHub(1000)
 	s.ttlKeyHeap = newTtlKeyHeap()
+	s.readonlySet = types.NewUnsafeSet(append(namespaces, "/")...)
 	return s
 }
 
@@ -203,7 +210,7 @@ func (s *store) CompareAndSwap(nodePath string, prevValue string, prevIndex uint
 
 	nodePath = path.Clean(path.Join("/", nodePath))
 	// we do not allow the user to change "/"
-	if nodePath == "/" {
+	if s.readonlySet.Contains(nodePath) {
 		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", s.CurrentIndex)
 	}
 
@@ -258,7 +265,7 @@ func (s *store) Delete(nodePath string, dir, recursive bool) (*Event, error) {
 
 	nodePath = path.Clean(path.Join("/", nodePath))
 	// we do not allow the user to change "/"
-	if nodePath == "/" {
+	if s.readonlySet.Contains(nodePath) {
 		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", s.CurrentIndex)
 	}
 
@@ -401,7 +408,7 @@ func (s *store) Update(nodePath string, newValue string, expireTime time.Time) (
 
 	nodePath = path.Clean(path.Join("/", nodePath))
 	// we do not allow the user to change "/"
-	if nodePath == "/" {
+	if s.readonlySet.Contains(nodePath) {
 		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", s.CurrentIndex)
 	}
 
@@ -461,7 +468,7 @@ func (s *store) internalCreate(nodePath string, dir bool, value string, unique,
 	nodePath = path.Clean(path.Join("/", nodePath))
 
 	// we do not allow the user to change "/"
-	if nodePath == "/" {
+	if s.readonlySet.Contains(nodePath) {
 		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", currIndex)
 	}
 

+ 22 - 11
store/store_test.go

@@ -23,6 +23,15 @@ import (
 	etcdErr "github.com/coreos/etcd/error"
 )
 
+func TestNewStoreWithNamespaces(t *testing.T) {
+	s := newStore("/0", "/1")
+
+	_, err := s.Get("/0", false, false)
+	assert.Nil(t, err, "")
+	_, err = s.Get("/1", false, false)
+	assert.Nil(t, err, "")
+}
+
 // Ensure that the store can retrieve an existing value.
 func TestStoreGetValue(t *testing.T) {
 	s := newStore()
@@ -433,22 +442,24 @@ func TestStoreDeleteDiretoryFailsIfNonRecursiveAndDir(t *testing.T) {
 }
 
 func TestRootRdOnly(t *testing.T) {
-	s := newStore()
+	s := newStore("/0")
 
-	_, err := s.Set("/", true, "", Permanent)
-	assert.NotNil(t, err, "")
+	for _, tt := range []string{"/", "/0"} {
+		_, err := s.Set(tt, true, "", Permanent)
+		assert.NotNil(t, err, "")
 
-	_, err = s.Delete("/", true, true)
-	assert.NotNil(t, err, "")
+		_, err = s.Delete(tt, true, true)
+		assert.NotNil(t, err, "")
 
-	_, err = s.Create("/", true, "", false, Permanent)
-	assert.NotNil(t, err, "")
+		_, err = s.Create(tt, true, "", false, Permanent)
+		assert.NotNil(t, err, "")
 
-	_, err = s.Update("/", "", Permanent)
-	assert.NotNil(t, err, "")
+		_, err = s.Update(tt, "", Permanent)
+		assert.NotNil(t, err, "")
 
-	_, err = s.CompareAndSwap("/", "", 0, "", Permanent)
-	assert.NotNil(t, err, "")
+		_, err = s.CompareAndSwap(tt, "", 0, "", Permanent)
+		assert.NotNil(t, err, "")
+	}
 }
 
 func TestStoreCompareAndDeletePrevValue(t *testing.T) {