Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
H
helm3
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
helm3
Commits
d644c220
Commit
d644c220
authored
May 05, 2016
by
Matt Butcher
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #643 from technosophos/feat/install-k8s
feat(helm, tiller): implement k8s portion of install
parents
f7272f43
6db7c39b
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
196 additions
and
43 deletions
+196
-43
status.proto
_proto/hapi/release/status.proto
+6
-3
install.go
cmd/helm/install.go
+15
-6
environment.go
cmd/tiller/environment/environment.go
+43
-7
environment_test.go
cmd/tiller/environment/environment_test.go
+17
-5
release_server.go
cmd/tiller/release_server.go
+49
-9
release_server_test.go
cmd/tiller/release_server_test.go
+2
-0
alpine-pod.yaml
docs/examples/alpine/templates/alpine-pod.yaml
+6
-2
engine.go
pkg/engine/engine.go
+7
-1
engine_test.go
pkg/engine/engine_test.go
+34
-3
helm.go
pkg/helm/helm.go
+2
-1
status.pb.go
pkg/proto/hapi/release/status.pb.go
+15
-6
No files found.
_proto/hapi/release/status.proto
View file @
d644c220
...
@@ -12,13 +12,16 @@ option go_package = "release";
...
@@ -12,13 +12,16 @@ option go_package = "release";
//
//
message
Status
{
message
Status
{
enum
Code
{
enum
Code
{
// Status_UNKNOWN indicates that a release is in an uncertain state.
UNKNOWN
=
0
;
UNKNOWN
=
0
;
// Status_DEPLOYED indicates that the release has been pushed to Kubernetes.
DEPLOYED
=
1
;
DEPLOYED
=
1
;
// Status_DELETED indicates that a release has been deleted from Kubermetes.
DELETED
=
2
;
DELETED
=
2
;
// Status_SUPERSEDED indicates that this release object is outdated and a newer one exists.
SUPERSEDED
=
3
;
SUPERSEDED
=
3
;
// Status_FAILED indicates that the release was not successfully deployed.
FAILED
=
4
;
}
}
Code
code
=
1
;
Code
code
=
1
;
...
...
cmd/helm/install.go
View file @
d644c220
...
@@ -3,11 +3,13 @@ package main
...
@@ -3,11 +3,13 @@ package main
import
(
import
(
"fmt"
"fmt"
"os"
"os"
"time"
"github.com/spf13/cobra"
"github.com/spf13/cobra"
"github.com/kubernetes/helm/pkg/helm"
"github.com/kubernetes/helm/pkg/helm"
"github.com/kubernetes/helm/pkg/proto/hapi/release"
"github.com/kubernetes/helm/pkg/proto/hapi/release"
"github.com/kubernetes/helm/pkg/timeconv"
)
)
const
installDesc
=
`
const
installDesc
=
`
...
@@ -25,9 +27,14 @@ const (
...
@@ -25,9 +27,14 @@ const (
// install flags & args
// install flags & args
var
(
var
(
installArg
string
// name or relative path of the chart to install
// installArg is the name or relative path of the chart to install
tillerHost
string
// override TILLER_HOST envVar
installArg
string
verbose
bool
// enable verbose install
// tillerHost overrides TILLER_HOST envVar
tillerHost
string
// verbose enables verbose output
verbose
bool
// installDryRun performs a dry-run install
installDryRun
bool
)
)
var
installCmd
=
&
cobra
.
Command
{
var
installCmd
=
&
cobra
.
Command
{
...
@@ -40,7 +47,7 @@ var installCmd = &cobra.Command{
...
@@ -40,7 +47,7 @@ var installCmd = &cobra.Command{
func
runInstall
(
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
func
runInstall
(
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
setupInstallEnv
(
args
)
setupInstallEnv
(
args
)
res
,
err
:=
helm
.
InstallRelease
(
installArg
)
res
,
err
:=
helm
.
InstallRelease
(
installArg
,
installDryRun
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -59,8 +66,9 @@ func printRelease(rel *release.Release) {
...
@@ -59,8 +66,9 @@ func printRelease(rel *release.Release) {
}
}
fmt
.
Printf
(
"release.name: %s
\n
"
,
rel
.
Name
)
fmt
.
Printf
(
"release.name: %s
\n
"
,
rel
.
Name
)
if
verbose
{
if
verbose
{
fmt
.
Printf
(
"release.info: %s
\n
"
,
rel
.
GetInfo
())
fmt
.
Printf
(
"release.info: %s %s
\n
"
,
timeconv
.
Format
(
rel
.
Info
.
LastDeployed
,
time
.
ANSIC
),
rel
.
Info
.
Status
)
fmt
.
Printf
(
"release.chart: %s
\n
"
,
rel
.
GetChart
())
fmt
.
Printf
(
"release.chart: %s %s
\n
"
,
rel
.
Chart
.
Metadata
.
Name
,
rel
.
Chart
.
Metadata
.
Version
)
fmt
.
Printf
(
"release.manifest: %s
\n
"
,
rel
.
Manifest
)
}
}
}
}
...
@@ -92,6 +100,7 @@ func fatalf(format string, args ...interface{}) {
...
@@ -92,6 +100,7 @@ func fatalf(format string, args ...interface{}) {
func
init
()
{
func
init
()
{
installCmd
.
Flags
()
.
StringVar
(
&
tillerHost
,
"host"
,
defaultHost
,
"address of tiller server"
)
installCmd
.
Flags
()
.
StringVar
(
&
tillerHost
,
"host"
,
defaultHost
,
"address of tiller server"
)
installCmd
.
Flags
()
.
BoolVarP
(
&
verbose
,
"verbose"
,
"v"
,
false
,
"enable verbose install"
)
installCmd
.
Flags
()
.
BoolVarP
(
&
verbose
,
"verbose"
,
"v"
,
false
,
"enable verbose install"
)
installCmd
.
Flags
()
.
BoolVar
(
&
installDryRun
,
"dry-run"
,
false
,
"simulate an install"
)
RootCommand
.
AddCommand
(
installCmd
)
RootCommand
.
AddCommand
(
installCmd
)
}
}
cmd/tiller/environment/environment.go
View file @
d644c220
/*Package environment describes the operating environment for Tiller.
Tiller's environment encapsulates all of the service dependencies Tiller has.
These dependencies are expressed as interfaces so that alternate implementations
(mocks, etc.) can be easily generated.
*/
package
environment
package
environment
import
(
import
(
"io"
"github.com/kubernetes/helm/pkg/engine"
"github.com/kubernetes/helm/pkg/engine"
"github.com/kubernetes/helm/pkg/kube"
"github.com/kubernetes/helm/pkg/proto/hapi/chart"
"github.com/kubernetes/helm/pkg/proto/hapi/chart"
"github.com/kubernetes/helm/pkg/proto/hapi/release"
"github.com/kubernetes/helm/pkg/proto/hapi/release"
"github.com/kubernetes/helm/pkg/storage"
"github.com/kubernetes/helm/pkg/storage"
...
@@ -10,6 +19,9 @@ import (
...
@@ -10,6 +19,9 @@ import (
// GoTplEngine is the name of the Go template engine, as registered in the EngineYard.
// GoTplEngine is the name of the Go template engine, as registered in the EngineYard.
const
GoTplEngine
=
"gotpl"
const
GoTplEngine
=
"gotpl"
// DefaultNamespace is the default namespace for Tiller.
const
DefaultNamespace
=
"helm"
// DefaultEngine points to the engine that the EngineYard should treat as the
// DefaultEngine points to the engine that the EngineYard should treat as the
// default. A chart that does not specify an engine may be run through the
// default. A chart that does not specify an engine may be run through the
// default engine.
// default engine.
...
@@ -52,7 +64,11 @@ func (y EngineYard) Default() Engine {
...
@@ -52,7 +64,11 @@ 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
(
*
chart
.
Chart
,
*
chart
.
Config
)
(
map
[
string
]
string
,
error
)
// Render renders a chart.
//
// It receives a chart, a config, and a map of overrides to the config.
// Overrides are assumed to be passed from the system, not the user.
Render
(
*
chart
.
Chart
,
*
chart
.
Config
,
map
[
string
]
interface
{})
(
map
[
string
]
string
,
error
)
}
}
// ReleaseStorage represents a storage engine for a Release.
// ReleaseStorage represents a storage engine for a Release.
...
@@ -106,19 +122,37 @@ type ReleaseStorage interface {
...
@@ -106,19 +122,37 @@ type ReleaseStorage interface {
//
//
// A KubeClient must be concurrency safe.
// A KubeClient must be concurrency safe.
type
KubeClient
interface
{
type
KubeClient
interface
{
//
Install takes a map where the key is a "file name" (read: unique relational
//
Create creates one or more resources.
//
id) and the value is a Kubernetes manifest containing one or more resource
//
//
definitions
.
//
namespace must contain a valid existing namespace
.
//
//
// TODO: Can these be in YAML or JSON, or must they be in one particular
// reader must contain a YAML stream (one or more YAML documents separated
// format?
// by "\n---\n").
Install
(
manifests
map
[
string
]
string
)
error
//
// config is optional. If nil, the client will use its existing configuration.
// If set, the client will override its default configuration with the
// passed in one.
Create
(
namespace
string
,
reader
io
.
Reader
)
error
}
// PrintingKubeClient implements KubeClient, but simply prints the reader to
// the given output.
type
PrintingKubeClient
struct
{
Out
io
.
Writer
}
// Create prints the values of what would be created with a real KubeClient.
func
(
p
*
PrintingKubeClient
)
Create
(
ns
string
,
r
io
.
Reader
)
error
{
_
,
err
:=
io
.
Copy
(
p
.
Out
,
r
)
return
err
}
}
// Environment provides the context for executing a client request.
// Environment provides the context for executing a client request.
//
//
// All services in a context are concurrency safe.
// All services in a context are concurrency safe.
type
Environment
struct
{
type
Environment
struct
{
// The default namespace
Namespace
string
// EngineYard provides access to the known template engines.
// EngineYard provides access to the known template engines.
EngineYard
EngineYard
EngineYard
EngineYard
// Releases stores records of releases.
// Releases stores records of releases.
...
@@ -136,7 +170,9 @@ func New() *Environment {
...
@@ -136,7 +170,9 @@ func New() *Environment {
GoTplEngine
:
e
,
GoTplEngine
:
e
,
}
}
return
&
Environment
{
return
&
Environment
{
Namespace
:
DefaultNamespace
,
EngineYard
:
ey
,
EngineYard
:
ey
,
Releases
:
storage
.
NewMemory
(),
Releases
:
storage
.
NewMemory
(),
KubeClient
:
kube
.
New
(
nil
),
//&PrintingKubeClient{Out: os.Stdout},
}
}
}
}
cmd/tiller/environment/environment_test.go
View file @
d644c220
package
environment
package
environment
import
(
import
(
"bytes"
"io"
"testing"
"testing"
"github.com/kubernetes/helm/pkg/proto/hapi/chart"
"github.com/kubernetes/helm/pkg/proto/hapi/chart"
...
@@ -11,7 +13,7 @@ type mockEngine struct {
...
@@ -11,7 +13,7 @@ type mockEngine struct {
out
map
[
string
]
string
out
map
[
string
]
string
}
}
func
(
e
*
mockEngine
)
Render
(
chrt
*
chart
.
Chart
,
v
*
chart
.
Config
)
(
map
[
string
]
string
,
error
)
{
func
(
e
*
mockEngine
)
Render
(
chrt
*
chart
.
Chart
,
v
*
chart
.
Config
,
o
map
[
string
]
interface
{}
)
(
map
[
string
]
string
,
error
)
{
return
e
.
out
,
nil
return
e
.
out
,
nil
}
}
...
@@ -48,13 +50,14 @@ func (r *mockReleaseStorage) Query(labels map[string]string) ([]*release.Release
...
@@ -48,13 +50,14 @@ func (r *mockReleaseStorage) Query(labels map[string]string) ([]*release.Release
type
mockKubeClient
struct
{
type
mockKubeClient
struct
{
}
}
func
(
k
*
mockKubeClient
)
Install
(
manifests
map
[
string
]
string
)
error
{
func
(
k
*
mockKubeClient
)
Create
(
ns
string
,
r
io
.
Reader
)
error
{
return
nil
return
nil
}
}
var
_
Engine
=
&
mockEngine
{}
var
_
Engine
=
&
mockEngine
{}
var
_
ReleaseStorage
=
&
mockReleaseStorage
{}
var
_
ReleaseStorage
=
&
mockReleaseStorage
{}
var
_
KubeClient
=
&
mockKubeClient
{}
var
_
KubeClient
=
&
mockKubeClient
{}
var
_
KubeClient
=
&
PrintingKubeClient
{}
func
TestEngine
(
t
*
testing
.
T
)
{
func
TestEngine
(
t
*
testing
.
T
)
{
eng
:=
&
mockEngine
{
out
:
map
[
string
]
string
{
"albatross"
:
"test"
}}
eng
:=
&
mockEngine
{
out
:
map
[
string
]
string
{
"albatross"
:
"test"
}}
...
@@ -64,7 +67,7 @@ func TestEngine(t *testing.T) {
...
@@ -64,7 +67,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
(
&
chart
.
Chart
{},
&
chart
.
Config
{});
err
!=
nil
{
}
else
if
out
,
err
:=
engine
.
Render
(
&
chart
.
Chart
{},
&
chart
.
Config
{}
,
map
[
string
]
interface
{}{}
);
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"
])
...
@@ -102,9 +105,18 @@ func TestKubeClient(t *testing.T) {
...
@@ -102,9 +105,18 @@ func TestKubeClient(t *testing.T) {
env
:=
New
()
env
:=
New
()
env
.
KubeClient
=
kc
env
.
KubeClient
=
kc
manifests
:=
map
[
string
]
string
{}
manifests
:=
map
[
string
]
string
{
"foo"
:
"name: value
\n
"
,
"bar"
:
"name: value
\n
"
,
}
b
:=
bytes
.
NewBuffer
(
nil
)
for
_
,
content
:=
range
manifests
{
b
.
WriteString
(
"
\n
---
\n
"
)
b
.
WriteString
(
content
)
}
if
err
:=
env
.
KubeClient
.
Install
(
manifests
);
err
!=
nil
{
if
err
:=
env
.
KubeClient
.
Create
(
"sharry-bobbins"
,
b
);
err
!=
nil
{
t
.
Errorf
(
"Kubeclient failed: %s"
,
err
)
t
.
Errorf
(
"Kubeclient failed: %s"
,
err
)
}
}
}
}
cmd/tiller/release_server.go
View file @
d644c220
...
@@ -9,6 +9,7 @@ import (
...
@@ -9,6 +9,7 @@ import (
"github.com/kubernetes/helm/cmd/tiller/environment"
"github.com/kubernetes/helm/cmd/tiller/environment"
"github.com/kubernetes/helm/pkg/proto/hapi/release"
"github.com/kubernetes/helm/pkg/proto/hapi/release"
"github.com/kubernetes/helm/pkg/proto/hapi/services"
"github.com/kubernetes/helm/pkg/proto/hapi/services"
"github.com/kubernetes/helm/pkg/storage"
"github.com/kubernetes/helm/pkg/timeconv"
"github.com/kubernetes/helm/pkg/timeconv"
"github.com/technosophos/moniker"
"github.com/technosophos/moniker"
ctx
"golang.org/x/net/context"
ctx
"golang.org/x/net/context"
...
@@ -99,19 +100,44 @@ func (s *releaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease
...
@@ -99,19 +100,44 @@ func (s *releaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease
return
nil
,
errNotImplemented
return
nil
,
errNotImplemented
}
}
func
(
s
*
releaseServer
)
uniqName
()
(
string
,
error
)
{
maxTries
:=
5
for
i
:=
0
;
i
<
maxTries
;
i
++
{
namer
:=
moniker
.
New
()
name
:=
namer
.
NameSep
(
"-"
)
if
_
,
err
:=
s
.
env
.
Releases
.
Read
(
name
);
err
==
storage
.
ErrNotFound
{
return
name
,
nil
}
log
.
Printf
(
"info: Name %q is taken. Searching again."
,
name
)
}
log
.
Printf
(
"warning: No available release names found after %d tries"
,
maxTries
)
return
"ERROR"
,
errors
.
New
(
"no available release name found"
)
}
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
)
{
if
req
.
Chart
==
nil
{
if
req
.
Chart
==
nil
{
return
nil
,
errMissingChart
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
.
NameSep
(
"-"
)
ts
:=
timeconv
.
Now
()
ts
:=
timeconv
.
Now
()
name
,
err
:=
s
.
uniqName
()
if
err
!=
nil
{
return
nil
,
err
}
overrides
:=
map
[
string
]
interface
{}{
"Release"
:
map
[
string
]
interface
{}{
"Name"
:
name
,
"Time"
:
ts
,
"Namespace"
:
s
.
env
.
Namespace
,
"Service"
:
"Tiller"
,
},
"Chart"
:
req
.
Chart
.
Metadata
,
}
// Render the templates
// Render the templates
files
,
err
:=
s
.
env
.
EngineYard
.
Default
()
.
Render
(
req
.
Chart
,
req
.
Values
)
// TODO: Fix based on whether chart has `engine: SOMETHING` set.
files
,
err
:=
s
.
env
.
EngineYard
.
Default
()
.
Render
(
req
.
Chart
,
req
.
Values
,
overrides
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -139,16 +165,30 @@ func (s *releaseServer) InstallRelease(c ctx.Context, req *services.InstallRelea
...
@@ -139,16 +165,30 @@ func (s *releaseServer) InstallRelease(c ctx.Context, req *services.InstallRelea
Manifest
:
b
.
String
(),
Manifest
:
b
.
String
(),
}
}
res
:=
&
services
.
InstallReleaseResponse
{
Release
:
r
}
if
req
.
DryRun
{
if
req
.
DryRun
{
log
.
Printf
(
"Dry run for %s"
,
name
)
log
.
Printf
(
"Dry run for %s"
,
name
)
return
&
services
.
InstallReleaseResponse
{
Release
:
r
}
,
nil
return
res
,
nil
}
}
if
err
:=
s
.
env
.
Releases
.
Create
(
r
);
err
!=
nil
{
if
err
:=
s
.
env
.
KubeClient
.
Create
(
s
.
env
.
Namespace
,
b
);
err
!=
nil
{
return
nil
,
err
r
.
Info
.
Status
.
Code
=
release
.
Status_FAILED
log
.
Printf
(
"warning: Release %q failed: %s"
,
name
,
err
)
return
res
,
fmt
.
Errorf
(
"release %s failed: %s"
,
name
,
err
)
}
}
return
&
services
.
InstallReleaseResponse
{
Release
:
r
},
nil
// This is a tricky case. The release has been created, but the result
// cannot be recorded. The truest thing to tell the user is that the
// release was created. However, the user will not be able to do anything
// further with this release.
//
// One possible strategy would be to do a timed retry to see if we can get
// this stored in the future.
if
err
:=
s
.
env
.
Releases
.
Create
(
r
);
err
!=
nil
{
log
.
Printf
(
"warning: Failed to record release %q: %s"
,
name
,
err
)
}
return
res
,
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
)
{
...
...
cmd/tiller/release_server_test.go
View file @
d644c220
...
@@ -2,6 +2,7 @@ package main
...
@@ -2,6 +2,7 @@ package main
import
(
import
(
"fmt"
"fmt"
"os"
"strings"
"strings"
"testing"
"testing"
...
@@ -219,6 +220,7 @@ func TestListReleases(t *testing.T) {
...
@@ -219,6 +220,7 @@ func TestListReleases(t *testing.T) {
func
mockEnvironment
()
*
environment
.
Environment
{
func
mockEnvironment
()
*
environment
.
Environment
{
e
:=
environment
.
New
()
e
:=
environment
.
New
()
e
.
Releases
=
storage
.
NewMemory
()
e
.
Releases
=
storage
.
NewMemory
()
e
.
KubeClient
=
&
environment
.
PrintingKubeClient
{
Out
:
os
.
Stdout
}
return
e
return
e
}
}
...
...
docs/examples/alpine/templates/alpine-pod.yaml
View file @
d644c220
apiVersion
:
v1
apiVersion
:
v1
kind
:
Pod
kind
:
Pod
metadata
:
metadata
:
name
:
{{
default "alpine" .n
ame
}}
name
:
{{
.Release.Name
}}
-{{.Chart.N
ame}}
labels
:
labels
:
heritage
:
helm
heritage
:
{{
.Release.Service
}}
chartName
:
{{
.Chart.Name
}}
chartVersion
:
{{
.Chart.Version
}}
annotations
:
"
helm.sh/created"
:
{{
.Release.Time.Seconds
}}
spec
:
spec
:
restartPolicy
:
{{
default "Never" .restart_policy
}}
restartPolicy
:
{{
default "Never" .restart_policy
}}
containers
:
containers
:
...
...
pkg/engine/engine.go
View file @
d644c220
...
@@ -59,7 +59,7 @@ func New() *Engine {
...
@@ -59,7 +59,7 @@ func New() *Engine {
// - Scalar values and arrays are replaced, maps are merged
// - Scalar values and arrays are replaced, maps are merged
// - A chart has access to all of the variables for it, as well as all of
// - A chart has access to all of the variables for it, as well as all of
// the values destined for its dependencies.
// the values destined for its dependencies.
func
(
e
*
Engine
)
Render
(
chrt
*
chart
.
Chart
,
vals
*
chart
.
Config
)
(
map
[
string
]
string
,
error
)
{
func
(
e
*
Engine
)
Render
(
chrt
*
chart
.
Chart
,
vals
*
chart
.
Config
,
overrides
map
[
string
]
interface
{}
)
(
map
[
string
]
string
,
error
)
{
var
cvals
chartutil
.
Values
var
cvals
chartutil
.
Values
// Parse values if not nil. We merge these at the top level because
// Parse values if not nil. We merge these at the top level because
...
@@ -69,6 +69,12 @@ func (e *Engine) Render(chrt *chart.Chart, vals *chart.Config) (map[string]strin
...
@@ -69,6 +69,12 @@ func (e *Engine) Render(chrt *chart.Chart, vals *chart.Config) (map[string]strin
if
err
!=
nil
{
if
err
!=
nil
{
return
map
[
string
]
string
{},
err
return
map
[
string
]
string
{},
err
}
}
// Override the top-level values. Overrides are NEVER merged deeply.
// The assumption is that an override is intended to set an explicit
// and exact value.
for
k
,
v
:=
range
overrides
{
evals
[
k
]
=
v
}
cvals
=
coalesceValues
(
chrt
,
evals
)
cvals
=
coalesceValues
(
chrt
,
evals
)
}
}
...
...
pkg/engine/engine_test.go
View file @
d644c220
...
@@ -22,7 +22,38 @@ func TestEngine(t *testing.T) {
...
@@ -22,7 +22,38 @@ func TestEngine(t *testing.T) {
}
}
func
TestRender
(
t
*
testing
.
T
)
{
func
TestRender
(
t
*
testing
.
T
)
{
t
.
Skip
()
c
:=
&
chart
.
Chart
{
Metadata
:
&
chart
.
Metadata
{
Name
:
"moby"
,
Version
:
"1.2.3"
,
},
Templates
:
[]
*
chart
.
Template
{
{
Name
:
"test1"
,
Data
:
[]
byte
(
"{{.outer | title }} {{.inner | title}}"
)},
},
Values
:
&
chart
.
Config
{
Raw
:
`outer = "DEFAULT"\ninner= "DEFAULT"\n`
,
},
}
vals
:=
&
chart
.
Config
{
Raw
:
`outer = "BAD"
inner= "inn"`
,
}
overrides
:=
map
[
string
]
interface
{}{
"outer"
:
"spouter"
,
}
e
:=
New
()
out
,
err
:=
e
.
Render
(
c
,
vals
,
overrides
)
if
err
!=
nil
{
t
.
Errorf
(
"Failed to render templates: %s"
,
err
)
}
expect
:=
"Spouter Inn"
if
out
[
"test1"
]
!=
expect
{
t
.
Errorf
(
"Expected %q, got %q"
,
expect
,
out
[
"test1"
])
}
}
}
func
TestRenderInternals
(
t
*
testing
.
T
)
{
func
TestRenderInternals
(
t
*
testing
.
T
)
{
...
@@ -129,7 +160,7 @@ func TestRenderDependency(t *testing.T) {
...
@@ -129,7 +160,7 @@ func TestRenderDependency(t *testing.T) {
},
},
}
}
out
,
err
:=
e
.
Render
(
ch
,
nil
)
out
,
err
:=
e
.
Render
(
ch
,
nil
,
map
[
string
]
interface
{}{}
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"failed to render chart: %s"
,
err
)
t
.
Fatalf
(
"failed to render chart: %s"
,
err
)
...
@@ -190,7 +221,7 @@ func TestRenderNestedValues(t *testing.T) {
...
@@ -190,7 +221,7 @@ func TestRenderNestedValues(t *testing.T) {
what = "flower"`
,
what = "flower"`
,
}
}
out
,
err
:=
e
.
Render
(
outer
,
&
inject
)
out
,
err
:=
e
.
Render
(
outer
,
&
inject
,
map
[
string
]
interface
{}{}
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"failed to render templates: %s"
,
err
)
t
.
Fatalf
(
"failed to render templates: %s"
,
err
)
}
}
...
...
pkg/helm/helm.go
View file @
d644c220
...
@@ -71,7 +71,7 @@ func UninstallRelease(name string) (*services.UninstallReleaseResponse, error) {
...
@@ -71,7 +71,7 @@ func UninstallRelease(name string) (*services.UninstallReleaseResponse, error) {
}
}
// InstallRelease installs a new chart and returns the release response.
// InstallRelease installs a new chart and returns the release response.
func
InstallRelease
(
chStr
string
)
(
*
services
.
InstallReleaseResponse
,
error
)
{
func
InstallRelease
(
chStr
string
,
dryRun
bool
)
(
*
services
.
InstallReleaseResponse
,
error
)
{
chfi
,
err
:=
chartutil
.
LoadChart
(
chStr
)
chfi
,
err
:=
chartutil
.
LoadChart
(
chStr
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -90,5 +90,6 @@ func InstallRelease(chStr string) (*services.InstallReleaseResponse, error) {
...
@@ -90,5 +90,6 @@ func InstallRelease(chStr string) (*services.InstallReleaseResponse, error) {
return
Config
.
client
()
.
install
(
&
services
.
InstallReleaseRequest
{
return
Config
.
client
()
.
install
(
&
services
.
InstallReleaseRequest
{
Chart
:
chpb
,
Chart
:
chpb
,
Values
:
vals
,
Values
:
vals
,
DryRun
:
dryRun
,
})
})
}
}
pkg/proto/hapi/release/status.pb.go
View file @
d644c220
...
@@ -17,10 +17,16 @@ var _ = math.Inf
...
@@ -17,10 +17,16 @@ var _ = math.Inf
type
Status_Code
int32
type
Status_Code
int32
const
(
const
(
// Status_UNKNOWN indicates that a release is in an uncertain state.
Status_UNKNOWN
Status_Code
=
0
Status_UNKNOWN
Status_Code
=
0
// Status_DEPLOYED indicates that the release has been pushed to Kubernetes.
Status_DEPLOYED
Status_Code
=
1
Status_DEPLOYED
Status_Code
=
1
// Status_DELETED indicates that a release has been deleted from Kubermetes.
Status_DELETED
Status_Code
=
2
Status_DELETED
Status_Code
=
2
// Status_SUPERSEDED indicates that this release object is outdated and a newer one exists.
Status_SUPERSEDED
Status_Code
=
3
Status_SUPERSEDED
Status_Code
=
3
// Status_FAILED indicates that the release was not successfully deployed.
Status_FAILED
Status_Code
=
4
)
)
var
Status_Code_name
=
map
[
int32
]
string
{
var
Status_Code_name
=
map
[
int32
]
string
{
...
@@ -28,12 +34,14 @@ var Status_Code_name = map[int32]string{
...
@@ -28,12 +34,14 @@ var Status_Code_name = map[int32]string{
1
:
"DEPLOYED"
,
1
:
"DEPLOYED"
,
2
:
"DELETED"
,
2
:
"DELETED"
,
3
:
"SUPERSEDED"
,
3
:
"SUPERSEDED"
,
4
:
"FAILED"
,
}
}
var
Status_Code_value
=
map
[
string
]
int32
{
var
Status_Code_value
=
map
[
string
]
int32
{
"UNKNOWN"
:
0
,
"UNKNOWN"
:
0
,
"DEPLOYED"
:
1
,
"DEPLOYED"
:
1
,
"DELETED"
:
2
,
"DELETED"
:
2
,
"SUPERSEDED"
:
3
,
"SUPERSEDED"
:
3
,
"FAILED"
:
4
,
}
}
func
(
x
Status_Code
)
String
()
string
{
func
(
x
Status_Code
)
String
()
string
{
...
@@ -68,19 +76,20 @@ func init() {
...
@@ -68,19 +76,20 @@ func init() {
}
}
var
fileDescriptor2
=
[]
byte
{
var
fileDescriptor2
=
[]
byte
{
// 2
15
bytes of a gzipped FileDescriptorProto
// 2
26
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
,
0x2f
,
0x4a
,
0xcd
,
0x49
,
0x4d
,
0x2c
,
0x4e
,
0xd5
,
0x2f
,
0x2e
,
0x49
,
0x2c
,
0x29
,
0x2d
,
0xd6
,
0xd4
,
0x2f
,
0x4a
,
0xcd
,
0x49
,
0x4d
,
0x2c
,
0x4e
,
0xd5
,
0x2f
,
0x2e
,
0x49
,
0x2c
,
0x29
,
0x2d
,
0xd6
,
0x2b
,
0x28
,
0xca
,
0x2f
,
0xc9
,
0x17
,
0xe2
,
0x01
,
0x49
,
0xe9
,
0x41
,
0xa5
,
0xa4
,
0x24
,
0xd3
,
0xf3
,
0x2b
,
0x28
,
0xca
,
0x2f
,
0xc9
,
0x17
,
0xe2
,
0x01
,
0x49
,
0xe9
,
0x41
,
0xa5
,
0xa4
,
0x24
,
0xd3
,
0xf3
,
0xf3
,
0xd3
,
0x73
,
0x52
,
0xf5
,
0xc1
,
0x72
,
0x49
,
0xa5
,
0x69
,
0xfa
,
0x89
,
0x79
,
0x95
,
0x10
,
0x85
,
0xf3
,
0xd3
,
0x73
,
0x52
,
0xf5
,
0xc1
,
0x72
,
0x49
,
0xa5
,
0x69
,
0xfa
,
0x89
,
0x79
,
0x95
,
0x10
,
0x85
,
0x4a
,
0x
c
b
,
0x19
,
0xb9
,
0xd8
,
0x82
,
0xc1
,
0x3a
,
0x85
,
0x74
,
0xb9
,
0x58
,
0x92
,
0xf3
,
0x53
,
0x52
,
0x4a
,
0x
9
b
,
0x19
,
0xb9
,
0xd8
,
0x82
,
0xc1
,
0x3a
,
0x85
,
0x74
,
0xb9
,
0x58
,
0x92
,
0xf3
,
0x53
,
0x52
,
0x25
,
0x18
,
0x15
,
0x18
,
0x35
,
0xf8
,
0x8c
,
0x24
,
0xf5
,
0x90
,
0x8d
,
0xd0
,
0x83
,
0xa8
,
0xd1
,
0x73
,
0x25
,
0x18
,
0x15
,
0x18
,
0x35
,
0xf8
,
0x8c
,
0x24
,
0xf5
,
0x90
,
0x8d
,
0xd0
,
0x83
,
0xa8
,
0xd1
,
0x73
,
0x06
,
0x2a
,
0x08
,
0x02
,
0x2b
,
0x13
,
0xd2
,
0xe3
,
0x62
,
0x4f
,
0x49
,
0x2d
,
0x49
,
0xcc
,
0xcc
,
0x29
,
0x06
,
0x2a
,
0x08
,
0x02
,
0x2b
,
0x13
,
0xd2
,
0xe3
,
0x62
,
0x4f
,
0x49
,
0x2d
,
0x49
,
0xcc
,
0xcc
,
0x29
,
0x96
,
0x60
,
0x02
,
0xea
,
0xe0
,
0x36
,
0x12
,
0xd1
,
0x83
,
0x58
,
0xa3
,
0x07
,
0xb3
,
0x46
,
0xcf
,
0x31
,
0x96
,
0x60
,
0x02
,
0xea
,
0xe0
,
0x36
,
0x12
,
0xd1
,
0x83
,
0x58
,
0xa3
,
0x07
,
0xb3
,
0x46
,
0xcf
,
0x31
,
0xaf
,
0x32
,
0x08
,
0xa6
,
0x48
,
0xc9
,
0x8
e
,
0x8b
,
0x05
,
0xa4
,
0x5b
,
0x88
,
0x9b
,
0x8b
,
0x3d
,
0xd4
,
0xaf
,
0x32
,
0x08
,
0xa6
,
0x48
,
0xc9
,
0x8
b
,
0x8b
,
0x05
,
0xa4
,
0x5b
,
0x88
,
0x9b
,
0x8b
,
0x3d
,
0xd4
,
0xcf
,
0xdb
,
0xcf
,
0x3f
,
0xdc
,
0x4f
,
0x80
,
0x41
,
0x88
,
0x87
,
0x8b
,
0xc3
,
0xc5
,
0x35
,
0xc0
,
0xc7
,
0xcf
,
0xdb
,
0xcf
,
0x3f
,
0xdc
,
0x4f
,
0x80
,
0x41
,
0x88
,
0x87
,
0x8b
,
0xc3
,
0xc5
,
0x35
,
0xc0
,
0xc7
,
0x3f
,
0xd2
,
0xd5
,
0x45
,
0x80
,
0x11
,
0x24
,
0xe5
,
0xe2
,
0xea
,
0xe3
,
0x1a
,
0x02
,
0xe4
,
0x30
,
0x09
,
0x3f
,
0xd2
,
0xd5
,
0x45
,
0x80
,
0x11
,
0x24
,
0xe5
,
0xe2
,
0xea
,
0xe3
,
0x1a
,
0x02
,
0xe4
,
0x30
,
0x09
,
0xf1
,
0x71
,
0x71
,
0x05
,
0x87
,
0x06
,
0xb8
,
0x06
,
0x05
,
0xbb
,
0xba
,
0x00
,
0xf9
,
0xcc
,
0x4e
,
0x9c
,
0xf1
,
0x71
,
0x71
,
0x05
,
0x87
,
0x06
,
0xb8
,
0x06
,
0x05
,
0xbb
,
0xba
,
0x00
,
0xf9
,
0xcc
,
0x42
,
0x5c
,
0x51
,
0xec
,
0x50
,
0xc7
,
0x24
,
0xb1
,
0x81
,
0x6d
,
0x30
,
0x06
,
0x04
,
0x00
,
0x00
,
0xff
,
0xff
,
0x0d
,
0x5c
,
0x6c
,
0x6e
,
0x8e
,
0x9e
,
0x3e
,
0x40
,
0x36
,
0x8b
,
0x13
,
0x67
,
0x14
,
0x3b
,
0xd4
,
0x61
,
0x49
,
0xcd
,
0xe7
,
0x6f
,
0x01
,
0x01
,
0x00
,
0x00
,
0x6c
,
0x60
,
0xdb
,
0x8c
,
0x01
,
0x01
,
0x00
,
0x00
,
0xff
,
0xff
,
0x8c
,
0x99
,
0x9a
,
0x3b
,
0x0d
,
0x01
,
0x00
,
0x00
,
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment