add truncindex

fix #222

Signed-off-by: yanxuean <yan.xuean@zte.com.cn>
This commit is contained in:
yanxuean
2017-09-09 09:25:31 +08:00
parent 0e6e593481
commit 5ee3423820
18 changed files with 1452 additions and 116 deletions

View File

@@ -20,6 +20,7 @@ import (
"sync"
"github.com/containerd/containerd"
"github.com/docker/docker/pkg/truncindex"
cio "github.com/kubernetes-incubator/cri-containerd/pkg/server/io"
"github.com/kubernetes-incubator/cri-containerd/pkg/store"
@@ -92,7 +93,7 @@ func (c *Container) Delete() error {
type Store struct {
lock sync.RWMutex
containers map[string]Container
// TODO(random-liu): Add trunc index.
idIndex *truncindex.TruncIndex
}
// LoadStore loads containers from runtime.
@@ -101,7 +102,10 @@ func LoadStore() *Store { return nil }
// NewStore creates a container store.
func NewStore() *Store {
return &Store{containers: make(map[string]Container)}
return &Store{
containers: make(map[string]Container),
idIndex: truncindex.NewTruncIndex([]string{}),
}
}
// Add a container into the store. Returns store.ErrAlreadyExist if the
@@ -112,6 +116,9 @@ func (s *Store) Add(c Container) error {
if _, ok := s.containers[c.ID]; ok {
return store.ErrAlreadyExist
}
if err := s.idIndex.Add(c.ID); err != nil {
return err
}
s.containers[c.ID] = c
return nil
}
@@ -121,6 +128,13 @@ func (s *Store) Add(c Container) error {
func (s *Store) Get(id string) (Container, error) {
s.lock.RLock()
defer s.lock.RUnlock()
id, err := s.idIndex.Get(id)
if err != nil {
if err == truncindex.ErrNotExist {
err = store.ErrNotExist
}
return Container{}, err
}
if c, ok := s.containers[id]; ok {
return c, nil
}
@@ -142,5 +156,12 @@ func (s *Store) List() []Container {
func (s *Store) Delete(id string) {
s.lock.Lock()
defer s.lock.Unlock()
id, err := s.idIndex.Get(id)
if err != nil {
// Note: The idIndex.Delete and delete doesn't handle truncated index.
// So we need to return if there are error.
return
}
s.idIndex.Delete(id) // nolint: errcheck
delete(s.containers, id)
}

View File

@@ -28,7 +28,6 @@ import (
)
func TestContainerStore(t *testing.T) {
ids := []string{"1", "2", "3"}
metadatas := map[string]Metadata{
"1": {
ID: "1",
@@ -43,32 +42,44 @@ func TestContainerStore(t *testing.T) {
ImageRef: "TestImage-1",
LogPath: "/test/log/path/1",
},
"2": {
ID: "2",
Name: "Container-2",
SandboxID: "Sandbox-2",
"2abcd": {
ID: "2abcd",
Name: "Container-2abcd",
SandboxID: "Sandbox-2abcd",
Config: &runtime.ContainerConfig{
Metadata: &runtime.ContainerMetadata{
Name: "TestPod-2",
Name: "TestPod-2abcd",
Attempt: 2,
},
},
ImageRef: "TestImage-2",
LogPath: "/test/log/path/2",
},
"3": {
ID: "3",
Name: "Container-3",
SandboxID: "Sandbox-3",
"4a333": {
ID: "4a333",
Name: "Container-4a333",
SandboxID: "Sandbox-4a333",
Config: &runtime.ContainerConfig{
Metadata: &runtime.ContainerMetadata{
Name: "TestPod-3",
Name: "TestPod-4a333",
Attempt: 3,
},
},
ImageRef: "TestImage-3",
LogPath: "/test/log/path/3",
},
"4abcd": {
ID: "4abcd",
Name: "Container-4abcd",
SandboxID: "Sandbox-4abcd",
Config: &runtime.ContainerConfig{
Metadata: &runtime.ContainerMetadata{
Name: "TestPod-4abcd",
Attempt: 1,
},
},
ImageRef: "TestImage-4abcd",
},
}
statuses := map[string]Status{
"1": {
@@ -80,29 +91,39 @@ func TestContainerStore(t *testing.T) {
Reason: "TestReason-1",
Message: "TestMessage-1",
},
"2": {
"2abcd": {
Pid: 2,
CreatedAt: time.Now().UnixNano(),
StartedAt: time.Now().UnixNano(),
FinishedAt: time.Now().UnixNano(),
ExitCode: 2,
Reason: "TestReason-2",
Message: "TestMessage-2",
Reason: "TestReason-2abcd",
Message: "TestMessage-2abcd",
},
"3": {
"4a333": {
Pid: 3,
CreatedAt: time.Now().UnixNano(),
StartedAt: time.Now().UnixNano(),
FinishedAt: time.Now().UnixNano(),
ExitCode: 3,
Reason: "TestReason-3",
Message: "TestMessage-3",
Reason: "TestReason-4a333",
Message: "TestMessage-4a333",
Removing: true,
},
"4abcd": {
Pid: 4,
CreatedAt: time.Now().UnixNano(),
StartedAt: time.Now().UnixNano(),
FinishedAt: time.Now().UnixNano(),
ExitCode: 4,
Reason: "TestReason-4abcd",
Message: "TestMessage-4abcd",
Removing: true,
},
}
assert := assertlib.New(t)
containers := map[string]Container{}
for _, id := range ids {
for id := range metadatas {
container, err := NewContainer(
metadatas[id],
WithFakeStatus(statuses[id]),
@@ -119,29 +140,35 @@ func TestContainerStore(t *testing.T) {
}
t.Logf("should be able to get container")
genTruncIndex := func(normalName string) string { return normalName[:(len(normalName)+1)/2] }
for id, c := range containers {
got, err := s.Get(id)
got, err := s.Get(genTruncIndex(id))
assert.NoError(err)
assert.Equal(c, got)
}
t.Logf("should be able to list containers")
cs := s.List()
assert.Len(cs, 3)
assert.Len(cs, len(containers))
testID := "2"
t.Logf("add should return already exists error for duplicated container")
assert.Equal(store.ErrAlreadyExist, s.Add(containers[testID]))
cntrNum := len(containers)
for testID, v := range containers {
truncID := genTruncIndex(testID)
t.Logf("should be able to delete container")
s.Delete(testID)
cs = s.List()
assert.Len(cs, 2)
t.Logf("add should return already exists error for duplicated container")
assert.Equal(store.ErrAlreadyExist, s.Add(v))
t.Logf("get should return not exist error after deletion")
c, err := s.Get(testID)
assert.Equal(Container{}, c)
assert.Equal(store.ErrNotExist, err)
t.Logf("should be able to delete container")
s.Delete(truncID)
cntrNum--
cs = s.List()
assert.Len(cs, cntrNum)
t.Logf("get should return not exist error after deletion")
c, err := s.Get(truncID)
assert.Equal(Container{}, c)
assert.Equal(store.ErrNotExist, err)
}
}
func TestWithContainerIO(t *testing.T) {