feat(storage): add basic implementation of storage

This is an in-memory storage layer for storing releases. This will be
superseded by the Kubernetes ConfigMap implementtion.
pull/613/head
Matt Butcher 9 years ago
parent a4a0c79fc4
commit fa6a33c349

@ -12,6 +12,10 @@ var DefaultEngine = GoTplEngine
// EngineYard maps engine names to engine implementations.
type EngineYard map[string]Engine
// Get retrieves a template engine by name.
//
// If no matching template engine is found, the second return value will
// be false.
func (y EngineYard) Get(k string) (Engine, bool) {
e, ok := y[k]
return e, ok
@ -49,8 +53,16 @@ type Engine interface {
//
// Release storage must be concurrency safe.
type ReleaseStorage interface {
// Get takes a name and returns the accompanying release.
Get(key string) (*hapi.Release, error)
// Set saves the release with the given name.
Set(key string, val *hapi.Release) error
// List lists all active (non-deleted, non-superseded) releases.
//
// To get deleted or superseded releases, use Query.
List() ([]*hapi.Release, error)
// Query takes a map of labels and returns any releases that match.
Query(map[string]string) ([]*hapi.Release, error)
}
// KubeClient represents a client capable of communicating with the Kubernetes API.

@ -27,6 +27,14 @@ func (r *mockReleaseStorage) Set(k string, v *hapi.Release) error {
return nil
}
func (r *mockReleaseStorage) List() ([]*hapi.Release, error) {
return []*hapi.Release{}, nil
}
func (r *mockReleaseStorage) Query(labels map[string]string) ([]*hapi.Release, error) {
return []*hapi.Release{}, nil
}
type mockKubeClient struct {
}

@ -9,7 +9,10 @@ import (
"github.com/deis/tiller/pkg/hapi"
)
// Engine is an implementation of 'cmd/tiller/environment'.Engine that uses Go templates.
type Engine struct {
// FuncMap contains the template functions that will be passed to each
// render call. This may only be modified before the first call to Render.
FuncMap template.FuncMap
}

@ -0,0 +1,7 @@
/*Package storage implements storage for Tiller objects.
Tiller stores releases (see 'cmd/tiller/environment'.Environment). The backend
storage mechanism may be implemented with different backends. This package
and its subpackages provide storage layers for Tiller objects.
*/
package storage

@ -0,0 +1,53 @@
package storage
import (
"errors"
"github.com/deis/tiller/pkg/hapi"
)
// Memory is an in-memory ReleaseStorage implementation.
type Memory struct {
releases map[string]*hapi.Release
}
func NewMemory() *Memory {
return &Memory{
releases: map[string]*hapi.Release{},
}
}
var ErrNotFound = errors.New("release not found")
// Get returns the named Release.
//
// If the release is not found, an ErrNotFound error is returned.
func (m *Memory) Get(k string) (*hapi.Release, error) {
v, ok := m.releases[k]
if !ok {
return v, ErrNotFound
}
return v, nil
}
// Set sets a release.
//
// TODO: Is there any reason why Set doesn't just use the release name?
func (m *Memory) Set(k string, rel *hapi.Release) error {
m.releases[k] = rel
return nil
}
// List returns all releases
func (m *Memory) List() ([]*hapi.Release, error) {
buf := make([]*hapi.Release, len(m.releases))
i := 0
for _, v := range m.releases {
buf[i] = v
i++
}
return buf, nil
}
func (m *Memory) Query(labels map[string]string) ([]*hapi.Release, error) {
return []*hapi.Release{}, errors.New("Cannot implement until hapi.Release is defined.")
}

@ -0,0 +1,70 @@
package storage
import (
"testing"
"github.com/deis/tiller/pkg/hapi"
)
func TestSet(t *testing.T) {
k := "test-1"
r := &hapi.Release{Name: k}
ms := NewMemory()
if err := ms.Set(k, r); err != nil {
t.Fatalf("Failed set: %s", err)
}
if ms.releases[k].Name != k {
t.Errorf("Unexpected release name: %s", ms.releases[k].Name)
}
}
func TestGet(t *testing.T) {
k := "test-1"
r := &hapi.Release{Name: k}
ms := NewMemory()
ms.Set(k, r)
if out, err := ms.Get(k); err != nil {
t.Errorf("Could not get %s: %s", k, err)
} else if out.Name != k {
t.Errorf("Expected %s, got %s", k, out.Name)
}
}
func TestList(t *testing.T) {
ms := NewMemory()
rels := []string{"a", "b", "c"}
for _, k := range rels {
ms.Set(k, &hapi.Release{Name: k})
}
l, err := ms.List()
if err != nil {
t.Error(err)
}
if len(l) != 3 {
t.Errorf("Expected 3, got %d", len(l))
}
for _, n := range rels {
foundN := false
for _, rr := range l {
if rr.Name == n {
foundN = true
break
}
}
if !foundN {
t.Errorf("Did not find %s in list.", n)
}
}
}
func TestQuery(t *testing.T) {
t.Skip("Not Implemented")
}
Loading…
Cancel
Save