mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #2232 from yichengq/319
fix the problem of StoreKeysPrefix key in store
This commit is contained in:
commit
a387e2a989
@ -141,7 +141,7 @@ type EtcdServer struct {
|
|||||||
// NewServer creates a new EtcdServer from the supplied configuration. The
|
// NewServer creates a new EtcdServer from the supplied configuration. The
|
||||||
// configuration is considered static for the lifetime of the EtcdServer.
|
// configuration is considered static for the lifetime of the EtcdServer.
|
||||||
func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
|
func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
|
||||||
st := store.New()
|
st := store.New(StoreAdminPrefix, StoreKeysPrefix)
|
||||||
var w *wal.WAL
|
var w *wal.WAL
|
||||||
var n raft.Node
|
var n raft.Node
|
||||||
var s *raft.MemoryStorage
|
var s *raft.MemoryStorage
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/jonboulle/clockwork"
|
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/jonboulle/clockwork"
|
||||||
etcdErr "github.com/coreos/etcd/error"
|
etcdErr "github.com/coreos/etcd/error"
|
||||||
|
"github.com/coreos/etcd/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The default version to set when the store is first initialized.
|
// The default version to set when the store is first initialized.
|
||||||
@ -68,21 +69,27 @@ type store struct {
|
|||||||
ttlKeyHeap *ttlKeyHeap // need to recovery manually
|
ttlKeyHeap *ttlKeyHeap // need to recovery manually
|
||||||
worldLock sync.RWMutex // stop the world lock
|
worldLock sync.RWMutex // stop the world lock
|
||||||
clock clockwork.Clock
|
clock clockwork.Clock
|
||||||
|
readonlySet types.Set
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() Store {
|
// The given namespaces will be created as initial directories in the returned store.
|
||||||
s := newStore()
|
func New(namespaces ...string) Store {
|
||||||
|
s := newStore(namespaces...)
|
||||||
s.clock = clockwork.NewRealClock()
|
s.clock = clockwork.NewRealClock()
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStore() *store {
|
func newStore(namespaces ...string) *store {
|
||||||
s := new(store)
|
s := new(store)
|
||||||
s.CurrentVersion = defaultVersion
|
s.CurrentVersion = defaultVersion
|
||||||
s.Root = newDir(s, "/", s.CurrentIndex, nil, "", Permanent)
|
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.Stats = newStats()
|
||||||
s.WatcherHub = newWatchHub(1000)
|
s.WatcherHub = newWatchHub(1000)
|
||||||
s.ttlKeyHeap = newTtlKeyHeap()
|
s.ttlKeyHeap = newTtlKeyHeap()
|
||||||
|
s.readonlySet = types.NewUnsafeSet(append(namespaces, "/")...)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +210,7 @@ func (s *store) CompareAndSwap(nodePath string, prevValue string, prevIndex uint
|
|||||||
|
|
||||||
nodePath = path.Clean(path.Join("/", nodePath))
|
nodePath = path.Clean(path.Join("/", nodePath))
|
||||||
// we do not allow the user to change "/"
|
// we do not allow the user to change "/"
|
||||||
if nodePath == "/" {
|
if s.readonlySet.Contains(nodePath) {
|
||||||
return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", s.CurrentIndex)
|
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))
|
nodePath = path.Clean(path.Join("/", nodePath))
|
||||||
// we do not allow the user to change "/"
|
// we do not allow the user to change "/"
|
||||||
if nodePath == "/" {
|
if s.readonlySet.Contains(nodePath) {
|
||||||
return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", s.CurrentIndex)
|
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))
|
nodePath = path.Clean(path.Join("/", nodePath))
|
||||||
// we do not allow the user to change "/"
|
// we do not allow the user to change "/"
|
||||||
if nodePath == "/" {
|
if s.readonlySet.Contains(nodePath) {
|
||||||
return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", s.CurrentIndex)
|
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))
|
nodePath = path.Clean(path.Join("/", nodePath))
|
||||||
|
|
||||||
// we do not allow the user to change "/"
|
// we do not allow the user to change "/"
|
||||||
if nodePath == "/" {
|
if s.readonlySet.Contains(nodePath) {
|
||||||
return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", currIndex)
|
return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", currIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,15 @@ import (
|
|||||||
etcdErr "github.com/coreos/etcd/error"
|
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.
|
// Ensure that the store can retrieve an existing value.
|
||||||
func TestStoreGetValue(t *testing.T) {
|
func TestStoreGetValue(t *testing.T) {
|
||||||
s := newStore()
|
s := newStore()
|
||||||
@ -433,22 +442,24 @@ func TestStoreDeleteDiretoryFailsIfNonRecursiveAndDir(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRootRdOnly(t *testing.T) {
|
func TestRootRdOnly(t *testing.T) {
|
||||||
s := newStore()
|
s := newStore("/0")
|
||||||
|
|
||||||
_, err := s.Set("/", true, "", Permanent)
|
for _, tt := range []string{"/", "/0"} {
|
||||||
|
_, err := s.Set(tt, true, "", Permanent)
|
||||||
assert.NotNil(t, err, "")
|
assert.NotNil(t, err, "")
|
||||||
|
|
||||||
_, err = s.Delete("/", true, true)
|
_, err = s.Delete(tt, true, true)
|
||||||
assert.NotNil(t, err, "")
|
assert.NotNil(t, err, "")
|
||||||
|
|
||||||
_, err = s.Create("/", true, "", false, Permanent)
|
_, err = s.Create(tt, true, "", false, Permanent)
|
||||||
assert.NotNil(t, err, "")
|
assert.NotNil(t, err, "")
|
||||||
|
|
||||||
_, err = s.Update("/", "", Permanent)
|
_, err = s.Update(tt, "", Permanent)
|
||||||
assert.NotNil(t, err, "")
|
assert.NotNil(t, err, "")
|
||||||
|
|
||||||
_, err = s.CompareAndSwap("/", "", 0, "", Permanent)
|
_, err = s.CompareAndSwap(tt, "", 0, "", Permanent)
|
||||||
assert.NotNil(t, err, "")
|
assert.NotNil(t, err, "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStoreCompareAndDeletePrevValue(t *testing.T) {
|
func TestStoreCompareAndDeletePrevValue(t *testing.T) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user