Merge pull request #32 from technosophos/feat/helm-install

feat(tiller): add template and release to install
pull/613/head
Matt Butcher 9 years ago
commit 77322a5f06

@ -18,7 +18,7 @@ message Chart {
hapi.chart.Metadata metadata = 1; hapi.chart.Metadata metadata = 1;
// Templates for this chart. // Templates for this chart.
hapi.chart.Templates templates = 2; repeated hapi.chart.Template templates = 2;
// Charts that this chart depends on. // Charts that this chart depends on.
repeated Chart dependencies = 3; repeated Chart dependencies = 3;

@ -4,20 +4,14 @@ package hapi.chart;
option go_package = "chart"; option go_package = "chart";
// Template represents a template as a name/value pair.
// //
// Template: // By convention, name is a relative path within the scope of the chart's
// // base directory.
// TODO
//
message Templates {
// TODO
repeated Template templates = 1;
}
message Template { message Template {
// TODO // Name is the path-like name of the template.
string template_name = 1; string name = 1;
// TODO // Data is the template as byte data.
bytes template_data = 2; bytes data = 2;
} }

@ -2,7 +2,8 @@ package environment
import ( import (
"github.com/deis/tiller/pkg/engine" "github.com/deis/tiller/pkg/engine"
"github.com/deis/tiller/pkg/hapi" "github.com/deis/tiller/pkg/proto/hapi/chart"
"github.com/deis/tiller/pkg/proto/hapi/release"
"github.com/deis/tiller/pkg/storage" "github.com/deis/tiller/pkg/storage"
) )
@ -51,7 +52,7 @@ func (y EngineYard) Default() Engine {
// An Engine must be capable of executing multiple concurrent requests, but // An Engine must be capable of executing multiple concurrent requests, but
// without tainting one request's environment with data from another request. // without tainting one request's environment with data from another request.
type Engine interface { type Engine interface {
Render(*hapi.Chart, *hapi.Values) (map[string]string, error) Render(*chart.Chart, *chart.Config) (map[string]string, error)
} }
// ReleaseStorage represents a storage engine for a Release. // ReleaseStorage represents a storage engine for a Release.
@ -64,14 +65,14 @@ type ReleaseStorage interface {
// If a release with the same name exists, this returns an error. // If a release with the same name exists, this returns an error.
// //
// It may return other errors in cases where it cannot write to storage. // It may return other errors in cases where it cannot write to storage.
Create(*hapi.Release) error Create(*release.Release) error
// Read takes a name and returns a release that has that name. // Read takes a name and returns a release that has that name.
// //
// It will only return releases that are not deleted and not superseded. // It will only return releases that are not deleted and not superseded.
// //
// It will return an error if no relevant release can be found, or if storage // It will return an error if no relevant release can be found, or if storage
// is not properly functioning. // is not properly functioning.
Read(name string) (*hapi.Release, error) Read(name string) (*release.Release, error)
// Update looks for a release with the same name and updates it with the // Update looks for a release with the same name and updates it with the
// present release contents. // present release contents.
@ -81,24 +82,24 @@ type ReleaseStorage interface {
// //
// It will return an error if a previous release is not found. It may also // It will return an error if a previous release is not found. It may also
// return an error if the storage backend encounters an error. // return an error if the storage backend encounters an error.
Update(*hapi.Release) error Update(*release.Release) error
// Delete marks a Release as deleted. // Delete marks a Release as deleted.
// //
// It returns the deleted record. If the record is not found or if the // It returns the deleted record. If the record is not found or if the
// underlying storage encounters an error, this will return an error. // underlying storage encounters an error, this will return an error.
Delete(name string) (*hapi.Release, error) Delete(name string) (*release.Release, error)
// List lists all active (non-deleted, non-superseded) releases. // List lists all active (non-deleted, non-superseded) releases.
// //
// To get deleted or superseded releases, use Query. // To get deleted or superseded releases, use Query.
List() ([]*hapi.Release, error) List() ([]*release.Release, error)
// Query takes a map of labels and returns any releases that match. // Query takes a map of labels and returns any releases that match.
// //
// Query will search all releases, including deleted and superseded ones. // Query will search all releases, including deleted and superseded ones.
// The provided map will be used to filter results. // The provided map will be used to filter results.
Query(map[string]string) ([]*hapi.Release, error) Query(map[string]string) ([]*release.Release, error)
} }
// KubeClient represents a client capable of communicating with the Kubernetes API. // KubeClient represents a client capable of communicating with the Kubernetes API.

@ -3,45 +3,46 @@ package environment
import ( import (
"testing" "testing"
"github.com/deis/tiller/pkg/hapi" "github.com/deis/tiller/pkg/proto/hapi/chart"
"github.com/deis/tiller/pkg/proto/hapi/release"
) )
type mockEngine struct { type mockEngine struct {
out map[string]string out map[string]string
} }
func (e *mockEngine) Render(chrt *hapi.Chart, v *hapi.Values) (map[string]string, error) { func (e *mockEngine) Render(chrt *chart.Chart, v *chart.Config) (map[string]string, error) {
return e.out, nil return e.out, nil
} }
type mockReleaseStorage struct { type mockReleaseStorage struct {
rel *hapi.Release rel *release.Release
} }
func (r *mockReleaseStorage) Create(v *hapi.Release) error { func (r *mockReleaseStorage) Create(v *release.Release) error {
r.rel = v r.rel = v
return nil return nil
} }
func (r *mockReleaseStorage) Read(k string) (*hapi.Release, error) { func (r *mockReleaseStorage) Read(k string) (*release.Release, error) {
return r.rel, nil return r.rel, nil
} }
func (r *mockReleaseStorage) Update(v *hapi.Release) error { func (r *mockReleaseStorage) Update(v *release.Release) error {
r.rel = v r.rel = v
return nil return nil
} }
func (r *mockReleaseStorage) Delete(k string) (*hapi.Release, error) { func (r *mockReleaseStorage) Delete(k string) (*release.Release, error) {
return r.rel, nil return r.rel, nil
} }
func (r *mockReleaseStorage) List() ([]*hapi.Release, error) { func (r *mockReleaseStorage) List() ([]*release.Release, error) {
return []*hapi.Release{}, nil return []*release.Release{}, nil
} }
func (r *mockReleaseStorage) Query(labels map[string]string) ([]*hapi.Release, error) { func (r *mockReleaseStorage) Query(labels map[string]string) ([]*release.Release, error) {
return []*hapi.Release{}, nil return []*release.Release{}, nil
} }
type mockKubeClient struct { type mockKubeClient struct {
@ -63,7 +64,7 @@ func TestEngine(t *testing.T) {
if engine, ok := env.EngineYard.Get("test"); !ok { if engine, ok := env.EngineYard.Get("test"); !ok {
t.Errorf("failed to get engine from EngineYard") t.Errorf("failed to get engine from EngineYard")
} else if out, err := engine.Render(&hapi.Chart{}, &hapi.Values{}); err != nil { } else if out, err := engine.Render(&chart.Chart{}, &chart.Config{}); err != nil {
t.Errorf("unexpected template error: %s", err) t.Errorf("unexpected template error: %s", err)
} else if out["albatross"] != "test" { } else if out["albatross"] != "test" {
t.Errorf("expected 'test', got %q", out["albatross"]) t.Errorf("expected 'test', got %q", out["albatross"])
@ -75,7 +76,7 @@ func TestReleaseStorage(t *testing.T) {
env := New() env := New()
env.Releases = rs env.Releases = rs
release := &hapi.Release{Name: "mariner"} release := &release.Release{Name: "mariner"}
if err := env.Releases.Create(release); err != nil { if err := env.Releases.Create(release); err != nil {
t.Fatalf("failed to store release: %s", err) t.Fatalf("failed to store release: %s", err)

@ -4,7 +4,9 @@ import (
"errors" "errors"
"github.com/deis/tiller/cmd/tiller/environment" "github.com/deis/tiller/cmd/tiller/environment"
"github.com/deis/tiller/pkg/proto/hapi/release"
"github.com/deis/tiller/pkg/proto/hapi/services" "github.com/deis/tiller/pkg/proto/hapi/services"
"github.com/technosophos/moniker"
ctx "golang.org/x/net/context" ctx "golang.org/x/net/context"
) )
@ -19,8 +21,11 @@ type releaseServer struct {
env *environment.Environment env *environment.Environment
} }
// errNotImplemented is a temporary error for uninmplemented callbacks. var (
var errNotImplemented = errors.New("not implemented") // errNotImplemented is a temporary error for uninmplemented callbacks.
errNotImplemented = errors.New("not implemented")
errMissingChart = errors.New("no chart provided")
)
func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream services.ReleaseService_ListReleasesServer) error { func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream services.ReleaseService_ListReleasesServer) error {
return errNotImplemented return errNotImplemented
@ -39,7 +44,36 @@ func (s *releaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease
} }
func (s *releaseServer) InstallRelease(c ctx.Context, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) { func (s *releaseServer) InstallRelease(c ctx.Context, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
return &services.InstallReleaseResponse{}, errNotImplemented if req.Chart == nil {
return nil, errMissingChart
}
// We should probably make a name generator part of the Environment.
namer := moniker.New()
// TODO: Make sure this is unique.
name := namer.Name()
// Render the templates
_, err := s.env.EngineYard.Default().Render(req.Chart, req.Values)
if err != nil {
return nil, err
}
// Store a release.
r := &release.Release{
Name: name,
Chart: req.Chart,
Config: req.Values,
Info: &release.Info{
Status: &release.Status{Code: release.Status_UNKNOWN},
},
}
if err := s.env.Releases.Create(r); err != nil {
return nil, err
}
return &services.InstallReleaseResponse{Release: r}, nil
} }
func (s *releaseServer) UninstallRelease(c ctx.Context, req *services.UninstallReleaseRequest) (*services.UninstallReleaseResponse, error) { func (s *releaseServer) UninstallRelease(c ctx.Context, req *services.UninstallReleaseRequest) (*services.UninstallReleaseResponse, error) {

@ -0,0 +1,38 @@
package main
import (
"github.com/deis/tiller/cmd/tiller/environment"
"github.com/deis/tiller/pkg/proto/hapi/chart"
"github.com/deis/tiller/pkg/proto/hapi/services"
"github.com/deis/tiller/pkg/storage"
"golang.org/x/net/context"
"testing"
)
func rsFixture() *releaseServer {
return &releaseServer{
env: mockEnvironment(),
}
}
func TestInstallRelease(t *testing.T) {
c := context.Background()
rs := rsFixture()
req := &services.InstallReleaseRequest{
Chart: &chart.Chart{},
}
res, err := rs.InstallRelease(c, req)
if err != nil {
t.Errorf("Failed install: %s", err)
}
if res.Release.Name == "" {
t.Errorf("Expected release name.")
}
}
func mockEnvironment() *environment.Environment {
e := environment.New()
e.Releases = storage.NewMemory()
return e
}

10
glide.lock generated

@ -1,5 +1,5 @@
hash: e7c99013acb06eb359cf20390579af9a4553ef0fbed3f7bbb784b4ab7c8df807 hash: 264d156a2a07d53efbf5f608ead3eb31c261de5124e0235139b3f99c6ead4dba
updated: 2016-04-15T15:15:21.87772545-06:00 updated: 2016-04-18T17:25:07.662942088-06:00
imports: imports:
- name: github.com/aokoli/goutils - name: github.com/aokoli/goutils
version: 9c37978a95bd5c709a15883b6242714ea6709e64 version: 9c37978a95bd5c709a15883b6242714ea6709e64
@ -11,6 +11,8 @@ imports:
version: f0a097ddac24fb00e07d2ac17f8671423f3ea47c version: f0a097ddac24fb00e07d2ac17f8671423f3ea47c
subpackages: subpackages:
- proto - proto
- ptypes/any
- ptypes/timestamp
- name: github.com/Masterminds/semver - name: github.com/Masterminds/semver
version: 808ed7761c233af2de3f9729a041d68c62527f3a version: 808ed7761c233af2de3f9729a041d68c62527f3a
- name: github.com/Masterminds/sprig - name: github.com/Masterminds/sprig
@ -21,6 +23,8 @@ imports:
- cobra - cobra
- name: github.com/spf13/pflag - name: github.com/spf13/pflag
version: 8f6a28b0916586e7f22fe931ae2fcfc380b1c0e6 version: 8f6a28b0916586e7f22fe931ae2fcfc380b1c0e6
- name: github.com/technosophos/moniker
version: 9f956786b91d9786ca11aa5be6104542fa911546
- name: golang.org/x/net - name: golang.org/x/net
version: fb93926129b8ec0056f2f458b1f519654814edf0 version: fb93926129b8ec0056f2f458b1f519654814edf0
subpackages: subpackages:
@ -30,7 +34,7 @@ imports:
- http2/hpack - http2/hpack
- internal/timeseries - internal/timeseries
- name: google.golang.org/grpc - name: google.golang.org/grpc
version: 8eeecf2291de9d171d0b1392a27ff3975679f4f5 version: dec33edc378cf4971a2741cfd86ed70a644d6ba3
subpackages: subpackages:
- codes - codes
- credentials - credentials

@ -13,3 +13,4 @@ import:
- package: github.com/Masterminds/semver - package: github.com/Masterminds/semver
version: 1.1.0 version: 1.1.0
- package: github.com/BurntSushi/toml - package: github.com/BurntSushi/toml
- package: github.com/technosophos/moniker

@ -6,7 +6,8 @@ import (
"text/template" "text/template"
"github.com/Masterminds/sprig" "github.com/Masterminds/sprig"
"github.com/deis/tiller/pkg/hapi" chartutil "github.com/deis/tiller/pkg/chart"
"github.com/deis/tiller/pkg/proto/hapi/chart"
) )
// Engine is an implementation of 'cmd/tiller/environment'.Engine that uses Go templates. // Engine is an implementation of 'cmd/tiller/environment'.Engine that uses Go templates.
@ -38,13 +39,41 @@ func New() *Engine {
// //
// This will look in the chart's 'templates' data (e.g. the 'templates/' directory) // This will look in the chart's 'templates' data (e.g. the 'templates/' directory)
// and attempt to render the templates there using the values passed in. // and attempt to render the templates there using the values passed in.
func (e *Engine) Render(chart *hapi.Chart, vals *hapi.Values) (map[string]string, error) { func (e *Engine) Render(chrt *chart.Chart, vals *chart.Config) (map[string]string, error) {
// Uncomment this once the proto files compile. var cvals chartutil.Values
//return render(chart.Chartfile.Name, chart.Templates, vals) if chrt.Values == nil {
return map[string]string{}, nil cvals = map[string]interface{}{}
} else {
var err error
cvals, err = chartutil.ReadValues([]byte(chrt.Values.Raw))
if err != nil {
return map[string]string{}, err
}
}
// Parse values if not nil
if vals != nil {
evals, err := chartutil.ReadValues([]byte(vals.Raw))
if err != nil {
return map[string]string{}, err
}
// Coalesce chart default values and values
for k, v := range evals {
// FIXME: This needs to merge tables. Ideally, this feature should
// be part of the Values type.
cvals[k] = v
}
}
// Render the charts
tmap := make(map[string]string, len(chrt.Templates))
for _, tpl := range chrt.Templates {
tmap[tpl.Name] = string(tpl.Data)
}
return e.render(tmap, cvals)
} }
func (e *Engine) render(name string, tpls map[string]string, v interface{}) (map[string]string, error) { func (e *Engine) render(tpls map[string]string, v interface{}) (map[string]string, error) {
// Basically, what we do here is start with an empty parent template and then // Basically, what we do here is start with an empty parent template and then
// build up a list of templates -- one for each file. Once all of the templates // build up a list of templates -- one for each file. Once all of the templates
// have been parsed, we loop through again and execute every template. // have been parsed, we loop through again and execute every template.
@ -52,7 +81,7 @@ func (e *Engine) render(name string, tpls map[string]string, v interface{}) (map
// The idea with this process is to make it possible for more complex templates // The idea with this process is to make it possible for more complex templates
// to share common blocks, but to make the entire thing feel like a file-based // to share common blocks, but to make the entire thing feel like a file-based
// template engine. // template engine.
t := template.New(name) t := template.New("gotpl")
files := []string{} files := []string{}
for fname, tpl := range tpls { for fname, tpl := range tpls {
t = t.New(fname).Funcs(e.FuncMap) t = t.New(fname).Funcs(e.FuncMap)

@ -35,7 +35,7 @@ func TestRenderInternals(t *testing.T) {
} }
vals := map[string]string{"Name": "one", "Value": "two"} vals := map[string]string{"Name": "one", "Value": "two"}
out, err := e.render("irrelevant", tpls, vals) out, err := e.render(tpls, vals)
if err != nil { if err != nil {
t.Fatalf("Failed template rendering: %s", err) t.Fatalf("Failed template rendering: %s", err)
} }
@ -68,7 +68,7 @@ func TestParallelRenderInternals(t *testing.T) {
tt := fmt.Sprintf("expect-%d", i) tt := fmt.Sprintf("expect-%d", i)
tpls := map[string]string{fname: `{{.val}}`} tpls := map[string]string{fname: `{{.val}}`}
v := map[string]string{"val": tt} v := map[string]string{"val": tt}
out, err := e.render("intentionally_duplicated", tpls, v) out, err := e.render(tpls, v)
if err != nil { if err != nil {
t.Errorf("Failed to render %s: %s", tt, err) t.Errorf("Failed to render %s: %s", tt, err)
} }

@ -16,7 +16,6 @@ It has these top-level messages:
Config Config
Maintainer Maintainer
Metadata Metadata
Templates
Template Template
*/ */
package chart package chart
@ -43,7 +42,7 @@ type Chart struct {
// Contents of the Chartfile. // Contents of the Chartfile.
Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata" json:"metadata,omitempty"` Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata" json:"metadata,omitempty"`
// Templates for this chart. // Templates for this chart.
Templates *Templates `protobuf:"bytes,2,opt,name=templates" json:"templates,omitempty"` Templates []*Template `protobuf:"bytes,2,rep,name=templates" json:"templates,omitempty"`
// Charts that this chart depends on. // Charts that this chart depends on.
Dependencies []*Chart `protobuf:"bytes,3,rep,name=dependencies" json:"dependencies,omitempty"` Dependencies []*Chart `protobuf:"bytes,3,rep,name=dependencies" json:"dependencies,omitempty"`
// Default config for this template. // Default config for this template.
@ -62,7 +61,7 @@ func (m *Chart) GetMetadata() *Metadata {
return nil return nil
} }
func (m *Chart) GetTemplates() *Templates { func (m *Chart) GetTemplates() []*Template {
if m != nil { if m != nil {
return m.Templates return m.Templates
} }
@ -88,18 +87,18 @@ func init() {
} }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 200 bytes of a gzipped FileDescriptorProto // 197 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0xcb, 0x48, 0x2c, 0xc8, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0xcb, 0x48, 0x2c, 0xc8,
0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0x81, 0x90, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x5c, 0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0x81, 0x90, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x5c,
0x20, 0x71, 0x3d, 0xb0, 0x88, 0x94, 0x38, 0xb2, 0x9a, 0xfc, 0xbc, 0xb4, 0xcc, 0x74, 0x88, 0x22, 0x20, 0x71, 0x3d, 0xb0, 0x88, 0x94, 0x38, 0xb2, 0x9a, 0xfc, 0xbc, 0xb4, 0xcc, 0x74, 0x88, 0x22,
0x29, 0x49, 0x24, 0x89, 0xdc, 0xd4, 0x92, 0xc4, 0x94, 0xc4, 0x92, 0x44, 0x2c, 0x52, 0x25, 0xa9, 0x29, 0x49, 0x24, 0x89, 0xdc, 0xd4, 0x92, 0xc4, 0x94, 0xc4, 0x92, 0x44, 0x2c, 0x52, 0x25, 0xa9,
0xb9, 0x05, 0x39, 0x89, 0x25, 0xa9, 0x10, 0x29, 0xa5, 0x8b, 0x8c, 0x5c, 0xac, 0xce, 0x20, 0x09, 0xb9, 0x05, 0x39, 0x89, 0x25, 0xa9, 0x10, 0x29, 0xa5, 0x0b, 0x8c, 0x5c, 0xac, 0xce, 0x20, 0x09,
0x21, 0x03, 0x2e, 0x0e, 0x98, 0x36, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x11, 0x3d, 0x84, 0x21, 0x03, 0x2e, 0x0e, 0x98, 0x36, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x11, 0x3d, 0x84,
0xbd, 0x7a, 0xbe, 0x50, 0xb9, 0x20, 0xb8, 0x2a, 0x21, 0x63, 0x2e, 0x4e, 0x98, 0x69, 0xc5, 0x12, 0xbd, 0x7a, 0xbe, 0x50, 0xb9, 0x20, 0xb8, 0x2a, 0x21, 0x23, 0x2e, 0x4e, 0x98, 0x69, 0xc5, 0x12,
0x4c, 0x60, 0x2d, 0xa2, 0xc8, 0x5a, 0x42, 0x60, 0x92, 0x41, 0x08, 0x75, 0x42, 0xa6, 0x5c, 0x3c, 0x4c, 0x0a, 0xcc, 0xe8, 0x5a, 0x42, 0xa0, 0x92, 0x41, 0x08, 0x65, 0x42, 0xa6, 0x5c, 0x3c, 0x29,
0x29, 0xa9, 0x05, 0xa9, 0x79, 0x29, 0xa9, 0x79, 0xc9, 0x99, 0x40, 0x7d, 0xcc, 0x0a, 0xcc, 0x40, 0xa9, 0x05, 0xa9, 0x79, 0x29, 0xa9, 0x79, 0xc9, 0x99, 0x40, 0x6d, 0xcc, 0x60, 0x6d, 0x82, 0xc8,
0x7d, 0x82, 0xc8, 0xfa, 0xc0, 0xee, 0x09, 0x42, 0x51, 0x26, 0xa4, 0xc5, 0xc5, 0x56, 0x96, 0x98, 0xda, 0xc0, 0xce, 0x09, 0x42, 0x51, 0x26, 0xa4, 0xc5, 0xc5, 0x56, 0x96, 0x98, 0x53, 0x0a, 0xd4,
0x53, 0x0a, 0xd4, 0xc0, 0x02, 0xb6, 0x48, 0x08, 0x45, 0x03, 0x38, 0x1c, 0x82, 0xa0, 0x2a, 0x9c, 0xc0, 0x02, 0x76, 0x9a, 0x10, 0x8a, 0x06, 0x70, 0x30, 0x04, 0x41, 0x55, 0x38, 0xb1, 0x47, 0xb1,
0xd8, 0xa3, 0x58, 0xc1, 0xe2, 0x49, 0x6c, 0x60, 0x3f, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x82, 0xc5, 0x93, 0xd8, 0xc0, 0x5e, 0x34, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xb5, 0xff, 0x0f,
0x12, 0xa6, 0x6a, 0xa8, 0x58, 0x01, 0x00, 0x00, 0xec, 0x57, 0x01, 0x00, 0x00,
} }

@ -13,55 +13,33 @@ var _ = proto.Marshal
var _ = fmt.Errorf var _ = fmt.Errorf
var _ = math.Inf var _ = math.Inf
// Template represents a template as a name/value pair.
// //
// Template: // By convention, name is a relative path within the scope of the chart's
// // base directory.
// TODO
//
type Templates struct {
// TODO
Templates []*Template `protobuf:"bytes,1,rep,name=templates" json:"templates,omitempty"`
}
func (m *Templates) Reset() { *m = Templates{} }
func (m *Templates) String() string { return proto.CompactTextString(m) }
func (*Templates) ProtoMessage() {}
func (*Templates) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} }
func (m *Templates) GetTemplates() []*Template {
if m != nil {
return m.Templates
}
return nil
}
type Template struct { type Template struct {
// TODO // Name is the path-like name of the template.
TemplateName string `protobuf:"bytes,1,opt,name=template_name,json=templateName" json:"template_name,omitempty"` Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
// TODO // Data is the template as byte data.
TemplateData []byte `protobuf:"bytes,2,opt,name=template_data,json=templateData,proto3" json:"template_data,omitempty"` Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
} }
func (m *Template) Reset() { *m = Template{} } func (m *Template) Reset() { *m = Template{} }
func (m *Template) String() string { return proto.CompactTextString(m) } func (m *Template) String() string { return proto.CompactTextString(m) }
func (*Template) ProtoMessage() {} func (*Template) ProtoMessage() {}
func (*Template) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{1} } func (*Template) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} }
func init() { func init() {
proto.RegisterType((*Templates)(nil), "hapi.chart.Templates")
proto.RegisterType((*Template)(nil), "hapi.chart.Template") proto.RegisterType((*Template)(nil), "hapi.chart.Template")
} }
var fileDescriptor3 = []byte{ var fileDescriptor3 = []byte{
// 146 bytes of a gzipped FileDescriptorProto // 106 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0x48, 0x2c, 0xc8, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0x48, 0x2c, 0xc8,
0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0xd1, 0x2f, 0x49, 0xcd, 0x2d, 0xc8, 0x49, 0x2c, 0x49, 0xd5, 0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0xd1, 0x2f, 0x49, 0xcd, 0x2d, 0xc8, 0x49, 0x2c, 0x49, 0xd5,
0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x02, 0x49, 0xe9, 0x81, 0xa5, 0x94, 0xec, 0xb9, 0x38, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x02, 0x49, 0xe9, 0x81, 0xa5, 0x94, 0x8c, 0xb8, 0x38,
0x43, 0xa0, 0xb2, 0xc5, 0x42, 0x46, 0x5c, 0x9c, 0x30, 0xa5, 0xc5, 0x12, 0x8c, 0x0a, 0xcc, 0x1a, 0x42, 0xa0, 0xb2, 0x42, 0x42, 0x5c, 0x2c, 0x79, 0x89, 0xb9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a,
0xdc, 0x46, 0x22, 0x7a, 0x08, 0xc5, 0x7a, 0x30, 0x95, 0x41, 0x08, 0x65, 0x4a, 0x21, 0x5c, 0x1c, 0x9c, 0x41, 0x60, 0x36, 0x48, 0x2c, 0x25, 0xb1, 0x24, 0x51, 0x82, 0x09, 0x28, 0xc6, 0x13, 0x04,
0x30, 0x61, 0x21, 0x65, 0x2e, 0x5e, 0x98, 0x44, 0x7c, 0x5e, 0x62, 0x6e, 0x2a, 0xd0, 0x0c, 0x46, 0x66, 0x3b, 0xb1, 0x47, 0xb1, 0x82, 0x35, 0x27, 0xb1, 0x81, 0xcd, 0x33, 0x06, 0x04, 0x00, 0x00,
0x0d, 0xce, 0x20, 0x1e, 0x98, 0xa0, 0x1f, 0x50, 0x0c, 0x45, 0x51, 0x4a, 0x62, 0x49, 0xa2, 0x04, 0xff, 0xff, 0x53, 0xee, 0x0e, 0x67, 0x6c, 0x00, 0x00, 0x00,
0x13, 0x50, 0x11, 0x0f, 0x42, 0x91, 0x0b, 0x50, 0xcc, 0x89, 0x3d, 0x8a, 0x15, 0x6c, 0x65, 0x12,
0x1b, 0xd8, 0xc9, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x48, 0xda, 0x77, 0x0e, 0xcf, 0x00,
0x00, 0x00,
} }

@ -3,17 +3,17 @@ package storage
import ( import (
"errors" "errors"
"github.com/deis/tiller/pkg/hapi" "github.com/deis/tiller/pkg/proto/hapi/release"
) )
// Memory is an in-memory ReleaseStorage implementation. // Memory is an in-memory ReleaseStorage implementation.
type Memory struct { type Memory struct {
releases map[string]*hapi.Release releases map[string]*release.Release
} }
func NewMemory() *Memory { func NewMemory() *Memory {
return &Memory{ return &Memory{
releases: map[string]*hapi.Release{}, releases: map[string]*release.Release{},
} }
} }
@ -22,7 +22,7 @@ var ErrNotFound = errors.New("release not found")
// Read returns the named Release. // Read returns the named Release.
// //
// If the release is not found, an ErrNotFound error is returned. // If the release is not found, an ErrNotFound error is returned.
func (m *Memory) Read(k string) (*hapi.Release, error) { func (m *Memory) Read(k string) (*release.Release, error) {
v, ok := m.releases[k] v, ok := m.releases[k]
if !ok { if !ok {
return v, ErrNotFound return v, ErrNotFound
@ -31,7 +31,7 @@ func (m *Memory) Read(k string) (*hapi.Release, error) {
} }
// Create sets a release. // Create sets a release.
func (m *Memory) Create(rel *hapi.Release) error { func (m *Memory) Create(rel *release.Release) error {
m.releases[rel.Name] = rel m.releases[rel.Name] = rel
return nil return nil
} }
@ -39,7 +39,7 @@ func (m *Memory) Create(rel *hapi.Release) error {
var ErrNoRelease = errors.New("no release found") var ErrNoRelease = errors.New("no release found")
// Update sets a release. // Update sets a release.
func (m *Memory) Update(rel *hapi.Release) error { func (m *Memory) Update(rel *release.Release) error {
if _, ok := m.releases[rel.Name]; !ok { if _, ok := m.releases[rel.Name]; !ok {
return ErrNoRelease return ErrNoRelease
} }
@ -50,7 +50,7 @@ func (m *Memory) Update(rel *hapi.Release) error {
return nil return nil
} }
func (m *Memory) Delete(name string) (*hapi.Release, error) { func (m *Memory) Delete(name string) (*release.Release, error) {
rel, ok := m.releases[name] rel, ok := m.releases[name]
if !ok { if !ok {
return nil, ErrNoRelease return nil, ErrNoRelease
@ -60,8 +60,8 @@ func (m *Memory) Delete(name string) (*hapi.Release, error) {
} }
// List returns all releases // List returns all releases
func (m *Memory) List() ([]*hapi.Release, error) { func (m *Memory) List() ([]*release.Release, error) {
buf := make([]*hapi.Release, len(m.releases)) buf := make([]*release.Release, len(m.releases))
i := 0 i := 0
for _, v := range m.releases { for _, v := range m.releases {
buf[i] = v buf[i] = v
@ -69,6 +69,6 @@ func (m *Memory) List() ([]*hapi.Release, error) {
} }
return buf, nil return buf, nil
} }
func (m *Memory) Query(labels map[string]string) ([]*hapi.Release, error) { func (m *Memory) Query(labels map[string]string) ([]*release.Release, error) {
return []*hapi.Release{}, errors.New("Cannot implement until hapi.Release is defined.") return []*release.Release{}, errors.New("Cannot implement until release.Release is defined.")
} }

@ -3,12 +3,12 @@ package storage
import ( import (
"testing" "testing"
"github.com/deis/tiller/pkg/hapi" "github.com/deis/tiller/pkg/proto/hapi/release"
) )
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
k := "test-1" k := "test-1"
r := &hapi.Release{Name: k} r := &release.Release{Name: k}
ms := NewMemory() ms := NewMemory()
if err := ms.Create(r); err != nil { if err := ms.Create(r); err != nil {
@ -22,7 +22,7 @@ func TestCreate(t *testing.T) {
func TestRead(t *testing.T) { func TestRead(t *testing.T) {
k := "test-1" k := "test-1"
r := &hapi.Release{Name: k} r := &release.Release{Name: k}
ms := NewMemory() ms := NewMemory()
ms.Create(r) ms.Create(r)
@ -36,7 +36,7 @@ func TestRead(t *testing.T) {
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
k := "test-1" k := "test-1"
r := &hapi.Release{Name: k} r := &release.Release{Name: k}
ms := NewMemory() ms := NewMemory()
if err := ms.Create(r); err != nil { if err := ms.Create(r); err != nil {
@ -56,7 +56,7 @@ func TestList(t *testing.T) {
rels := []string{"a", "b", "c"} rels := []string{"a", "b", "c"}
for _, k := range rels { for _, k := range rels {
ms.Create(&hapi.Release{Name: k}) ms.Create(&release.Release{Name: k})
} }
l, err := ms.List() l, err := ms.List()

Loading…
Cancel
Save