add driver package to encapsulate storage backends

pull/1008/head
fibonacci1729 8 years ago
parent 943eadec38
commit 6dd5c9783e

@ -0,0 +1,53 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package driver // import "k8s.io/helm/pkg/storage/driver"
import (
"errors"
rspb "k8s.io/helm/pkg/proto/hapi/release"
)
var (
// ErrReleaseNotFound indicates that a release is not found.
ErrReleaseNotFound = errors.New("release not found")
// Temporary error while WIP.
ErrNotImplemented = errors.New("not implemented")
)
type Creator interface {
Create(*rspb.Release) error
}
type Updator interface {
Update(*rspb.Release) error
}
type Deletor interface {
Delete(string) (*rspb.Release, error)
}
type Queryor interface {
Get(string) (*rspb.Release, error)
All(string, ...interface{}) ([]*rspb.Release, error)
}
type Driver interface {
Creator
Updator
Deletor
Queryor
}

@ -0,0 +1,106 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package driver // import "k8s.io/helm/pkg/storage/driver"
import (
"sync"
rspb "k8s.io/helm/pkg/proto/hapi/release"
)
// Memory is an in-memory storage driver implementation.
type Memory struct {
sync.RWMutex
cache map[string]*rspb.Release
}
func NewMemory() *Memory {
return &Memory{cache: map[string]*rspb.Release{}}
}
// Get returns the release named by key.
func (mem *Memory) Get(key string) (*rspb.Release, error) {
defer unlock(mem.rlock())
if rls, ok := mem.cache[key]; ok {
return rls, nil
}
return nil, ErrReleaseNotFound
}
// All returns all releases whose status is not Status_DELETED.
func (mem *Memory) All(key string, opts ...interface{}) ([]*rspb.Release, error) {
defer unlock(mem.rlock())
var releases []*rspb.Release
for _, rls := range mem.cache {
if rls.Info.Status.Code != rspb.Status_DELETED {
releases = append(releases, rls)
}
}
return releases, nil
}
// Create creates a new release or error.
func (mem *Memory) Create(rls *rspb.Release) error {
defer unlock(mem.wlock())
mem.cache[rls.Name] = rls
return nil
}
// Update updates a release or error.
func (mem *Memory) Update(rls *rspb.Release) error {
defer unlock(mem.wlock())
if old, ok := mem.cache[rls.Name]; ok {
// FIXME: when release update is complete, old release should
// be marked as superseded, creating the new release.
_ = old
mem.cache[rls.Name] = rls
return nil
}
return ErrReleaseNotFound
}
// Delete deletes a release or error.
func (mem *Memory) Delete(key string) (*rspb.Release, error) {
defer unlock(mem.wlock())
if old, ok := mem.cache[key]; ok {
old.Info.Status.Code = rspb.Status_DELETED
delete(mem.cache, key)
return old, nil
}
return nil, ErrReleaseNotFound
}
func (mem *Memory) wlock() func() {
mem.Lock()
return func() {
mem.Unlock()
}
}
func (mem *Memory) rlock() func() {
mem.RLock()
return func() {
mem.RUnlock()
}
}
func unlock(fn func()) { fn() }

@ -0,0 +1,92 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package driver // import "k8s.io/helm/pkg/storage/driver"
import (
"testing"
rspb "k8s.io/helm/pkg/proto/hapi/release"
)
func TestMemoryGet(t *testing.T) {
key := "test-1"
rls := &rspb.Release{Name: key}
mem := NewMemory()
mem.Create(rls)
res, err := mem.Get(key)
switch {
case err != nil:
t.Errorf("Could not get %s: %s", key, err)
case res.Name != key:
t.Errorf("Expected %s, got %s", key, res.Name)
}
}
func TestMemoryAll(t *testing.T) {
t.Skip("MemoryAll")
}
func TestMemoryCreate(t *testing.T) {
key := "test-1"
rls := &rspb.Release{Name: key}
mem := NewMemory()
err := mem.Create(rls)
switch {
case err != nil:
t.Fatalf("Failed create: %s", err)
case mem.cache[key].Name != key:
t.Errorf("Unexpected release name: %s", mem.cache[key].Name)
}
}
func TestMemoryUpdate(t *testing.T) {
key := "test-1"
rls := &rspb.Release{Name: key}
mem := NewMemory()
if err := mem.Create(rls); err != nil {
t.Fatalf("Failed create: %s", err)
}
if err := mem.Update(rls); err != nil {
t.Fatalf("Failed update: %s", err)
}
if mem.cache[key].Name != key {
t.Errorf("Unexpected release name: %s", mem.cache[key].Name)
}
}
func TestMemoryDelete(t *testing.T) {
key := "test-1"
rls := &rspb.Release{Name: key}
mem := NewMemory()
if err := mem.Create(rls); err != nil {
t.Fatalf("Failed create: %s", err)
}
res, err := mem.Delete(key)
switch {
case err != nil:
t.Fatalf("Failed delete: %s", err)
case mem.cache[key] != nil:
t.Errorf("Expected nil, got %s", mem.cache[key])
case res.Info.Status.Code != release.Status_DELETED:
t.Errorf("Expected Status_DELETED, got %s", res.Info.Status.Code)
}
}
Loading…
Cancel
Save