diff --git a/.gitignore b/.gitignore
index 12b7ab7bc61202ca4833b7900f47d6dc2683d580..b94f87b2685dbf958f71d0b838d04bdd330a5e6d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ _dist/
 _proto/*.pb.go
 bin/
 rootfs/tiller
+rootfs/rudder
 vendor/
 *.exe
 .idea/
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 5811e2005255db0ca52559aa48c164b7c1f7bab3..0000000000000000000000000000000000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-language: go
-
-go:
-  - '1.7.x'
-
-go_import_path: k8s.io/helm
-
-before_install:
-  - make bootstrap
-
-script:
-  - make test
diff --git a/Makefile b/Makefile
index d9d869a3b073dd960a82bcb66e4781e750adc3a3..2070fd4d0558b3e0d4da445f7f1c230b143d4c8c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,10 @@
-DOCKER_REGISTRY ?= gcr.io
-IMAGE_PREFIX    ?= kubernetes-helm
-SHORT_NAME      ?= tiller
-TARGETS         = darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le windows/amd64
-DIST_DIRS       = find * -type d -exec
-APP             = helm
+DOCKER_REGISTRY   ?= gcr.io
+IMAGE_PREFIX      ?= kubernetes-helm
+SHORT_NAME        ?= tiller
+SHORT_NAME_RUDDER ?= rudder
+TARGETS           = darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le windows/amd64
+DIST_DIRS         = find * -type d -exec
+APP               = helm
 
 # go option
 GO        ?= go
@@ -66,6 +67,19 @@ docker-build: check-docker docker-binary
 	docker build --rm -t ${IMAGE} rootfs
 	docker tag ${IMAGE} ${MUTABLE_IMAGE}
 
+.PHONY: docker-binary-rudder
+docker-binary-rudder: BINDIR = ./rootfs
+docker-binary-rudder: GOFLAGS += -a -installsuffix cgo
+docker-binary-rudder:
+	GOOS=linux GOARCH=amd64 CGO_ENABLED=0 $(GO) build -o $(BINDIR)/rudder $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' k8s.io/helm/cmd/rudder
+
+.PHONY: docker-build-experimental
+docker-build-experimental: check-docker docker-binary docker-binary-rudder
+	docker build --rm -t ${IMAGE} rootfs -f rootfs/Dockerfile.experimental
+	docker tag ${IMAGE} ${MUTABLE_IMAGE}
+	docker build --rm -t ${IMAGE_RUDDER} rootfs -f rootfs/Dockerfile.rudder
+	docker tag ${IMAGE_RUDDER} ${MUTABLE_IMAGE_RUDDER}
+
 .PHONY: test
 test: build
 test: TESTFLAGS += -race -v
@@ -74,6 +88,8 @@ test: test-unit
 
 .PHONY: test-unit
 test-unit:
+	@echo
+	@echo "==> Running unit tests <=="
 	HELM_HOME=/no/such/dir $(GO) test $(GOFLAGS) -run $(TESTS) $(PKG) $(TESTFLAGS)
 
 .PHONY: test-style
diff --git a/README.md b/README.md
index 08351149e4b7bde871c760aa324bfb0d08cdefd6..4972e7b5b164d7a0264ad78970a30f359fbcb118 100644
--- a/README.md
+++ b/README.md
@@ -33,9 +33,9 @@ Think of it like apt/yum/homebrew for Kubernetes.
 
 Binary downloads of the Helm client can be found at the following links:
 
-- [OSX](https://kubernetes-helm.storage.googleapis.com/helm-v2.3.0-darwin-amd64.tar.gz)
-- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.3.0-linux-amd64.tar.gz)
-- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.3.0-linux-386.tar.gz)
+- [OSX](https://kubernetes-helm.storage.googleapis.com/helm-v2.4.2-darwin-amd64.tar.gz)
+- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.4.2-linux-amd64.tar.gz)
+- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.4.2-linux-386.tar.gz)
 
 Unpack the `helm` binary and add it to your PATH and you are good to go!
 macOS/[homebrew](https://brew.sh/) users can also use `brew install kubernetes-helm`.
@@ -45,7 +45,6 @@ To rapidly get Helm up and running, start with the [Quick Start Guide](docs/quic
 See the [installation guide](docs/install.md) for more options,
 including installing pre-releases.
 
-
 ## Docs
 
 Get started with the [Quick Start guide](docs/quickstart.md) or plunge into the [complete documentation](docs/index.md)
diff --git a/_proto/Makefile b/_proto/Makefile
index 078514a9c84217257db52e764103bb080171588f..39f72d441ecad001f6b8917bc8ff943ac5e3843e 100644
--- a/_proto/Makefile
+++ b/_proto/Makefile
@@ -20,6 +20,10 @@ services_ias = $(subst $(space),$(comma),$(addsuffix =$(import_path)/$(services_
 services_pbs = $(sort $(wildcard hapi/services/*.proto))
 services_pkg = services
 
+rudder_ias = $(subst $(space),$(comma),$(addsuffix =$(import_path)/$(rudder_pkg),$(addprefix M,$(rudder_pbs))))
+rudder_pbs = $(sort $(wildcard hapi/rudder/*.proto))
+rudder_pkg = rudder
+
 version_ias    = $(subst $(space),$(comma),$(addsuffix =$(import_path)/$(version_pkg),$(addprefix M,$(version_pbs))))
 version_pbs    = $(sort $(wildcard hapi/version/*.proto))
 version_pkg    = version
@@ -27,7 +31,7 @@ version_pkg    = version
 google_deps	 = Mgoogle/protobuf/timestamp.proto=github.com/golang/protobuf/ptypes/timestamp,Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any
 
 .PHONY: all
-all: chart release services version
+all: chart release services rudder version
 
 .PHONY: chart
 chart:
@@ -41,6 +45,10 @@ release:
 services:
 	PATH=../bin:$(PATH) protoc --$(target)_out=plugins=$(plugins),$(google_deps),$(chart_ias),$(version_ias),$(release_ias):$(dst) $(services_pbs)
 
+.PHONY: rudder
+rudder:
+	PATH=../bin:$(PATH) protoc --$(target)_out=plugins=$(plugins),$(google_deps),$(chart_ias),$(version_ias),$(release_ias):$(dst) $(rudder_pbs)
+
 .PHONY: version
 version:
 	PATH=../bin:$(PATH) protoc --$(target)_out=plugins=$(plugins),$(google_deps):$(dst) $(version_pbs)
diff --git a/_proto/hapi/release/test_run.proto b/_proto/hapi/release/test_run.proto
index a441e729fcbd304643c72a2020d869a561f49185..60734ae0384a68fd7793efb0de5ae268cb68536e 100644
--- a/_proto/hapi/release/test_run.proto
+++ b/_proto/hapi/release/test_run.proto
@@ -26,6 +26,7 @@ message TestRun {
         UNKNOWN = 0;
         SUCCESS = 1;
         FAILURE = 2;
+        RUNNING = 3;
     }
 
     string name = 1;
diff --git a/_proto/hapi/rudder/rudder.proto b/_proto/hapi/rudder/rudder.proto
new file mode 100644
index 0000000000000000000000000000000000000000..3a37c9e99d21f6b72cb155d7dd83c095e30ae64b
--- /dev/null
+++ b/_proto/hapi/rudder/rudder.proto
@@ -0,0 +1,120 @@
+// Copyright 2017 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.
+
+syntax = "proto3";
+
+package hapi.services.rudder;
+
+import "hapi/release/info.proto";
+import "hapi/release/release.proto";
+
+option go_package = "rudder";
+
+service ReleaseModuleService {
+	rpc Version(VersionReleaseRequest) returns (VersionReleaseResponse)  {
+	}
+
+	// InstallRelease requests installation of a chart as a new release.
+	rpc InstallRelease(InstallReleaseRequest) returns (InstallReleaseResponse) {
+	}
+
+	// DeleteRelease requests deletion of a named release.
+	rpc DeleteRelease(DeleteReleaseRequest) returns (DeleteReleaseResponse) {
+	}
+
+	// RollbackRelease rolls back a release to a previous version.
+	rpc RollbackRelease(RollbackReleaseRequest) returns (RollbackReleaseResponse) {
+	}
+
+	// UpgradeRelease updates release content.
+	rpc UpgradeRelease(UpgradeReleaseRequest) returns (UpgradeReleaseResponse) {
+	}
+
+	// ReleaseStatus retrieves release status.
+	rpc ReleaseStatus(ReleaseStatusRequest) returns (ReleaseStatusResponse) {
+	}
+}
+
+message Result {
+	enum Status {
+		// No status set
+		UNKNOWN = 0;
+		// Operation was successful
+		SUCCESS = 1;
+		// Operation had no results (e.g. upgrade identical, rollback to same, delete non-existent)
+		UNCHANGED = 2;
+		// Operation failed
+		ERROR = 3;
+	}
+	string info = 1;
+	repeated string log = 2;
+}
+
+message VersionReleaseRequest {
+}
+
+message VersionReleaseResponse {
+	string name = 1;     // The canonical name of the release module
+	string version = 2;  // The version of the release module
+}
+
+message InstallReleaseRequest {
+	hapi.release.Release release = 1;
+}
+message InstallReleaseResponse {
+	hapi.release.Release release = 1;
+	Result result = 2;
+}
+
+message DeleteReleaseRequest {
+	hapi.release.Release release = 1;
+}
+message DeleteReleaseResponse {
+	hapi.release.Release release = 1;
+	Result result = 2;
+}
+
+message UpgradeReleaseRequest{
+        hapi.release.Release current = 1;
+        hapi.release.Release target = 2;
+        int64 Timeout = 3;
+        bool Wait = 4;
+        bool Recreate = 5;
+        bool Force = 6;
+}
+message UpgradeReleaseResponse{
+	hapi.release.Release release = 1;
+	Result result = 2;
+}
+
+message RollbackReleaseRequest{
+        hapi.release.Release current = 1;
+        hapi.release.Release target = 2;
+        int64 Timeout = 3;
+        bool Wait = 4;
+        bool Recreate = 5;
+        bool Force = 6;
+}
+message RollbackReleaseResponse{
+	hapi.release.Release release = 1;
+	Result result = 2;
+}
+
+message ReleaseStatusRequest{
+        hapi.release.Release release = 1;
+}
+message ReleaseStatusResponse{
+	hapi.release.Release release = 1;
+	hapi.release.Info info = 2;
+}
diff --git a/_proto/hapi/services/tiller.proto b/_proto/hapi/services/tiller.proto
index f16d68238989c908c9fb79b11e0369ab9013bacb..1fb6a86e9d5ada9db8737f3b8f41f61b91c70a9c 100644
--- a/_proto/hapi/services/tiller.proto
+++ b/_proto/hapi/services/tiller.proto
@@ -20,6 +20,7 @@ import "hapi/chart/chart.proto";
 import "hapi/chart/config.proto";
 import "hapi/release/release.proto";
 import "hapi/release/info.proto";
+import "hapi/release/test_run.proto";
 import "hapi/release/status.proto";
 import "hapi/version/version.proto";
 
@@ -206,6 +207,8 @@ message UpdateReleaseRequest {
 	// ReuseValues will cause Tiller to reuse the values from the last release.
 	// This is ignored if reset_values is set.
 	bool reuse_values = 10;
+	// Force resource update through delete/recreate if needed.
+	bool force = 11;
 }
 
 // UpdateReleaseResponse is the response to an update request.
@@ -229,6 +232,8 @@ message RollbackReleaseRequest {
 	// wait, if true, will wait until all Pods, PVCs, and Services are in a ready state
 	// before marking the release as successful. It will wait for as long as timeout
 	bool wait = 7;
+	// Force resource update through delete/recreate if needed.
+	bool force = 8;
 }
 
 // RollbackReleaseResponse is the response to an update request.
@@ -327,4 +332,6 @@ message TestReleaseRequest {
 // TestReleaseResponse represents a message from executing a test
 message TestReleaseResponse {
 	string msg = 1;
+	hapi.release.TestRun.Status status = 2;
+
 }
diff --git a/circle.yml b/circle.yml
index 46b1bee3dd088745495a07ffc7c5255f349a3131..5b30c8be4bdf116fdd80d0fa9533e46e8158c5dc 100644
--- a/circle.yml
+++ b/circle.yml
@@ -3,7 +3,7 @@ machine:
     - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0
 
   environment:
-    GOVERSION: "1.7.5"
+    GOVERSION: "1.8.3"
     GOPATH:  "${HOME}/.go_workspace"
     WORKDIR: "${GOPATH}/src/k8s.io/helm"
     PROJECT_NAME: "kubernetes-helm"
diff --git a/cmd/helm/completion.go b/cmd/helm/completion.go
index ddb8f06c7d1452ebd9d22f1f102242b88331b94d..b1cd04140ca135e86a9bba68cec9cb8e2fd455c8 100644
--- a/cmd/helm/completion.go
+++ b/cmd/helm/completion.go
@@ -16,32 +16,214 @@ limitations under the License.
 package main
 
 import (
+	"bytes"
+	"fmt"
 	"io"
 
 	"github.com/spf13/cobra"
 )
 
 const completionDesc = `
-Generate bash autocompletions script for Helm.
+Generate autocompletions script for Helm for the specified shell (bash or zsh).
 
-This command can generate shell autocompletions.
+This command can generate shell autocompletions. e.g.
 
-	$ helm completion
+	$ helm completion bash
 
 Can be sourced as such
 
-	$ source <(helm completion)
+	$ source <(helm completion bash)
 `
 
+var (
+	completionShells = map[string]func(out io.Writer, cmd *cobra.Command) error{
+		"bash": runCompletionBash,
+		"zsh":  runCompletionZsh,
+	}
+)
+
 func newCompletionCmd(out io.Writer) *cobra.Command {
+	shells := []string{}
+	for s := range completionShells {
+		shells = append(shells, s)
+	}
+
 	cmd := &cobra.Command{
-		Use:    "completion",
-		Short:  "Generate bash autocompletions script",
-		Long:   completionDesc,
-		Hidden: false,
-		RunE: func(cmd *cobra.Command, _ []string) error {
-			return cmd.Root().GenBashCompletion(out)
+		Use:   "completion SHELL",
+		Short: "Generate autocompletions script for the specified shell (bash or zsh)",
+		Long:  completionDesc,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return runCompletion(out, cmd, args)
 		},
+		ValidArgs: shells,
 	}
+
 	return cmd
 }
+
+func runCompletion(out io.Writer, cmd *cobra.Command, args []string) error {
+	if len(args) == 0 {
+		return fmt.Errorf("shell not specified")
+	}
+	if len(args) > 1 {
+		return fmt.Errorf("too many arguments, expected only the shell type")
+	}
+	run, found := completionShells[args[0]]
+	if !found {
+		return fmt.Errorf("unsupported shell type %q", args[0])
+	}
+
+	return run(out, cmd)
+}
+
+func runCompletionBash(out io.Writer, cmd *cobra.Command) error {
+	return cmd.Root().GenBashCompletion(out)
+}
+
+func runCompletionZsh(out io.Writer, cmd *cobra.Command) error {
+	zshInitialization := `
+__helm_bash_source() {
+	alias shopt=':'
+	alias _expand=_bash_expand
+	alias _complete=_bash_comp
+	emulate -L sh
+	setopt kshglob noshglob braceexpand
+	source "$@"
+}
+__helm_type() {
+	# -t is not supported by zsh
+	if [ "$1" == "-t" ]; then
+		shift
+		# fake Bash 4 to disable "complete -o nospace". Instead
+		# "compopt +-o nospace" is used in the code to toggle trailing
+		# spaces. We don't support that, but leave trailing spaces on
+		# all the time
+		if [ "$1" = "__helm_compopt" ]; then
+			echo builtin
+			return 0
+		fi
+	fi
+	type "$@"
+}
+__helm_compgen() {
+	local completions w
+	completions=( $(compgen "$@") ) || return $?
+	# filter by given word as prefix
+	while [[ "$1" = -* && "$1" != -- ]]; do
+		shift
+		shift
+	done
+	if [[ "$1" == -- ]]; then
+		shift
+	fi
+	for w in "${completions[@]}"; do
+		if [[ "${w}" = "$1"* ]]; then
+			echo "${w}"
+		fi
+	done
+}
+__helm_compopt() {
+	true # don't do anything. Not supported by bashcompinit in zsh
+}
+__helm_declare() {
+	if [ "$1" == "-F" ]; then
+		whence -w "$@"
+	else
+		builtin declare "$@"
+	fi
+}
+__helm_ltrim_colon_completions()
+{
+	if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
+		# Remove colon-word prefix from COMPREPLY items
+		local colon_word=${1%${1##*:}}
+		local i=${#COMPREPLY[*]}
+		while [[ $((--i)) -ge 0 ]]; do
+			COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
+		done
+	fi
+}
+__helm_get_comp_words_by_ref() {
+	cur="${COMP_WORDS[COMP_CWORD]}"
+	prev="${COMP_WORDS[${COMP_CWORD}-1]}"
+	words=("${COMP_WORDS[@]}")
+	cword=("${COMP_CWORD[@]}")
+}
+__helm_filedir() {
+	local RET OLD_IFS w qw
+	__debug "_filedir $@ cur=$cur"
+	if [[ "$1" = \~* ]]; then
+		# somehow does not work. Maybe, zsh does not call this at all
+		eval echo "$1"
+		return 0
+	fi
+	OLD_IFS="$IFS"
+	IFS=$'\n'
+	if [ "$1" = "-d" ]; then
+		shift
+		RET=( $(compgen -d) )
+	else
+		RET=( $(compgen -f) )
+	fi
+	IFS="$OLD_IFS"
+	IFS="," __debug "RET=${RET[@]} len=${#RET[@]}"
+	for w in ${RET[@]}; do
+		if [[ ! "${w}" = "${cur}"* ]]; then
+			continue
+		fi
+		if eval "[[ \"\${w}\" = *.$1 || -d \"\${w}\" ]]"; then
+			qw="$(__helm_quote "${w}")"
+			if [ -d "${w}" ]; then
+				COMPREPLY+=("${qw}/")
+			else
+				COMPREPLY+=("${qw}")
+			fi
+		fi
+	done
+}
+__helm_quote() {
+	if [[ $1 == \'* || $1 == \"* ]]; then
+		# Leave out first character
+		printf %q "${1:1}"
+	else
+		printf %q "$1"
+	fi
+}
+autoload -U +X bashcompinit && bashcompinit
+# use word boundary patterns for BSD or GNU sed
+LWORD='[[:<:]]'
+RWORD='[[:>:]]'
+if sed --help 2>&1 | grep -q GNU; then
+	LWORD='\<'
+	RWORD='\>'
+fi
+__helm_convert_bash_to_zsh() {
+	sed \
+	-e 's/declare -F/whence -w/' \
+	-e 's/_get_comp_words_by_ref "\$@"/_get_comp_words_by_ref "\$*"/' \
+	-e 's/local \([a-zA-Z0-9_]*\)=/local \1; \1=/' \
+	-e 's/flags+=("\(--.*\)=")/flags+=("\1"); two_word_flags+=("\1")/' \
+	-e 's/must_have_one_flag+=("\(--.*\)=")/must_have_one_flag+=("\1")/' \
+	-e "s/${LWORD}_filedir${RWORD}/__helm_filedir/g" \
+	-e "s/${LWORD}_get_comp_words_by_ref${RWORD}/__helm_get_comp_words_by_ref/g" \
+	-e "s/${LWORD}__ltrim_colon_completions${RWORD}/__helm_ltrim_colon_completions/g" \
+	-e "s/${LWORD}compgen${RWORD}/__helm_compgen/g" \
+	-e "s/${LWORD}compopt${RWORD}/__helm_compopt/g" \
+	-e "s/${LWORD}declare${RWORD}/__helm_declare/g" \
+	-e "s/\\\$(type${RWORD}/\$(__helm_type/g" \
+	<<'BASH_COMPLETION_EOF'
+`
+	out.Write([]byte(zshInitialization))
+
+	buf := new(bytes.Buffer)
+	cmd.Root().GenBashCompletion(buf)
+	out.Write(buf.Bytes())
+
+	zshTail := `
+BASH_COMPLETION_EOF
+}
+__helm_bash_source <(__helm_convert_bash_to_zsh)
+`
+	out.Write([]byte(zshTail))
+	return nil
+}
diff --git a/cmd/helm/create_test.go b/cmd/helm/create_test.go
index a49d3cfa9e43e42e391c51fa781e368976d65cc6..d45843eda6580226e6e6c86828a9cd0833d95517 100644
--- a/cmd/helm/create_test.go
+++ b/cmd/helm/create_test.go
@@ -87,7 +87,7 @@ func TestCreateStarterCmd(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	old := helmpath.Home(environment.DefaultHelmHome())
+	old := helmpath.Home(environment.DefaultHelmHome)
 	settings.Home = thome
 	defer func() {
 		settings.Home = old
diff --git a/cmd/helm/delete.go b/cmd/helm/delete.go
index 2390573d9efaeda03d72a2ebc536730eea8dfff6..67ab4379c1883f030addcfcfdfdd6ccbe5836600 100755
--- a/cmd/helm/delete.go
+++ b/cmd/helm/delete.go
@@ -52,12 +52,12 @@ func newDeleteCmd(c helm.Interface, out io.Writer) *cobra.Command {
 	}
 
 	cmd := &cobra.Command{
-		Use:               "delete [flags] RELEASE_NAME [...]",
-		Aliases:           []string{"del"},
-		SuggestFor:        []string{"remove", "rm"},
-		Short:             "given a release name, delete the release from Kubernetes",
-		Long:              deleteDesc,
-		PersistentPreRunE: setupConnection,
+		Use:        "delete [flags] RELEASE_NAME [...]",
+		Aliases:    []string{"del"},
+		SuggestFor: []string{"remove", "rm"},
+		Short:      "given a release name, delete the release from Kubernetes",
+		Long:       deleteDesc,
+		PreRunE:    setupConnection,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			if len(args) == 0 {
 				return errors.New("command 'delete' requires a release name")
diff --git a/cmd/helm/dependency_build.go b/cmd/helm/dependency_build.go
index 3a92edd07b3335b81974f4a3fe9a4322797a5c46..1168a2ed272f8efc2983ddda884d7a775921862a 100644
--- a/cmd/helm/dependency_build.go
+++ b/cmd/helm/dependency_build.go
@@ -21,7 +21,7 @@ import (
 	"github.com/spf13/cobra"
 
 	"k8s.io/helm/pkg/downloader"
-	"k8s.io/helm/pkg/getter/defaultgetters"
+	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/helm/helmpath"
 )
 
@@ -77,7 +77,7 @@ func (d *dependencyBuildCmd) run() error {
 		ChartPath: d.chartpath,
 		HelmHome:  d.helmhome,
 		Keyring:   d.keyring,
-		Getters:   defaultgetters.Get(settings),
+		Getters:   getter.All(settings),
 	}
 	if d.verify {
 		man.Verify = downloader.VerifyIfPossible
diff --git a/cmd/helm/dependency_update.go b/cmd/helm/dependency_update.go
index 1838acb0adb7a7242b7a2f09f9ba6793f5339142..188f21e8832940e2ec6d8f255e0bed0f7585da46 100644
--- a/cmd/helm/dependency_update.go
+++ b/cmd/helm/dependency_update.go
@@ -21,7 +21,7 @@ import (
 
 	"github.com/spf13/cobra"
 	"k8s.io/helm/pkg/downloader"
-	"k8s.io/helm/pkg/getter/defaultgetters"
+	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/helm/helmpath"
 )
 
@@ -95,7 +95,7 @@ func (d *dependencyUpdateCmd) run() error {
 		HelmHome:   d.helmhome,
 		Keyring:    d.keyring,
 		SkipUpdate: d.skipRefresh,
-		Getters:    defaultgetters.Get(settings),
+		Getters:    getter.All(settings),
 	}
 	if d.verify {
 		man.Verify = downloader.VerifyIfPossible
diff --git a/cmd/helm/fetch.go b/cmd/helm/fetch.go
index 3dbf645cc7819a9592fef4f702285239304a20bb..a639e7f0268f49fd0cf1156bea4c104643281805 100644
--- a/cmd/helm/fetch.go
+++ b/cmd/helm/fetch.go
@@ -26,7 +26,8 @@ import (
 	"github.com/spf13/cobra"
 	"k8s.io/helm/pkg/chartutil"
 	"k8s.io/helm/pkg/downloader"
-	"k8s.io/helm/pkg/getter/defaultgetters"
+	"k8s.io/helm/pkg/getter"
+	"k8s.io/helm/pkg/repo"
 )
 
 const fetchDesc = `
@@ -50,11 +51,18 @@ type fetchCmd struct {
 	chartRef string
 	destdir  string
 	version  string
+	repoURL  string
 
 	verify      bool
 	verifyLater bool
 	keyring     string
 
+	certFile string
+	keyFile  string
+	caFile   string
+
+	devel bool
+
 	out io.Writer
 }
 
@@ -67,8 +75,14 @@ func newFetchCmd(out io.Writer) *cobra.Command {
 		Long:  fetchDesc,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			if len(args) == 0 {
-				return fmt.Errorf("This command needs at least one argument, url or repo/name of the chart.")
+				return fmt.Errorf("need at least one argument, url or repo/name of the chart")
 			}
+
+			if fch.version == "" && fch.devel {
+				debug("setting version to >0.0.0-a")
+				fch.version = ">0.0.0-a"
+			}
+
 			for i := 0; i < len(args); i++ {
 				fch.chartRef = args[i]
 				if err := fch.run(); err != nil {
@@ -87,6 +101,11 @@ func newFetchCmd(out io.Writer) *cobra.Command {
 	f.StringVar(&fch.version, "version", "", "specific version of a chart. Without this, the latest version is fetched")
 	f.StringVar(&fch.keyring, "keyring", defaultKeyring(), "keyring containing public keys")
 	f.StringVarP(&fch.destdir, "destination", "d", ".", "location to write the chart. If this and tardir are specified, tardir is appended to this")
+	f.StringVar(&fch.repoURL, "repo", "", "chart repository url where to locate the requested chart")
+	f.StringVar(&fch.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
+	f.StringVar(&fch.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
+	f.StringVar(&fch.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
+	f.BoolVar(&fch.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-a'. If --version is set, this is ignored.")
 
 	return cmd
 }
@@ -97,7 +116,7 @@ func (f *fetchCmd) run() error {
 		Out:      f.out,
 		Keyring:  f.keyring,
 		Verify:   downloader.VerifyNever,
-		Getters:  defaultgetters.Get(settings),
+		Getters:  getter.All(settings),
 	}
 
 	if f.verify {
@@ -118,6 +137,14 @@ func (f *fetchCmd) run() error {
 		defer os.RemoveAll(dest)
 	}
 
+	if f.repoURL != "" {
+		chartURL, err := repo.FindChartInRepoURL(f.repoURL, f.chartRef, f.version, f.certFile, f.keyFile, f.caFile, getter.All(settings))
+		if err != nil {
+			return err
+		}
+		f.chartRef = chartURL
+	}
+
 	saved, v, err := c.DownloadTo(f.chartRef, f.version, dest)
 	if err != nil {
 		return err
diff --git a/cmd/helm/fetch_test.go b/cmd/helm/fetch_test.go
index 8c1f2a74b00d9018cbee041d30c001e5c179b2fc..4d81ed38e7007b1ee411bc0764dfcee5d1593b36 100644
--- a/cmd/helm/fetch_test.go
+++ b/cmd/helm/fetch_test.go
@@ -34,12 +34,14 @@ func TestFetchCmd(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	old := helmpath.Home(environment.DefaultHelmHome())
+	old := helmpath.Home(environment.DefaultHelmHome)
 	settings.Home = hh
 	defer func() {
 		settings.Home = old
 		os.RemoveAll(hh.String())
 	}()
+	srv := repotest.NewServer(hh.String())
+	defer srv.Stop()
 
 	// all flags will get "--home=TMDIR -d outdir" appended.
 	tests := []struct {
@@ -105,11 +107,34 @@ func TestFetchCmd(t *testing.T) {
 			expectDir:    true,
 			expectVerify: true,
 		},
+		{
+			name:       "Chart fetch using repo URL",
+			chart:      "signtest",
+			expectFile: "./signtest-0.1.0.tgz",
+			flags:      []string{"--repo", srv.URL()},
+		},
+		{
+			name:       "Fail fetching non-existent chart on repo URL",
+			chart:      "someChart",
+			flags:      []string{"--repo", srv.URL()},
+			failExpect: "Failed to fetch chart",
+			fail:       true,
+		},
+		{
+			name:       "Specific version chart fetch using repo URL",
+			chart:      "signtest",
+			expectFile: "./signtest-0.1.0.tgz",
+			flags:      []string{"--repo", srv.URL(), "--version", "0.1.0"},
+		},
+		{
+			name:       "Specific version chart fetch using repo URL",
+			chart:      "signtest",
+			flags:      []string{"--repo", srv.URL(), "--version", "0.2.0"},
+			failExpect: "Failed to fetch chart version",
+			fail:       true,
+		},
 	}
 
-	srv := repotest.NewServer(hh.String())
-	defer srv.Stop()
-
 	if _, err := srv.CopyCharts("testdata/testcharts/*.tgz*"); err != nil {
 		t.Fatal(err)
 	}
diff --git a/cmd/helm/get.go b/cmd/helm/get.go
index b540d24feddd494037699af94815e201d22be803..fc5871f46f10a6a19c8ca9f46826382318ae6b92 100644
--- a/cmd/helm/get.go
+++ b/cmd/helm/get.go
@@ -54,10 +54,10 @@ func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
 	}
 
 	cmd := &cobra.Command{
-		Use:               "get [flags] RELEASE_NAME",
-		Short:             "download a named release",
-		Long:              getHelp,
-		PersistentPreRunE: setupConnection,
+		Use:     "get [flags] RELEASE_NAME",
+		Short:   "download a named release",
+		Long:    getHelp,
+		PreRunE: setupConnection,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			if len(args) == 0 {
 				return errReleaseRequired
diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go
index ced336ac441d198ab2fa2b2a6433abdc0cbb46ef..096a989f612ef12991e8b1d6f8c078b61209a453 100644
--- a/cmd/helm/helm.go
+++ b/cmd/helm/helm.go
@@ -19,7 +19,6 @@ package main // import "k8s.io/helm/cmd/helm"
 import (
 	"errors"
 	"fmt"
-	"io"
 	"io/ioutil"
 	"log"
 	"os"
@@ -33,30 +32,22 @@ import (
 
 	"k8s.io/helm/pkg/helm"
 	helm_env "k8s.io/helm/pkg/helm/environment"
-	"k8s.io/helm/pkg/helm/helmpath"
 	"k8s.io/helm/pkg/helm/portforwarder"
 	"k8s.io/helm/pkg/kube"
 	tiller_env "k8s.io/helm/pkg/tiller/environment"
 	"k8s.io/helm/pkg/tlsutil"
 )
 
-const (
-	localRepoIndexFilePath = "index.yaml"
-)
-
 var (
 	tlsCaCertFile string // path to TLS CA certificate file
 	tlsCertFile   string // path to TLS certificate file
 	tlsKeyFile    string // path to TLS key file
 	tlsVerify     bool   // enable TLS and verify remote certificates
 	tlsEnable     bool   // enable TLS
-)
 
-var (
-	kubeContext string
-	settings    helm_env.EnvSettings
-	// TODO refactor out this global var
+	kubeContext  string
 	tillerTunnel *kube.Tunnel
+	settings     helm_env.EnvSettings
 )
 
 var globalUsage = `The Kubernetes package manager
@@ -83,37 +74,58 @@ Environment:
   $KUBECONFIG         set an alternative Kubernetes configuration file (default "~/.kube/config")
 `
 
-func newRootCmd(out io.Writer) *cobra.Command {
-	var helmHomeTemp string
+func setFlagFromEnv(name, envar string, cmd *cobra.Command) {
+	if cmd.Flags().Changed(name) {
+		return
+	}
+	if v, ok := os.LookupEnv(envar); ok {
+		cmd.Flags().Set(name, v)
+	}
+}
+
+func setFlagsFromEnv(flags map[string]string, cmd *cobra.Command) {
+	for name, envar := range flags {
+		setFlagFromEnv(name, envar, cmd)
+	}
+}
+
+func addRootFlags(cmd *cobra.Command) {
+	pf := cmd.PersistentFlags()
+	pf.StringVar((*string)(&settings.Home), "home", helm_env.DefaultHelmHome, "location of your Helm config. Overrides $HELM_HOME")
+	pf.StringVar(&settings.TillerHost, "host", "", "address of tiller. Overrides $HELM_HOST")
+	pf.StringVar(&kubeContext, "kube-context", "", "name of the kubeconfig context to use")
+	pf.BoolVar(&settings.Debug, "debug", false, "enable verbose output")
+	pf.StringVar(&settings.TillerNamespace, "tiller-namespace", tiller_env.DefaultTillerNamespace, "namespace of tiller")
+}
 
+func initRootFlags(cmd *cobra.Command) {
+	setFlagsFromEnv(map[string]string{
+		"debug":            helm_env.DebugEnvVar,
+		"home":             helm_env.HomeEnvVar,
+		"host":             helm_env.HostEnvVar,
+		"tiller-namespace": tiller_env.TillerNamespaceEnvVar,
+	}, cmd.Root())
+
+	tlsCaCertFile = os.ExpandEnv(tlsCaCertFile)
+	tlsCertFile = os.ExpandEnv(tlsCertFile)
+	tlsKeyFile = os.ExpandEnv(tlsKeyFile)
+}
+
+func newRootCmd() *cobra.Command {
 	cmd := &cobra.Command{
 		Use:          "helm",
 		Short:        "The Helm package manager for Kubernetes.",
 		Long:         globalUsage,
 		SilenceUsage: true,
-		PersistentPreRun: func(cmd *cobra.Command, args []string) {
-			tlsCaCertFile = os.ExpandEnv(tlsCaCertFile)
-			tlsCertFile = os.ExpandEnv(tlsCertFile)
-			tlsKeyFile = os.ExpandEnv(tlsKeyFile)
+		PersistentPreRun: func(cmd *cobra.Command, _ []string) {
+			initRootFlags(cmd)
 		},
-		PersistentPostRun: func(cmd *cobra.Command, args []string) {
+		PersistentPostRun: func(*cobra.Command, []string) {
 			teardown()
 		},
 	}
-	p := cmd.PersistentFlags()
-	p.StringVar(&helmHomeTemp, "home", helm_env.DefaultHelmHome(), "location of your Helm config. Overrides $HELM_HOME")
-	settings.Home = helmpath.Home(helmHomeTemp)
-	p.StringVar(&settings.TillerHost, "host", helm_env.DefaultHelmHost(), "address of tiller. Overrides $HELM_HOST")
-	p.StringVar(&kubeContext, "kube-context", "", "name of the kubeconfig context to use")
-	p.BoolVar(&settings.Debug, "debug", false, "enable verbose output")
-	p.StringVar(&settings.TillerNamespace, "tiller-namespace", tiller_env.GetTillerNamespace(), "namespace of tiller")
-
-	if os.Getenv(helm_env.PluginDisableEnvVar) != "1" {
-		settings.PlugDirs = os.Getenv(helm_env.PluginEnvVar)
-		if settings.PlugDirs == "" {
-			settings.PlugDirs = settings.Home.Plugins()
-		}
-	}
+	addRootFlags(cmd)
+	out := cmd.OutOrStdout()
 
 	cmd.AddCommand(
 		// chart commands
@@ -166,7 +178,7 @@ func init() {
 }
 
 func main() {
-	cmd := newRootCmd(os.Stdout)
+	cmd := newRootCmd()
 	if err := cmd.Execute(); err != nil {
 		os.Exit(1)
 	}
diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go
index 016b79d6b13f702c8cadbf2d10b5c1f1ea52cb17..d3078dae02e4f031a076cc9c13d2fdea85287bb2 100644
--- a/cmd/helm/helm_test.go
+++ b/cmd/helm/helm_test.go
@@ -23,7 +23,9 @@ import (
 	"io/ioutil"
 	"math/rand"
 	"os"
+	"path/filepath"
 	"regexp"
+	"sync"
 	"testing"
 
 	"github.com/golang/protobuf/ptypes/timestamp"
@@ -122,8 +124,9 @@ func releaseMock(opts *releaseOptions) *release.Release {
 }
 
 type fakeReleaseClient struct {
-	rels []*release.Release
-	err  error
+	rels      []*release.Release
+	responses map[string]release.TestRun_Status
+	err       error
 }
 
 var _ helm.Interface = &fakeReleaseClient{}
@@ -198,7 +201,27 @@ func (c *fakeReleaseClient) ReleaseHistory(rlsName string, opts ...helm.HistoryO
 }
 
 func (c *fakeReleaseClient) RunReleaseTest(rlsName string, opts ...helm.ReleaseTestOption) (<-chan *rls.TestReleaseResponse, <-chan error) {
-	return nil, nil
+
+	results := make(chan *rls.TestReleaseResponse)
+	errc := make(chan error, 1)
+
+	go func() {
+		var wg sync.WaitGroup
+		for m, s := range c.responses {
+			wg.Add(1)
+
+			go func(msg string, status release.TestRun_Status) {
+				defer wg.Done()
+				results <- &rls.TestReleaseResponse{Msg: msg, Status: status}
+			}(m, s)
+		}
+
+		wg.Wait()
+		close(results)
+		close(errc)
+	}()
+
+	return results, errc
 }
 
 func (c *fakeReleaseClient) Option(opt ...helm.Option) helm.Interface {
@@ -299,7 +322,7 @@ func ensureTestHome(home helmpath.Home, t *testing.T) error {
 		}
 	}
 
-	localRepoIndexFile := home.LocalRepository(localRepoIndexFilePath)
+	localRepoIndexFile := home.LocalRepository(localRepositoryIndexFile)
 	if fi, err := os.Stat(localRepoIndexFile); err != nil {
 		i := repo.NewIndexFile()
 		if err := i.WriteFile(localRepoIndexFile, 0644); err != nil {
@@ -315,3 +338,79 @@ func ensureTestHome(home helmpath.Home, t *testing.T) error {
 	t.Logf("$HELM_HOME has been configured at %s.\n", settings.Home.String())
 	return nil
 }
+
+func TestRootCmd(t *testing.T) {
+	oldhome := os.Getenv("HELM_HOME")
+	defer os.Setenv("HELM_HOME", oldhome)
+
+	tests := []struct {
+		name   string
+		args   []string
+		envars map[string]string
+		home   string
+	}{
+		{
+			name: "defaults",
+			args: []string{"home"},
+			home: filepath.Join(os.Getenv("HOME"), "/.helm"),
+		},
+		{
+			name: "with --home set",
+			args: []string{"--home", "/foo"},
+			home: "/foo",
+		},
+		{
+			name: "subcommands with --home set",
+			args: []string{"home", "--home", "/foo"},
+			home: "/foo",
+		},
+		{
+			name:   "with $HELM_HOME set",
+			args:   []string{"home"},
+			envars: map[string]string{"HELM_HOME": "/bar"},
+			home:   "/bar",
+		},
+		{
+			name:   "subcommands with $HELM_HOME set",
+			args:   []string{"home"},
+			envars: map[string]string{"HELM_HOME": "/bar"},
+			home:   "/bar",
+		},
+		{
+			name:   "with $HELM_HOME and --home set",
+			args:   []string{"home", "--home", "/foo"},
+			envars: map[string]string{"HELM_HOME": "/bar"},
+			home:   "/foo",
+		},
+	}
+
+	// ensure not set locally
+	os.Unsetenv("HELM_HOME")
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			defer os.Unsetenv("HELM_HOME")
+
+			for k, v := range tt.envars {
+				os.Setenv(k, v)
+			}
+
+			cmd := newRootCmd()
+			cmd.SetOutput(ioutil.Discard)
+			cmd.SetArgs(tt.args)
+			cmd.Run = func(*cobra.Command, []string) {}
+			if err := cmd.Execute(); err != nil {
+				t.Errorf("unexpected error: %s", err)
+			}
+
+			if settings.Home.String() != tt.home {
+				t.Errorf("expected home %q, got %q", tt.home, settings.Home)
+			}
+			homeFlag := cmd.Flag("home").Value.String()
+			homeFlag = os.ExpandEnv(homeFlag)
+			if homeFlag != tt.home {
+				t.Errorf("expected home %q, got %q", tt.home, homeFlag)
+			}
+		})
+	}
+}
diff --git a/cmd/helm/history.go b/cmd/helm/history.go
index 21c444dabf3b08996e59569695324dd044bff46f..08f1656f58b7b81363be7fcc40dbc85d09894222 100644
--- a/cmd/helm/history.go
+++ b/cmd/helm/history.go
@@ -56,11 +56,11 @@ func newHistoryCmd(c helm.Interface, w io.Writer) *cobra.Command {
 	his := &historyCmd{out: w, helmc: c}
 
 	cmd := &cobra.Command{
-		Use:               "history [flags] RELEASE_NAME",
-		Long:              historyHelp,
-		Short:             "fetch release history",
-		Aliases:           []string{"hist"},
-		PersistentPreRunE: setupConnection,
+		Use:     "history [flags] RELEASE_NAME",
+		Long:    historyHelp,
+		Short:   "fetch release history",
+		Aliases: []string{"hist"},
+		PreRunE: setupConnection,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			switch {
 			case len(args) == 0:
diff --git a/cmd/helm/home.go b/cmd/helm/home.go
index 25809b52166322d38a2174b3b7a7bd3be630c19e..e96edd7a127994ecbcd2af21f0867c2bb53ce0e8 100644
--- a/cmd/helm/home.go
+++ b/cmd/helm/home.go
@@ -35,7 +35,7 @@ func newHomeCmd(out io.Writer) *cobra.Command {
 		Long:  longHomeHelp,
 		Run: func(cmd *cobra.Command, args []string) {
 			h := settings.Home
-			fmt.Fprintf(out, "%s\n", h)
+			fmt.Fprintln(out, h)
 			if settings.Debug {
 				fmt.Fprintf(out, "Repository: %s\n", h.Repository())
 				fmt.Fprintf(out, "RepositoryFile: %s\n", h.RepositoryFile())
@@ -47,6 +47,5 @@ func newHomeCmd(out io.Writer) *cobra.Command {
 			}
 		},
 	}
-
 	return cmd
 }
diff --git a/cmd/helm/init.go b/cmd/helm/init.go
index a2bec7a654269aef1caf6fe792b1d8b7334c1c0d..dab6e0bc7ba4aabd183ddb5f666208a8b7f2755e 100644
--- a/cmd/helm/init.go
+++ b/cmd/helm/init.go
@@ -27,7 +27,7 @@ import (
 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
 
 	"k8s.io/helm/cmd/helm/installer"
-	"k8s.io/helm/pkg/getter/defaultgetters"
+	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/helm/helmpath"
 	"k8s.io/helm/pkg/repo"
 )
@@ -54,8 +54,9 @@ To dump a manifest containing the Tiller deployment YAML, combine the
 `
 
 const (
-	stableRepository = "stable"
-	localRepository  = "local"
+	stableRepository         = "stable"
+	localRepository          = "local"
+	localRepositoryIndexFile = "index.yaml"
 )
 
 var (
@@ -66,17 +67,18 @@ var (
 )
 
 type initCmd struct {
-	image       string
-	clientOnly  bool
-	canary      bool
-	upgrade     bool
-	namespace   string
-	dryRun      bool
-	skipRefresh bool
-	out         io.Writer
-	home        helmpath.Home
-	opts        installer.Options
-	kubeClient  internalclientset.Interface
+	image          string
+	clientOnly     bool
+	canary         bool
+	upgrade        bool
+	namespace      string
+	dryRun         bool
+	skipRefresh    bool
+	out            io.Writer
+	home           helmpath.Home
+	opts           installer.Options
+	kubeClient     internalclientset.Interface
+	serviceAccount string
 }
 
 func newInitCmd(out io.Writer) *cobra.Command {
@@ -116,6 +118,7 @@ func newInitCmd(out io.Writer) *cobra.Command {
 	f.StringVar(&localRepositoryURL, "local-repo-url", localRepositoryURL, "URL for local repository")
 
 	f.BoolVar(&i.opts.EnableHostNetwork, "net-host", false, "install tiller with net=host")
+	f.StringVar(&i.serviceAccount, "service-account", "", "name of service account")
 
 	return cmd
 }
@@ -154,6 +157,7 @@ func (i *initCmd) run() error {
 	i.opts.Namespace = i.namespace
 	i.opts.UseCanary = i.canary
 	i.opts.ImageSpec = i.image
+	i.opts.ServiceAccount = i.serviceAccount
 
 	if settings.Debug {
 		writeYAMLManifest := func(apiVersion, kind, body string, first, last bool) error {
@@ -293,7 +297,7 @@ func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool) err
 		if err != nil {
 			return err
 		}
-		lr, err := initLocalRepo(home.LocalRepository(localRepoIndexFilePath), home.CacheIndex("local"))
+		lr, err := initLocalRepo(home.LocalRepository(localRepositoryIndexFile), home.CacheIndex("local"))
 		if err != nil {
 			return err
 		}
@@ -314,7 +318,7 @@ func initStableRepo(cacheFile string, skipRefresh bool) (*repo.Entry, error) {
 		URL:   stableRepositoryURL,
 		Cache: cacheFile,
 	}
-	r, err := repo.NewChartRepository(&c, defaultgetters.Get(settings))
+	r, err := repo.NewChartRepository(&c, getter.All(settings))
 	if err != nil {
 		return nil, err
 	}
diff --git a/cmd/helm/init_test.go b/cmd/helm/init_test.go
index 4d82c297b8dfe699b01ca24732e93c381cda5ca4..874d9d4dc2b0208ab023bd7324eadb804eb291e4 100644
--- a/cmd/helm/init_test.go
+++ b/cmd/helm/init_test.go
@@ -214,7 +214,7 @@ func TestEnsureHome(t *testing.T) {
 		t.Errorf("%s should not be a directory", fi)
 	}
 
-	if fi, err := os.Stat(hh.LocalRepository(localRepoIndexFilePath)); err != nil {
+	if fi, err := os.Stat(hh.LocalRepository(localRepositoryIndexFile)); err != nil {
 		t.Errorf("%s", err)
 	} else if fi.IsDir() {
 		t.Errorf("%s should not be a directory", fi)
diff --git a/cmd/helm/inspect.go b/cmd/helm/inspect.go
index c3d539b3ab8a02dfdb75d54e9b87e1e4d9fabb7e..6369b5ddcff4cd5f527a38bef583b6ea77c80df9 100644
--- a/cmd/helm/inspect.go
+++ b/cmd/helm/inspect.go
@@ -50,6 +50,11 @@ type inspectCmd struct {
 	keyring   string
 	out       io.Writer
 	version   string
+	repoURL   string
+
+	certFile string
+	keyFile  string
+	caFile   string
 }
 
 const (
@@ -72,7 +77,8 @@ func newInspectCmd(out io.Writer) *cobra.Command {
 			if err := checkArgsLength(len(args), "chart name"); err != nil {
 				return err
 			}
-			cp, err := locateChartPath(args[0], insp.version, insp.verify, insp.keyring)
+			cp, err := locateChartPath(insp.repoURL, args[0], insp.version, insp.verify, insp.keyring,
+				insp.certFile, insp.keyFile, insp.caFile)
 			if err != nil {
 				return err
 			}
@@ -90,7 +96,8 @@ func newInspectCmd(out io.Writer) *cobra.Command {
 			if err := checkArgsLength(len(args), "chart name"); err != nil {
 				return err
 			}
-			cp, err := locateChartPath(args[0], insp.version, insp.verify, insp.keyring)
+			cp, err := locateChartPath(insp.repoURL, args[0], insp.version, insp.verify, insp.keyring,
+				insp.certFile, insp.keyFile, insp.caFile)
 			if err != nil {
 				return err
 			}
@@ -108,7 +115,8 @@ func newInspectCmd(out io.Writer) *cobra.Command {
 			if err := checkArgsLength(len(args), "chart name"); err != nil {
 				return err
 			}
-			cp, err := locateChartPath(args[0], insp.version, insp.verify, insp.keyring)
+			cp, err := locateChartPath(insp.repoURL, args[0], insp.version, insp.verify, insp.keyring,
+				insp.certFile, insp.keyFile, insp.caFile)
 			if err != nil {
 				return err
 			}
@@ -136,6 +144,30 @@ func newInspectCmd(out io.Writer) *cobra.Command {
 	valuesSubCmd.Flags().StringVar(&insp.version, verflag, "", verdesc)
 	chartSubCmd.Flags().StringVar(&insp.version, verflag, "", verdesc)
 
+	repoURL := "repo"
+	repoURLdesc := "chart repository url where to locate the requested chart"
+	inspectCommand.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc)
+	valuesSubCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc)
+	chartSubCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc)
+
+	certFile := "cert-file"
+	certFiledesc := "verify certificates of HTTPS-enabled servers using this CA bundle"
+	inspectCommand.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc)
+	valuesSubCmd.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc)
+	chartSubCmd.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc)
+
+	keyFile := "key-file"
+	keyFiledesc := "identify HTTPS client using this SSL key file"
+	inspectCommand.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc)
+	valuesSubCmd.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc)
+	chartSubCmd.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc)
+
+	caFile := "ca-file"
+	caFiledesc := "chart repository url where to locate the requested chart"
+	inspectCommand.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc)
+	valuesSubCmd.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc)
+	chartSubCmd.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc)
+
 	inspectCommand.AddCommand(valuesSubCmd)
 	inspectCommand.AddCommand(chartSubCmd)
 
diff --git a/cmd/helm/install.go b/cmd/helm/install.go
index d01ee514aa105271bb6c711d9861968c1a3f22d6..f438ebe04eef41f3137c873fa7dd046a1b89a4cd 100644
--- a/cmd/helm/install.go
+++ b/cmd/helm/install.go
@@ -34,11 +34,12 @@ import (
 
 	"k8s.io/helm/pkg/chartutil"
 	"k8s.io/helm/pkg/downloader"
-	"k8s.io/helm/pkg/getter/defaultgetters"
+	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/helm"
 	"k8s.io/helm/pkg/kube"
 	"k8s.io/helm/pkg/proto/hapi/chart"
 	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/repo"
 	"k8s.io/helm/pkg/strvals"
 )
 
@@ -115,6 +116,12 @@ type installCmd struct {
 	version      string
 	timeout      int64
 	wait         bool
+	repoURL      string
+	devel        bool
+
+	certFile string
+	keyFile  string
+	caFile   string
 }
 
 type valueFiles []string
@@ -141,15 +148,23 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
 	}
 
 	cmd := &cobra.Command{
-		Use:               "install [CHART]",
-		Short:             "install a chart archive",
-		Long:              installDesc,
-		PersistentPreRunE: setupConnection,
+		Use:     "install [CHART]",
+		Short:   "install a chart archive",
+		Long:    installDesc,
+		PreRunE: setupConnection,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			if err := checkArgsLength(len(args), "chart name"); err != nil {
 				return err
 			}
-			cp, err := locateChartPath(args[0], inst.version, inst.verify, inst.keyring)
+
+			debug("Original chart version: %q", inst.version)
+			if inst.version == "" && inst.devel {
+				debug("setting version to >0.0.0-a")
+				inst.version = ">0.0.0-a"
+			}
+
+			cp, err := locateChartPath(inst.repoURL, args[0], inst.version, inst.verify, inst.keyring,
+				inst.certFile, inst.keyFile, inst.caFile)
 			if err != nil {
 				return err
 			}
@@ -173,6 +188,11 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
 	f.StringVar(&inst.version, "version", "", "specify the exact chart version to install. If this is not specified, the latest version is installed")
 	f.Int64Var(&inst.timeout, "timeout", 300, "time in seconds to wait for any individual kubernetes operation (like Jobs for hooks)")
 	f.BoolVar(&inst.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
+	f.StringVar(&inst.repoURL, "repo", "", "chart repository url where to locate the requested chart")
+	f.StringVar(&inst.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
+	f.StringVar(&inst.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
+	f.StringVar(&inst.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
+	f.BoolVar(&inst.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-a'. If --version is set, this is ignored.")
 
 	return cmd
 }
@@ -206,7 +226,14 @@ func (i *installCmd) run() error {
 	}
 
 	if req, err := chartutil.LoadRequirements(chartRequested); err == nil {
-		checkDependencies(chartRequested, req, i.out)
+		// If checkDependencies returns an error, we have unfullfilled dependencies.
+		// As of Helm 2.4.0, this is treated as a stopping condition:
+		// https://github.com/kubernetes/helm/issues/2209
+		if err := checkDependencies(chartRequested, req, i.out); err != nil {
+			return prettyError(err)
+		}
+	} else if err != chartutil.ErrRequirementsNotFound {
+		return fmt.Errorf("cannot load requirements: %v", err)
 	}
 
 	res, err := i.client.InstallReleaseFromChart(
@@ -326,7 +353,8 @@ func (i *installCmd) printRelease(rel *release.Release) {
 // - URL
 //
 // If 'verify' is true, this will attempt to also verify the chart.
-func locateChartPath(name, version string, verify bool, keyring string) (string, error) {
+func locateChartPath(repoURL, name, version string, verify bool, keyring,
+	certFile, keyFile, caFile string) (string, error) {
 	name = strings.TrimSpace(name)
 	version = strings.TrimSpace(version)
 	if fi, err := os.Stat(name); err == nil {
@@ -357,11 +385,19 @@ func locateChartPath(name, version string, verify bool, keyring string) (string,
 		HelmHome: settings.Home,
 		Out:      os.Stdout,
 		Keyring:  keyring,
-		Getters:  defaultgetters.Get(settings),
+		Getters:  getter.All(settings),
 	}
 	if verify {
 		dl.Verify = downloader.VerifyAlways
 	}
+	if repoURL != "" {
+		chartURL, err := repo.FindChartInRepoURL(repoURL, name, version,
+			certFile, keyFile, caFile, getter.All(settings))
+		if err != nil {
+			return "", err
+		}
+		name = chartURL
+	}
 
 	filename, _, err := dl.DownloadTo(name, version, ".")
 	if err == nil {
@@ -398,7 +434,9 @@ func defaultNamespace() string {
 	return "default"
 }
 
-func checkDependencies(ch *chart.Chart, reqs *chartutil.Requirements, out io.Writer) {
+func checkDependencies(ch *chart.Chart, reqs *chartutil.Requirements, out io.Writer) error {
+	missing := []string{}
+
 	deps := ch.GetDependencies()
 	for _, r := range reqs.Dependencies {
 		found := false
@@ -409,7 +447,12 @@ func checkDependencies(ch *chart.Chart, reqs *chartutil.Requirements, out io.Wri
 			}
 		}
 		if !found {
-			fmt.Fprintf(out, "Warning: %s is in requirements.yaml but not in the charts/ directory!\n", r.Name)
+			missing = append(missing, r.Name)
 		}
 	}
+
+	if len(missing) > 0 {
+		return fmt.Errorf("found in requirements.yaml, but missing in charts/ directory: %s", strings.Join(missing, ", "))
+	}
+	return nil
 }
diff --git a/cmd/helm/install_test.go b/cmd/helm/install_test.go
index ee0ffe0e86711d79b1dca4c13887ea782e281038..b2e47a1dd6397dd6c6d7e10ea316425b85750231 100644
--- a/cmd/helm/install_test.go
+++ b/cmd/helm/install_test.go
@@ -134,9 +134,15 @@ func TestInstall(t *testing.T) {
 		},
 		// Install, chart with missing dependencies in /charts
 		{
-			name:     "install chart with missing dependencies",
-			args:     []string{"testdata/testcharts/chart-missing-deps"},
-			expected: "Warning: reqsubchart2 is in requirements.yaml but not in the charts/ directory!",
+			name: "install chart with missing dependencies",
+			args: []string{"testdata/testcharts/chart-missing-deps"},
+			err:  true,
+		},
+		// Install, chart with bad requirements.yaml in /charts
+		{
+			name: "install chart with bad requirements.yaml",
+			args: []string{"testdata/testcharts/chart-bad-requirements"},
+			err:  true,
 		},
 	}
 
diff --git a/cmd/helm/installer/install.go b/cmd/helm/installer/install.go
index 90e832b07f166786f0d39983d030fd08c92b00a8..9d6a6aeb1c547d36a31c91acebad9a334f78ee29 100644
--- a/cmd/helm/installer/install.go
+++ b/cmd/helm/installer/install.go
@@ -58,6 +58,7 @@ func Upgrade(client internalclientset.Interface, opts *Options) error {
 	}
 	obj.Spec.Template.Spec.Containers[0].Image = opts.selectImage()
 	obj.Spec.Template.Spec.Containers[0].ImagePullPolicy = opts.pullPolicy()
+	obj.Spec.Template.Spec.ServiceAccountName = opts.ServiceAccount
 	if _, err := client.Extensions().Deployments(opts.Namespace).Update(obj); err != nil {
 		return err
 	}
@@ -131,6 +132,7 @@ func generateDeployment(opts *Options) *extensions.Deployment {
 					Labels: labels,
 				},
 				Spec: api.PodSpec{
+					ServiceAccountName: opts.ServiceAccount,
 					Containers: []api.Container{
 						{
 							Name:            "tiller",
@@ -164,6 +166,9 @@ func generateDeployment(opts *Options) *extensions.Deployment {
 							},
 						},
 					},
+					NodeSelector: map[string]string{
+						"beta.kubernetes.io/os": "linux",
+					},
 					SecurityContext: &api.PodSecurityContext{
 						HostNetwork: opts.EnableHostNetwork,
 					},
diff --git a/cmd/helm/installer/install_test.go b/cmd/helm/installer/install_test.go
index 63f8419b3d7416834cd8bfde097d472a28eeb114..22af4d61e20579c0baef7cb16315421d0fd38c0d 100644
--- a/cmd/helm/installer/install_test.go
+++ b/cmd/helm/installer/install_test.go
@@ -70,6 +70,34 @@ func TestDeploymentManifest(t *testing.T) {
 	}
 }
 
+func TestDeploymentManifestForServiceAccount(t *testing.T) {
+	tests := []struct {
+		name            string
+		image           string
+		canary          bool
+		expect          string
+		imagePullPolicy api.PullPolicy
+		serviceAccount  string
+	}{
+		{"withSA", "", false, "gcr.io/kubernetes-helm/tiller:latest", "IfNotPresent", "service-account"},
+		{"withoutSA", "", false, "gcr.io/kubernetes-helm/tiller:latest", "IfNotPresent", ""},
+	}
+	for _, tt := range tests {
+		o, err := DeploymentManifest(&Options{Namespace: api.NamespaceDefault, ImageSpec: tt.image, UseCanary: tt.canary, ServiceAccount: tt.serviceAccount})
+		if err != nil {
+			t.Fatalf("%s: error %q", tt.name, err)
+		}
+
+		var d extensions.Deployment
+		if err := yaml.Unmarshal([]byte(o), &d); err != nil {
+			t.Fatalf("%s: error %q", tt.name, err)
+		}
+		if got := d.Spec.Template.Spec.ServiceAccountName; got != tt.serviceAccount {
+			t.Errorf("%s: expected service account value %q, got %q", tt.name, tt.serviceAccount, got)
+		}
+	}
+}
+
 func TestDeploymentManifest_WithTLS(t *testing.T) {
 	tests := []struct {
 		opts   Options
@@ -301,11 +329,12 @@ func TestInstall_canary(t *testing.T) {
 
 func TestUpgrade(t *testing.T) {
 	image := "gcr.io/kubernetes-helm/tiller:v2.0.0"
-
+	serviceAccount := "newServiceAccount"
 	existingDeployment := deployment(&Options{
-		Namespace: api.NamespaceDefault,
-		ImageSpec: "imageToReplace",
-		UseCanary: false,
+		Namespace:      api.NamespaceDefault,
+		ImageSpec:      "imageToReplace",
+		ServiceAccount: "serviceAccountToReplace",
+		UseCanary:      false,
 	})
 	existingService := service(api.NamespaceDefault)
 
@@ -319,13 +348,17 @@ func TestUpgrade(t *testing.T) {
 		if i != image {
 			t.Errorf("expected image = '%s', got '%s'", image, i)
 		}
+		sa := obj.Spec.Template.Spec.ServiceAccountName
+		if sa != serviceAccount {
+			t.Errorf("expected serviceAccountName = '%s', got '%s'", serviceAccount, sa)
+		}
 		return true, obj, nil
 	})
 	fc.AddReactor("get", "services", func(action testcore.Action) (bool, runtime.Object, error) {
 		return true, existingService, nil
 	})
 
-	opts := &Options{Namespace: api.NamespaceDefault, ImageSpec: image}
+	opts := &Options{Namespace: api.NamespaceDefault, ImageSpec: image, ServiceAccount: serviceAccount}
 	if err := Upgrade(fc, opts); err != nil {
 		t.Errorf("unexpected error: %#+v", err)
 	}
diff --git a/cmd/helm/installer/options.go b/cmd/helm/installer/options.go
index eb9519f5dc21a5525c635f59af5ae52993ec2b25..6fb804a46f534dd621f2692e93e481471d6a78c4 100644
--- a/cmd/helm/installer/options.go
+++ b/cmd/helm/installer/options.go
@@ -43,6 +43,9 @@ type Options struct {
 	// Namespace is the kubernetes namespace to use to deploy tiller.
 	Namespace string
 
+	// ServiceAccount is the Kubernetes service account to add to tiller
+	ServiceAccount string
+
 	// ImageSpec indentifies the image tiller will use when deployed.
 	//
 	// Valid if and only if UseCanary is false.
diff --git a/cmd/helm/list.go b/cmd/helm/list.go
index 0919a1c3bb152bc7dcac9b9ad812a20268debe21..391e83e20d031406ba68ed444e4003ae3ea7aea7 100644
--- a/cmd/helm/list.go
+++ b/cmd/helm/list.go
@@ -82,11 +82,11 @@ func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
 	}
 
 	cmd := &cobra.Command{
-		Use:               "list [flags] [FILTER]",
-		Short:             "list releases",
-		Long:              listHelp,
-		Aliases:           []string{"ls"},
-		PersistentPreRunE: setupConnection,
+		Use:     "list [flags] [FILTER]",
+		Short:   "list releases",
+		Long:    listHelp,
+		Aliases: []string{"ls"},
+		PreRunE: setupConnection,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			if len(args) > 0 {
 				list.filter = strings.Join(args, " ")
diff --git a/cmd/helm/load_plugins.go b/cmd/helm/load_plugins.go
index af4e2f2bfe43b15e0f19fb1cd4214bdb44273d15..ee773cb4b08ee7a44c7f7adaac925b45bd0e2483 100644
--- a/cmd/helm/load_plugins.go
+++ b/cmd/helm/load_plugins.go
@@ -25,19 +25,10 @@ import (
 
 	"github.com/spf13/cobra"
 
-	"k8s.io/helm/pkg/helm/helmpath"
+	helm_env "k8s.io/helm/pkg/helm/environment"
 	"k8s.io/helm/pkg/plugin"
 )
 
-const pluginEnvVar = "HELM_PLUGIN"
-
-func pluginDirs(home helmpath.Home) string {
-	if dirs := os.Getenv(pluginEnvVar); dirs != "" {
-		return dirs
-	}
-	return home.Plugins()
-}
-
 // loadPlugins loads plugins into the command list.
 //
 // This follows a different pattern than the other commands because it has
@@ -46,16 +37,25 @@ func pluginDirs(home helmpath.Home) string {
 func loadPlugins(baseCmd *cobra.Command, out io.Writer) {
 
 	// If HELM_NO_PLUGINS is set to 1, do not load plugins.
-	if settings.PlugDirs == "" {
+	if os.Getenv(helm_env.PluginDisableEnvVar) == "1" {
 		return
 	}
 
-	found, err := findPlugins(settings.PlugDirs)
+	found, err := findPlugins(settings.PluginDirs())
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "failed to load plugins: %s", err)
 		return
 	}
 
+	processParent := func(cmd *cobra.Command, args []string) ([]string, error) {
+		k, u := manuallyProcessArgs(args)
+		if err := cmd.Parent().ParseFlags(k); err != nil {
+			return nil, err
+		}
+		initRootFlags(cmd)
+		return u, nil
+	}
+
 	// Now we create commands for all of these.
 	for _, plug := range found {
 		plug := plug
@@ -69,9 +69,8 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) {
 			Short: md.Usage,
 			Long:  md.Description,
 			RunE: func(cmd *cobra.Command, args []string) error {
-
-				k, u := manuallyProcessArgs(args)
-				if err := cmd.Parent().ParseFlags(k); err != nil {
+				u, err := processParent(cmd, args)
+				if err != nil {
 					return err
 				}
 
@@ -99,10 +98,9 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) {
 		}
 
 		if md.UseTunnel {
-			c.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
+			c.PreRunE = func(cmd *cobra.Command, args []string) error {
 				// Parse the parent flag, but not the local flags.
-				k, _ := manuallyProcessArgs(args)
-				if err := c.Parent().ParseFlags(k); err != nil {
+				if _, err := processParent(cmd, args); err != nil {
 					return err
 				}
 				return setupConnection(cmd, args)
diff --git a/cmd/helm/package.go b/cmd/helm/package.go
index a2da2c338792eacf8a7ac8b8b77d6599ae355f9f..e5ab3643df4b11eccd4e2180e438706f5162100b 100644
--- a/cmd/helm/package.go
+++ b/cmd/helm/package.go
@@ -30,6 +30,8 @@ import (
 	"golang.org/x/crypto/ssh/terminal"
 
 	"k8s.io/helm/pkg/chartutil"
+	"k8s.io/helm/pkg/downloader"
+	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/helm/helmpath"
 	"k8s.io/helm/pkg/proto/hapi/chart"
 	"k8s.io/helm/pkg/provenance"
@@ -48,13 +50,14 @@ Versioned chart archives are used by Helm package repositories.
 `
 
 type packageCmd struct {
-	save        bool
-	sign        bool
-	path        string
-	key         string
-	keyring     string
-	version     string
-	destination string
+	save             bool
+	sign             bool
+	path             string
+	key              string
+	keyring          string
+	version          string
+	destination      string
+	dependencyUpdate bool
 
 	out  io.Writer
 	home helmpath.Home
@@ -72,7 +75,7 @@ func newPackageCmd(out io.Writer) *cobra.Command {
 		RunE: func(cmd *cobra.Command, args []string) error {
 			pkg.home = settings.Home
 			if len(args) == 0 {
-				return fmt.Errorf("This command needs at least one argument, the path to the chart.")
+				return fmt.Errorf("need at least one argument, the path to the chart")
 			}
 			if pkg.sign {
 				if pkg.key == "" {
@@ -99,6 +102,7 @@ func newPackageCmd(out io.Writer) *cobra.Command {
 	f.StringVar(&pkg.keyring, "keyring", defaultKeyring(), "location of a public keyring")
 	f.StringVar(&pkg.version, "version", "", "set the version on the chart to this semver version")
 	f.StringVarP(&pkg.destination, "destination", "d", ".", "location to write the chart.")
+	f.BoolVarP(&pkg.dependencyUpdate, "dependency-update", "u", false, `update dependencies from "requirements.yaml" to dir "charts/" before packaging`)
 
 	return cmd
 }
@@ -109,6 +113,21 @@ func (p *packageCmd) run(cmd *cobra.Command, args []string) error {
 		return err
 	}
 
+	if p.dependencyUpdate {
+		downloadManager := &downloader.Manager{
+			Out:       p.out,
+			ChartPath: path,
+			HelmHome:  settings.Home,
+			Keyring:   p.keyring,
+			Getters:   getter.All(settings),
+			Debug:     settings.Debug,
+		}
+
+		if err := downloadManager.Update(); err != nil {
+			return err
+		}
+	}
+
 	ch, err := chartutil.LoadDir(path)
 	if err != nil {
 		return err
@@ -127,7 +146,13 @@ func (p *packageCmd) run(cmd *cobra.Command, args []string) error {
 	}
 
 	if reqs, err := chartutil.LoadRequirements(ch); err == nil {
-		checkDependencies(ch, reqs, p.out)
+		if err := checkDependencies(ch, reqs, p.out); err != nil {
+			return err
+		}
+	} else {
+		if err != chartutil.ErrRequirementsNotFound {
+			return err
+		}
 	}
 
 	var dest string
@@ -144,7 +169,9 @@ func (p *packageCmd) run(cmd *cobra.Command, args []string) error {
 
 	name, err := chartutil.Save(ch, dest)
 	if err == nil {
-		debug("Saved %s to current directory\n", name)
+		fmt.Fprintf(p.out, "Successfully packaged chart and saved it to: %s\n", name)
+	} else {
+		return fmt.Errorf("Failed to save: %s", err)
 	}
 
 	// Save to $HELM_HOME/local directory. This is second, because we don't want
@@ -154,7 +181,7 @@ func (p *packageCmd) run(cmd *cobra.Command, args []string) error {
 		if err := repo.AddChartToLocalRepo(ch, lr); err != nil {
 			return err
 		}
-		debug("Saved %s to %s\n", name, lr)
+		debug("Successfully saved %s to %s\n", name, lr)
 	}
 
 	if p.sign {
diff --git a/cmd/helm/package_test.go b/cmd/helm/package_test.go
index 1d25260d4598c781695c73cebbd6695c661db856..2a0f6d9f51d1a0656c94adc077e75c06aba848ae 100644
--- a/cmd/helm/package_test.go
+++ b/cmd/helm/package_test.go
@@ -64,7 +64,7 @@ func TestPackage(t *testing.T) {
 			name:   "package without chart path",
 			args:   []string{},
 			flags:  map[string]string{},
-			expect: "This command needs at least one argument, the path to the chart.",
+			expect: "need at least one argument, the path to the chart",
 			err:    true,
 		},
 		{
@@ -118,8 +118,8 @@ func TestPackage(t *testing.T) {
 		{
 			name:    "package testdata/testcharts/chart-missing-deps",
 			args:    []string{"testdata/testcharts/chart-missing-deps"},
-			expect:  "Warning: reqsubchart2 is in requirements.yaml but not in the charts/ directory!\n",
 			hasfile: "chart-missing-deps-0.1.0.tgz",
+			err:     true,
 		},
 	}
 
diff --git a/cmd/helm/plugin.go b/cmd/helm/plugin.go
index 37d9205b789a741be918a804e004ceab2c0a5568..47e1b361cf4daa46c319fccaf195043afa800124 100644
--- a/cmd/helm/plugin.go
+++ b/cmd/helm/plugin.go
@@ -41,6 +41,7 @@ func newPluginCmd(out io.Writer) *cobra.Command {
 		newPluginInstallCmd(out),
 		newPluginListCmd(out),
 		newPluginRemoveCmd(out),
+		newPluginUpdateCmd(out),
 	)
 	return cmd
 }
diff --git a/cmd/helm/plugin_list.go b/cmd/helm/plugin_list.go
index 0bf9acbc89a2487e39aea97a2c9a7bd1bc075ca4..e7618f38a7170f4b501d7a97200a268527e5e525 100644
--- a/cmd/helm/plugin_list.go
+++ b/cmd/helm/plugin_list.go
@@ -44,11 +44,8 @@ func newPluginListCmd(out io.Writer) *cobra.Command {
 }
 
 func (pcmd *pluginListCmd) run() error {
-	plugdirs := pluginDirs(pcmd.home)
-
-	debug("pluginDirs: %s", plugdirs)
-
-	plugins, err := findPlugins(plugdirs)
+	debug("pluginDirs: %s", settings.PluginDirs())
+	plugins, err := findPlugins(settings.PluginDirs())
 	if err != nil {
 		return err
 	}
diff --git a/cmd/helm/plugin_remove.go b/cmd/helm/plugin_remove.go
index da2041f8962d1dc3524a742ac1b110fd758a9155..83bc863bf6067574f070d80ac12cd266817681d4 100644
--- a/cmd/helm/plugin_remove.go
+++ b/cmd/helm/plugin_remove.go
@@ -16,9 +16,11 @@ limitations under the License.
 package main
 
 import (
+	"errors"
 	"fmt"
 	"io"
 	"os"
+	"strings"
 
 	"k8s.io/helm/pkg/helm/helmpath"
 	"k8s.io/helm/pkg/plugin"
@@ -48,8 +50,8 @@ func newPluginRemoveCmd(out io.Writer) *cobra.Command {
 }
 
 func (pcmd *pluginRemoveCmd) complete(args []string) error {
-	if err := checkArgsLength(len(args), "plugin"); err != nil {
-		return err
+	if len(args) == 0 {
+		return errors.New("please provide plugin name to remove")
 	}
 	pcmd.names = args
 	pcmd.home = settings.Home
@@ -57,21 +59,26 @@ func (pcmd *pluginRemoveCmd) complete(args []string) error {
 }
 
 func (pcmd *pluginRemoveCmd) run() error {
-	plugdirs := pluginDirs(pcmd.home)
-	debug("loading installed plugins from %s", plugdirs)
-	plugins, err := findPlugins(plugdirs)
+	debug("loading installed plugins from %s", settings.PluginDirs())
+	plugins, err := findPlugins(settings.PluginDirs())
 	if err != nil {
 		return err
 	}
-
+	var errorPlugins []string
 	for _, name := range pcmd.names {
 		if found := findPlugin(plugins, name); found != nil {
 			if err := removePlugin(found, pcmd.home); err != nil {
-				return err
+				errorPlugins = append(errorPlugins, fmt.Sprintf("Failed to remove plugin %s, got error (%v)", name, err))
+			} else {
+				fmt.Fprintf(pcmd.out, "Removed plugin: %s\n", name)
 			}
-			fmt.Fprintf(pcmd.out, "Removed plugin: %s\n", name)
+		} else {
+			errorPlugins = append(errorPlugins, fmt.Sprintf("Plugin: %s not found", name))
 		}
 	}
+	if len(errorPlugins) > 0 {
+		return fmt.Errorf(strings.Join(errorPlugins, "\n"))
+	}
 	return nil
 }
 
diff --git a/cmd/helm/plugin_test.go b/cmd/helm/plugin_test.go
index 095de706330ffd83a1767709a572a0aa95927477..77ef00c5dae9b839cf21171a7520e806b217aa23 100644
--- a/cmd/helm/plugin_test.go
+++ b/cmd/helm/plugin_test.go
@@ -23,6 +23,7 @@ import (
 	"strings"
 	"testing"
 
+	helm_env "k8s.io/helm/pkg/helm/environment"
 	"k8s.io/helm/pkg/helm/helmpath"
 	"k8s.io/helm/pkg/plugin"
 
@@ -71,7 +72,6 @@ func TestLoadPlugins(t *testing.T) {
 		settings.Home = old
 	}()
 	hh := settings.Home
-	settings.PlugDirs = hh.Plugins()
 
 	out := bytes.NewBuffer(nil)
 	cmd := &cobra.Command{}
@@ -139,12 +139,11 @@ func TestLoadPlugins(t *testing.T) {
 func TestLoadPlugins_HelmNoPlugins(t *testing.T) {
 	// Set helm home to point to testdata
 	old := settings.Home
-	oldPlugDirs := settings.PlugDirs
 	settings.Home = "testdata/helmhome"
-	settings.PlugDirs = ""
+	os.Setenv(helm_env.PluginDisableEnvVar, "1")
 	defer func() {
 		settings.Home = old
-		settings.PlugDirs = oldPlugDirs
+		os.Unsetenv(helm_env.PluginDisableEnvVar)
 	}()
 
 	out := bytes.NewBuffer(nil)
@@ -161,7 +160,6 @@ func TestSetupEnv(t *testing.T) {
 	name := "pequod"
 	settings.Home = helmpath.Home("testdata/helmhome")
 	base := filepath.Join(settings.Home.Plugins(), name)
-	settings.PlugDirs = settings.Home.Plugins()
 	settings.Debug = true
 	defer func() {
 		settings.Debug = false
diff --git a/cmd/helm/plugin_update.go b/cmd/helm/plugin_update.go
new file mode 100644
index 0000000000000000000000000000000000000000..2e19a21755158f7d719e44dbde06daa0558e7780
--- /dev/null
+++ b/cmd/helm/plugin_update.go
@@ -0,0 +1,113 @@
+/*
+Copyright 2017 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 main
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"path/filepath"
+	"strings"
+
+	"k8s.io/helm/pkg/helm/helmpath"
+	"k8s.io/helm/pkg/plugin"
+	"k8s.io/helm/pkg/plugin/installer"
+
+	"github.com/spf13/cobra"
+)
+
+type pluginUpdateCmd struct {
+	names []string
+	home  helmpath.Home
+	out   io.Writer
+}
+
+func newPluginUpdateCmd(out io.Writer) *cobra.Command {
+	pcmd := &pluginUpdateCmd{out: out}
+	cmd := &cobra.Command{
+		Use:   "update <plugin>...",
+		Short: "update one or more Helm plugins",
+		PreRunE: func(cmd *cobra.Command, args []string) error {
+			return pcmd.complete(args)
+		},
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return pcmd.run()
+		},
+	}
+	return cmd
+}
+
+func (pcmd *pluginUpdateCmd) complete(args []string) error {
+	if len(args) == 0 {
+		return errors.New("please provide plugin name to update")
+	}
+	pcmd.names = args
+	pcmd.home = settings.Home
+	return nil
+}
+
+func (pcmd *pluginUpdateCmd) run() error {
+	installer.Debug = settings.Debug
+	debug("loading installed plugins from %s", settings.PluginDirs())
+	plugins, err := findPlugins(settings.PluginDirs())
+	if err != nil {
+		return err
+	}
+	var errorPlugins []string
+
+	for _, name := range pcmd.names {
+		if found := findPlugin(plugins, name); found != nil {
+			if err := updatePlugin(found, pcmd.home); err != nil {
+				errorPlugins = append(errorPlugins, fmt.Sprintf("Failed to update plugin %s, got error (%v)", name, err))
+			} else {
+				fmt.Fprintf(pcmd.out, "Updated plugin: %s\n", name)
+			}
+		} else {
+			errorPlugins = append(errorPlugins, fmt.Sprintf("Plugin: %s not found", name))
+		}
+	}
+	if len(errorPlugins) > 0 {
+		return fmt.Errorf(strings.Join(errorPlugins, "\n"))
+	}
+	return nil
+}
+
+func updatePlugin(p *plugin.Plugin, home helmpath.Home) error {
+	exactLocation, err := filepath.EvalSymlinks(p.Dir)
+	if err != nil {
+		return err
+	}
+	absExactLocation, err := filepath.Abs(exactLocation)
+	if err != nil {
+		return err
+	}
+
+	i, err := installer.FindSource(absExactLocation, home)
+	if err != nil {
+		return err
+	}
+	if err := installer.Update(i); err != nil {
+		return err
+	}
+
+	debug("loading plugin from %s", i.Path())
+	updatedPlugin, err := plugin.LoadDir(i.Path())
+	if err != nil {
+		return err
+	}
+
+	return runHook(updatedPlugin, plugin.Update, home)
+}
diff --git a/cmd/helm/release_testing.go b/cmd/helm/release_testing.go
index 76a8f40e3c7765cc2b0a180a6ca8380e032d8dc4..1aadd4de33823d320ddc4eda2b1d1d0616a987d9 100644
--- a/cmd/helm/release_testing.go
+++ b/cmd/helm/release_testing.go
@@ -23,6 +23,7 @@ import (
 	"github.com/spf13/cobra"
 
 	"k8s.io/helm/pkg/helm"
+	"k8s.io/helm/pkg/proto/hapi/release"
 )
 
 const releaseTestDesc = `
@@ -47,10 +48,10 @@ func newReleaseTestCmd(c helm.Interface, out io.Writer) *cobra.Command {
 	}
 
 	cmd := &cobra.Command{
-		Use:               "test [RELEASE]",
-		Short:             "test a release",
-		Long:              releaseTestDesc,
-		PersistentPreRunE: setupConnection,
+		Use:     "test [RELEASE]",
+		Short:   "test a release",
+		Long:    releaseTestDesc,
+		PreRunE: setupConnection,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			if err := checkArgsLength(len(args), "release name"); err != nil {
 				return err
@@ -75,16 +76,35 @@ func (t *releaseTestCmd) run() (err error) {
 		helm.ReleaseTestTimeout(t.timeout),
 		helm.ReleaseTestCleanup(t.cleanup),
 	)
+	testErr := &testErr{}
 
 	for {
 		select {
 		case err := <-errc:
+			if prettyError(err) == nil && testErr.failed > 0 {
+				return testErr.Error()
+			}
 			return prettyError(err)
 		case res, ok := <-c:
 			if !ok {
 				break
 			}
+
+			if res.Status == release.TestRun_FAILURE {
+				testErr.failed++
+			}
+
 			fmt.Fprintf(t.out, res.Msg+"\n")
+
 		}
 	}
+
+}
+
+type testErr struct {
+	failed int
+}
+
+func (err *testErr) Error() error {
+	return fmt.Errorf("%v test(s) failed", err.failed)
 }
diff --git a/cmd/helm/release_testing_test.go b/cmd/helm/release_testing_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..2c7a5867ac6e33672863283c3f13e6d68033e50f
--- /dev/null
+++ b/cmd/helm/release_testing_test.go
@@ -0,0 +1,105 @@
+/*
+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 main
+
+import (
+	"bytes"
+	"testing"
+
+	"k8s.io/helm/pkg/proto/hapi/release"
+)
+
+func TestReleaseTesting(t *testing.T) {
+	tests := []struct {
+		name      string
+		args      []string
+		flags     []string
+		responses map[string]release.TestRun_Status
+		fail      bool
+	}{
+		{
+			name:      "basic test",
+			args:      []string{"example-release"},
+			flags:     []string{},
+			responses: map[string]release.TestRun_Status{"PASSED: green lights everywhere": release.TestRun_SUCCESS},
+			fail:      false,
+		},
+		{
+			name:      "test failure",
+			args:      []string{"example-fail"},
+			flags:     []string{},
+			responses: map[string]release.TestRun_Status{"FAILURE: red lights everywhere": release.TestRun_FAILURE},
+			fail:      true,
+		},
+		{
+			name:      "test unknown",
+			args:      []string{"example-unknown"},
+			flags:     []string{},
+			responses: map[string]release.TestRun_Status{"UNKNOWN: yellow lights everywhere": release.TestRun_UNKNOWN},
+			fail:      false,
+		},
+		{
+			name:      "test error",
+			args:      []string{"example-error"},
+			flags:     []string{},
+			responses: map[string]release.TestRun_Status{"ERROR: yellow lights everywhere": release.TestRun_FAILURE},
+			fail:      true,
+		},
+		{
+			name:      "test running",
+			args:      []string{"example-running"},
+			flags:     []string{},
+			responses: map[string]release.TestRun_Status{"RUNNING: things are happpeningggg": release.TestRun_RUNNING},
+			fail:      false,
+		},
+		{
+			name:  "multiple tests example",
+			args:  []string{"example-suite"},
+			flags: []string{},
+			responses: map[string]release.TestRun_Status{
+				"RUNNING: things are happpeningggg":           release.TestRun_RUNNING,
+				"PASSED: party time":                          release.TestRun_SUCCESS,
+				"RUNNING: things are happening again":         release.TestRun_RUNNING,
+				"FAILURE: good thing u checked :)":            release.TestRun_FAILURE,
+				"RUNNING: things are happpeningggg yet again": release.TestRun_RUNNING,
+				"PASSED: feel free to party again":            release.TestRun_SUCCESS},
+			fail: true,
+		},
+	}
+
+	for _, tt := range tests {
+		c := &fakeReleaseClient{responses: tt.responses}
+
+		buf := bytes.NewBuffer(nil)
+		cmd := newReleaseTestCmd(c, buf)
+		cmd.ParseFlags(tt.flags)
+
+		err := cmd.RunE(cmd, tt.args)
+		if err == nil && tt.fail {
+			t.Errorf("%q did not fail but should have failed", tt.name)
+		}
+
+		if err != nil {
+			if tt.fail {
+				continue
+			} else {
+				t.Errorf("%q reported error: %s", tt.name, err)
+			}
+		}
+
+	}
+}
diff --git a/cmd/helm/repo_add.go b/cmd/helm/repo_add.go
index 92bf61107edbe9149066b238ce831166c34586e6..1bdbfddb17c0d318c19199fc2009030fd975283d 100644
--- a/cmd/helm/repo_add.go
+++ b/cmd/helm/repo_add.go
@@ -22,7 +22,7 @@ import (
 
 	"github.com/spf13/cobra"
 
-	"k8s.io/helm/pkg/getter/defaultgetters"
+	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/helm/helmpath"
 	"k8s.io/helm/pkg/repo"
 )
@@ -85,7 +85,7 @@ func addRepository(name, url string, home helmpath.Home, certFile, keyFile, caFi
 	}
 
 	if noUpdate && f.Has(name) {
-		return fmt.Errorf("The repository name you provided (%s) already exists. Please specify a different name.", name)
+		return fmt.Errorf("repository name (%s) already exists, please specify a different name", name)
 	}
 
 	cif := home.CacheIndex(name)
@@ -98,7 +98,7 @@ func addRepository(name, url string, home helmpath.Home, certFile, keyFile, caFi
 		CAFile:   caFile,
 	}
 
-	r, err := repo.NewChartRepository(&c, defaultgetters.Get(settings))
+	r, err := repo.NewChartRepository(&c, getter.All(settings))
 	if err != nil {
 		return err
 	}
diff --git a/cmd/helm/repo_update.go b/cmd/helm/repo_update.go
index d45633497da4fb5d74b2bc3d3b1e415df31db693..5e710a26738758bb6f7fff82bb610ec262e89ec4 100644
--- a/cmd/helm/repo_update.go
+++ b/cmd/helm/repo_update.go
@@ -24,7 +24,7 @@ import (
 
 	"github.com/spf13/cobra"
 
-	"k8s.io/helm/pkg/getter/defaultgetters"
+	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/helm/helmpath"
 	"k8s.io/helm/pkg/repo"
 )
@@ -55,7 +55,7 @@ func newRepoUpdateCmd(out io.Writer) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:     "update",
 		Aliases: []string{"up"},
-		Short:   "update information on available charts in the chart repositories",
+		Short:   "update information of available charts locally from chart repositories",
 		Long:    updateDesc,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			u.home = settings.Home
@@ -76,7 +76,7 @@ func (u *repoUpdateCmd) run() error {
 	}
 	var repos []*repo.ChartRepository
 	for _, cfg := range f.Repositories {
-		r, err := repo.NewChartRepository(cfg, defaultgetters.Get(settings))
+		r, err := repo.NewChartRepository(cfg, getter.All(settings))
 		if err != nil {
 			return err
 		}
diff --git a/cmd/helm/repo_update_test.go b/cmd/helm/repo_update_test.go
index ecd23543d06008e38538264b30cccdf108c0cbe3..17eaed60b3320f4015b93c2ca4e47fa9e042cb5f 100644
--- a/cmd/helm/repo_update_test.go
+++ b/cmd/helm/repo_update_test.go
@@ -23,7 +23,7 @@ import (
 	"strings"
 	"testing"
 
-	"k8s.io/helm/pkg/getter/defaultgetters"
+	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/helm/helmpath"
 	"k8s.io/helm/pkg/repo"
 	"k8s.io/helm/pkg/repo/repotest"
@@ -85,7 +85,7 @@ func TestUpdateCharts(t *testing.T) {
 		Name:  "charts",
 		URL:   ts.URL(),
 		Cache: hh.CacheIndex("charts"),
-	}, defaultgetters.Get(settings))
+	}, getter.All(settings))
 	if err != nil {
 		t.Error(err)
 	}
diff --git a/cmd/helm/reset.go b/cmd/helm/reset.go
index c37e3d6874afbeb3a846ab77d26e4481ab7bf1b5..7e040ca9e69c4f2ee4457287edb7d7faa616e853 100644
--- a/cmd/helm/reset.go
+++ b/cmd/helm/reset.go
@@ -54,10 +54,15 @@ func newResetCmd(client helm.Interface, out io.Writer) *cobra.Command {
 	}
 
 	cmd := &cobra.Command{
-		Use:               "reset",
-		Short:             "uninstalls Tiller from a cluster",
-		Long:              resetDesc,
-		PersistentPreRunE: setupConnection,
+		Use:   "reset",
+		Short: "uninstalls Tiller from a cluster",
+		Long:  resetDesc,
+		PreRunE: func(cmd *cobra.Command, args []string) error {
+			if err := setupConnection(cmd, args); !d.force && err != nil {
+				return err
+			}
+			return nil
+		},
 		RunE: func(cmd *cobra.Command, args []string) error {
 			if len(args) != 0 {
 				return errors.New("This command does not accept arguments")
@@ -72,7 +77,7 @@ func newResetCmd(client helm.Interface, out io.Writer) *cobra.Command {
 	}
 
 	f := cmd.Flags()
-	f.BoolVarP(&d.force, "force", "f", false, "forces Tiller uninstall even if there are releases installed")
+	f.BoolVarP(&d.force, "force", "f", false, "forces Tiller uninstall even if there are releases installed, or if tiller is not in ready state")
 	f.BoolVar(&d.removeHelmHome, "remove-helm-home", false, "if set deletes $HELM_HOME")
 
 	return cmd
@@ -91,12 +96,12 @@ func (d *resetCmd) run() error {
 	res, err := d.client.ListReleases(
 		helm.ReleaseListStatuses([]release.Status_Code{release.Status_DEPLOYED}),
 	)
-	if err != nil {
+	if !d.force && err != nil {
 		return prettyError(err)
 	}
 
-	if len(res.Releases) > 0 && !d.force {
-		return fmt.Errorf("There are still %d deployed releases (Tip: use --force).", len(res.Releases))
+	if !d.force && res != nil && len(res.Releases) > 0 {
+		return fmt.Errorf("there are still %d deployed releases (Tip: use --force)", len(res.Releases))
 	}
 
 	if err := installer.Uninstall(d.kubeClient, &installer.Options{Namespace: d.namespace}); err != nil {
diff --git a/cmd/helm/reset_test.go b/cmd/helm/reset_test.go
index 855b4c5bd16e35f5c11cee8a85866cee248f8649..5df8f2234808f17e52223ed08a8338c767bad9bc 100644
--- a/cmd/helm/reset_test.go
+++ b/cmd/helm/reset_test.go
@@ -120,7 +120,7 @@ func TestReset_deployedReleases(t *testing.T) {
 		namespace:  api.NamespaceDefault,
 	}
 	err = cmd.run()
-	expected := "There are still 1 deployed releases (Tip: use --force)"
+	expected := "there are still 1 deployed releases (Tip: use --force)"
 	if !strings.Contains(err.Error(), expected) {
 		t.Errorf("unexpected error: %v", err)
 	}
diff --git a/cmd/helm/rollback.go b/cmd/helm/rollback.go
index bcc780c1d4bb03027794766294d65b0d1479eef5..95c27e2a5f23484347fd892ab80d9b7558a7f8ec 100644
--- a/cmd/helm/rollback.go
+++ b/cmd/helm/rollback.go
@@ -30,7 +30,7 @@ const rollbackDesc = `
 This command rolls back a release to a previous revision.
 
 The first argument of the rollback command is the name of a release, and the
-second is a revision (version) number. To see revision numbers, run 
+second is a revision (version) number. To see revision numbers, run
 'helm history RELEASE'.
 `
 
@@ -39,6 +39,7 @@ type rollbackCmd struct {
 	revision     int32
 	dryRun       bool
 	recreate     bool
+	force        bool
 	disableHooks bool
 	out          io.Writer
 	client       helm.Interface
@@ -53,10 +54,10 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
 	}
 
 	cmd := &cobra.Command{
-		Use:               "rollback [flags] [RELEASE] [REVISION]",
-		Short:             "roll back a release to a previous revision",
-		Long:              rollbackDesc,
-		PersistentPreRunE: setupConnection,
+		Use:     "rollback [flags] [RELEASE] [REVISION]",
+		Short:   "roll back a release to a previous revision",
+		Long:    rollbackDesc,
+		PreRunE: setupConnection,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			if err := checkArgsLength(len(args), "release name", "revision number"); err != nil {
 				return err
@@ -78,6 +79,7 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
 	f := cmd.Flags()
 	f.BoolVar(&rollback.dryRun, "dry-run", false, "simulate a rollback")
 	f.BoolVar(&rollback.recreate, "recreate-pods", false, "performs pods restart for the resource if applicable")
+	f.BoolVar(&rollback.force, "force", false, "force resource update through delete/recreate if needed")
 	f.BoolVar(&rollback.disableHooks, "no-hooks", false, "prevent hooks from running during rollback")
 	f.Int64Var(&rollback.timeout, "timeout", 300, "time in seconds to wait for any individual kubernetes operation (like Jobs for hooks)")
 	f.BoolVar(&rollback.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
@@ -90,6 +92,7 @@ func (r *rollbackCmd) run() error {
 		r.name,
 		helm.RollbackDryRun(r.dryRun),
 		helm.RollbackRecreate(r.recreate),
+		helm.RollbackForce(r.force),
 		helm.RollbackDisableHooks(r.disableHooks),
 		helm.RollbackVersion(r.revision),
 		helm.RollbackTimeout(r.timeout),
diff --git a/cmd/helm/serve.go b/cmd/helm/serve.go
index 028af9751d5a06edaecf9162dffb19b00af581f5..1c9a772fea148b98d8f695dc1cde41622bc5563a 100644
--- a/cmd/helm/serve.go
+++ b/cmd/helm/serve.go
@@ -55,19 +55,29 @@ func newServeCmd(out io.Writer) *cobra.Command {
 		Use:   "serve",
 		Short: "start a local http web server",
 		Long:  serveDesc,
+		PreRunE: func(cmd *cobra.Command, args []string) error {
+			return srv.complete(args)
+		},
 		RunE: func(cmd *cobra.Command, args []string) error {
 			return srv.run()
 		},
 	}
 
 	f := cmd.Flags()
-	f.StringVar(&srv.repoPath, "repo-path", settings.Home.LocalRepository(), "local directory path from which to serve charts")
+	f.StringVar(&srv.repoPath, "repo-path", "", "local directory path from which to serve charts")
 	f.StringVar(&srv.address, "address", "127.0.0.1:8879", "address to listen on")
 	f.StringVar(&srv.url, "url", "", "external URL of chart repository")
 
 	return cmd
 }
 
+func (s *serveCmd) complete(args []string) error {
+	if s.repoPath == "" {
+		s.repoPath = settings.Home.LocalRepository()
+	}
+	return nil
+}
+
 func (s *serveCmd) run() error {
 	repoPath, err := filepath.Abs(s.repoPath)
 	if err != nil {
diff --git a/cmd/helm/status.go b/cmd/helm/status.go
index b635e618608ea8560e47f259293432b9c1e00ca9..36269c4b1f58fafcac7ca459f3dc045377ece291 100644
--- a/cmd/helm/status.go
+++ b/cmd/helm/status.go
@@ -57,10 +57,10 @@ func newStatusCmd(client helm.Interface, out io.Writer) *cobra.Command {
 	}
 
 	cmd := &cobra.Command{
-		Use:               "status [flags] RELEASE_NAME",
-		Short:             "displays the status of the named release",
-		Long:              statusHelp,
-		PersistentPreRunE: setupConnection,
+		Use:     "status [flags] RELEASE_NAME",
+		Short:   "displays the status of the named release",
+		Long:    statusHelp,
+		PreRunE: setupConnection,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			if len(args) == 0 {
 				return errReleaseRequired
diff --git a/cmd/helm/testdata/testcharts/chart-bad-requirements/.helmignore b/cmd/helm/testdata/testcharts/chart-bad-requirements/.helmignore
new file mode 100644
index 0000000000000000000000000000000000000000..f0c13194444163d1cba5c67d9e79231a62bc8f44
--- /dev/null
+++ b/cmd/helm/testdata/testcharts/chart-bad-requirements/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/cmd/helm/testdata/testcharts/chart-bad-requirements/Chart.yaml b/cmd/helm/testdata/testcharts/chart-bad-requirements/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..02be4c013bec0891fe2bb4df00870dfd27ae4386
--- /dev/null
+++ b/cmd/helm/testdata/testcharts/chart-bad-requirements/Chart.yaml
@@ -0,0 +1,3 @@
+description: A Helm chart for Kubernetes
+name: chart-missing-deps
+version: 0.1.0
diff --git a/cmd/helm/testdata/testcharts/chart-bad-requirements/charts/reqsubchart/.helmignore b/cmd/helm/testdata/testcharts/chart-bad-requirements/charts/reqsubchart/.helmignore
new file mode 100644
index 0000000000000000000000000000000000000000..f0c13194444163d1cba5c67d9e79231a62bc8f44
--- /dev/null
+++ b/cmd/helm/testdata/testcharts/chart-bad-requirements/charts/reqsubchart/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/cmd/helm/testdata/testcharts/chart-bad-requirements/charts/reqsubchart/Chart.yaml b/cmd/helm/testdata/testcharts/chart-bad-requirements/charts/reqsubchart/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c3813bc8c2fb54286fdb6ac8076d6f0f0d8ad100
--- /dev/null
+++ b/cmd/helm/testdata/testcharts/chart-bad-requirements/charts/reqsubchart/Chart.yaml
@@ -0,0 +1,3 @@
+description: A Helm chart for Kubernetes
+name: reqsubchart
+version: 0.1.0
diff --git a/cmd/helm/testdata/testcharts/chart-bad-requirements/charts/reqsubchart/values.yaml b/cmd/helm/testdata/testcharts/chart-bad-requirements/charts/reqsubchart/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0f0b63f2aab46ccbbef5985816bb9d514fc4a3ff
--- /dev/null
+++ b/cmd/helm/testdata/testcharts/chart-bad-requirements/charts/reqsubchart/values.yaml
@@ -0,0 +1,4 @@
+# Default values for reqsubchart.
+# This is a YAML-formatted file.
+# Declare name/value pairs to be passed into your templates.
+# name: value
diff --git a/cmd/helm/testdata/testcharts/chart-bad-requirements/requirements.yaml b/cmd/helm/testdata/testcharts/chart-bad-requirements/requirements.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..10c4d6dcbf386bb20e22c9b3544573d7cc39c6ef
--- /dev/null
+++ b/cmd/helm/testdata/testcharts/chart-bad-requirements/requirements.yaml
@@ -0,0 +1,4 @@
+dependencies:
+  - name: reqsubchart
+  version: 0.1.0
+  repository: "https://example.com/charts"
diff --git a/cmd/helm/testdata/testcharts/chart-bad-requirements/values.yaml b/cmd/helm/testdata/testcharts/chart-bad-requirements/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d57f76b0729ccf05c30e231baafa5e1c1819ea01
--- /dev/null
+++ b/cmd/helm/testdata/testcharts/chart-bad-requirements/values.yaml
@@ -0,0 +1,4 @@
+# Default values for reqtest.
+# This is a YAML-formatted file.
+# Declare name/value pairs to be passed into your templates.
+# name: value
diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go
index ea8d667a176b7334c7f1fe54a726f28d6d604a2b..3be680a9f5f030c2e0c2d0970692bd63d36f889e 100644
--- a/cmd/helm/upgrade.go
+++ b/cmd/helm/upgrade.go
@@ -62,6 +62,7 @@ type upgradeCmd struct {
 	client       helm.Interface
 	dryRun       bool
 	recreate     bool
+	force        bool
 	disableHooks bool
 	valueFiles   valueFiles
 	values       []string
@@ -74,6 +75,12 @@ type upgradeCmd struct {
 	resetValues  bool
 	reuseValues  bool
 	wait         bool
+	repoURL      string
+	devel        bool
+
+	certFile string
+	keyFile  string
+	caFile   string
 }
 
 func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
@@ -84,15 +91,20 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
 	}
 
 	cmd := &cobra.Command{
-		Use:               "upgrade [RELEASE] [CHART]",
-		Short:             "upgrade a release",
-		Long:              upgradeDesc,
-		PersistentPreRunE: setupConnection,
+		Use:     "upgrade [RELEASE] [CHART]",
+		Short:   "upgrade a release",
+		Long:    upgradeDesc,
+		PreRunE: setupConnection,
 		RunE: func(cmd *cobra.Command, args []string) error {
 			if err := checkArgsLength(len(args), "release name", "chart path"); err != nil {
 				return err
 			}
 
+			if upgrade.version == "" && upgrade.devel {
+				debug("setting version to >0.0.0-a")
+				upgrade.version = ">0.0.0-a"
+			}
+
 			upgrade.release = args[0]
 			upgrade.chart = args[1]
 			upgrade.client = ensureHelmClient(upgrade.client)
@@ -105,6 +117,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
 	f.VarP(&upgrade.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
 	f.BoolVar(&upgrade.dryRun, "dry-run", false, "simulate an upgrade")
 	f.BoolVar(&upgrade.recreate, "recreate-pods", false, "performs pods restart for the resource if applicable")
+	f.BoolVar(&upgrade.force, "force", false, "force resource update through delete/recreate if needed")
 	f.StringArrayVar(&upgrade.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
 	f.BoolVar(&upgrade.disableHooks, "disable-hooks", false, "disable pre/post upgrade hooks. DEPRECATED. Use no-hooks")
 	f.BoolVar(&upgrade.disableHooks, "no-hooks", false, "disable pre/post upgrade hooks")
@@ -117,6 +130,11 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
 	f.BoolVar(&upgrade.resetValues, "reset-values", false, "when upgrading, reset the values to the ones built into the chart")
 	f.BoolVar(&upgrade.reuseValues, "reuse-values", false, "when upgrading, reuse the last release's values, and merge in any new values. If '--reset-values' is specified, this is ignored.")
 	f.BoolVar(&upgrade.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
+	f.StringVar(&upgrade.repoURL, "repo", "", "chart repository url where to locate the requested chart")
+	f.StringVar(&upgrade.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
+	f.StringVar(&upgrade.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
+	f.StringVar(&upgrade.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
+	f.BoolVar(&upgrade.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-a'. If --version is set, this is ignored.")
 
 	f.MarkDeprecated("disable-hooks", "use --no-hooks instead")
 
@@ -124,7 +142,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
 }
 
 func (u *upgradeCmd) run() error {
-	chartPath, err := locateChartPath(u.chart, u.version, u.verify, u.keyring)
+	chartPath, err := locateChartPath(u.repoURL, u.chart, u.version, u.verify, u.keyring, u.certFile, u.keyFile, u.caFile)
 	if err != nil {
 		return err
 	}
@@ -166,8 +184,14 @@ func (u *upgradeCmd) run() error {
 	// Check chart requirements to make sure all dependencies are present in /charts
 	if ch, err := chartutil.Load(chartPath); err == nil {
 		if req, err := chartutil.LoadRequirements(ch); err == nil {
-			checkDependencies(ch, req, u.out)
+			if err := checkDependencies(ch, req, u.out); err != nil {
+				return err
+			}
+		} else if err != chartutil.ErrRequirementsNotFound {
+			return fmt.Errorf("cannot load requirements: %v", err)
 		}
+	} else {
+		return prettyError(err)
 	}
 
 	resp, err := u.client.UpdateRelease(
@@ -176,6 +200,7 @@ func (u *upgradeCmd) run() error {
 		helm.UpdateValueOverrides(rawVals),
 		helm.UpgradeDryRun(u.dryRun),
 		helm.UpgradeRecreate(u.recreate),
+		helm.UpgradeForce(u.force),
 		helm.UpgradeDisableHooks(u.disableHooks),
 		helm.UpgradeTimeout(u.timeout),
 		helm.ResetValues(u.resetValues),
diff --git a/cmd/helm/upgrade_test.go b/cmd/helm/upgrade_test.go
index a913016e210fd206669209c59f0bb763012d0e81..d9bff45bba8512b91677e319758df095b48d12f1 100644
--- a/cmd/helm/upgrade_test.go
+++ b/cmd/helm/upgrade_test.go
@@ -82,6 +82,7 @@ func TestUpgradeCmd(t *testing.T) {
 
 	originalDepsPath := filepath.Join("testdata/testcharts/reqtest")
 	missingDepsPath := filepath.Join("testdata/testcharts/chart-missing-deps")
+	badDepsPath := filepath.Join("testdata/testcharts/chart-bad-requirements")
 	var ch3 *chart.Chart
 	ch3, err = chartutil.Load(originalDepsPath)
 	if err != nil {
@@ -138,10 +139,16 @@ func TestUpgradeCmd(t *testing.T) {
 			expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n",
 		},
 		{
-			name:     "upgrade a release with missing dependencies",
-			args:     []string{"bonkers-bunny", missingDepsPath},
-			resp:     releaseMock(&releaseOptions{name: "bonkers-bunny", version: 1, chart: ch3}),
-			expected: "Warning: reqsubchart2 is in requirements.yaml but not in the charts/ directory!",
+			name: "upgrade a release with missing dependencies",
+			args: []string{"bonkers-bunny", missingDepsPath},
+			resp: releaseMock(&releaseOptions{name: "bonkers-bunny", version: 1, chart: ch3}),
+			err:  true,
+		},
+		{
+			name: "upgrade a release with bad dependencies",
+			args: []string{"bonkers-bunny", badDepsPath},
+			resp: releaseMock(&releaseOptions{name: "bonkers-bunny", version: 1, chart: ch3}),
+			err:  true,
 		},
 	}
 
diff --git a/cmd/rudder/rudder.go b/cmd/rudder/rudder.go
new file mode 100644
index 0000000000000000000000000000000000000000..e1ba4736a2771c95069463205115ab86a41d0c95
--- /dev/null
+++ b/cmd/rudder/rudder.go
@@ -0,0 +1,139 @@
+/*
+Copyright 2017 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 main
+
+import (
+	"bytes"
+	"fmt"
+	"net"
+
+	"golang.org/x/net/context"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/grpclog"
+	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
+
+	"k8s.io/helm/pkg/kube"
+	rudderAPI "k8s.io/helm/pkg/proto/hapi/rudder"
+	"k8s.io/helm/pkg/rudder"
+	"k8s.io/helm/pkg/tiller"
+	"k8s.io/helm/pkg/version"
+)
+
+var kubeClient *kube.Client
+var clientset internalclientset.Interface
+
+func main() {
+	var err error
+	kubeClient = kube.New(nil)
+	clientset, err = kubeClient.ClientSet()
+	if err != nil {
+		grpclog.Fatalf("Cannot initialize Kubernetes connection: %s", err)
+	}
+
+	lis, err := net.Listen("tcp", fmt.Sprintf(":%d", rudder.GrpcPort))
+	if err != nil {
+		grpclog.Fatalf("failed to listen: %v", err)
+	}
+	grpcServer := grpc.NewServer()
+	rudderAPI.RegisterReleaseModuleServiceServer(grpcServer, &ReleaseModuleServiceServer{})
+
+	grpclog.Print("Server starting")
+	grpcServer.Serve(lis)
+	grpclog.Print("Server started")
+}
+
+// ReleaseModuleServiceServer provides implementation for rudderAPI.ReleaseModuleServiceServer
+type ReleaseModuleServiceServer struct{}
+
+// Version returns Rudder version based on helm version
+func (r *ReleaseModuleServiceServer) Version(ctx context.Context, in *rudderAPI.VersionReleaseRequest) (*rudderAPI.VersionReleaseResponse, error) {
+	grpclog.Print("version")
+	return &rudderAPI.VersionReleaseResponse{
+		Name:    "helm-rudder-native",
+		Version: version.Version,
+	}, nil
+}
+
+// InstallRelease creates a release using kubeClient.Create
+func (r *ReleaseModuleServiceServer) InstallRelease(ctx context.Context, in *rudderAPI.InstallReleaseRequest) (*rudderAPI.InstallReleaseResponse, error) {
+	grpclog.Print("install")
+	b := bytes.NewBufferString(in.Release.Manifest)
+	err := kubeClient.Create(in.Release.Namespace, b, 500, false)
+	if err != nil {
+		grpclog.Printf("error when creating release: %v", err)
+	}
+	return &rudderAPI.InstallReleaseResponse{}, err
+}
+
+// DeleteRelease deletes a provided release
+func (r *ReleaseModuleServiceServer) DeleteRelease(ctx context.Context, in *rudderAPI.DeleteReleaseRequest) (*rudderAPI.DeleteReleaseResponse, error) {
+	grpclog.Print("delete")
+
+	resp := &rudderAPI.DeleteReleaseResponse{}
+	rel := in.Release
+	vs, err := tiller.GetVersionSet(clientset.Discovery())
+	if err != nil {
+		return resp, fmt.Errorf("Could not get apiVersions from Kubernetes: %v", err)
+	}
+
+	kept, errs := tiller.DeleteRelease(rel, vs, kubeClient)
+	rel.Manifest = kept
+
+	allErrors := ""
+	for _, e := range errs {
+		allErrors = allErrors + "\n" + e.Error()
+	}
+
+	if len(allErrors) > 0 {
+		err = fmt.Errorf(allErrors)
+	}
+
+	return &rudderAPI.DeleteReleaseResponse{
+		Release: rel,
+	}, err
+}
+
+// RollbackRelease rolls back the release
+func (r *ReleaseModuleServiceServer) RollbackRelease(ctx context.Context, in *rudderAPI.RollbackReleaseRequest) (*rudderAPI.RollbackReleaseResponse, error) {
+	grpclog.Print("rollback")
+	c := bytes.NewBufferString(in.Current.Manifest)
+	t := bytes.NewBufferString(in.Target.Manifest)
+	err := kubeClient.Update(in.Target.Namespace, c, t, in.Force, in.Recreate, in.Timeout, in.Wait)
+	return &rudderAPI.RollbackReleaseResponse{}, err
+}
+
+// UpgradeRelease upgrades manifests using kubernetes client
+func (r *ReleaseModuleServiceServer) UpgradeRelease(ctx context.Context, in *rudderAPI.UpgradeReleaseRequest) (*rudderAPI.UpgradeReleaseResponse, error) {
+	grpclog.Print("upgrade")
+	c := bytes.NewBufferString(in.Current.Manifest)
+	t := bytes.NewBufferString(in.Target.Manifest)
+	err := kubeClient.Update(in.Target.Namespace, c, t, in.Force, in.Recreate, in.Timeout, in.Wait)
+	// upgrade response object should be changed to include status
+	return &rudderAPI.UpgradeReleaseResponse{}, err
+}
+
+// ReleaseStatus retrieves release status
+func (r *ReleaseModuleServiceServer) ReleaseStatus(ctx context.Context, in *rudderAPI.ReleaseStatusRequest) (*rudderAPI.ReleaseStatusResponse, error) {
+	grpclog.Print("status")
+
+	resp, err := kubeClient.Get(in.Release.Namespace, bytes.NewBufferString(in.Release.Manifest))
+	in.Release.Info.Status.Resources = resp
+	return &rudderAPI.ReleaseStatusResponse{
+		Release: in.Release,
+		Info:    in.Release.Info,
+	}, err
+}
diff --git a/cmd/tiller/tiller.go b/cmd/tiller/tiller.go
index 2f193936e906713c861579a14688ab60fd9f6132..6abd35ec92cdf1a0432345c456ee799eb7cff663 100644
--- a/cmd/tiller/tiller.go
+++ b/cmd/tiller/tiller.go
@@ -29,6 +29,7 @@ import (
 
 	goprom "github.com/grpc-ecosystem/go-grpc-prometheus"
 	"github.com/spf13/cobra"
+	"github.com/spf13/pflag"
 
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials"
@@ -69,12 +70,15 @@ var rootServer *grpc.Server
 // Any changes to env should be done before rootServer.Serve() is called.
 var env = environment.New()
 
+var logger *log.Logger
+
 var (
-	grpcAddr      = ":44134"
-	probeAddr     = ":44135"
-	traceAddr     = ":44136"
-	enableTracing = false
-	store         = storageConfigMap
+	grpcAddr             = ":44134"
+	probeAddr            = ":44135"
+	traceAddr            = ":44136"
+	enableTracing        = false
+	store                = storageConfigMap
+	remoteReleaseModules = false
 )
 
 var (
@@ -92,63 +96,83 @@ Tiller is the server for Helm. It provides in-cluster resource management.
 By default, Tiller listens for gRPC connections on port 44134.
 `
 
-var rootCommand = &cobra.Command{
-	Use:   "tiller",
-	Short: "The Kubernetes Helm server.",
-	Long:  globalUsage,
-	Run:   start,
+func addFlags(flags *pflag.FlagSet) {
+	flags.StringVarP(&grpcAddr, "listen", "l", ":44134", "address:port to listen on")
+	flags.StringVar(&store, "storage", storageConfigMap, "storage driver to use. One of 'configmap' or 'memory'")
+	flags.BoolVar(&enableTracing, "trace", false, "enable rpc tracing")
+	flags.BoolVar(&remoteReleaseModules, "experimental-release", false, "enable experimental release modules")
+
+	flags.BoolVar(&tlsEnable, "tls", tlsEnableEnvVarDefault(), "enable TLS")
+	flags.BoolVar(&tlsVerify, "tls-verify", tlsVerifyEnvVarDefault(), "enable TLS and verify remote certificate")
+	flags.StringVar(&keyFile, "tls-key", tlsDefaultsFromEnv("tls-key"), "path to TLS private key file")
+	flags.StringVar(&certFile, "tls-cert", tlsDefaultsFromEnv("tls-cert"), "path to TLS certificate file")
+	flags.StringVar(&caCertFile, "tls-ca-cert", tlsDefaultsFromEnv("tls-ca-cert"), "trust certificates signed by this CA")
 }
 
-func init() {
-	log.SetFlags(log.Flags() | log.Lshortfile)
+func initLog() {
+	if enableTracing {
+		log.SetFlags(log.Lshortfile)
+	}
+	logger = newLogger("main")
 }
 
 func main() {
-	p := rootCommand.PersistentFlags()
-	p.StringVarP(&grpcAddr, "listen", "l", ":44134", "address:port to listen on")
-	p.StringVar(&store, "storage", storageConfigMap, "storage driver to use. One of 'configmap' or 'memory'")
-	p.BoolVar(&enableTracing, "trace", false, "enable rpc tracing")
-
-	p.BoolVar(&tlsEnable, "tls", tlsEnableEnvVarDefault(), "enable TLS")
-	p.BoolVar(&tlsVerify, "tls-verify", tlsVerifyEnvVarDefault(), "enable TLS and verify remote certificate")
-	p.StringVar(&keyFile, "tls-key", tlsDefaultsFromEnv("tls-key"), "path to TLS private key file")
-	p.StringVar(&certFile, "tls-cert", tlsDefaultsFromEnv("tls-cert"), "path to TLS certificate file")
-	p.StringVar(&caCertFile, "tls-ca-cert", tlsDefaultsFromEnv("tls-ca-cert"), "trust certificates signed by this CA")
-
-	if err := rootCommand.Execute(); err != nil {
-		fmt.Fprint(os.Stderr, err)
-		os.Exit(1)
+	root := &cobra.Command{
+		Use:   "tiller",
+		Short: "The Kubernetes Helm server.",
+		Long:  globalUsage,
+		Run:   start,
+		PreRun: func(_ *cobra.Command, _ []string) {
+			initLog()
+		},
+	}
+	addFlags(root.Flags())
+
+	if err := root.Execute(); err != nil {
+		logger.Fatal(err)
 	}
 }
 
+func newLogger(prefix string) *log.Logger {
+	if len(prefix) > 0 {
+		prefix = fmt.Sprintf("[%s] ", prefix)
+	}
+	return log.New(os.Stderr, prefix, log.Flags())
+}
+
 func start(c *cobra.Command, args []string) {
 	clientset, err := kube.New(nil).ClientSet()
 	if err != nil {
-		fmt.Fprintf(os.Stderr, "Cannot initialize Kubernetes connection: %s\n", err)
-		os.Exit(1)
+		logger.Fatalf("Cannot initialize Kubernetes connection: %s", err)
 	}
 
 	switch store {
 	case storageMemory:
 		env.Releases = storage.Init(driver.NewMemory())
 	case storageConfigMap:
-		env.Releases = storage.Init(driver.NewConfigMaps(clientset.Core().ConfigMaps(namespace())))
+		cfgmaps := driver.NewConfigMaps(clientset.Core().ConfigMaps(namespace()))
+		cfgmaps.Log = newLogger("storage/driver").Printf
+
+		env.Releases = storage.Init(cfgmaps)
+		env.Releases.Log = newLogger("storage").Printf
 	}
 
+	kubeClient := kube.New(nil)
+	kubeClient.Log = newLogger("kube").Printf
+	env.KubeClient = kubeClient
+
 	if tlsEnable || tlsVerify {
 		opts := tlsutil.Options{CertFile: certFile, KeyFile: keyFile}
 		if tlsVerify {
 			opts.CaCertFile = caCertFile
 		}
-
 	}
 
 	var opts []grpc.ServerOption
 	if tlsEnable || tlsVerify {
 		cfg, err := tlsutil.ServerConfig(tlsOptions())
 		if err != nil {
-			fmt.Fprintf(os.Stderr, "Could not create server TLS configuration: %v\n", err)
-			os.Exit(1)
+			logger.Fatalf("Could not create server TLS configuration: %v", err)
 		}
 		opts = append(opts, grpc.Creds(credentials.NewTLS(cfg)))
 	}
@@ -157,14 +181,13 @@ func start(c *cobra.Command, args []string) {
 
 	lstn, err := net.Listen("tcp", grpcAddr)
 	if err != nil {
-		fmt.Fprintf(os.Stderr, "Server died: %s\n", err)
-		os.Exit(1)
+		logger.Fatalf("Server died: %s", err)
 	}
 
-	fmt.Printf("Starting Tiller %s (tls=%t)\n", version.GetVersion(), tlsEnable || tlsVerify)
-	fmt.Printf("GRPC listening on %s\n", grpcAddr)
-	fmt.Printf("Probes listening on %s\n", probeAddr)
-	fmt.Printf("Storage driver is %s\n", env.Releases.Name())
+	logger.Printf("Starting Tiller %s (tls=%t)", version.GetVersion(), tlsEnable || tlsVerify)
+	logger.Printf("GRPC listening on %s", grpcAddr)
+	logger.Printf("Probes listening on %s", probeAddr)
+	logger.Printf("Storage driver is %s", env.Releases.Name())
 
 	if enableTracing {
 		startTracing(traceAddr)
@@ -173,7 +196,8 @@ func start(c *cobra.Command, args []string) {
 	srvErrCh := make(chan error)
 	probeErrCh := make(chan error)
 	go func() {
-		svc := tiller.NewReleaseServer(env, clientset)
+		svc := tiller.NewReleaseServer(env, clientset, remoteReleaseModules)
+		svc.Log = newLogger("tiller").Printf
 		services.RegisterReleaseServiceServer(rootServer, svc)
 		if err := rootServer.Serve(lstn); err != nil {
 			srvErrCh <- err
@@ -194,10 +218,9 @@ func start(c *cobra.Command, args []string) {
 
 	select {
 	case err := <-srvErrCh:
-		fmt.Fprintf(os.Stderr, "Server died: %s\n", err)
-		os.Exit(1)
+		logger.Fatalf("Server died: %s", err)
 	case err := <-probeErrCh:
-		fmt.Fprintf(os.Stderr, "Probes server died: %s\n", err)
+		logger.Printf("Probes server died: %s", err)
 	}
 }
 
diff --git a/cmd/tiller/trace.go b/cmd/tiller/trace.go
index b9e0583f2f47082acec6644e8bc48e02de009569..71d7e8f7268a4ddf5697813be095a40e9af88f6f 100644
--- a/cmd/tiller/trace.go
+++ b/cmd/tiller/trace.go
@@ -17,8 +17,6 @@ limitations under the License.
 package main // import "k8s.io/helm/cmd/tiller"
 
 import (
-	"fmt"
-	"log"
 	"net/http"
 
 	_ "net/http/pprof"
@@ -27,7 +25,7 @@ import (
 )
 
 func startTracing(addr string) {
-	fmt.Printf("Tracing server is listening on %s\n", addr)
+	logger.Printf("Tracing server is listening on %s\n", addr)
 	grpc.EnableTracing = true
 
 	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
@@ -41,7 +39,7 @@ func startTracing(addr string) {
 
 	go func() {
 		if err := http.ListenAndServe(addr, nil); err != nil {
-			log.Printf("tracing error: %s", err)
+			logger.Printf("tracing error: %s", err)
 		}
 	}()
 }
diff --git a/docs/chart_best_practices/index.md b/docs/chart_best_practices/README.md
similarity index 100%
rename from docs/chart_best_practices/index.md
rename to docs/chart_best_practices/README.md
diff --git a/docs/chart_repository_faq.md b/docs/chart_repository_faq.md
new file mode 100644
index 0000000000000000000000000000000000000000..78e47a46172c4faf1f701842edf14db5623ac053
--- /dev/null
+++ b/docs/chart_repository_faq.md
@@ -0,0 +1,17 @@
+# Chart Repositories: Frequently Asked Questions
+
+This section tracks some of the more frequently encountered issues with using chart repositories.
+
+**We'd love your help** making this document better. To add, correct, or remove
+information, [file an issue](https://github.com/kubernetes/helm/issues) or
+send us a pull request.
+
+## Fetching
+
+**Q: Why do I get a `unsupported protocol scheme ""` error when trying to fetch a chart from my custom repo?**
+
+A: (Helm < 2.5.0) This is likely caused by you creating your chart repo index without specifying the `--url` flag.
+Try recreating your `index.yaml` file with a command like `heml repo index --url http://my-repo/charts .`,
+and then re-uploading it to your custom charts repo.
+
+This behavior was changed in Helm 2.5.0.
diff --git a/docs/chart_template_guide/control_structures.md b/docs/chart_template_guide/control_structures.md
index 8723aacefe62da008efe7027261d81a55576d5ea..7575ebc356a21930777ecd18c6b590a0e78dc89e 100644
--- a/docs/chart_template_guide/control_structures.md
+++ b/docs/chart_template_guide/control_structures.md
@@ -170,7 +170,7 @@ data:
   {{- end}}
 ```
 
-Just for the same of making this point clear, let's adjust the above, and substitute an `*` for each whitespace that will be deleted following this rule. an `*` at the end of the line indicates a newline character that would be removed
+Just for the sake of making this point clear, let's adjust the above, and substitute an `*` for each whitespace that will be deleted following this rule. an `*` at the end of the line indicates a newline character that would be removed
 
 ```yaml
 apiVersion: v1
diff --git a/docs/chart_template_guide/named_templates.md b/docs/chart_template_guide/named_templates.md
index daea98b19497a1fc0f55479316a7803509f739c6..1dc9c7618799a3c0e8948bdd421b5f53791010cc 100644
--- a/docs/chart_template_guide/named_templates.md
+++ b/docs/chart_template_guide/named_templates.md
@@ -170,87 +170,6 @@ metadata:
 
 Now `{{ .Chart.Name }}` resolves to `mychart`, and `{{ .Chart.Version }}` resolves to `0.1.0`.
 
-## Creating override-able sections with `block`
-
-Say we want to create a template in our `_helpers.tpl` file, but then override part of its behavior in our template. This is what blocks are for. Sometimes we don't want to just insert a template with `template`, but we want to sketch out a default and let another template override our default. This makes it possible for one chart to define a base template, but allow another chart to strategically override some of its behavior.
-
-Blocks are declared like this:
-
-```yaml
-{{ block "NAME" PIPELINE }}
-{{ end }}
-```
-
-Here, "NAME" is the name that a `define` block can use to override it, and PIPELINE is the pipeline that will set the scope. So let's rewrite our `labels:` section to use this strategy. We'll create a basic labels section in our `_helpers.tpl` file, but add some extra labels in the `configmap.yaml` template.
-
-Let's start with `_helpers.tpl`:
-
-```yaml
-{{- define "my_labels" }}
-  labels:
-    chart: {{ .Chart.Name }}
-    version: {{ .Chart.Version }}
-    {{ block "my_extra_labels" . }}extras: false{{ end }}
-{{- end }}
-```
-
-Inside of our `my_labels` template, we now declare a block called `my_extra_labels`. By default, this section will have one extra label: `extras: false`. If we were to execute this using the same `configmap.yaml` file from last time, we'd get this:
-
-```yaml
-# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: tinseled-womba-configmap
-  labels:
-    chart: mychart
-    version: 0.1.0
-    extras: false
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "pizza"
-```
-
-But inside of our `configmap.yaml` template, we can override `my_extra_labels`:
-
-```yaml
-{{- define "my_extra_labels" }}chart: {{ .Chart.Name }}{{ end -}}
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-  {{- template "my_labels" . }}
-data:
-  myvalue: "Hello World"
-  {{- range $key, $val := .Values.favorite }}
-  {{ $key }}: {{ $val | quote }}
-  {{- end }}
-```
-
-On the first line, we redefine `my_extra_labels` to include `chart: {{ .Chart.Name }}`. If we
-run this, we will get:
-
-```yaml
-# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: ignorant-scorp-configmap
-  labels:
-    chart: mychart
-    version: 0.1.0
-    chart: mychart
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "pizza"
-```
-
-Gone is the `extras: false` section, since that part of the template is now overridden by our new template, which placed `chart: mychart` into the output.
-
-Blocks are not frequently used in Helm charts. But they do provide one mechanism for creating "abstract" charts, and then selectively overriding parts of the abstract template with concrete implementations.
-
 ## The `include` function
 
 Say we've defined a simple template that looks like this:
diff --git a/docs/chart_template_guide/subcharts_and_globals.md b/docs/chart_template_guide/subcharts_and_globals.md
index 69d828c1144588b991d107d10c8291e486807979..26e9a60cbd717ac711ee9ff8e0d4f6fa388ee3a0 100644
--- a/docs/chart_template_guide/subcharts_and_globals.md
+++ b/docs/chart_template_guide/subcharts_and_globals.md
@@ -175,57 +175,33 @@ Globals are useful for passing information like this, though it does take some p
 
 ## Sharing Templates with Subcharts
 
-Parent charts and subcharts can share templates. This can become very powerful when coupled with `block`s. For example, we can define a `block` in the `subchart` ConfigMap like this:
+Parent charts and subcharts can share templates. Any defined block in any chart is
+available to other charts.
 
-```yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-cfgmap2
-  {{block "labels" . }}from: mysubchart{{ end }}
-data:
-  dessert: {{ .Values.dessert }}
-  salad: {{ .Values.global.salad }}
-```
-
-Running this would produce:
-
-```yaml
-# Source: mychart/charts/mysubchart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: gaudy-mastiff-cfgmap2
-  from: mysubchart
-data:
-  dessert: ice cream
-  salad: caesar
-```
-
-Note that the `from:` line says `mysubchart`. In a previous section, we created `mychart/templates/_helpers.tpl`. Let's define a new named template there called `labels` to match the declaration on the block above.
+For example, we can define a simple template like this:
 
 ```yaml
 {{- define "labels" }}from: mychart{{ end }}
 ```
 
-Recall how the labels on templates are _globally shared_. That means that if we create a block named `labels` in one chart, and then define an override named `labels` in another chart, the override will be applied.
+Recall how the labels on templates are _globally shared_. Thus, the `labels` chart
+can be included from any other chart.
 
-Now if we do a `helm install --dry-run --debug mychart`, it will override the block:
+While chart developers have a choice between `include` and `template`, one advantage
+of using `include` is that `include` can dynamically reference templates:
 
 ```yaml
-# Source: mychart/charts/mysubchart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: nasal-cheetah-cfgmap2
-  from: mychart
-data:
-  dessert: ice cream
-  salad: caesar
+{{ include $mytemplate }}
 ```
 
-Now `from:` is set to `mychart` because the block was overridden.
+The above will dereference `$mytemplate`. The `template` function, in contrast,
+will only accept a string literal.
+
+## Avoid Using Blocks
 
-Using this method, you can write flexible "base" charts that can be added as subcharts to many different charts, and which will support selective overriding using blocks.
+The Go template language provides a `block` keyword that allows developers to provide
+a default implementation which is overridden later. In Helm charts, blocks are not
+the best tool for overriding because it if multiple implementations of the same block
+are provided, the one selected is unpredictable.
 
-This section of the guide has focused on subcharts. We've seen how to inherit values, how to use global values, and how to override templates with blocks. In the next section we will turn to debugging, and learn how to catch errors in templates.
+The suggestion is to instead use `include`.
diff --git a/docs/chart_tests.md b/docs/chart_tests.md
index cb25d5dfc1f318dad680c2921bfbf27165e50371..4311ffaeb9617b2b142f476a1071b56a38134485 100644
--- a/docs/chart_tests.md
+++ b/docs/chart_tests.md
@@ -1,8 +1,8 @@
 # Chart Tests
 
-A chart contains a number of Kubernetes resources and components that work together. As a chart author, you may want to write some tests that validate that your charts works as expected when it is installed. These tests also help the chart consumer understand what your chart is supposed to do.
+A chart contains a number of Kubernetes resources and components that work together. As a chart author, you may want to write some tests that validate that your chart works as expected when it is installed. These tests also help the chart consumer understand what your chart is supposed to do.
 
-A **test** in a helm chart lives under the `templates/` directory and is a pod definition that specifies a container with a given command to run. The container should exist successfully (exit 0) for a test to be considered a success. The pod definiton must contain one of the helm test hook annotations: `helm.sh/hooks: test-success` or `helm.sh/hooks: test-failure`.
+A **test** in a helm chart lives under the `templates/` directory and is a pod definition that specifies a container with a given command to run. The container should exit successfully (exit 0) for a test to be considered a success. The pod definiton must contain one of the helm test hook annotations: `helm.sh/hooks: test-success` or `helm.sh/hooks: test-failure`.
 
 Example tests:
 - Validate that your configuration from the values.yaml file was properly injected.
@@ -17,12 +17,12 @@ You can run the pre-defined tests in Helm on a release using the command `helm t
 
 In Helm, there are two test hooks: `test-success` and `test-failure`
 
-`test-success` indiciates that test pod should complete successfully. In other words, the containers in the pod should exit 0.
-`test-failure` is a way to assert that a test pod should not complete successfully. If the containers in the pod do not exit 0, that indiciates success.
+`test-success` indicates that test pod should complete successfully. In other words, the containers in the pod should exit 0.
+`test-failure` is a way to assert that a test pod should not complete successfully. If the containers in the pod do not exit 0, that indicates success.
 
 ## Example Test
 
-Here is an example of a helm test pod definition in an example maraidb chart:
+Here is an example of a helm test pod definition in an example mariadb chart:
 
 ```
 mariadb/
diff --git a/docs/charts.md b/docs/charts.md
index b1aa10ad4a43c66e9c0350a99b1af2a1dee3e4cf..071eb4980cbae24f297aff51ddc9082e438a4132 100644
--- a/docs/charts.md
+++ b/docs/charts.md
@@ -229,6 +229,43 @@ Managing charts with `requirements.yaml` is a good way to easily keep
 charts updated, and also share requirements information throughout a
 team.
 
+#### Alias field in requirements.yaml
+
+In addition to the other fields above, each requirements entry may contain
+the optional field `alias`.
+
+Adding an alias for a dependency chart would put
+a chart in dependencies using alias as name of new dependency.
+
+One can use `alias` in cases where they need to access a chart
+with other name(s).
+
+````
+# parentchart/requirements.yaml
+dependencies:
+      - name: subchart
+        repository: http://localhost:10191
+        version: 0.1.0
+        alias: new-subchart-1
+      - name: subchart
+        repository: http://localhost:10191
+        version: 0.1.0
+        alias: new-subchart-2
+      - name: subchart
+        repository: http://localhost:10191
+        version: 0.1.0
+````
+
+In the above example we will get 3 depenendencies in all for `parentchart`
+```
+subchart
+new-subchart-1
+new-subchart-2
+```
+
+Manual way of achieving this is copy/pasting same chart in
+`charts/` directory multiple times with different name.
+
 #### Tags and Condition fields in requirements.yaml
 
 In addition to the other fields above, each requirements entry may contain
@@ -687,17 +724,6 @@ parent chart.
 
 Also, global variables of parent charts take precedence over the global variables from subcharts.
 
-_Global sections are restricted to only simple key/value pairs. They do
-not support nesting._
-
-For example, the following is **illegal** and will not work:
-
-```yaml
-global:
-  foo:  # It is illegal to nest an object inside of global.
-    bar: baz
-```
-
 ### References
 
 When it comes to writing templates and values files, there are several
diff --git a/docs/charts_hooks.md b/docs/charts_hooks.md
index a5babc4817e02a0ada679d232c629ccddd240faa..6ac9bc2b0e9bb4e16da6f38549358d2b8b915a2e 100644
--- a/docs/charts_hooks.md
+++ b/docs/charts_hooks.md
@@ -79,8 +79,13 @@ Helm client will pause while the Job is run.
 
 For all other kinds, as soon as Kubernetes marks the resource as loaded
 (added or updated), the resource is considered "Ready". When many
-resources are declared in a hook, the resources are executed serially,
-but the order of their execution is not guaranteed.
+resources are declared in a hook, the resources are executed serially. If they
+have hook weights (see below), they are executed in weighted order. Otherwise,
+ordering is not guaranteed. (In Helm 2.3.0 and after, they are sorted
+alphabetically. That behavior, though, is not considered binding and could change
+in the future.) It is considered good practice to add a hook weight, and set it
+to `0` if weight is not important.
+
 
 ### Hook resources are unmanaged
 
@@ -150,19 +155,20 @@ One resource can implement multiple hooks:
 
 Similarly, there is no limit to the number of different resources that
 may implement a given hook. For example, one could declare both a secret
-and a config map as a pre-install hook. It is important to keep in mind,
-though, that there are no ordering guarantees about hooks.
+and a config map as a pre-install hook.
 
 When subcharts declare hooks, those are also evaluated. There is no way
-for a top-level chart to disable the hooks declared by subcharts. And
-again, there is no guaranteed ordering.
+for a top-level chart to disable the hooks declared by subcharts.
 
-It is also possible to define a weight for a hook which will help build a deterministic executing order. Weights are defined using the following annotation:
+It is also possible to define a weight for a hook which will help build a
+deterministic executing order. Weights are defined using the following annotation:
 
 ```
   annotations:
     "helm.sh/hook-weight": "5"
 ```
 
-Hook weights can be positive or negative numbers but must be represented as strings. When Tiller starts the execution cycle of hooks of a particular Kind it will sort those hooks in ascending order. 
+Hook weights can be positive or negative numbers but must be represented as
+strings. When Tiller starts the execution cycle of hooks of a particular Kind it
+will sort those hooks in ascending order. 
 
diff --git a/docs/charts_tips_and_tricks.md b/docs/charts_tips_and_tricks.md
index 01d9ea83c985291e6b2fe3fb0992c6ddae452062..0ed1ab83e1b5d93480b85c18a298f97ebe456125 100644
--- a/docs/charts_tips_and_tricks.md
+++ b/docs/charts_tips_and_tricks.md
@@ -78,7 +78,7 @@ Go provides a way for setting template options to control behavior
 when a map is indexed with a key that's not present in the map. This
 is typically set with template.Options("missingkey=option"), where option
 can be default, zero, or error. While setting this option to error will
-stop execution with an arror, this would apply to every missing key in the
+stop execution with an error, this would apply to every missing key in the
 map. There may be situations where a chart developer wants to enforce this
 behavior for select values in the values.yml file.
 
diff --git a/docs/developers.md b/docs/developers.md
index 163ba1b9dce815cc2d9be01157fc39def627954b..e0aeb374af6e0516ad6cc0e4f56cdd5725b2f5a1 100644
--- a/docs/developers.md
+++ b/docs/developers.md
@@ -174,6 +174,7 @@ Common commit types:
 - feat: Add a new feature
 - docs: Change documentation
 - test: Improve testing
+- ref: refactor existing code
 
 Common scopes:
 
diff --git a/docs/examples/alpine/README.md b/docs/examples/alpine/README.md
index 3c32de5db6abcf366c2f162edcf822e7e1eb5e5b..eb4fb95719a6e06a896c3632aa24a13180265840 100644
--- a/docs/examples/alpine/README.md
+++ b/docs/examples/alpine/README.md
@@ -1,4 +1,4 @@
-#Alpine: A simple Helm chart
+# Alpine: A simple Helm chart
 
 Run a single pod of Alpine Linux.
 
diff --git a/docs/helm/helm.md b/docs/helm/helm.md
index 3b63cc5f2584a9155f41c21188f924d6e6b07da7..4567049da19be28f2f9165e670bcf4b79a0c47cf 100644
--- a/docs/helm/helm.md
+++ b/docs/helm/helm.md
@@ -33,14 +33,14 @@ Environment:
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
 ```
 
 ### SEE ALSO
-* [helm completion](helm_completion.md)	 - Generate bash autocompletions script
+* [helm completion](helm_completion.md)	 - Generate autocompletions script for the specified shell (bash or zsh)
 * [helm create](helm_create.md)	 - create a new chart with the given name
 * [helm delete](helm_delete.md)	 - given a release name, delete the release from Kubernetes
 * [helm dependency](helm_dependency.md)	 - manage a chart's dependencies
@@ -66,4 +66,4 @@ Environment:
 * [helm verify](helm_verify.md)	 - verify that a chart at the given path has been signed and is valid
 * [helm version](helm_version.md)	 - print the client/server version information
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_completion.md b/docs/helm/helm_completion.md
index 0e05b6700f157a97d3ed5004345d9579c5fcdf28..4b7c540a15ca3167c78d99152b4a276d4034e108 100644
--- a/docs/helm/helm_completion.md
+++ b/docs/helm/helm_completion.md
@@ -1,31 +1,31 @@
 ## helm completion
 
-Generate bash autocompletions script
+Generate autocompletions script for the specified shell (bash or zsh)
 
 ### Synopsis
 
 
 
-Generate bash autocompletions script for Helm.
+Generate autocompletions script for Helm for the specified shell (bash or zsh).
 
-This command can generate shell autocompletions.
+This command can generate shell autocompletions. e.g.
 
-	$ helm completion
+	$ helm completion bash
 
 Can be sourced as such
 
-	$ source <(helm completion)
+	$ source <(helm completion bash)
 
 
 ```
-helm completion
+helm completion SHELL
 ```
 
 ### Options inherited from parent commands
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -34,4 +34,4 @@ helm completion
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_create.md b/docs/helm/helm_create.md
index 442becc8707c129d539d45a4b329051cd5c8eb5b..8284be8ff484eda9c3591ff2b3a0b1d767f34c0f 100644
--- a/docs/helm/helm_create.md
+++ b/docs/helm/helm_create.md
@@ -44,7 +44,7 @@ helm create NAME
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -53,4 +53,4 @@ helm create NAME
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_delete.md b/docs/helm/helm_delete.md
index 97620edaaf190e6c70d22bb5c7a12f93dee80575..0d15b9d0202ac0abb41a5fe4bd223cdf71f94e99 100644
--- a/docs/helm/helm_delete.md
+++ b/docs/helm/helm_delete.md
@@ -35,7 +35,7 @@ helm delete [flags] RELEASE_NAME [...]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -44,4 +44,4 @@ helm delete [flags] RELEASE_NAME [...]
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_dependency.md b/docs/helm/helm_dependency.md
index 69417bc249416e6e16e03df5de4da0e4267e2754..629a27d38c813d241238e756cde31332e6e7c226 100644
--- a/docs/helm/helm_dependency.md
+++ b/docs/helm/helm_dependency.md
@@ -58,7 +58,7 @@ for this case.
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -70,4 +70,4 @@ for this case.
 * [helm dependency list](helm_dependency_list.md)	 - list the dependencies for the given chart
 * [helm dependency update](helm_dependency_update.md)	 - update charts/ based on the contents of requirements.yaml
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_dependency_build.md b/docs/helm/helm_dependency_build.md
index 4cd1494441c688903639f5de34f7a8c6f79ba592..9c5d6af78256c101344fca178303d611fa7bea28 100644
--- a/docs/helm/helm_dependency_build.md
+++ b/docs/helm/helm_dependency_build.md
@@ -31,7 +31,7 @@ helm dependency build [flags] CHART
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -40,4 +40,4 @@ helm dependency build [flags] CHART
 ### SEE ALSO
 * [helm dependency](helm_dependency.md)	 - manage a chart's dependencies
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_dependency_list.md b/docs/helm/helm_dependency_list.md
index e0223c07eb9fcb4ec23841599f76efac777c49e3..ec5e861fd6c3a54aeed09ad2be55b37c685d7ebe 100644
--- a/docs/helm/helm_dependency_list.md
+++ b/docs/helm/helm_dependency_list.md
@@ -23,7 +23,7 @@ helm dependency list [flags] CHART
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -32,4 +32,4 @@ helm dependency list [flags] CHART
 ### SEE ALSO
 * [helm dependency](helm_dependency.md)	 - manage a chart's dependencies
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_dependency_update.md b/docs/helm/helm_dependency_update.md
index 553d1f8312e8f256aa81be8b8e2a690b52df0b46..8fb8fd2d1472f5fc2a27fb81807b672140fca564 100644
--- a/docs/helm/helm_dependency_update.md
+++ b/docs/helm/helm_dependency_update.md
@@ -36,7 +36,7 @@ helm dependency update [flags] CHART
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -45,4 +45,4 @@ helm dependency update [flags] CHART
 ### SEE ALSO
 * [helm dependency](helm_dependency.md)	 - manage a chart's dependencies
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_fetch.md b/docs/helm/helm_fetch.md
index 904e0577ed8b89857d7260eebee4699313c93ffa..a95781997a54b16fda8f74f8aebb425cc916859e 100644
--- a/docs/helm/helm_fetch.md
+++ b/docs/helm/helm_fetch.md
@@ -27,9 +27,14 @@ helm fetch [flags] [chart URL | repo/chartname] [...]
 ### Options
 
 ```
+      --ca-file string       verify certificates of HTTPS-enabled servers using this CA bundle
+      --cert-file string     identify HTTPS client using this SSL certificate file
   -d, --destination string   location to write the chart. If this and tardir are specified, tardir is appended to this (default ".")
+      --devel                use development versions, too. Equivalent to version '>0.0.0-a'. If --version is set, this is ignored.
+      --key-file string      identify HTTPS client using this SSL key file
       --keyring string       keyring containing public keys (default "~/.gnupg/pubring.gpg")
       --prov                 fetch the provenance file, but don't perform verification
+      --repo string          chart repository url where to locate the requested chart
       --untar                if set to true, will untar the chart after downloading it
       --untardir string      if untar is specified, this flag specifies the name of the directory into which the chart is expanded (default ".")
       --verify               verify the package against its signature
@@ -40,7 +45,7 @@ helm fetch [flags] [chart URL | repo/chartname] [...]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -49,4 +54,4 @@ helm fetch [flags] [chart URL | repo/chartname] [...]
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_get.md b/docs/helm/helm_get.md
index d67af83889622930487323b947fed8e57d6c81cc..efa3c458acb7d2ad6e9c07549ab4cf0f0de392db 100644
--- a/docs/helm/helm_get.md
+++ b/docs/helm/helm_get.md
@@ -37,7 +37,7 @@ helm get [flags] RELEASE_NAME
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -49,4 +49,4 @@ helm get [flags] RELEASE_NAME
 * [helm get manifest](helm_get_manifest.md)	 - download the manifest for a named release
 * [helm get values](helm_get_values.md)	 - download the values file for a named release
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_get_hooks.md b/docs/helm/helm_get_hooks.md
index 9e4cbbaca0ccde98bb52ee9793ba5571f4462faf..d2fad8b694651e3792fac767e80e0cb139829e8f 100644
--- a/docs/helm/helm_get_hooks.md
+++ b/docs/helm/helm_get_hooks.md
@@ -25,7 +25,7 @@ helm get hooks [flags] RELEASE_NAME
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -34,4 +34,4 @@ helm get hooks [flags] RELEASE_NAME
 ### SEE ALSO
 * [helm get](helm_get.md)	 - download a named release
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_get_manifest.md b/docs/helm/helm_get_manifest.md
index aa68c4de850a166fcae2c41e395b6cbdef36d9db..053ef652d55266c68a36aa6ed763d1cb507fe14c 100644
--- a/docs/helm/helm_get_manifest.md
+++ b/docs/helm/helm_get_manifest.md
@@ -27,7 +27,7 @@ helm get manifest [flags] RELEASE_NAME
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -36,4 +36,4 @@ helm get manifest [flags] RELEASE_NAME
 ### SEE ALSO
 * [helm get](helm_get.md)	 - download a named release
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_get_values.md b/docs/helm/helm_get_values.md
index 67568c6a8fd1c134b4e36a339cc13b6d34592430..5cdcbd7d2eda6845b6693ae747f4da7180b8f080 100644
--- a/docs/helm/helm_get_values.md
+++ b/docs/helm/helm_get_values.md
@@ -24,7 +24,7 @@ helm get values [flags] RELEASE_NAME
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -33,4 +33,4 @@ helm get values [flags] RELEASE_NAME
 ### SEE ALSO
 * [helm get](helm_get.md)	 - download a named release
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_history.md b/docs/helm/helm_history.md
index 1852c66163488fcbee54a5f13149d8db10587430..590c8a6844bde77c3da62a587895d03288e2ad0d 100644
--- a/docs/helm/helm_history.md
+++ b/docs/helm/helm_history.md
@@ -40,7 +40,7 @@ helm history [flags] RELEASE_NAME
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -49,4 +49,4 @@ helm history [flags] RELEASE_NAME
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_home.md b/docs/helm/helm_home.md
index d86f3ce806f0844165d2b629ac7821a9d423f8d3..683142f71b52a739b554145b10dfa99c67cb69e9 100644
--- a/docs/helm/helm_home.md
+++ b/docs/helm/helm_home.md
@@ -18,7 +18,7 @@ helm home
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -27,4 +27,4 @@ helm home
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_init.md b/docs/helm/helm_init.md
index 3fe94b79cf4655c743c415832d2e80d420d3cd23..2d498c554c218161a3077b79f8314af90e3b4a44 100644
--- a/docs/helm/helm_init.md
+++ b/docs/helm/helm_init.md
@@ -38,6 +38,7 @@ helm init
       --dry-run                  do not install local or remote
       --local-repo-url string    URL for local repository (default "http://127.0.0.1:8879/charts")
       --net-host                 install tiller with net=host
+      --service-account string   name of service account
       --skip-refresh             do not refresh (download) the local repository cache
       --stable-repo-url string   URL for stable repository (default "https://kubernetes-charts.storage.googleapis.com")
   -i, --tiller-image string      override tiller image
@@ -53,7 +54,7 @@ helm init
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -62,4 +63,4 @@ helm init
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 18-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_inspect.md b/docs/helm/helm_inspect.md
index df8b5eb2dfada75e7fbb8b2beda19d7af463f0e7..30f09a72fc8f45b183f00e57cbb556d7df1e4984 100644
--- a/docs/helm/helm_inspect.md
+++ b/docs/helm/helm_inspect.md
@@ -19,16 +19,20 @@ helm inspect [CHART]
 ### Options
 
 ```
-      --keyring string   path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
-      --verify           verify the provenance data for this chart
-      --version string   version of the chart. By default, the newest chart is shown
+      --ca-file string     chart repository url where to locate the requested chart
+      --cert-file string   verify certificates of HTTPS-enabled servers using this CA bundle
+      --key-file string    identify HTTPS client using this SSL key file
+      --keyring string     path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
+      --repo string        chart repository url where to locate the requested chart
+      --verify             verify the provenance data for this chart
+      --version string     version of the chart. By default, the newest chart is shown
 ```
 
 ### Options inherited from parent commands
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -39,4 +43,4 @@ helm inspect [CHART]
 * [helm inspect chart](helm_inspect_chart.md)	 - shows inspect chart
 * [helm inspect values](helm_inspect_values.md)	 - shows inspect values
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_inspect_chart.md b/docs/helm/helm_inspect_chart.md
index 9980b5a46982e569887d1befbec6d8060da9a767..5e49e282b93574de30cf27bec35c24a1d96d56c4 100644
--- a/docs/helm/helm_inspect_chart.md
+++ b/docs/helm/helm_inspect_chart.md
@@ -17,16 +17,20 @@ helm inspect chart [CHART]
 ### Options
 
 ```
-      --keyring string   path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
-      --verify           verify the provenance data for this chart
-      --version string   version of the chart. By default, the newest chart is shown
+      --ca-file string     chart repository url where to locate the requested chart
+      --cert-file string   verify certificates of HTTPS-enabled servers using this CA bundle
+      --key-file string    identify HTTPS client using this SSL key file
+      --keyring string     path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
+      --repo string        chart repository url where to locate the requested chart
+      --verify             verify the provenance data for this chart
+      --version string     version of the chart. By default, the newest chart is shown
 ```
 
 ### Options inherited from parent commands
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -35,4 +39,4 @@ helm inspect chart [CHART]
 ### SEE ALSO
 * [helm inspect](helm_inspect.md)	 - inspect a chart
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_inspect_values.md b/docs/helm/helm_inspect_values.md
index 650a64358548c1030f627667a2f7c4ea10ad21f6..f4921597528dd2618cc2a899a84180d455ca1545 100644
--- a/docs/helm/helm_inspect_values.md
+++ b/docs/helm/helm_inspect_values.md
@@ -17,16 +17,20 @@ helm inspect values [CHART]
 ### Options
 
 ```
-      --keyring string   path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
-      --verify           verify the provenance data for this chart
-      --version string   version of the chart. By default, the newest chart is shown
+      --ca-file string     chart repository url where to locate the requested chart
+      --cert-file string   verify certificates of HTTPS-enabled servers using this CA bundle
+      --key-file string    identify HTTPS client using this SSL key file
+      --keyring string     path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
+      --repo string        chart repository url where to locate the requested chart
+      --verify             verify the provenance data for this chart
+      --version string     version of the chart. By default, the newest chart is shown
 ```
 
 ### Options inherited from parent commands
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -35,4 +39,4 @@ helm inspect values [CHART]
 ### SEE ALSO
 * [helm inspect](helm_inspect.md)	 - inspect a chart
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_install.md b/docs/helm/helm_install.md
index 0f5736887b8ffcfc21be831f1a113c49be8bf617..f8e0885ff85a4d6f7f51926bd2dcfd74f7be7014 100644
--- a/docs/helm/helm_install.md
+++ b/docs/helm/helm_install.md
@@ -68,13 +68,18 @@ helm install [CHART]
 ### Options
 
 ```
+      --ca-file string         verify certificates of HTTPS-enabled servers using this CA bundle
+      --cert-file string       identify HTTPS client using this SSL certificate file
+      --devel                  use development versions, too. Equivalent to version '>0.0.0-a'. If --version is set, this is ignored.
       --dry-run                simulate an install
+      --key-file string        identify HTTPS client using this SSL key file
       --keyring string         location of public keys used for verification (default "~/.gnupg/pubring.gpg")
   -n, --name string            release name. If unspecified, it will autogenerate one for you
       --name-template string   specify template used to name the release
       --namespace string       namespace to install the release into
       --no-hooks               prevent hooks from running during install
       --replace                re-use the given name, even if that name is already used. This is unsafe in production
+      --repo string            chart repository url where to locate the requested chart
       --set stringArray        set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
       --timeout int            time in seconds to wait for any individual kubernetes operation (like Jobs for hooks) (default 300)
       --tls                    enable TLS for request
@@ -92,7 +97,7 @@ helm install [CHART]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -101,4 +106,4 @@ helm install [CHART]
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_lint.md b/docs/helm/helm_lint.md
index 00f287569bba0c303b19dd29979cc337c1110112..61e6737c4a4c974e34dd13efb3a7f882976cc26d 100644
--- a/docs/helm/helm_lint.md
+++ b/docs/helm/helm_lint.md
@@ -28,7 +28,7 @@ helm lint [flags] PATH
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -37,4 +37,4 @@ helm lint [flags] PATH
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_list.md b/docs/helm/helm_list.md
index 26e4ffcd1b60956ad937c76f9b806a2834b8ff11..a69f5ba2c395c7f1ad25e293f372401bfb9a4a72 100644
--- a/docs/helm/helm_list.md
+++ b/docs/helm/helm_list.md
@@ -61,7 +61,7 @@ helm list [flags] [FILTER]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -70,4 +70,4 @@ helm list [flags] [FILTER]
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_package.md b/docs/helm/helm_package.md
index d7afd118b4abbb593471e00a7bbbbe8a081977bc..595ec556482a6b092edff1fe0f5b907be2143682 100644
--- a/docs/helm/helm_package.md
+++ b/docs/helm/helm_package.md
@@ -23,6 +23,7 @@ helm package [flags] [CHART_PATH] [...]
 ### Options
 
 ```
+  -u, --dependency-update    update dependencies from "requirements.yaml" to dir "charts/" before packaging
   -d, --destination string   location to write the chart. (default ".")
       --key string           name of the key to use when signing. Used if --sign is true
       --keyring string       location of a public keyring (default "~/.gnupg/pubring.gpg")
@@ -35,7 +36,7 @@ helm package [flags] [CHART_PATH] [...]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -44,4 +45,4 @@ helm package [flags] [CHART_PATH] [...]
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 5-Jun-2017
diff --git a/docs/helm/helm_plugin.md b/docs/helm/helm_plugin.md
index 96d474dea5098a6e6fb6814a631452925e76ae6d..b38f3e01384b90394797121c4dcba4c147f410dd 100644
--- a/docs/helm/helm_plugin.md
+++ b/docs/helm/helm_plugin.md
@@ -13,7 +13,7 @@ Manage client-side Helm plugins.
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -24,5 +24,6 @@ Manage client-side Helm plugins.
 * [helm plugin install](helm_plugin_install.md)	 - install one or more Helm plugins
 * [helm plugin list](helm_plugin_list.md)	 - list installed Helm plugins
 * [helm plugin remove](helm_plugin_remove.md)	 - remove one or more Helm plugins
+* [helm plugin update](helm_plugin_update.md)	 - update one or more Helm plugins
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_plugin_install.md b/docs/helm/helm_plugin_install.md
index 8480eb2ed487904acb57b7dded44893b26015c53..7b4f8904e9ba4587760b01c9dede3d12f078f00c 100644
--- a/docs/helm/helm_plugin_install.md
+++ b/docs/helm/helm_plugin_install.md
@@ -21,7 +21,7 @@ helm plugin install [options] <path|url>...
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -30,4 +30,4 @@ helm plugin install [options] <path|url>...
 ### SEE ALSO
 * [helm plugin](helm_plugin.md)	 - add, list, or remove Helm plugins
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_plugin_list.md b/docs/helm/helm_plugin_list.md
index cfa321706ee1b7528cc27dd1c3a6222b6479fe16..53f37b8d0daebc275c3bf9802143f8aead8af36a 100644
--- a/docs/helm/helm_plugin_list.md
+++ b/docs/helm/helm_plugin_list.md
@@ -15,7 +15,7 @@ helm plugin list
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -24,4 +24,4 @@ helm plugin list
 ### SEE ALSO
 * [helm plugin](helm_plugin.md)	 - add, list, or remove Helm plugins
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_plugin_remove.md b/docs/helm/helm_plugin_remove.md
index 47c16f6e89055153e8ca58f18fe3684be50b3109..0559f395c313dd73938392de3154d821ae4ea37b 100644
--- a/docs/helm/helm_plugin_remove.md
+++ b/docs/helm/helm_plugin_remove.md
@@ -15,7 +15,7 @@ helm plugin remove <plugin>...
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -24,4 +24,4 @@ helm plugin remove <plugin>...
 ### SEE ALSO
 * [helm plugin](helm_plugin.md)	 - add, list, or remove Helm plugins
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_plugin_update.md b/docs/helm/helm_plugin_update.md
new file mode 100644
index 0000000000000000000000000000000000000000..c0dac090aba7b95f4b8c27a16e0dafcb8618232e
--- /dev/null
+++ b/docs/helm/helm_plugin_update.md
@@ -0,0 +1,27 @@
+## helm plugin update
+
+update one or more Helm plugins
+
+### Synopsis
+
+
+update one or more Helm plugins
+
+```
+helm plugin update <plugin>...
+```
+
+### Options inherited from parent commands
+
+```
+      --debug                     enable verbose output
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
+      --host string               address of tiller. Overrides $HELM_HOST
+      --kube-context string       name of the kubeconfig context to use
+      --tiller-namespace string   namespace of tiller (default "kube-system")
+```
+
+### SEE ALSO
+* [helm plugin](helm_plugin.md)	 - add, list, or remove Helm plugins
+
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_repo.md b/docs/helm/helm_repo.md
index 8e5d0da57b822642def3dc44620ff040ac1cbf74..3378a1850d9d905f120e799c819d47635cdaf21a 100644
--- a/docs/helm/helm_repo.md
+++ b/docs/helm/helm_repo.md
@@ -17,7 +17,7 @@ Example usage:
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -29,6 +29,6 @@ Example usage:
 * [helm repo index](helm_repo_index.md)	 - generate an index file given a directory containing packaged charts
 * [helm repo list](helm_repo_list.md)	 - list chart repositories
 * [helm repo remove](helm_repo_remove.md)	 - remove a chart repository
-* [helm repo update](helm_repo_update.md)	 - update information on available charts in the chart repositories
+* [helm repo update](helm_repo_update.md)	 - update information of available charts locally from chart repositories
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_repo_add.md b/docs/helm/helm_repo_add.md
index 5567fe4155c6da314f61b25a7615d38693566b83..f7f3e872779dca36c4390df36332253e90320894 100644
--- a/docs/helm/helm_repo_add.md
+++ b/docs/helm/helm_repo_add.md
@@ -24,7 +24,7 @@ helm repo add [flags] [NAME] [URL]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -33,4 +33,4 @@ helm repo add [flags] [NAME] [URL]
 ### SEE ALSO
 * [helm repo](helm_repo.md)	 - add, list, remove, update, and index chart repositories
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_repo_index.md b/docs/helm/helm_repo_index.md
index a98ecbffa0608bdb870576e30c4af6a19e7beeb1..79c8ee608806f34e808a61ad15a0b8b65dabcec7 100644
--- a/docs/helm/helm_repo_index.md
+++ b/docs/helm/helm_repo_index.md
@@ -31,7 +31,7 @@ helm repo index [flags] [DIR]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -40,4 +40,4 @@ helm repo index [flags] [DIR]
 ### SEE ALSO
 * [helm repo](helm_repo.md)	 - add, list, remove, update, and index chart repositories
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_repo_list.md b/docs/helm/helm_repo_list.md
index e5138458c2958012268be780b1b680c622a5a158..4f8f2e1ddb988aed25716f9d46c61e12db9444eb 100644
--- a/docs/helm/helm_repo_list.md
+++ b/docs/helm/helm_repo_list.md
@@ -15,7 +15,7 @@ helm repo list [flags]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -24,4 +24,4 @@ helm repo list [flags]
 ### SEE ALSO
 * [helm repo](helm_repo.md)	 - add, list, remove, update, and index chart repositories
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_repo_remove.md b/docs/helm/helm_repo_remove.md
index 0d1b1d06f4cac2e11076e19fa033060633a91040..075b15fce762ba5a0e8fc0366d73cdd83f38396e 100644
--- a/docs/helm/helm_repo_remove.md
+++ b/docs/helm/helm_repo_remove.md
@@ -15,7 +15,7 @@ helm repo remove [flags] [NAME]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -24,4 +24,4 @@ helm repo remove [flags] [NAME]
 ### SEE ALSO
 * [helm repo](helm_repo.md)	 - add, list, remove, update, and index chart repositories
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_repo_update.md b/docs/helm/helm_repo_update.md
index e3787cd568bfe734c1b90d2c5468a8d85e0eacb6..3758f822ffe8c6496258f30b7032aeccc0fa5e00 100644
--- a/docs/helm/helm_repo_update.md
+++ b/docs/helm/helm_repo_update.md
@@ -1,6 +1,6 @@
 ## helm repo update
 
-update information on available charts in the chart repositories
+update information of available charts locally from chart repositories
 
 ### Synopsis
 
@@ -21,7 +21,7 @@ helm repo update
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -30,4 +30,4 @@ helm repo update
 ### SEE ALSO
 * [helm repo](helm_repo.md)	 - add, list, remove, update, and index chart repositories
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_reset.md b/docs/helm/helm_reset.md
index e07f3a7075d68a7545460d09f6aa4e52c9dac510..bc3299d481eabe354b274caaafff9e391e421d9e 100644
--- a/docs/helm/helm_reset.md
+++ b/docs/helm/helm_reset.md
@@ -18,7 +18,7 @@ helm reset
 ### Options
 
 ```
-  -f, --force                forces Tiller uninstall even if there are releases installed
+  -f, --force                forces Tiller uninstall even if there are releases installed, or if tiller is not in ready state
       --remove-helm-home     if set deletes $HELM_HOME
       --tls                  enable TLS for request
       --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
@@ -31,7 +31,7 @@ helm reset
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -40,4 +40,4 @@ helm reset
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_rollback.md b/docs/helm/helm_rollback.md
index a5500008c5ac73aba9b7b6039866e9fd510d52fd..3a3ed1a24fa2048a17221ef1a72a2eb14d8b0369 100644
--- a/docs/helm/helm_rollback.md
+++ b/docs/helm/helm_rollback.md
@@ -9,7 +9,7 @@ roll back a release to a previous revision
 This command rolls back a release to a previous revision.
 
 The first argument of the rollback command is the name of a release, and the
-second is a revision (version) number. To see revision numbers, run 
+second is a revision (version) number. To see revision numbers, run
 'helm history RELEASE'.
 
 
@@ -21,6 +21,7 @@ helm rollback [flags] [RELEASE] [REVISION]
 
 ```
       --dry-run              simulate a rollback
+      --force                force resource update through delete/recreate if needed
       --no-hooks             prevent hooks from running during rollback
       --recreate-pods        performs pods restart for the resource if applicable
       --timeout int          time in seconds to wait for any individual kubernetes operation (like Jobs for hooks) (default 300)
@@ -36,7 +37,7 @@ helm rollback [flags] [RELEASE] [REVISION]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -45,4 +46,4 @@ helm rollback [flags] [RELEASE] [REVISION]
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_search.md b/docs/helm/helm_search.md
index 6f1f8a645f09162d0529dbee54b11fe6d9a92e97..48579c5b8eca8f7298e4fbfd66185251766a529d 100644
--- a/docs/helm/helm_search.md
+++ b/docs/helm/helm_search.md
@@ -28,7 +28,7 @@ helm search [keyword]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -37,4 +37,4 @@ helm search [keyword]
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 18-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_serve.md b/docs/helm/helm_serve.md
index 7c928c9a009ca53685893465a10347d71dbd9ecb..1a317e9e42d995e387b832beb3399dac7ab94a3d 100644
--- a/docs/helm/helm_serve.md
+++ b/docs/helm/helm_serve.md
@@ -28,7 +28,7 @@ helm serve
 
 ```
       --address string     address to listen on (default "127.0.0.1:8879")
-      --repo-path string   local directory path from which to serve charts (default "~/.helm/repository/local")
+      --repo-path string   local directory path from which to serve charts
       --url string         external URL of chart repository
 ```
 
@@ -36,7 +36,7 @@ helm serve
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -45,4 +45,4 @@ helm serve
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_status.md b/docs/helm/helm_status.md
index 893c3325ac9340cfc218327379ff0dfe479ec301..a737d7a64daf48fc2ade72e247895e63ef2152f9 100644
--- a/docs/helm/helm_status.md
+++ b/docs/helm/helm_status.md
@@ -35,7 +35,7 @@ helm status [flags] RELEASE_NAME
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -44,4 +44,4 @@ helm status [flags] RELEASE_NAME
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_test.md b/docs/helm/helm_test.md
index 795a81c6638a055835193c8e24158a68acbe30d5..8d7b39a593e42e377d06bd0e7d5b45914684a1fa 100644
--- a/docs/helm/helm_test.md
+++ b/docs/helm/helm_test.md
@@ -32,7 +32,7 @@ helm test [RELEASE]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -41,4 +41,4 @@ helm test [RELEASE]
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_upgrade.md b/docs/helm/helm_upgrade.md
index 931073937d426c5d119f096ccdf84a41b9ed8a3a..1fbefcba3d4f1eebcd5d80c114170552e0b2db1c 100644
--- a/docs/helm/helm_upgrade.md
+++ b/docs/helm/helm_upgrade.md
@@ -36,12 +36,18 @@ helm upgrade [RELEASE] [CHART]
 ### Options
 
 ```
+      --ca-file string       verify certificates of HTTPS-enabled servers using this CA bundle
+      --cert-file string     identify HTTPS client using this SSL certificate file
+      --devel                use development versions, too. Equivalent to version '>0.0.0-a'. If --version is set, this is ignored.
       --dry-run              simulate an upgrade
+      --force                force resource update through delete/recreate if needed
   -i, --install              if a release by this name doesn't already exist, run an install
+      --key-file string      identify HTTPS client using this SSL key file
       --keyring string       path to the keyring that contains public signing keys (default "~/.gnupg/pubring.gpg")
       --namespace string     namespace to install the release into (only used if --install is set) (default "default")
       --no-hooks             disable pre/post upgrade hooks
       --recreate-pods        performs pods restart for the resource if applicable
+      --repo string          chart repository url where to locate the requested chart
       --reset-values         when upgrading, reset the values to the ones built into the chart
       --reuse-values         when upgrading, reuse the last release's values, and merge in any new values. If '--reset-values' is specified, this is ignored.
       --set stringArray      set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
@@ -61,7 +67,7 @@ helm upgrade [RELEASE] [CHART]
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -70,4 +76,4 @@ helm upgrade [RELEASE] [CHART]
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_verify.md b/docs/helm/helm_verify.md
index 57ff2f191ccd0f7e5778653960068bd8664c20ba..10ddab05929704cb7820a5ff541a83b23cdf9921 100644
--- a/docs/helm/helm_verify.md
+++ b/docs/helm/helm_verify.md
@@ -30,7 +30,7 @@ helm verify [flags] PATH
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -39,4 +39,4 @@ helm verify [flags] PATH
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/helm/helm_version.md b/docs/helm/helm_version.md
index de65607b19ee406fa6cb6dd51a8b68ebbd78f899..16e2f5b928c12116529198224e4142bb1d95408e 100644
--- a/docs/helm/helm_version.md
+++ b/docs/helm/helm_version.md
@@ -44,7 +44,7 @@ helm version
 
 ```
       --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
+      --home string               location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
       --host string               address of tiller. Overrides $HELM_HOST
       --kube-context string       name of the kubeconfig context to use
       --tiller-namespace string   namespace of tiller (default "kube-system")
@@ -53,4 +53,4 @@ helm version
 ### SEE ALSO
 * [helm](helm.md)	 - The Helm package manager for Kubernetes.
 
-###### Auto generated by spf13/cobra on 16-Apr-2017
+###### Auto generated by spf13/cobra on 29-May-2017
diff --git a/docs/man/man1/helm.1 b/docs/man/man1/helm.1
index 026ca69e4ce39e47d796ec754b9a9c3ccacbb04b..4128830f4a94f6fadfb26ea52b2a3a71804ab3be 100644
--- a/docs/man/man1/helm.1
+++ b/docs/man/man1/helm.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -63,7 +63,7 @@ Environment:
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -82,4 +82,4 @@ Environment:
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_completion.1 b/docs/man/man1/helm_completion.1
index 0468bd4f4a0b5e34ab0e707d05f4105aa8eee660..83217073f6c6da1c3fd48ef2c8f8b38f3ceabf24 100644
--- a/docs/man/man1/helm_completion.1
+++ b/docs/man/man1/helm_completion.1
@@ -1,30 +1,30 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
 
 .SH NAME
 .PP
-helm\-completion \- Generate bash autocompletions script
+helm\-completion \- Generate autocompletions script for the specified shell (bash or zsh)
 
 
 .SH SYNOPSIS
 .PP
-\fBhelm completion\fP
+\fBhelm completion SHELL\fP
 
 
 .SH DESCRIPTION
 .PP
-Generate bash autocompletions script for Helm.
+Generate autocompletions script for Helm for the specified shell (bash or zsh).
 
 .PP
-This command can generate shell autocompletions.
+This command can generate shell autocompletions. e.g.
 
 .PP
 .RS
 
 .nf
-$ helm completion
+$ helm completion bash
 
 .fi
 .RE
@@ -36,7 +36,7 @@ Can be sourced as such
 .RS
 
 .nf
-$ source <(helm completion)
+$ source <(helm completion bash)
 
 .fi
 .RE
@@ -52,7 +52,7 @@ $ source <(helm completion)
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -71,4 +71,4 @@ $ source <(helm completion)
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_create.1 b/docs/man/man1/helm_create.1
index 4261d753fd8b0a77825442374fc343d3d72ce72c..3a1f4b26f4b8e8199c6290e78c7e95ba8a4da6bf 100644
--- a/docs/man/man1/helm_create.1
+++ b/docs/man/man1/helm_create.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -64,7 +64,7 @@ will be overwritten, but other files will be left alone.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -83,4 +83,4 @@ will be overwritten, but other files will be left alone.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_delete.1 b/docs/man/man1/helm_delete.1
index 3df4e0dedaed444ef0d061807c0f9ec75d6dc226..ecce68398f0f6eb458310b7952191eb80f6dd2d2 100644
--- a/docs/man/man1/helm_delete.1
+++ b/docs/man/man1/helm_delete.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -71,7 +71,7 @@ deleting them.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -90,4 +90,4 @@ deleting them.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_dependency.1 b/docs/man/man1/helm_dependency.1
index 9287dcb1f704b45c2c1394d122860a7ab4f72064..fd4fc195e74dc74cc0c245dab3b7865fe902d317 100644
--- a/docs/man/man1/helm_dependency.1
+++ b/docs/man/man1/helm_dependency.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -95,7 +95,7 @@ for this case.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -114,4 +114,4 @@ for this case.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_dependency_build.1 b/docs/man/man1/helm_dependency_build.1
index a42f44a58c681c93939d7adefdcdd0d5825e9d13..adc225a815b355c9ba2399cea1dab4e48191f33f 100644
--- a/docs/man/man1/helm_dependency_build.1
+++ b/docs/man/man1/helm_dependency_build.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -47,7 +47,7 @@ of 'helm dependency update'.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -66,4 +66,4 @@ of 'helm dependency update'.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_dependency_list.1 b/docs/man/man1/helm_dependency_list.1
index 9061d3ebe2e148791eeba4603798697dd23412a3..30a686bb41b6e9106dfe039d635aba5c7db958a0 100644
--- a/docs/man/man1/helm_dependency_list.1
+++ b/docs/man/man1/helm_dependency_list.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -36,7 +36,7 @@ if it cannot find a requirements.yaml.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -55,4 +55,4 @@ if it cannot find a requirements.yaml.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_dependency_update.1 b/docs/man/man1/helm_dependency_update.1
index eebee95d7218bc36cbe7fca23406d464ca0f563a..02d9ec94bdc848076d7bafffe9467755dee5eb76 100644
--- a/docs/man/man1/helm_dependency_update.1
+++ b/docs/man/man1/helm_dependency_update.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -56,7 +56,7 @@ in the requirements.yaml file, but (b) at the wrong version.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -75,4 +75,4 @@ in the requirements.yaml file, but (b) at the wrong version.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_fetch.1 b/docs/man/man1/helm_fetch.1
index 0de710574a3ee6f921ae8d3623267d67b8a51ec5..9a8ad185c1b3f56fecc5617c1656581892950512 100644
--- a/docs/man/man1/helm_fetch.1
+++ b/docs/man/man1/helm_fetch.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -33,10 +33,26 @@ result in an error, and the chart will not be saved locally.
 
 
 .SH OPTIONS
+.PP
+\fB\-\-ca\-file\fP=""
+    verify certificates of HTTPS\-enabled servers using this CA bundle
+
+.PP
+\fB\-\-cert\-file\fP=""
+    identify HTTPS client using this SSL certificate file
+
 .PP
 \fB\-d\fP, \fB\-\-destination\fP="."
     location to write the chart. If this and tardir are specified, tardir is appended to this
 
+.PP
+\fB\-\-devel\fP[=false]
+    use development versions, too. Equivalent to version '>0.0.0\-a'. If \-\-version is set, this is ignored.
+
+.PP
+\fB\-\-key\-file\fP=""
+    identify HTTPS client using this SSL key file
+
 .PP
 \fB\-\-keyring\fP="~/.gnupg/pubring.gpg"
     keyring containing public keys
@@ -45,6 +61,10 @@ result in an error, and the chart will not be saved locally.
 \fB\-\-prov\fP[=false]
     fetch the provenance file, but don't perform verification
 
+.PP
+\fB\-\-repo\fP=""
+    chart repository url where to locate the requested chart
+
 .PP
 \fB\-\-untar\fP[=false]
     if set to true, will untar the chart after downloading it
@@ -72,7 +92,7 @@ result in an error, and the chart will not be saved locally.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -91,4 +111,4 @@ result in an error, and the chart will not be saved locally.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_get.1 b/docs/man/man1/helm_get.1
index 6a5f96a20de4c0d76f9f2e59283b5fd040c33e2f..e680f49dcdd58f3efa027f1e653a54159b17138f 100644
--- a/docs/man/man1/helm_get.1
+++ b/docs/man/man1/helm_get.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -67,7 +67,7 @@ chart, the supplied values, and the generated manifest file.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -86,4 +86,4 @@ chart, the supplied values, and the generated manifest file.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_get_hooks.1 b/docs/man/man1/helm_get_hooks.1
index 8ba348e54a333af5eef34ea1f6a516b3e2de008e..34e460d19336a11ed8b5020001a58ef80b01b2d3 100644
--- a/docs/man/man1/helm_get_hooks.1
+++ b/docs/man/man1/helm_get_hooks.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -37,7 +37,7 @@ Hooks are formatted in YAML and separated by the YAML '\-\-\-\\n' separator.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -56,4 +56,4 @@ Hooks are formatted in YAML and separated by the YAML '\-\-\-\\n' separator.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_get_manifest.1 b/docs/man/man1/helm_get_manifest.1
index 21fa6363c69712bd5e89c5483aebfbe5917e9cca..7132db38e5fa3f940147d0143ed8d278b18e1f67 100644
--- a/docs/man/man1/helm_get_manifest.1
+++ b/docs/man/man1/helm_get_manifest.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -39,7 +39,7 @@ charts, those resources will also be included in the manifest.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -58,4 +58,4 @@ charts, those resources will also be included in the manifest.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_get_values.1 b/docs/man/man1/helm_get_values.1
index c897e7378287a44153344e272a2397e1c650bb10..349f97c1443d6e65ff166e1e032352d02f651b9d 100644
--- a/docs/man/man1/helm_get_values.1
+++ b/docs/man/man1/helm_get_values.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -38,7 +38,7 @@ This command downloads a values file for a given release.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -57,4 +57,4 @@ This command downloads a values file for a given release.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_history.1 b/docs/man/man1/helm_history.1
index cde92fa82af90c4d75dc77ad223cbb1007c4c8a3..40789ef92795d8dd58c09d840cb9ce7779fc89dc 100644
--- a/docs/man/man1/helm_history.1
+++ b/docs/man/man1/helm_history.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -75,7 +75,7 @@ REVISION   UPDATED                      STATUS           CHART        DESCRIPTIO
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -94,4 +94,4 @@ REVISION   UPDATED                      STATUS           CHART        DESCRIPTIO
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_home.1 b/docs/man/man1/helm_home.1
index a0887aac486cb417e462893ad48c9189e41c4587..77024d53ebfb52c6f23b2db227f0119c33f6b2bf 100644
--- a/docs/man/man1/helm_home.1
+++ b/docs/man/man1/helm_home.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -29,7 +29,7 @@ any helm configuration files live.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -48,4 +48,4 @@ any helm configuration files live.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_init.1 b/docs/man/man1/helm_init.1
index 9fea8ba4037d72fd5d0ed4584b5b785136309c8f..74871ebe811337723e6976528faf2b1121c060fb 100644
--- a/docs/man/man1/helm_init.1
+++ b/docs/man/man1/helm_init.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -61,6 +61,10 @@ To dump a manifest containing the Tiller deployment YAML, combine the
 \fB\-\-net\-host\fP[=false]
     install tiller with net=host
 
+.PP
+\fB\-\-service\-account\fP=""
+    name of service account
+
 .PP
 \fB\-\-skip\-refresh\fP[=false]
     do not refresh (download) the local repository cache
@@ -109,7 +113,7 @@ To dump a manifest containing the Tiller deployment YAML, combine the
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -128,4 +132,4 @@ To dump a manifest containing the Tiller deployment YAML, combine the
 
 .SH HISTORY
 .PP
-18\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_inspect.1 b/docs/man/man1/helm_inspect.1
index bce08dfcd12f4aa2fbc776fc358e89e42d12b458..0783476c7c0cf6998175059262ff49c6c4b82245 100644
--- a/docs/man/man1/helm_inspect.1
+++ b/docs/man/man1/helm_inspect.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -23,10 +23,26 @@ Inspect prints the contents of the Chart.yaml file and the values.yaml file.
 
 
 .SH OPTIONS
+.PP
+\fB\-\-ca\-file\fP=""
+    chart repository url where to locate the requested chart
+
+.PP
+\fB\-\-cert\-file\fP=""
+    verify certificates of HTTPS\-enabled servers using this CA bundle
+
+.PP
+\fB\-\-key\-file\fP=""
+    identify HTTPS client using this SSL key file
+
 .PP
 \fB\-\-keyring\fP="~/.gnupg/pubring.gpg"
     path to the keyring containing public verification keys
 
+.PP
+\fB\-\-repo\fP=""
+    chart repository url where to locate the requested chart
+
 .PP
 \fB\-\-verify\fP[=false]
     verify the provenance data for this chart
@@ -46,7 +62,7 @@ Inspect prints the contents of the Chart.yaml file and the values.yaml file.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -65,4 +81,4 @@ Inspect prints the contents of the Chart.yaml file and the values.yaml file.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_inspect_chart.1 b/docs/man/man1/helm_inspect_chart.1
index 892a5f6d1ed9627daf79453c233f06e8269a8711..f728df410d285c41ef0f161bb0a78ffa35eb3ef6 100644
--- a/docs/man/man1/helm_inspect_chart.1
+++ b/docs/man/man1/helm_inspect_chart.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -20,10 +20,26 @@ of the Charts.yaml file
 
 
 .SH OPTIONS
+.PP
+\fB\-\-ca\-file\fP=""
+    chart repository url where to locate the requested chart
+
+.PP
+\fB\-\-cert\-file\fP=""
+    verify certificates of HTTPS\-enabled servers using this CA bundle
+
+.PP
+\fB\-\-key\-file\fP=""
+    identify HTTPS client using this SSL key file
+
 .PP
 \fB\-\-keyring\fP="~/.gnupg/pubring.gpg"
     path to the keyring containing public verification keys
 
+.PP
+\fB\-\-repo\fP=""
+    chart repository url where to locate the requested chart
+
 .PP
 \fB\-\-verify\fP[=false]
     verify the provenance data for this chart
@@ -43,7 +59,7 @@ of the Charts.yaml file
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -62,4 +78,4 @@ of the Charts.yaml file
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_inspect_values.1 b/docs/man/man1/helm_inspect_values.1
index ed46871bd21a35e2f1e82e004b5ff2b031031b4e..c87dd9c6022d58a3f8f0250c35571e38a629cd4e 100644
--- a/docs/man/man1/helm_inspect_values.1
+++ b/docs/man/man1/helm_inspect_values.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -20,10 +20,26 @@ of the values.yaml file
 
 
 .SH OPTIONS
+.PP
+\fB\-\-ca\-file\fP=""
+    chart repository url where to locate the requested chart
+
+.PP
+\fB\-\-cert\-file\fP=""
+    verify certificates of HTTPS\-enabled servers using this CA bundle
+
+.PP
+\fB\-\-key\-file\fP=""
+    identify HTTPS client using this SSL key file
+
 .PP
 \fB\-\-keyring\fP="~/.gnupg/pubring.gpg"
     path to the keyring containing public verification keys
 
+.PP
+\fB\-\-repo\fP=""
+    chart repository url where to locate the requested chart
+
 .PP
 \fB\-\-verify\fP[=false]
     verify the provenance data for this chart
@@ -43,7 +59,7 @@ of the values.yaml file
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -62,4 +78,4 @@ of the values.yaml file
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_install.1 b/docs/man/man1/helm_install.1
index 521680e504486a7bcaafd3f41fcaa923f602ad45..8fe99acb385c1ba8cfec042ef53398b903c20232 100644
--- a/docs/man/man1/helm_install.1
+++ b/docs/man/man1/helm_install.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -114,10 +114,26 @@ charts in a repository, use 'helm search'.
 
 
 .SH OPTIONS
+.PP
+\fB\-\-ca\-file\fP=""
+    verify certificates of HTTPS\-enabled servers using this CA bundle
+
+.PP
+\fB\-\-cert\-file\fP=""
+    identify HTTPS client using this SSL certificate file
+
+.PP
+\fB\-\-devel\fP[=false]
+    use development versions, too. Equivalent to version '>0.0.0\-a'. If \-\-version is set, this is ignored.
+
 .PP
 \fB\-\-dry\-run\fP[=false]
     simulate an install
 
+.PP
+\fB\-\-key\-file\fP=""
+    identify HTTPS client using this SSL key file
+
 .PP
 \fB\-\-keyring\fP="~/.gnupg/pubring.gpg"
     location of public keys used for verification
@@ -142,6 +158,10 @@ charts in a repository, use 'helm search'.
 \fB\-\-replace\fP[=false]
     re\-use the given name, even if that name is already used. This is unsafe in production
 
+.PP
+\fB\-\-repo\fP=""
+    chart repository url where to locate the requested chart
+
 .PP
 \fB\-\-set\fP=[]
     set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
@@ -197,7 +217,7 @@ charts in a repository, use 'helm search'.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -216,4 +236,4 @@ charts in a repository, use 'helm search'.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_lint.1 b/docs/man/man1/helm_lint.1
index 0ade88c5acb310c7c45e586348e5bd6bbd9547d9..e0d522685905b6e6eb6a3264859f6ddd7abe5327 100644
--- a/docs/man/man1/helm_lint.1
+++ b/docs/man/man1/helm_lint.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -40,7 +40,7 @@ or recommendation, it will emit [WARNING] messages.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -59,4 +59,4 @@ or recommendation, it will emit [WARNING] messages.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_list.1 b/docs/man/man1/helm_list.1
index aef144aa70b8187e9c7a708a1f3e84c58467cba4..d4fccf96055d7babd91255346358c1ace00ca832 100644
--- a/docs/man/man1/helm_list.1
+++ b/docs/man/man1/helm_list.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -129,7 +129,7 @@ flag with the '\-\-offset' flag allows you to page through results.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -148,4 +148,4 @@ flag with the '\-\-offset' flag allows you to page through results.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_package.1 b/docs/man/man1/helm_package.1
index b50ef10d6dc60d838c11906d4fa6999d1a1677ef..07185a4c2280c702edbd3c2b170ffd91263436e1 100644
--- a/docs/man/man1/helm_package.1
+++ b/docs/man/man1/helm_package.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -63,7 +63,7 @@ Versioned chart archives are used by Helm package repositories.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -82,4 +82,4 @@ Versioned chart archives are used by Helm package repositories.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_plugin.1 b/docs/man/man1/helm_plugin.1
index 36bae074fb7962a286287843222096714c8eede6..7af4f39fcb90160bf59d03f4482754022e7df9ce 100644
--- a/docs/man/man1/helm_plugin.1
+++ b/docs/man/man1/helm_plugin.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -28,7 +28,7 @@ Manage client\-side Helm plugins.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -42,9 +42,9 @@ Manage client\-side Helm plugins.
 
 .SH SEE ALSO
 .PP
-\fBhelm(1)\fP, \fBhelm\-plugin\-install(1)\fP, \fBhelm\-plugin\-list(1)\fP, \fBhelm\-plugin\-remove(1)\fP
+\fBhelm(1)\fP, \fBhelm\-plugin\-install(1)\fP, \fBhelm\-plugin\-list(1)\fP, \fBhelm\-plugin\-remove(1)\fP, \fBhelm\-plugin\-update(1)\fP
 
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_plugin_install.1 b/docs/man/man1/helm_plugin_install.1
index fc4378048402256eda278cf74ca1d361bbd32291..d2a8d132602f95edd7f58a905974e4fedf6eba73 100644
--- a/docs/man/man1/helm_plugin_install.1
+++ b/docs/man/man1/helm_plugin_install.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -34,7 +34,7 @@ install one or more Helm plugins
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -53,4 +53,4 @@ install one or more Helm plugins
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_plugin_list.1 b/docs/man/man1/helm_plugin_list.1
index 0db846a2c679721523185c3e2ff4ce66064f7e6e..5fcebd748b1e0e8261c8110b307c91c3c696bd21 100644
--- a/docs/man/man1/helm_plugin_list.1
+++ b/docs/man/man1/helm_plugin_list.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -28,7 +28,7 @@ list installed Helm plugins
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -47,4 +47,4 @@ list installed Helm plugins
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_plugin_remove.1 b/docs/man/man1/helm_plugin_remove.1
index 9d3a20057539fc638bdb5177ea222e7a87af7f07..de64220ddaa39b50d580f1a5208e3d86862874d0 100644
--- a/docs/man/man1/helm_plugin_remove.1
+++ b/docs/man/man1/helm_plugin_remove.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -28,7 +28,7 @@ remove one or more Helm plugins
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -47,4 +47,4 @@ remove one or more Helm plugins
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_plugin_update.1 b/docs/man/man1/helm_plugin_update.1
new file mode 100644
index 0000000000000000000000000000000000000000..ad7d70a174de9c5a15c50a31ef4a63c0331b4056
--- /dev/null
+++ b/docs/man/man1/helm_plugin_update.1
@@ -0,0 +1,50 @@
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
+.nh
+.ad l
+
+
+.SH NAME
+.PP
+helm\-plugin\-update \- update one or more Helm plugins
+
+
+.SH SYNOPSIS
+.PP
+\fBhelm plugin update <plugin>\&...\fP
+
+
+.SH DESCRIPTION
+.PP
+update one or more Helm plugins
+
+
+.SH OPTIONS INHERITED FROM PARENT COMMANDS
+.PP
+\fB\-\-debug\fP[=false]
+    enable verbose output
+
+.PP
+\fB\-\-home\fP="~/.helm"
+    location of your Helm config. Overrides $HELM\_HOME
+
+.PP
+\fB\-\-host\fP="localhost:44134"
+    address of tiller. Overrides $HELM\_HOST
+
+.PP
+\fB\-\-kube\-context\fP=""
+    name of the kubeconfig context to use
+
+.PP
+\fB\-\-tiller\-namespace\fP="kube\-system"
+    namespace of tiller
+
+
+.SH SEE ALSO
+.PP
+\fBhelm\-plugin(1)\fP
+
+
+.SH HISTORY
+.PP
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_repo.1 b/docs/man/man1/helm_repo.1
index e073dabcf85bedf03ff3c5cfd8b379136267124f..19b2da8a3db8ec2410b7660007bd67ecb69cc6a9 100644
--- a/docs/man/man1/helm_repo.1
+++ b/docs/man/man1/helm_repo.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -33,7 +33,7 @@ Example usage:
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -52,4 +52,4 @@ Example usage:
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_repo_add.1 b/docs/man/man1/helm_repo_add.1
index 19e2606acf54ce85782c01a865fd05085a5b8891..3cd9f790b89ece3b16f1a3436a6ffe5dc1563d88 100644
--- a/docs/man/man1/helm_repo_add.1
+++ b/docs/man/man1/helm_repo_add.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -46,7 +46,7 @@ add a chart repository
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -65,4 +65,4 @@ add a chart repository
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_repo_index.1 b/docs/man/man1/helm_repo_index.1
index 260fa97f38ab8eb8936c15fded172eddf710ba49..edfcda6f55f29ad5b0eca4a7c9e2d254f77cd37f 100644
--- a/docs/man/man1/helm_repo_index.1
+++ b/docs/man/man1/helm_repo_index.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -47,7 +47,7 @@ into the existing index, with local charts taking priority over existing charts.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -66,4 +66,4 @@ into the existing index, with local charts taking priority over existing charts.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_repo_list.1 b/docs/man/man1/helm_repo_list.1
index 33a97d8168fe5f435e9839457413c8e417d95ddb..7623f73fe6174b86202bcee7abbfcf85734b63bd 100644
--- a/docs/man/man1/helm_repo_list.1
+++ b/docs/man/man1/helm_repo_list.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -28,7 +28,7 @@ list chart repositories
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -47,4 +47,4 @@ list chart repositories
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_repo_remove.1 b/docs/man/man1/helm_repo_remove.1
index b6d48a50d4b73026832f4f1a7ab510378e82970c..cfbf217a4486292c0563123d76c73c1a8c661b5f 100644
--- a/docs/man/man1/helm_repo_remove.1
+++ b/docs/man/man1/helm_repo_remove.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -28,7 +28,7 @@ remove a chart repository
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -47,4 +47,4 @@ remove a chart repository
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_repo_update.1 b/docs/man/man1/helm_repo_update.1
index 1a46691e975147a052ada8453f2b74ae2d21d907..42bf511dd1aa1b1f9f1c304214de5e39b9b50f11 100644
--- a/docs/man/man1/helm_repo_update.1
+++ b/docs/man/man1/helm_repo_update.1
@@ -1,11 +1,11 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
 
 .SH NAME
 .PP
-helm\-repo\-update \- update information on available charts in the chart repositories
+helm\-repo\-update \- update information of available charts locally from chart repositories
 
 
 .SH SYNOPSIS
@@ -33,7 +33,7 @@ future releases.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -52,4 +52,4 @@ future releases.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_reset.1 b/docs/man/man1/helm_reset.1
index 6d600d1d2436f9a041300f5cc8f122f5f49f5b48..bf735591d263195bfbda12f66480dc587d930354 100644
--- a/docs/man/man1/helm_reset.1
+++ b/docs/man/man1/helm_reset.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -60,7 +60,7 @@ $HELM\_HOME (default \~/.helm/)
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -79,4 +79,4 @@ $HELM\_HOME (default \~/.helm/)
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_rollback.1 b/docs/man/man1/helm_rollback.1
index 909573969cf9cf92a3642a2a703c200f2fbe4edc..d91ab881d80d72a12dddb22f1355fca118b7d2e9 100644
--- a/docs/man/man1/helm_rollback.1
+++ b/docs/man/man1/helm_rollback.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -28,6 +28,10 @@ second is a revision (version) number. To see revision numbers, run
 \fB\-\-dry\-run\fP[=false]
     simulate a rollback
 
+.PP
+\fB\-\-force\fP[=false]
+    force resource update through delete/recreate if needed
+
 .PP
 \fB\-\-no\-hooks\fP[=false]
     prevent hooks from running during rollback
@@ -75,7 +79,7 @@ second is a revision (version) number. To see revision numbers, run
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -94,4 +98,4 @@ second is a revision (version) number. To see revision numbers, run
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_search.1 b/docs/man/man1/helm_search.1
index 7afc38a1216373c691f326d38a09d008f260fac0..ac2467bf25f03664d425ed093214b3bbb90b8ac6 100644
--- a/docs/man/man1/helm_search.1
+++ b/docs/man/man1/helm_search.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -46,7 +46,7 @@ Repositories are managed with 'helm repo' commands.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -65,4 +65,4 @@ Repositories are managed with 'helm repo' commands.
 
 .SH HISTORY
 .PP
-18\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_serve.1 b/docs/man/man1/helm_serve.1
index a01385ac286979b81aeb67175922debe76ae2086..a4a9c51da79aee0634aefb56f130d617b8d3c348 100644
--- a/docs/man/man1/helm_serve.1
+++ b/docs/man/man1/helm_serve.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -39,7 +39,7 @@ for more information on hosting chart repositories in a production setting.
     address to listen on
 
 .PP
-\fB\-\-repo\-path\fP="~/.helm/repository/local"
+\fB\-\-repo\-path\fP=""
     local directory path from which to serve charts
 
 .PP
@@ -57,7 +57,7 @@ for more information on hosting chart repositories in a production setting.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -76,4 +76,4 @@ for more information on hosting chart repositories in a production setting.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_status.1 b/docs/man/man1/helm_status.1
index 380ef03a818c30769aca122d9e8db4d0db7a22e2..8f23668089eb0a64cffa17bb3ed657a24de97222 100644
--- a/docs/man/man1/helm_status.1
+++ b/docs/man/man1/helm_status.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -61,7 +61,7 @@ The status consists of:
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -80,4 +80,4 @@ The status consists of:
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_test.1 b/docs/man/man1/helm_test.1
index 5936f81eeb57e84209f3003e8af8c0b2138e5ae1..6da36b33b58c9dc9200fcabf962927a5ab577c35 100644
--- a/docs/man/man1/helm_test.1
+++ b/docs/man/man1/helm_test.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -62,7 +62,7 @@ The tests to be run are defined in the chart that was installed.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -81,4 +81,4 @@ The tests to be run are defined in the chart that was installed.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_upgrade.1 b/docs/man/man1/helm_upgrade.1
index 0190285b618dc181fb71b11ab5a3eebcd37dff15..5d5e919f65838c9c04e5d664b3ef33ba68623ba1 100644
--- a/docs/man/man1/helm_upgrade.1
+++ b/docs/man/man1/helm_upgrade.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -57,14 +57,34 @@ $ helm upgrade \-\-set foo=bar \-\-set foo=newbar redis ./redis
 
 
 .SH OPTIONS
+.PP
+\fB\-\-ca\-file\fP=""
+    verify certificates of HTTPS\-enabled servers using this CA bundle
+
+.PP
+\fB\-\-cert\-file\fP=""
+    identify HTTPS client using this SSL certificate file
+
+.PP
+\fB\-\-devel\fP[=false]
+    use development versions, too. Equivalent to version '>0.0.0\-a'. If \-\-version is set, this is ignored.
+
 .PP
 \fB\-\-dry\-run\fP[=false]
     simulate an upgrade
 
+.PP
+\fB\-\-force\fP[=false]
+    force resource update through delete/recreate if needed
+
 .PP
 \fB\-i\fP, \fB\-\-install\fP[=false]
     if a release by this name doesn't already exist, run an install
 
+.PP
+\fB\-\-key\-file\fP=""
+    identify HTTPS client using this SSL key file
+
 .PP
 \fB\-\-keyring\fP="~/.gnupg/pubring.gpg"
     path to the keyring that contains public signing keys
@@ -81,6 +101,10 @@ $ helm upgrade \-\-set foo=bar \-\-set foo=newbar redis ./redis
 \fB\-\-recreate\-pods\fP[=false]
     performs pods restart for the resource if applicable
 
+.PP
+\fB\-\-repo\fP=""
+    chart repository url where to locate the requested chart
+
 .PP
 \fB\-\-reset\-values\fP[=false]
     when upgrading, reset the values to the ones built into the chart
@@ -144,7 +168,7 @@ $ helm upgrade \-\-set foo=bar \-\-set foo=newbar redis ./redis
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -163,4 +187,4 @@ $ helm upgrade \-\-set foo=bar \-\-set foo=newbar redis ./redis
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_verify.1 b/docs/man/man1/helm_verify.1
index dcd18e7fda1ccb04258ae87749e90018c5c89f86..5297924ae8658a1ad8a0b01210e5ada649c89279 100644
--- a/docs/man/man1/helm_verify.1
+++ b/docs/man/man1/helm_verify.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -43,7 +43,7 @@ the 'helm package \-\-sign' command.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -62,4 +62,4 @@ the 'helm package \-\-sign' command.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/man/man1/helm_version.1 b/docs/man/man1/helm_version.1
index f97acf6da374908429d0500a6b7ef8ccb931f2db..1f1bf600d0917cb999dc1ae8f427dfa45c939312 100644
--- a/docs/man/man1/helm_version.1
+++ b/docs/man/man1/helm_version.1
@@ -1,4 +1,4 @@
-.TH "HELM" "1" "Apr 2017" "Auto generated by spf13/cobra" "" 
+.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" 
 .nh
 .ad l
 
@@ -81,7 +81,7 @@ use '\-\-server'.
     location of your Helm config. Overrides $HELM\_HOME
 
 .PP
-\fB\-\-host\fP=""
+\fB\-\-host\fP="localhost:44134"
     address of tiller. Overrides $HELM\_HOST
 
 .PP
@@ -100,4 +100,4 @@ use '\-\-server'.
 
 .SH HISTORY
 .PP
-16\-Apr\-2017 Auto generated by spf13/cobra
+19\-May\-2017 Auto generated by spf13/cobra
diff --git a/docs/related.md b/docs/related.md
index e471c653b790be77ec9331fb5911e7da12d93903..4787bc7cd24c96cf915fbfe7b2ba1019f4b6d858 100644
--- a/docs/related.md
+++ b/docs/related.md
@@ -34,6 +34,7 @@ or [pull request](https://github.com/kubernetes/helm/pulls).
 - [helm-last](https://github.com/adamreese/helm-last) - Plugin to show the latest release
 - [helm-nuke](https://github.com/adamreese/helm-nuke) - Plugin to destroy all releases
 - [App Registry](https://github.com/app-registry/helm-plugin) - Plugin to manage charts via the [App Registry specification](https://github.com/app-registry/spec)
+- [helm-secrets](https://github.com/futuresimple/helm-secrets) - Plugin to manage and store secrets safely
 
 We also encourage GitHub authors to use the [helm-plugin](https://github.com/search?q=topic%3Ahelm-plugin&type=Repositories)
 tag on their plugin repositories.
@@ -53,11 +54,13 @@ Tools layered on top of Helm or Tiller.
 - [Cog](https://github.com/ohaiwalt/cog-helm) - Helm chart to deploy Cog on Kubernetes
 - [Monocular](https://github.com/helm/monocular) - Web UI for Helm Chart repositories
 - [Helm Chart Publisher](https://github.com/luizbafilho/helm-chart-publisher) - HTTP API for publishing Helm Charts in an easy way
+- [Armada](https://github.com/att-comdev/armada) - Manage prefixed releases throughout various Kubernetes namespaces, and removes completed jobs for complex deployments. Used by the [Openstack-Helm](https://github.com/openstack/openstack-helm) team.
 
 ## Helm Included
 
 Platforms, distributions, and services that include Helm support.
 
+- [Kubernetic](https://kubernetic.com/) - Kubernetes Desktop Client
 - [Cabin](http://www.skippbox.com/cabin/) - Mobile App for Managing Kubernetes
 - [Qstack](https://qstack.com)
 - [Fabric8](https://fabric8.io) - Integrated development platform for Kubernetes
diff --git a/docs/using_helm.md b/docs/using_helm.md
index 00793e8e523aee677fc4a692f620c2bffa3588eb..e6b1b2b6592c8d249872a1e9b2c7f1482227268d 100755
--- a/docs/using_helm.md
+++ b/docs/using_helm.md
@@ -215,12 +215,13 @@ You can then override any of these settings in a YAML formatted file,
 and then pass that file during installation.
 
 ```console
-$ echo 'mariadbUser: user0` > config.yaml
+$ echo '{mariadbUser: user0, mariadbDatabase: user0db}' > config.yaml
 $ helm install -f config.yaml stable/mariadb
 ```
 
-The above will set the default MariaDB user to `user0`, but accept all
-the rest of the defaults for that chart.
+The above will create a default MariaDB user with the name `user0`, and
+grant this user access to a newly created `user0db` database, but will
+accept all the rest of the defaults for that chart.
 
 There are two ways to pass configuration data during install:
 
@@ -355,7 +356,7 @@ is not a full list of cli flags. To see a description of all flags, just run
   This defaults to 300 (5 minutes)
 - `--wait`: Waits until all Pods are in a ready state, PVCs are bound, Deployments
   have minimum (`Desired` minus `maxUnavailable`) Pods in ready state and
-  Services have and IP address (and Ingress if a `LoadBalancer`) before 
+  Services have an IP address (and Ingress if a `LoadBalancer`) before 
   marking the release as successful. It will wait for as long as the 
   `--timeout` value. If timeout is reached, the release will be marked as 
   `FAILED`.
@@ -473,6 +474,15 @@ Note: The `stable` repository is managed on the [Kubernetes Charts
 GitHub repository](https://github.com/kubernetes/charts). That project
 accepts chart source code, and (after audit) packages those for you.
 
+## Tiller, Namespaces and RBAC
+In some cases you may wish to scope Tiller or deploy multiple Tillers to a single cluster. Here are some best practices when operating in those circumstances.
+
+1. Tiller can be [installed](install.md) into any namespace. By default, it is installed into kube-system. You can run multiple Tillers provided they each run in their own namespace.
+2. Limiting Tiller to only be able to install into specific namespaces and/or resource types is controlled by Kubernetes [RBAC](https://kubernetes.io/docs/admin/authorization/rbac/) roles and rolebindings.
+3. Release names are unique PER TILLER INSTANCE.
+4. Charts should only contain resources that exist in a single namespace.
+5. It is not recommended to have multiple Tillers configured to manage resources in the same namespace.
+
 ## Conclusion
 
 This chapter has covered the basic usage patterns of the `helm` client,
diff --git a/glide.lock b/glide.lock
index 3524e3dcd75a72aae5e217b72a972c3920820dc8..efefa3de1b538bab4e482f2b223222c5c89a7d3c 100644
--- a/glide.lock
+++ b/glide.lock
@@ -1,5 +1,5 @@
-hash: e9366bddb36a7120a832959c89f72f75d56b9f10f84820420795c668d9cb0987
-updated: 2017-04-27T14:23:27.66000871-06:00
+hash: f705b8873fe2e7fb0cf436e2485edf218f558ae726015e6d59490d53464ae536
+updated: 2017-05-17T12:47:01.838888143-06:00
 imports:
 - name: bitbucket.org/ww/goautoneg
   version: 75cd24fc2f2c2a2088577d12123ddee5f54e0675
@@ -20,6 +20,8 @@ imports:
   version: 3ac7bf7a47d159a033b107610db8a1b6575507a4
   subpackages:
   - quantile
+- name: github.com/BurntSushi/toml
+  version: b26d9c308763d68093482582cea63d69be07a0f0
 - name: github.com/chai2010/gettext-go
   version: bf70f2a70fb1b1f36d90d671a72795984eab0fcb
 - name: github.com/coreos/go-oidc
@@ -47,7 +49,7 @@ imports:
 - name: github.com/dgrijalva/jwt-go
   version: 01aeca54ebda6e0fbfafd0a524d234159c05ec20
 - name: github.com/docker/distribution
-  version: cd27f179f2c10c5d300e6d09025b538c475b0d51
+  version: 03efb43768979f4d2ea5187bef995656441829e5
   subpackages:
   - digest
   - reference
@@ -100,6 +102,8 @@ imports:
   version: ba18e35c5c1b36ef6334cad706eb681153d2d379
 - name: github.com/exponent-io/jsonpath
   version: d6023ce2651d8eafb5c75bb0c7167536102ec9f5
+- name: github.com/facebookgo/atomicfile
+  version: 2de1f203e7d5e386a6833233882782932729f27e
 - name: github.com/facebookgo/symwalk
   version: 42004b9f322246749dd73ad71008b1f3160c0052
 - name: github.com/ghodss/yaml
@@ -150,6 +154,8 @@ imports:
   version: 34abd90a014618f61222a1b0a7b7eb834a2d0dc3
 - name: github.com/howeyc/gopass
   version: 3ca23474a7c7203e0a0a070fd33508f6efdb9b3d
+- name: github.com/huandu/xstrings
+  version: 3959339b333561bf62a38b424fd41517c2c90f40
 - name: github.com/imdario/mergo
   version: 6633656539c1639d9d78127b7d47c622b5d7b6dc
 - name: github.com/inconshreveable/mousetrap
@@ -167,9 +173,9 @@ imports:
 - name: github.com/Masterminds/semver
   version: 3f0ab6d4ab4bed1c61caf056b63a6e62190c7801
 - name: github.com/Masterminds/sprig
-  version: 23597e5f6ad0e4d590e71314bfd0251a4a3cf849
+  version: 9526be0327b26ad31aa70296a7b10704883976d5
 - name: github.com/Masterminds/vcs
-  version: 795e20f901c3d561de52811fb3488a2cb2c8588b
+  version: 3084677c2c188840777bff30054f2b553729d329
 - name: github.com/mattn/go-runewidth
   version: d6bea18f789704b5f83375793155289da36a3c7f
 - name: github.com/matttproud/golang_protobuf_extensions
@@ -180,10 +186,6 @@ imports:
   version: ad45545899c7b13c020ea92b2072220eefad42b8
 - name: github.com/naoina/go-stringutil
   version: 6b638e95a32d0c1131db0e7fe83775cbea4a0d0b
-- name: github.com/naoina/toml
-  version: 751171607256bb66e64c9f0220c00662420c38e9
-  subpackages:
-  - ast
 - name: github.com/pborman/uuid
   version: ca53cad383cad2479bbba7f7a1a05797ec1386e4
 - name: github.com/prometheus/client_golang
@@ -471,7 +473,7 @@ imports:
   - util/integer
   - util/jsonpath
 - name: k8s.io/kubernetes
-  version: 477efc3cbe6a7effca06bd1452fa356e2201e1ee
+  version: 0480917b552be33e2dba47386e51decb1a211df6
   subpackages:
   - federation/apis/federation
   - federation/apis/federation/install
@@ -623,6 +625,8 @@ imports:
   - pkg/watch/json
 - name: vbom.ml/util
   version: db5cfe13f5cc80a4990d98e2e1b0707a4d1a5394
+  repo: https://github.com/fvbommel/util.git
+  vcs: git
   subpackages:
   - sortorder
 testImports:
diff --git a/glide.yaml b/glide.yaml
index 62a0b58bd38ab90b6523cb5a070b667a88142c89..7b298a29e89d53e65c344748f544a3caf741dd0f 100644
--- a/glide.yaml
+++ b/glide.yaml
@@ -10,8 +10,12 @@ import:
   version: 9ff6c6923cfffbcd502984b8e0c80539a94968b7
 - package: github.com/Masterminds/vcs
   version: ~1.11.0
+
+  # Pin version of mergo that is compatible with both sprig and Kubernetes
+- package: github.com/imdario/mergo
+  version: 6633656539c1639d9d78127b7d47c622b5d7b6dc
 - package: github.com/Masterminds/sprig
-  version: ^2.10
+  version: ^2.12
 - package: github.com/ghodss/yaml
 - package: github.com/Masterminds/semver
   version: ~1.2.3
@@ -37,14 +41,20 @@ import:
 - package: github.com/gobwas/glob
   version: ^0.2.1
 - package: github.com/evanphx/json-patch
+- package: github.com/facebookgo/atomicfile
 - package: github.com/facebookgo/symwalk
-- package: github.com/naoina/toml
-  version: ~0.1.0
+- package: github.com/BurntSushi/toml
+  version: ~0.3.0
 - package: github.com/naoina/go-stringutil
   version: ~0.1.0
 - package: github.com/chai2010/gettext-go
 - package: github.com/prometheus/client_golang
   version: v0.8.0
+- package: vbom.ml/util
+  repo: https://github.com/fvbommel/util.git
+  vcs: git
+- package: github.com/docker/distribution
+  version: ~v2.4.0
 testImports:
 - package: github.com/stretchr/testify
   version: ^1.1.4
diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go
index 9db26ff83e5f66225263772acd2a1c4a9d04c6dd..8ab05e896833ea80369e5970ecdfbc28007d532a 100644
--- a/pkg/chartutil/create.go
+++ b/pkg/chartutil/create.go
@@ -195,7 +195,7 @@ const defaultNotes = `1. Get the application URL by running these commands:
 {{- else if contains "NodePort" .Values.service.type }}
   export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "fullname" . }})
   export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
-  echo http://$NODE_IP:$NODE_PORT/login
+  echo http://$NODE_IP:$NODE_PORT
 {{- else if contains "LoadBalancer" .Values.service.type }}
      NOTE: It may take a few minutes for the LoadBalancer IP to be available.
            You can watch the status of by running 'kubectl get svc -w {{ template "fullname" . }}'
diff --git a/pkg/chartutil/files.go b/pkg/chartutil/files.go
index 6d6f17ef5c6b3cc0063bd43a51482acb33de7bde..470ed711e861f339ca79f8a2a50a2e426bf0febb 100644
--- a/pkg/chartutil/files.go
+++ b/pkg/chartutil/files.go
@@ -16,16 +16,17 @@ limitations under the License.
 package chartutil
 
 import (
+	"bytes"
 	"encoding/base64"
 	"encoding/json"
 	"path"
 	"strings"
 
-	yaml "gopkg.in/yaml.v2"
+	"github.com/ghodss/yaml"
 
+	"github.com/BurntSushi/toml"
 	"github.com/gobwas/glob"
 	"github.com/golang/protobuf/ptypes/any"
-	"github.com/naoina/toml"
 )
 
 // Files is a map of files in a chart that can be accessed from a template.
@@ -197,12 +198,13 @@ func FromYaml(str string) map[string]interface{} {
 //
 // This is designed to be called from a template.
 func ToToml(v interface{}) string {
-	data, err := toml.Marshal(v)
+	b := bytes.NewBuffer(nil)
+	e := toml.NewEncoder(b)
+	err := e.Encode(v)
 	if err != nil {
-		// Swallow errors inside of a template.
-		return ""
+		return err.Error()
 	}
-	return string(data)
+	return b.String()
 }
 
 // ToJson takes an interface, marshals it to json, and returns a string. It will
diff --git a/pkg/chartutil/files_test.go b/pkg/chartutil/files_test.go
index e87fb718737f975f1b710554a4caadb627062cba..731c82e6f50d4e9a1eac344980f6874a71ff660c 100644
--- a/pkg/chartutil/files_test.go
+++ b/pkg/chartutil/files_test.go
@@ -112,9 +112,9 @@ func TestToYaml(t *testing.T) {
 }
 
 func TestToToml(t *testing.T) {
-	expect := "foo=\"bar\"\n"
+	expect := "foo = \"bar\"\n"
 	v := struct {
-		Foo string `json:"foo"`
+		Foo string `toml:"foo"`
 	}{
 		Foo: "bar",
 	}
@@ -122,6 +122,18 @@ func TestToToml(t *testing.T) {
 	if got := ToToml(v); got != expect {
 		t.Errorf("Expected %q, got %q", expect, got)
 	}
+
+	// Regression for https://github.com/kubernetes/helm/issues/2271
+	dict := map[string]map[string]string{
+		"mast": {
+			"sail": "white",
+		},
+	}
+	got := ToToml(dict)
+	expect = "[mast]\n  sail = \"white\"\n"
+	if got != expect {
+		t.Errorf("Expected:\n%s\nGot\n%s\n", expect, got)
+	}
 }
 
 func TestFromYaml(t *testing.T) {
diff --git a/pkg/chartutil/requirements.go b/pkg/chartutil/requirements.go
index 5f9fa3b3de688a84d965bc2d4f3e3e50541243b8..fbd686b9102ce1f8980b2f8795098f778f5fd3ae 100644
--- a/pkg/chartutil/requirements.go
+++ b/pkg/chartutil/requirements.go
@@ -65,6 +65,8 @@ type Dependency struct {
 	// ImportValues holds the mapping of source values to parent key to be imported. Each item can be a
 	// string or pair of child/parent sublist items.
 	ImportValues []interface{} `json:"import-values"`
+	// Alias usable alias to be used for the chart
+	Alias string `json:"alias"`
 }
 
 // ErrNoRequirementsFile to detect error condition
@@ -216,6 +218,32 @@ func ProcessRequirementsTags(reqs *Requirements, cvals Values) {
 
 }
 
+func getAliasDependency(charts []*chart.Chart, aliasChart *Dependency) *chart.Chart {
+	var chartFound chart.Chart
+	for _, existingChart := range charts {
+		if existingChart == nil {
+			continue
+		}
+		if existingChart.Metadata == nil {
+			continue
+		}
+		if existingChart.Metadata.Name != aliasChart.Name {
+			continue
+		}
+		if existingChart.Metadata.Version != aliasChart.Version {
+			continue
+		}
+		chartFound = *existingChart
+		newMetadata := *existingChart.Metadata
+		if aliasChart.Alias != "" {
+			newMetadata.Name = aliasChart.Alias
+		}
+		chartFound.Metadata = &newMetadata
+		return &chartFound
+	}
+	return nil
+}
+
 // ProcessRequirementsEnabled removes disabled charts from dependencies
 func ProcessRequirementsEnabled(c *chart.Chart, v *chart.Config) error {
 	reqs, err := LoadRequirements(c)
@@ -228,6 +256,18 @@ func ProcessRequirementsEnabled(c *chart.Chart, v *chart.Config) error {
 		// no requirements to process
 		return nil
 	}
+
+	var chartDependencies []*chart.Chart
+	for _, req := range reqs.Dependencies {
+		if chartDependency := getAliasDependency(c.Dependencies, req); chartDependency != nil {
+			chartDependencies = append(chartDependencies, chartDependency)
+		}
+		if req.Alias != "" {
+			req.Name = req.Alias
+		}
+	}
+	c.Dependencies = chartDependencies
+
 	// set all to true
 	for _, lr := range reqs.Dependencies {
 		lr.Enabled = true
@@ -322,22 +362,17 @@ func getParents(c *chart.Chart, out []*chart.Chart) []*chart.Chart {
 }
 
 // processImportValues merges values from child to parent based on the chart's dependencies' ImportValues field.
-func processImportValues(c *chart.Chart, v *chart.Config) error {
+func processImportValues(c *chart.Chart) error {
 	reqs, err := LoadRequirements(c)
 	if err != nil {
 		return err
 	}
-	// combine chart values and its dependencies' values
-	cvals, err := CoalesceValues(c, v)
+	// combine chart values and empty config to get Values
+	cvals, err := CoalesceValues(c, &chart.Config{})
 	if err != nil {
 		return err
 	}
-	nv := v.GetValues()
-	b := make(map[string]interface{}, len(nv))
-	// convert values to map
-	for kk, vvv := range nv {
-		b[kk] = vvv
-	}
+	b := make(map[string]interface{}, 0)
 	// import values from each dependency if specified in import-values
 	for _, r := range reqs.Dependencies {
 		if len(r.ImportValues) > 0 {
@@ -392,10 +427,10 @@ func processImportValues(c *chart.Chart, v *chart.Config) error {
 }
 
 // ProcessRequirementsImportValues imports specified chart values from child to parent.
-func ProcessRequirementsImportValues(c *chart.Chart, v *chart.Config) error {
+func ProcessRequirementsImportValues(c *chart.Chart) error {
 	pc := getParents(c, nil)
 	for i := len(pc) - 1; i >= 0; i-- {
-		processImportValues(pc[i], v)
+		processImportValues(pc[i])
 	}
 
 	return nil
diff --git a/pkg/chartutil/requirements_test.go b/pkg/chartutil/requirements_test.go
index b5dbe35dc8261e7b11c2b6a73ccb9c8a44102864..65d59e52f285443bb8311448be54bfdf981ba7f3 100644
--- a/pkg/chartutil/requirements_test.go
+++ b/pkg/chartutil/requirements_test.go
@@ -282,7 +282,7 @@ func TestProcessRequirementsImportValues(t *testing.T) {
 }
 func verifyRequirementsImportValues(t *testing.T, c *chart.Chart, v *chart.Config, e map[string]string) {
 
-	err := ProcessRequirementsImportValues(c, v)
+	err := ProcessRequirementsImportValues(c)
 	if err != nil {
 		t.Errorf("Error processing import values requirements %v", err)
 	}
@@ -320,3 +320,73 @@ func verifyRequirementsImportValues(t *testing.T, c *chart.Chart, v *chart.Confi
 
 	}
 }
+
+func TestGetAliasDependency(t *testing.T) {
+	c, err := Load("testdata/frobnitz")
+	if err != nil {
+		t.Fatalf("Failed to load testdata: %s", err)
+	}
+	req, err := LoadRequirements(c)
+	if err != nil {
+		t.Fatalf("Failed to load requirement for testdata: %s", err)
+	}
+	if len(req.Dependencies) == 0 {
+		t.Fatalf("There are no requirements to test")
+	}
+
+	// Success case
+	aliasChart := getAliasDependency(c.Dependencies, req.Dependencies[0])
+	if aliasChart == nil {
+		t.Fatalf("Failed to get dependency chart for alias %s", req.Dependencies[0].Name)
+	}
+	if req.Dependencies[0].Alias != "" {
+		if aliasChart.Metadata.Name != req.Dependencies[0].Alias {
+			t.Fatalf("Dependency chart name should be %s but got %s", req.Dependencies[0].Alias, aliasChart.Metadata.Name)
+		}
+	} else if aliasChart.Metadata.Name != req.Dependencies[0].Name {
+		t.Fatalf("Dependency chart name should be %s but got %s", req.Dependencies[0].Name, aliasChart.Metadata.Name)
+	}
+
+	// Failure case
+	req.Dependencies[0].Name = "something-else"
+	if aliasChart := getAliasDependency(c.Dependencies, req.Dependencies[0]); aliasChart != nil {
+		t.Fatalf("expected no chart but got %s", aliasChart.Metadata.Name)
+	}
+}
+
+func TestDependentChartAliases(t *testing.T) {
+	c, err := Load("testdata/dependent-chart-alias")
+	if err != nil {
+		t.Fatalf("Failed to load testdata: %s", err)
+	}
+
+	if len(c.Dependencies) == 0 {
+		t.Fatal("There are no dependencies to run this test")
+	}
+
+	origLength := len(c.Dependencies)
+	if err := ProcessRequirementsEnabled(c, c.Values); err != nil {
+		t.Fatalf("Expected no errors but got %q", err)
+	}
+
+	if len(c.Dependencies) == origLength {
+		t.Fatal("Expected alias dependencies to be added, but did not got that")
+	}
+
+	reqmts, err := LoadRequirements(c)
+	if err != nil {
+		t.Fatalf("Cannot load requirements for test chart, %v", err)
+	}
+
+	// var expectedDependencyCharts int
+	// for _, reqmt := range reqmts.Dependencies {
+	// 	expectedDependencyCharts++
+	// 	if len(reqmt.Alias) >= 0 {
+	// 		expectedDependencyCharts += len(reqmt.Alias)
+	// 	}
+	// }
+	if len(c.Dependencies) != len(reqmts.Dependencies) {
+		t.Fatalf("Expected number of chart dependencies %d, but got %d", len(reqmts.Dependencies), len(c.Dependencies))
+	}
+
+}
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/.helmignore b/pkg/chartutil/testdata/dependent-chart-alias/.helmignore
new file mode 100644
index 0000000000000000000000000000000000000000..9973a57b8035d98658162558e488aa24f7d8fa15
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/.helmignore
@@ -0,0 +1 @@
+ignore/
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/Chart.yaml b/pkg/chartutil/testdata/dependent-chart-alias/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7c071c27b3b55bfa0af2fb852acd67d12363b8d3
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/Chart.yaml
@@ -0,0 +1,17 @@
+apiVersion: v1
+name: frobnitz
+description: This is a frobnitz.
+version: "1.2.3"
+keywords:
+  - frobnitz
+  - sprocket
+  - dodad
+maintainers:
+  - name: The Helm Team
+    email: helm@example.com
+  - name: Someone Else
+    email: nobody@example.com
+sources:
+  - https://example.com/foo/bar
+home: http://example.com
+icon: https://example.com/64x64.png
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/INSTALL.txt b/pkg/chartutil/testdata/dependent-chart-alias/INSTALL.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2010438c200050456edaa55cf626d158d671d02d
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/INSTALL.txt
@@ -0,0 +1 @@
+This is an install document. The client may display this.
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/LICENSE b/pkg/chartutil/testdata/dependent-chart-alias/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..6121943b10a68319b2c1f66e659b8a69a4df7ed0
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/LICENSE
@@ -0,0 +1 @@
+LICENSE placeholder.
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/README.md b/pkg/chartutil/testdata/dependent-chart-alias/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..8cf4cc3d7c0f1d3c418e7ba4eab1335b606f063d
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/README.md
@@ -0,0 +1,11 @@
+# Frobnitz
+
+This is an example chart.
+
+## Usage
+
+This is an example. It has no usage.
+
+## Development
+
+For developer info, see the top-level repository.
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/charts/_ignore_me b/pkg/chartutil/testdata/dependent-chart-alias/charts/_ignore_me
new file mode 100644
index 0000000000000000000000000000000000000000..2cecca6824919777f7a23269d19f8f0137e527f3
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/charts/_ignore_me
@@ -0,0 +1 @@
+This should be ignored by the loader, but may be included in a chart.
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/Chart.yaml b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..38a4aaa54c58e8f5cc77108df3ee8f895e9a388c
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/Chart.yaml
@@ -0,0 +1,4 @@
+name: alpine
+description: Deploy a basic Alpine Linux pod
+version: 0.1.0
+home: https://k8s.io/helm
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/README.md b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a7c84fc416caba955a2e10a5ddec21768130be54
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/README.md
@@ -0,0 +1,9 @@
+This example was generated using the command `helm create alpine`.
+
+The `templates/` directory contains a very simple pod resource with a
+couple of parameters.
+
+The `values.toml` file contains the default values for the
+`alpine-pod.yaml` template.
+
+You can install this example using `helm install docs/examples/alpine`.
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/charts/mast1/Chart.yaml b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/charts/mast1/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..171e361564676fc5d4bd77a52519557a1b8937f2
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/charts/mast1/Chart.yaml
@@ -0,0 +1,4 @@
+name: mast1
+description: A Helm chart for Kubernetes
+version: 0.1.0
+home: ""
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/charts/mast1/values.yaml b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/charts/mast1/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..42c39c262c314b9dd6992814944b894160a87ca4
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/charts/mast1/values.yaml
@@ -0,0 +1,4 @@
+# Default values for mast1.
+# This is a YAML-formatted file.
+# Declare name/value pairs to be passed into your templates.
+# name = "value"
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/charts/mast2-0.1.0.tgz b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/charts/mast2-0.1.0.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..ced5a4a6adf946f76033b6ee584affc12433cb78
Binary files /dev/null and b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/charts/mast2-0.1.0.tgz differ
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/templates/alpine-pod.yaml b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/templates/alpine-pod.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..08cf3c2c1f52c4e57475a4625506c22699a0ff59
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/templates/alpine-pod.yaml
@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: {{.Release.Name}}-{{.Chart.Name}}
+  labels:
+    heritage: {{.Release.Service}}
+    chartName: {{.Chart.Name}}
+    chartVersion: {{.Chart.Version | quote}}
+  annotations:
+    "helm.sh/created": "{{.Release.Time.Seconds}}"
+spec:
+  restartPolicy: {{default "Never" .restart_policy}}
+  containers:
+  - name: waiter
+    image: "alpine:3.3"
+    command: ["/bin/sleep","9000"]
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/values.yaml b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6c2aab7ba9df3f92832ce2844b001108f84013d0
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/charts/alpine/values.yaml
@@ -0,0 +1,2 @@
+# The pod name
+name: "my-alpine"
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/charts/mariner-4.3.2.tgz b/pkg/chartutil/testdata/dependent-chart-alias/charts/mariner-4.3.2.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..3af333e76a3c268ce6d23f5ae8ba59387a75a38a
Binary files /dev/null and b/pkg/chartutil/testdata/dependent-chart-alias/charts/mariner-4.3.2.tgz differ
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/docs/README.md b/pkg/chartutil/testdata/dependent-chart-alias/docs/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..d40747cafd28860f06babbf27e85d56203e53e35
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/docs/README.md
@@ -0,0 +1 @@
+This is a placeholder for documentation.
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/icon.svg b/pkg/chartutil/testdata/dependent-chart-alias/icon.svg
new file mode 100644
index 0000000000000000000000000000000000000000..8921306066db91867ee2fd152c83ce75785c7803
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/icon.svg
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
+    xmlns:xlink="http://www.w3.org/1999/xlink"
+    version="1.0" width="256" height="256" id="test">
+  <desc>Example icon</desc>
+  <rect id="first" x="2" y="2" width="40" height="60" fill="navy"/>
+  <rect id="second" x="15" y="4" width="40" height="60" fill="red"/>
+</svg>
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/ignore/me.txt b/pkg/chartutil/testdata/dependent-chart-alias/ignore/me.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/requirements.lock b/pkg/chartutil/testdata/dependent-chart-alias/requirements.lock
new file mode 100644
index 0000000000000000000000000000000000000000..6fcc2ed9fbeb693c4eb334d2fd572d0f6ac3a92f
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/requirements.lock
@@ -0,0 +1,8 @@
+dependencies:
+  - name: alpine
+    version: "0.1.0"
+    repository: https://example.com/charts
+  - name: mariner
+    version: "4.3.2"
+    repository: https://example.com/charts
+digest: invalid
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/requirements.yaml b/pkg/chartutil/testdata/dependent-chart-alias/requirements.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..aab6cddf7cbfc8165e4f8533ee52124347921bc5
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/requirements.yaml
@@ -0,0 +1,12 @@
+dependencies:
+  - name: alpine
+    version: "0.1.0"
+    repository: https://example.com/charts
+  - name: mariner
+    version: "4.3.2"
+    repository: https://example.com/charts
+    alias: mariners2
+  - name: mariner
+    version: "4.3.2"
+    repository: https://example.com/charts
+    alias: mariners1
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/templates/template.tpl b/pkg/chartutil/testdata/dependent-chart-alias/templates/template.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..c651ee6a03cc43f952aae1583ea967c622d55ddc
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/templates/template.tpl
@@ -0,0 +1 @@
+Hello {{.Name | default "world"}}
diff --git a/pkg/chartutil/testdata/dependent-chart-alias/values.yaml b/pkg/chartutil/testdata/dependent-chart-alias/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..61f501258835165a881de21520fe570295a53241
--- /dev/null
+++ b/pkg/chartutil/testdata/dependent-chart-alias/values.yaml
@@ -0,0 +1,6 @@
+# A values file contains configuration.
+
+name: "Some Name"
+
+section:
+  name: "Name in a section"
diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go
index 1a4c3a7a95dbc66f387835ae10007a9f1ee39ae2..15e97f6a16048e345c897eee5f5b8360805bcf76 100644
--- a/pkg/downloader/chart_downloader.go
+++ b/pkg/downloader/chart_downloader.go
@@ -66,7 +66,7 @@ type ChartDownloader struct {
 	// HelmHome is the $HELM_HOME.
 	HelmHome helmpath.Home
 	// Getter collection for the operation
-	Getters []getter.Prop
+	Getters getter.Providers
 }
 
 // DownloadTo retrieves a chart. Depending on the settings, it may also download a provenance file.
@@ -161,7 +161,7 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, ge
 			// If there is no special config, return the default HTTP client and
 			// swallow the error.
 			if err == ErrNoOwnerRepo {
-				getterConstructor, err := getter.ConstructorByScheme(c.Getters, u.Scheme)
+				getterConstructor, err := c.Getters.ByScheme(u.Scheme)
 				if err != nil {
 					return u, nil, err
 				}
@@ -202,7 +202,7 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, ge
 
 	cv, err := i.Get(chartName, version)
 	if err != nil {
-		return u, r.Client, fmt.Errorf("chart %q not found in %s index. (try 'helm repo update'). %s", chartName, r.Config.Name, err)
+		return u, r.Client, fmt.Errorf("chart %q matching %s not found in %s index. (try 'helm repo update'). %s", chartName, version, r.Config.Name, err)
 	}
 
 	if len(cv.URLs) == 0 {
@@ -215,6 +215,12 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, ge
 		return u, r.Client, fmt.Errorf("invalid chart URL format: %s", ref)
 	}
 
+	// If the URL is relative (no scheme), prepend the chart repo's base URL
+	if !u.IsAbs() {
+		u, err = url.Parse(rc.URL + "/" + u.Path)
+		return u, r.Client, err
+	}
+
 	return u, r.Client, nil
 }
 
diff --git a/pkg/downloader/chart_downloader_test.go b/pkg/downloader/chart_downloader_test.go
index 17a66145b42341858b14bffffb355503dba0a30b..4049b79798caffcf7a1f966b0bd83ff195741f9b 100644
--- a/pkg/downloader/chart_downloader_test.go
+++ b/pkg/downloader/chart_downloader_test.go
@@ -25,8 +25,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"k8s.io/helm/pkg/getter/defaultgetters"
-	"k8s.io/helm/pkg/getter/http"
+	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/helm/environment"
 	"k8s.io/helm/pkg/helm/helmpath"
 	"k8s.io/helm/pkg/repo"
@@ -43,6 +42,7 @@ func TestResolveChartRef(t *testing.T) {
 		{name: "full URL, with authentication", ref: "http://username:password@example.com/foo-1.2.3.tgz", expect: "http://username:password@example.com/foo-1.2.3.tgz"},
 		{name: "reference, testing repo", ref: "testing/alpine", expect: "http://example.com/alpine-1.2.3.tgz"},
 		{name: "reference, version, testing repo", ref: "testing/alpine", version: "0.2.0", expect: "http://example.com/alpine-0.2.0.tgz"},
+		{name: "reference, version, malformed repo", ref: "malformed/alpine", version: "1.2.3", expect: "http://dl.example.com/alpine-1.2.3.tgz"},
 		{name: "full URL, HTTPS, irrelevant version", ref: "https://example.com/foo-1.2.3.tgz", version: "0.1.0", expect: "https://example.com/foo-1.2.3.tgz", fail: true},
 		{name: "full URL, file", ref: "file:///foo-1.2.3.tgz", fail: true},
 		{name: "invalid", ref: "invalid-1.2.3", fail: true},
@@ -52,7 +52,7 @@ func TestResolveChartRef(t *testing.T) {
 	c := ChartDownloader{
 		HelmHome: helmpath.Home("testdata/helmhome"),
 		Out:      os.Stderr,
-		Getters:  defaultgetters.Get(environment.EnvSettings{}),
+		Getters:  getter.All(environment.EnvSettings{}),
 	}
 
 	for _, tt := range tests {
@@ -89,7 +89,12 @@ func TestDownload(t *testing.T) {
 	}))
 	defer srv.Close()
 
-	getter, err := httpgetter.New(srv.URL, "", "", "")
+	provider, err := getter.ByScheme("http", environment.EnvSettings{})
+	if err != nil {
+		t.Fatal("No http provider found")
+	}
+
+	getter, err := provider.New(srv.URL, "", "", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -182,7 +187,7 @@ func TestDownloadTo(t *testing.T) {
 		Out:      os.Stderr,
 		Verify:   VerifyAlways,
 		Keyring:  "testdata/helm-test-key.pub",
-		Getters:  defaultgetters.Get(environment.EnvSettings{}),
+		Getters:  getter.All(environment.EnvSettings{}),
 	}
 	cname := "/signtest-0.1.0.tgz"
 	where, v, err := c.DownloadTo(srv.URL()+cname, "", dest)
@@ -245,7 +250,7 @@ func TestDownloadTo_VerifyLater(t *testing.T) {
 		HelmHome: hh,
 		Out:      os.Stderr,
 		Verify:   VerifyLater,
-		Getters:  defaultgetters.Get(environment.EnvSettings{}),
+		Getters:  getter.All(environment.EnvSettings{}),
 	}
 	cname := "/signtest-0.1.0.tgz"
 	where, _, err := c.DownloadTo(srv.URL()+cname, "", dest)
@@ -274,7 +279,7 @@ func TestScanReposForURL(t *testing.T) {
 		HelmHome: hh,
 		Out:      os.Stderr,
 		Verify:   VerifyLater,
-		Getters:  defaultgetters.Get(environment.EnvSettings{}),
+		Getters:  getter.All(environment.EnvSettings{}),
 	}
 
 	u := "http://example.com/alpine-0.2.0.tgz"
diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go
index 4f881591a11a9c024efe44ee37dc7b301942cea7..aea489edf0c5532a4ec3343dba75403f325c005b 100644
--- a/pkg/downloader/manager.go
+++ b/pkg/downloader/manager.go
@@ -56,7 +56,7 @@ type Manager struct {
 	// SkipUpdate indicates that the repository should not be updated first.
 	SkipUpdate bool
 	// Getter collection for the operation
-	Getters []getter.Prop
+	Getters []getter.Provider
 }
 
 // Build rebuilds a local charts directory from a lockfile.
@@ -572,5 +572,5 @@ func tarFromLocalDir(chartpath string, name string, repo string, version string)
 		return ch.Metadata.Version, err
 	}
 
-	return "", fmt.Errorf("Can't get a valid version for dependency %s.", name)
+	return "", fmt.Errorf("can't get a valid version for dependency %s", name)
 }
diff --git a/pkg/downloader/testdata/helmhome/repository/cache/malformed-index.yaml b/pkg/downloader/testdata/helmhome/repository/cache/malformed-index.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1956e9f83493bd433ca1abdfbafe9d5906aafbb4
--- /dev/null
+++ b/pkg/downloader/testdata/helmhome/repository/cache/malformed-index.yaml
@@ -0,0 +1,16 @@
+apiVersion: v1
+entries:
+  alpine:
+    - name: alpine
+      urls:
+        - alpine-1.2.3.tgz
+      checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d
+      home: https://k8s.io/helm
+      sources:
+      - https://github.com/kubernetes/helm
+      version: 1.2.3
+      description: Deploy a basic Alpine Linux pod
+      keywords: []
+      maintainers: []
+      engine: ""
+      icon: ""
diff --git a/pkg/downloader/testdata/helmhome/repository/repositories.yaml b/pkg/downloader/testdata/helmhome/repository/repositories.yaml
index 200f370bdc06ea7b12ef65c6fa9d6fde3301abe0..9b0cfe9729bc0f33e318f90aa481f1fea90b9867 100644
--- a/pkg/downloader/testdata/helmhome/repository/repositories.yaml
+++ b/pkg/downloader/testdata/helmhome/repository/repositories.yaml
@@ -8,3 +8,5 @@ repositories:
     url: "http://username:password@example.com"
   - name: kubernetes-charts
     url: "http://example.com/charts"
+  - name: malformed
+    url: "http://dl.example.com"
diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go
index a987fb3b8aea9755920fe2ed77c279f8ddaa1fad..595ec2c19de3cbff5236976967b7f3c3ca531760 100644
--- a/pkg/engine/engine.go
+++ b/pkg/engine/engine.go
@@ -20,6 +20,7 @@ import (
 	"bytes"
 	"fmt"
 	"path"
+	"sort"
 	"strings"
 	"text/template"
 
@@ -143,12 +144,12 @@ func (e *Engine) alterFuncMap(t *template.Template) template.FuncMap {
 	}
 
 	// Add the 'include' function here so we can close over t.
-	funcMap["include"] = func(name string, data interface{}) string {
+	funcMap["include"] = func(name string, data interface{}) (string, error) {
 		buf := bytes.NewBuffer(nil)
 		if err := t.ExecuteTemplate(buf, name, data); err != nil {
-			buf.WriteString(err.Error())
+			return "", err
 		}
-		return buf.String()
+		return buf.String(), nil
 	}
 
 	// Add the 'required' function here
@@ -203,9 +204,14 @@ func (e *Engine) render(tpls map[string]renderable) (map[string]string, error) {
 
 	funcMap := e.alterFuncMap(t)
 
+	// We want to parse the templates in a predictable order. The order favors
+	// higher-level (in file system) templates over deeply nested templates.
+	keys := sortTemplates(tpls)
+
 	files := []string{}
 
-	for fname, r := range tpls {
+	for _, fname := range keys {
+		r := tpls[fname]
 		t = t.New(fname).Funcs(funcMap)
 		if _, err := t.Parse(r.tpl); err != nil {
 			return map[string]string{}, fmt.Errorf("parse error in %q: %s", fname, err)
@@ -227,6 +233,11 @@ func (e *Engine) render(tpls map[string]renderable) (map[string]string, error) {
 	rendered := make(map[string]string, len(files))
 	var buf bytes.Buffer
 	for _, file := range files {
+		// Don't render partials. We don't care out the direct output of partials.
+		// They are only included from other templates.
+		if strings.HasPrefix(path.Base(file), "_") {
+			continue
+		}
 		// At render time, add information about the template that is being rendered.
 		vals := tpls[file].vals
 		vals["Template"] = map[string]interface{}{"Name": file, "BasePath": tpls[file].basePath}
@@ -244,6 +255,30 @@ func (e *Engine) render(tpls map[string]renderable) (map[string]string, error) {
 	return rendered, nil
 }
 
+func sortTemplates(tpls map[string]renderable) []string {
+	keys := make([]string, len(tpls))
+	i := 0
+	for key := range tpls {
+		keys[i] = key
+		i++
+	}
+	sort.Sort(sort.Reverse(byPathLen(keys)))
+	return keys
+}
+
+type byPathLen []string
+
+func (p byPathLen) Len() int      { return len(p) }
+func (p byPathLen) Swap(i, j int) { p[j], p[i] = p[i], p[j] }
+func (p byPathLen) Less(i, j int) bool {
+	a, b := p[i], p[j]
+	ca, cb := strings.Count(a, "/"), strings.Count(b, "/")
+	if ca == cb {
+		return strings.Compare(a, b) == -1
+	}
+	return ca < cb
+}
+
 // allTemplates returns all templates for a chart and its dependencies.
 //
 // As it goes, it also prepares the values in a scope-sensitive manner.
diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go
index fcf9c1c64f305e962b83f1c8c08ceabceb2ab789..7da4a91037219ebf4de85e382dc4cdbbba3a0ea5 100644
--- a/pkg/engine/engine_test.go
+++ b/pkg/engine/engine_test.go
@@ -27,6 +27,37 @@ import (
 	"github.com/golang/protobuf/ptypes/any"
 )
 
+func TestSortTemplates(t *testing.T) {
+	tpls := map[string]renderable{
+		"/mychart/templates/foo.tpl":                                 {},
+		"/mychart/templates/charts/foo/charts/bar/templates/foo.tpl": {},
+		"/mychart/templates/bar.tpl":                                 {},
+		"/mychart/templates/charts/foo/templates/bar.tpl":            {},
+		"/mychart/templates/_foo.tpl":                                {},
+		"/mychart/templates/charts/foo/templates/foo.tpl":            {},
+		"/mychart/templates/charts/bar/templates/foo.tpl":            {},
+	}
+	got := sortTemplates(tpls)
+	if len(got) != len(tpls) {
+		t.Fatal("Sorted results are missing templates")
+	}
+
+	expect := []string{
+		"/mychart/templates/charts/foo/charts/bar/templates/foo.tpl",
+		"/mychart/templates/charts/foo/templates/foo.tpl",
+		"/mychart/templates/charts/foo/templates/bar.tpl",
+		"/mychart/templates/charts/bar/templates/foo.tpl",
+		"/mychart/templates/foo.tpl",
+		"/mychart/templates/bar.tpl",
+		"/mychart/templates/_foo.tpl",
+	}
+	for i, e := range expect {
+		if got[i] != e {
+			t.Errorf("expected %q, got %q at index %d\n\tExp: %#v\n\tGot: %#v", e, got[i], i, expect, got)
+		}
+	}
+}
+
 func TestEngine(t *testing.T) {
 	e := New()
 
diff --git a/pkg/getter/defaultgetters/default.go b/pkg/getter/defaultgetters/default.go
deleted file mode 100644
index 8e5f0c862648cbfad4329a6bde55b4294ca96ac8..0000000000000000000000000000000000000000
--- a/pkg/getter/defaultgetters/default.go
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-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 defaultgetters
-
-import (
-	"os"
-
-	"k8s.io/helm/pkg/getter"
-	"k8s.io/helm/pkg/getter/http"
-	"k8s.io/helm/pkg/getter/plugin"
-	"k8s.io/helm/pkg/helm/environment"
-	"k8s.io/helm/pkg/helm/helmpath"
-	"k8s.io/helm/pkg/plugin"
-)
-
-// Get gathers the getter constructors for the downloaders.
-// Currently the build-in http getter and the discovered
-// plugins with downloader notations are collected.
-func Get(settings environment.EnvSettings) []getter.Prop {
-	result := []getter.Prop{
-		{
-			Schemes:     getter.Schemes{"http", "https"},
-			Constructor: httpgetter.New,
-		},
-	}
-	pluginDownloaders, _ := collectPlugins(settings)
-	result = append(result, pluginDownloaders...)
-	return result
-}
-
-func collectPlugins(settings environment.EnvSettings) ([]getter.Prop, error) {
-	plugdirs := os.Getenv(environment.PluginEnvVar)
-	if plugdirs == "" {
-		home := helmpath.Home(os.Getenv(environment.HomeEnvVar))
-		plugdirs = home.Plugins()
-	}
-
-	plugins, err := plugin.FindPlugins(plugdirs)
-	if err != nil {
-		return nil, err
-	}
-	var result []getter.Prop
-	for _, plugin := range plugins {
-		for _, downloader := range plugin.Metadata.Downloaders {
-			result = append(result, getter.Prop{
-				Schemes: downloader.Protocols,
-				Constructor: plugingetter.ConstructNew(
-					downloader.Command,
-					settings,
-					plugin.Metadata.Name,
-					plugin.Dir,
-				),
-			})
-		}
-	}
-	return result, nil
-}
diff --git a/pkg/getter/doc.go b/pkg/getter/doc.go
new file mode 100644
index 0000000000000000000000000000000000000000..fe51e49670ab95a5656cee8209c88705f8e6f612
--- /dev/null
+++ b/pkg/getter/doc.go
@@ -0,0 +1,21 @@
+/*
+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 getter provides a generalize tool for fetching data by scheme.
+
+This provides a method by which the plugin system can load arbitrary protocol
+handlers based upon a URL scheme.
+*/
+package getter
diff --git a/pkg/getter/getter.go b/pkg/getter/getter.go
index c8b131f31f51f5c125c1a71492951c285efb45c0..ca018884a01841908f20c811a12b32eeb13c7179 100644
--- a/pkg/getter/getter.go
+++ b/pkg/getter/getter.go
@@ -19,6 +19,8 @@ package getter
 import (
 	"bytes"
 	"fmt"
+
+	"k8s.io/helm/pkg/helm/environment"
 )
 
 // Getter is an interface to support GET to the specified URL.
@@ -27,27 +29,70 @@ type Getter interface {
 	Get(url string) (*bytes.Buffer, error)
 }
 
-//Schemes is the list to represent a specific Getter's protocol capabilities
-type Schemes []string
-
-//Constructor is the function for every getter which creates a specific instance
-//according to the configuration
+// Constructor is the function for every getter which creates a specific instance
+// according to the configuration
 type Constructor func(URL, CertFile, KeyFile, CAFile string) (Getter, error)
 
-//Prop represents any getter and its capability
-type Prop struct {
-	Schemes     Schemes
-	Constructor Constructor
+// Provider represents any getter and the schemes that it supports.
+//
+// For example, an HTTP provider may provide one getter that handles both
+// 'http' and 'https' schemes.
+type Provider struct {
+	Schemes []string
+	New     Constructor
+}
+
+// Provides returns true if the given scheme is supported by this Provider.
+func (p Provider) Provides(scheme string) bool {
+	for _, i := range p.Schemes {
+		if i == scheme {
+			return true
+		}
+	}
+	return false
+}
+
+// Providers is a collection of Provider objects.
+type Providers []Provider
+
+// ByScheme returns a Provider that handles the given scheme.
+//
+// If no provider handles this scheme, this will return an error.
+func (p Providers) ByScheme(scheme string) (Constructor, error) {
+	for _, pp := range p {
+		if pp.Provides(scheme) {
+			return pp.New, nil
+		}
+	}
+	return nil, fmt.Errorf("scheme %q not supported", scheme)
+}
+
+// All finds all of the registered getters as a list of Provider instances.
+// Currently the build-in http/https getter and the discovered
+// plugins with downloader notations are collected.
+func All(settings environment.EnvSettings) Providers {
+	result := Providers{
+		{
+			Schemes: []string{"http", "https"},
+			New:     newHTTPGetter,
+		},
+	}
+	pluginDownloaders, _ := collectPlugins(settings)
+	result = append(result, pluginDownloaders...)
+	return result
 }
 
-//ConstructorByScheme returns a contstructor based on the required scheme
-func ConstructorByScheme(props []Prop, requiredScheme string) (Constructor, error) {
-	for _, item := range props {
-		for _, itemScheme := range item.Schemes {
-			if itemScheme == requiredScheme {
-				return item.Constructor, nil
-			}
+// ByScheme returns a getter for the given scheme.
+//
+// If the scheme is not supported, this will return an error.
+func ByScheme(scheme string, settings environment.EnvSettings) (Provider, error) {
+	// Q: What do you call a scheme string who's the boss?
+	// A: Bruce Schemestring, of course.
+	a := All(settings)
+	for _, p := range a {
+		if p.Provides(scheme) {
+			return p, nil
 		}
 	}
-	return nil, fmt.Errorf("Getter not found")
+	return Provider{}, fmt.Errorf("scheme %q not supported", scheme)
 }
diff --git a/pkg/getter/getter_test.go b/pkg/getter/getter_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..6d38a0d28dd7df0ef6120b2f93423f8addbea08d
--- /dev/null
+++ b/pkg/getter/getter_test.go
@@ -0,0 +1,81 @@
+/*
+Copyright 2017 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 getter
+
+import (
+	"os"
+	"testing"
+)
+
+func TestProvider(t *testing.T) {
+	p := Provider{
+		[]string{"one", "three"},
+		func(h, e, l, m string) (Getter, error) { return nil, nil },
+	}
+
+	if !p.Provides("three") {
+		t.Error("Expected provider to provide three")
+	}
+}
+
+func TestProviders(t *testing.T) {
+	ps := Providers{
+		{[]string{"one", "three"}, func(h, e, l, m string) (Getter, error) { return nil, nil }},
+		{[]string{"two", "four"}, func(h, e, l, m string) (Getter, error) { return nil, nil }},
+	}
+
+	if _, err := ps.ByScheme("one"); err != nil {
+		t.Error(err)
+	}
+	if _, err := ps.ByScheme("four"); err != nil {
+		t.Error(err)
+	}
+
+	if _, err := ps.ByScheme("five"); err == nil {
+		t.Error("Did not expect handler for five")
+	}
+}
+
+func TestAll(t *testing.T) {
+	oldhh := os.Getenv("HELM_HOME")
+	defer os.Setenv("HELM_HOME", oldhh)
+	os.Setenv("HELM_HOME", "")
+
+	env := hh(false)
+
+	all := All(env)
+	if len(all) != 3 {
+		t.Errorf("expected 3 providers (default plus two plugins), got %d", len(all))
+	}
+
+	if _, err := all.ByScheme("test2"); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestByScheme(t *testing.T) {
+	oldhh := os.Getenv("HELM_HOME")
+	defer os.Setenv("HELM_HOME", oldhh)
+	os.Setenv("HELM_HOME", "")
+
+	env := hh(false)
+	if _, err := ByScheme("test", env); err != nil {
+		t.Error(err)
+	}
+	if _, err := ByScheme("https", env); err != nil {
+		t.Error(err)
+	}
+}
diff --git a/pkg/getter/http/http_getter.go b/pkg/getter/httpgetter.go
similarity index 80%
rename from pkg/getter/http/http_getter.go
rename to pkg/getter/httpgetter.go
index 57f6c742f4a6058574173e1cc86e451e9a73890f..1dfffb6d478a3732c81c0db5ea6e3c1f24029c22 100644
--- a/pkg/getter/http/http_getter.go
+++ b/pkg/getter/httpgetter.go
@@ -1,11 +1,10 @@
 /*
 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
+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,
@@ -14,7 +13,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package httpgetter
+package getter
 
 import (
 	"bytes"
@@ -22,18 +21,17 @@ import (
 	"io"
 	"net/http"
 
-	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/tlsutil"
 	"k8s.io/helm/pkg/urlutil"
 )
 
-//HTTPGetter is the efault HTTP(/S) backend handler
-type HTTPGetter struct {
+//httpGetter is the efault HTTP(/S) backend handler
+type httpGetter struct {
 	client *http.Client
 }
 
 //Get performs a Get from repo.Getter and returns the body.
-func (g *HTTPGetter) Get(href string) (*bytes.Buffer, error) {
+func (g *httpGetter) Get(href string) (*bytes.Buffer, error) {
 	buf := bytes.NewBuffer(nil)
 
 	resp, err := g.client.Get(href)
@@ -49,9 +47,9 @@ func (g *HTTPGetter) Get(href string) (*bytes.Buffer, error) {
 	return buf, err
 }
 
-//New constructs a valid http/https client as Getter
-func New(URL, CertFile, KeyFile, CAFile string) (getter.Getter, error) {
-	var client HTTPGetter
+// newHTTPGetter constructs a valid http/https client as Getter
+func newHTTPGetter(URL, CertFile, KeyFile, CAFile string) (Getter, error) {
+	var client httpGetter
 	if CertFile != "" && KeyFile != "" && CAFile != "" {
 		tlsConf, err := tlsutil.NewClientTLS(CertFile, KeyFile, CAFile)
 		if err != nil {
diff --git a/pkg/getter/httpgetter_test.go b/pkg/getter/httpgetter_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..477e0bc4f6b45c7749f05b767d6e2932a4879a32
--- /dev/null
+++ b/pkg/getter/httpgetter_test.go
@@ -0,0 +1,48 @@
+/*
+Copyright 2017 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 getter
+
+import (
+	"net/http"
+	"path/filepath"
+	"testing"
+)
+
+func TestHTTPGetter(t *testing.T) {
+	g, err := newHTTPGetter("http://example.com", "", "", "")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if hg, ok := g.(*httpGetter); !ok {
+		t.Fatal("Expected newHTTPGetter to produce an httpGetter")
+	} else if hg.client != http.DefaultClient {
+		t.Fatal("Expected newHTTPGetter to return a default HTTP client.")
+	}
+
+	// Test with SSL:
+	cd := "../../testdata"
+	join := filepath.Join
+	ca, pub, priv := join(cd, "ca.pem"), join(cd, "crt.pem"), join(cd, "key.pem")
+	g, err = newHTTPGetter("http://example.com/", pub, priv, ca)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if _, ok := g.(*httpGetter); !ok {
+		t.Fatal("Expected newHTTPGetter to produce an httpGetter")
+	}
+}
diff --git a/pkg/getter/plugin/plugin_getter.go b/pkg/getter/plugingetter.go
similarity index 61%
rename from pkg/getter/plugin/plugin_getter.go
rename to pkg/getter/plugingetter.go
index 3ae600591f02dc427ee509e80016617b7d06b60c..c747eef7fdd0bd8653810dbfc37f5430ed82ca82 100644
--- a/pkg/getter/plugin/plugin_getter.go
+++ b/pkg/getter/plugingetter.go
@@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package plugingetter
+package getter
 
 import (
 	"bytes"
@@ -22,14 +22,37 @@ import (
 	"os/exec"
 	"path/filepath"
 
-	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/helm/environment"
 	"k8s.io/helm/pkg/plugin"
 )
 
-// PluginGetter is a generic type to invoke custom downloaders,
+// collectPlugins scans for getter plugins.
+// This will load plugins according to the environment.
+func collectPlugins(settings environment.EnvSettings) (Providers, error) {
+	plugins, err := plugin.FindPlugins(settings.PluginDirs())
+	if err != nil {
+		return nil, err
+	}
+	var result Providers
+	for _, plugin := range plugins {
+		for _, downloader := range plugin.Metadata.Downloaders {
+			result = append(result, Provider{
+				Schemes: downloader.Protocols,
+				New: newPluginGetter(
+					downloader.Command,
+					settings,
+					plugin.Metadata.Name,
+					plugin.Dir,
+				),
+			})
+		}
+	}
+	return result, nil
+}
+
+// pluginGetter is a generic type to invoke custom downloaders,
 // implemented in plugins.
-type PluginGetter struct {
+type pluginGetter struct {
 	command                   string
 	certFile, keyFile, cAFile string
 	settings                  environment.EnvSettings
@@ -38,7 +61,7 @@ type PluginGetter struct {
 }
 
 // Get runs downloader plugin command
-func (p *PluginGetter) Get(href string) (*bytes.Buffer, error) {
+func (p *pluginGetter) Get(href string) (*bytes.Buffer, error) {
 	argv := []string{p.certFile, p.keyFile, p.cAFile, href}
 	prog := exec.Command(filepath.Join(p.base, p.command), argv...)
 	plugin.SetupPluginEnv(p.settings, p.name, p.base)
@@ -56,13 +79,10 @@ func (p *PluginGetter) Get(href string) (*bytes.Buffer, error) {
 	return buf, nil
 }
 
-// ConstructNew constructs a valid plugin getter
-func ConstructNew(command string,
-	settings environment.EnvSettings,
-	name string,
-	base string) getter.Constructor {
-	return func(URL, CertFile, KeyFile, CAFile string) (getter.Getter, error) {
-		result := &PluginGetter{
+// newPluginGetter constructs a valid plugin getter
+func newPluginGetter(command string, settings environment.EnvSettings, name, base string) Constructor {
+	return func(URL, CertFile, KeyFile, CAFile string) (Getter, error) {
+		result := &pluginGetter{
 			command:  command,
 			certFile: CertFile,
 			keyFile:  KeyFile,
diff --git a/pkg/getter/plugingetter_test.go b/pkg/getter/plugingetter_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..f1fe9bf29d327b217207c669b8416c2d90185207
--- /dev/null
+++ b/pkg/getter/plugingetter_test.go
@@ -0,0 +1,91 @@
+/*
+Copyright 2017 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 getter
+
+import (
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+
+	"k8s.io/helm/pkg/helm/environment"
+	"k8s.io/helm/pkg/helm/helmpath"
+)
+
+func hh(debug bool) environment.EnvSettings {
+	apath, err := filepath.Abs("./testdata")
+	if err != nil {
+		panic(err)
+	}
+	hp := helmpath.Home(apath)
+	return environment.EnvSettings{
+		Home:  hp,
+		Debug: debug,
+	}
+}
+
+func TestCollectPlugins(t *testing.T) {
+	// Reset HELM HOME to testdata.
+	oldhh := os.Getenv("HELM_HOME")
+	defer os.Setenv("HELM_HOME", oldhh)
+	os.Setenv("HELM_HOME", "")
+
+	env := hh(false)
+	p, err := collectPlugins(env)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(p) != 2 {
+		t.Errorf("Expected 2 plugins, got %d: %v", len(p), p)
+	}
+
+	if _, err := p.ByScheme("test2"); err != nil {
+		t.Error(err)
+	}
+
+	if _, err := p.ByScheme("test"); err != nil {
+		t.Error(err)
+	}
+
+	if _, err := p.ByScheme("nosuchthing"); err == nil {
+		t.Fatal("did not expect protocol handler for nosuchthing")
+	}
+}
+
+func TestPluginGetter(t *testing.T) {
+	oldhh := os.Getenv("HELM_HOME")
+	defer os.Setenv("HELM_HOME", oldhh)
+	os.Setenv("HELM_HOME", "")
+
+	env := hh(false)
+	pg := newPluginGetter("echo", env, "test", ".")
+	g, err := pg("test://foo/bar", "", "", "")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	data, err := g.Get("test://foo/bar")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	expect := "test://foo/bar"
+	got := strings.TrimSpace(data.String())
+	if got != expect {
+		t.Errorf("Expected %q, got %q", expect, got)
+	}
+}
diff --git a/pkg/getter/testdata/plugins/testgetter/get.sh b/pkg/getter/testdata/plugins/testgetter/get.sh
new file mode 100755
index 0000000000000000000000000000000000000000..cdd992369d80cc1fe718b388292bac722ff255ae
--- /dev/null
+++ b/pkg/getter/testdata/plugins/testgetter/get.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+echo ENVIRONMENT
+env
+
+echo ""
+echo ARGUMENTS
+echo $@
diff --git a/pkg/getter/testdata/plugins/testgetter/plugin.yaml b/pkg/getter/testdata/plugins/testgetter/plugin.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d1b929e3ff471e1148851fdceac1a85f8c33b145
--- /dev/null
+++ b/pkg/getter/testdata/plugins/testgetter/plugin.yaml
@@ -0,0 +1,15 @@
+name: "testgetter"
+version: "0.1.0"
+usage: "Fetch a package from a test:// source"
+description: |-
+  Print the environment that the plugin was given, then exit.
+
+  This registers the test:// protocol.
+
+command: "$HELM_PLUGIN_DIR/get.sh"
+ignoreFlags: true
+downloaders:
+#- command: "$HELM_PLUGIN_DIR/get.sh"
+- command: "echo"
+  protocols:
+    - "test"
diff --git a/pkg/getter/testdata/plugins/testgetter2/get.sh b/pkg/getter/testdata/plugins/testgetter2/get.sh
new file mode 100755
index 0000000000000000000000000000000000000000..cdd992369d80cc1fe718b388292bac722ff255ae
--- /dev/null
+++ b/pkg/getter/testdata/plugins/testgetter2/get.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+echo ENVIRONMENT
+env
+
+echo ""
+echo ARGUMENTS
+echo $@
diff --git a/pkg/getter/testdata/plugins/testgetter2/plugin.yaml b/pkg/getter/testdata/plugins/testgetter2/plugin.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f1a527ef9369d377393456c7bfd0846c022de649
--- /dev/null
+++ b/pkg/getter/testdata/plugins/testgetter2/plugin.yaml
@@ -0,0 +1,10 @@
+name: "testgetter2"
+version: "0.1.0"
+usage: "Fetch a different package from a test2:// source"
+description: "Handle test2 scheme"
+command: "$HELM_PLUGIN_DIR/get.sh"
+ignoreFlags: true
+downloaders:
+- command: "echo"
+  protocols:
+    - "test2"
diff --git a/pkg/getter/testdata/repository/cache/local-index.yaml b/pkg/getter/testdata/repository/cache/local-index.yaml
new file mode 120000
index 0000000000000000000000000000000000000000..ed068e99e4db900fe0b3bef5933d467f13dcc914
--- /dev/null
+++ b/pkg/getter/testdata/repository/cache/local-index.yaml
@@ -0,0 +1 @@
+repository/local/index.yaml
\ No newline at end of file
diff --git a/pkg/getter/testdata/repository/cache/stable-index.yaml b/pkg/getter/testdata/repository/cache/stable-index.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..bf187e3df74b8a743cf985a1896d5372c2cb4b45
--- /dev/null
+++ b/pkg/getter/testdata/repository/cache/stable-index.yaml
@@ -0,0 +1,7852 @@
+apiVersion: v1
+entries:
+  aws-cluster-autoscaler:
+  - apiVersion: v1
+    created: 2017-04-28T00:18:30.071110236Z
+    description: Scales worker nodes within autoscaling groups.
+    digest: 291eaabbf54913e71cda39d42a6e9c4c493a3672a5b0b5183ea1991a76d6c317
+    engine: gotpl
+    icon: https://github.com/kubernetes/kubernetes/blob/master/logo/logo.png
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: aws-cluster-autoscaler
+    sources:
+    - https://github.com/kubernetes/contrib/tree/master/cluster-autoscaler/cloudprovider/aws
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/aws-cluster-autoscaler-0.2.1.tgz
+    version: 0.2.1
+  - apiVersion: v1
+    created: 2017-03-02T18:48:30.418071154Z
+    description: Scales worker nodes within autoscaling groups.
+    digest: 52ee58b51619f641d0f6df4c778bcd068242379a1a040a269f0fc93867b79b13
+    engine: gotpl
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: aws-cluster-autoscaler
+    sources:
+    - https://github.com/kubernetes/contrib/tree/master/cluster-autoscaler/cloudprovider/aws
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/aws-cluster-autoscaler-0.2.0.tgz
+    version: 0.2.0
+  chaoskube:
+  - created: 2017-04-28T00:18:30.071358212Z
+    description: Chaoskube periodically kills random pods in your Kubernetes cluster.
+    digest: c90ff57a6205c725520dc600b439fc8eda120c3d8d4d4b7c9feee60bf62629cb
+    engine: gotpl
+    home: https://github.com/linki/chaoskube
+    maintainers:
+    - email: linki+kubernetes.io@posteo.de
+      name: Martin Linkhorst
+    name: chaoskube
+    sources:
+    - https://github.com/linki/chaoskube
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/chaoskube-0.5.0.tgz
+    version: 0.5.0
+  - created: 2017-03-14T23:48:31.878196764Z
+    description: Chaoskube periodically kills random pods in your Kubernetes cluster.
+    digest: cc211be37255f2fdf7cc74022f51473c2c4af98c06b0871ab8c9b8341ee9d349
+    engine: gotpl
+    home: https://github.com/linki/chaoskube
+    maintainers:
+    - email: linki+kubernetes.io@posteo.de
+      name: Martin Linkhorst
+    name: chaoskube
+    sources:
+    - https://github.com/linki/chaoskube
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/chaoskube-0.4.0.tgz
+    version: 0.4.0
+  - created: 2017-02-13T04:18:31.525717582Z
+    description: A Helm chart for chaoskube
+    digest: 6e6466b2a7294853fbad6a1dc5526e7fd6eb75bafd035748259511ccf49f9c47
+    engine: gotpl
+    home: https://github.com/linki/chaoskube
+    maintainers:
+    - email: linki+helm.sh@posteo.de
+      name: Martin Linkhorst
+    name: chaoskube
+    sources:
+    - https://github.com/linki/chaoskube
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/chaoskube-0.3.1.tgz
+    version: 0.3.1
+  - created: 2017-02-13T21:18:28.251529085Z
+    description: Chaoskube periodically kills random pods in your Kubernetes cluster.
+    digest: 6439a906666fc62e7aeb28186ce2f4a730216941163edd799176cc30616e713a
+    engine: gotpl
+    home: https://github.com/linki/chaoskube
+    maintainers:
+    - email: linki+kubernetes.io@posteo.de
+      name: Martin Linkhorst
+    name: chaoskube
+    sources:
+    - https://github.com/linki/chaoskube
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/chaoskube-0.3.1-1.tgz
+    version: 0.3.1-1
+  chronograf:
+  - created: 2017-04-28T00:18:30.071786276Z
+    description: Open-source web application written in Go and React.js that provides
+      the tools to visualize your monitoring data and easily create alerting and automation
+      rules.
+    digest: 5f6c0ada37696c624ebdfad1703666b91a84dedea81cbae4335109e7046c9f86
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/chronograf/
+    keywords:
+    - chronograf
+    - visualizaion
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: chronograf
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/chronograf-0.2.0.tgz
+    version: 0.2.0
+  - created: 2017-03-22T23:03:29.448801697Z
+    description: Open-source web application written in Go and React.js that provides
+      the tools to visualize your monitoring data and easily create alerting and automation
+      rules.
+    digest: 6bc90a815f7fc513bfa2b4d1a56a03e53444bfd08b742e0d0f1ff9f3b5db52f7
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/chronograf/
+    keywords:
+    - chronograf
+    - visualizaion
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: chronograf
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/chronograf-0.1.2.tgz
+    version: 0.1.2
+  - created: 2017-02-13T04:18:31.52604543Z
+    description: Chart for Chronograf
+    digest: 985fa74feb6ed111220ca7a8c5da529accd42def9d75f56c0c82902631bcf15f
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/chronograf/
+    keywords:
+    - chronograf
+    - visualizaion
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: chronograf
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/chronograf-0.1.1.tgz
+    version: 0.1.1
+  - created: 2017-01-28T00:33:31.060189495Z
+    description: Chart for Chronograf
+    digest: ea03695da15a018e84d05e0fd97d581f3fd348d8461aa098cd221b5010176a35
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/chronograf/
+    keywords:
+    - chronograf
+    - visualizaion
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: chronograf
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/chronograf-0.1.0.tgz
+    version: 0.1.0
+  cockroachdb:
+  - created: 2017-04-28T00:18:30.07217685Z
+    description: CockroachDB is a scalable, survivable, strongly-consistent SQL database.
+    digest: c51bf6c3d07067b80ca8661ff8460b2bb7d25d242f153045668ba95566fc8069
+    home: https://www.cockroachlabs.com
+    icon: https://raw.githubusercontent.com/cockroachdb/cockroach/master/docs/media/cockroach_db.png
+    maintainers:
+    - email: alex@cockroachlabs.com
+      name: Alex Robinson
+    name: cockroachdb
+    sources:
+    - https://github.com/cockroachdb/cockroach
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/cockroachdb-0.2.2.tgz
+    version: 0.2.2
+  - created: 2017-02-13T04:18:31.526409785Z
+    description: CockroachDB Helm chart for Kubernetes.
+    digest: 0eec741613e00f7092ec81469f919cd79fec52a22e8685063c0b0d8fd6570c37
+    home: https://www.cockroachlabs.com
+    maintainers:
+    - email: alex@cockroachlabs.com
+      name: Alex Robinson
+    name: cockroachdb
+    sources:
+    - https://github.com/cockroachdb/cockroach
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/cockroachdb-0.2.1.tgz
+    version: 0.2.1
+  - created: 2017-01-27T21:48:32.059935168Z
+    description: CockroachDB Helm chart for Kubernetes.
+    digest: 7b41add319a997fd3d862d6649b707313f59ac6fa137842db65230342baff619
+    home: https://www.cockroachlabs.com
+    maintainers:
+    - email: alex@cockroachlabs.com
+      name: Alex Robinson
+    name: cockroachdb
+    sources:
+    - https://github.com/cockroachdb/cockroach
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/cockroachdb-0.2.0.tgz
+    version: 0.2.0
+  concourse:
+  - created: 2017-04-28T00:18:30.074578589Z
+    description: Concourse is a simple and scalable CI system.
+    digest: b7ea57e289002deba839f52acf6a5919870ab99910f12bcc6edadd4ae5651826
+    engine: gotpl
+    home: https://concourse.ci/
+    icon: https://avatars1.githubusercontent.com/u/7809479
+    keywords:
+    - ci
+    - concourse
+    - concourse.ci
+    maintainers:
+    - email: frodenas@gmail.com
+      name: Ferran Rodenas
+    name: concourse
+    sources:
+    - https://github.com/concourse/bin
+    - https://github.com/kubernetes/charts
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/concourse-0.1.3.tgz
+    version: 0.1.3
+  - created: 2017-02-14T19:03:29.77100439Z
+    description: Concourse is a simple and scalable CI system.
+    digest: 5f8ed4eb5b0acf8da7b34772714154322405b796553a33fc6ffd779e0a556003
+    engine: gotpl
+    home: https://concourse.ci/
+    icon: https://avatars1.githubusercontent.com/u/7809479
+    keywords:
+    - ci
+    - concourse
+    - concourse.ci
+    maintainers:
+    - email: frodenas@gmail.com
+      name: Ferran Rodenas
+    name: concourse
+    sources:
+    - https://github.com/concourse/bin
+    - https://github.com/kubernetes/charts
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/concourse-0.1.2.tgz
+    version: 0.1.2
+  - created: 2017-02-13T21:18:28.254273427Z
+    description: Concourse is a simple and scalable CI system.
+    digest: cba53dadd21dbd85b31a1a522a5eaeb49cadfa595ba0762c02dca04905d35f20
+    engine: gotpl
+    home: https://concourse.ci/
+    icon: https://avatars1.githubusercontent.com/u/7809479
+    keywords:
+    - ci
+    - concourse
+    - concourse.ci
+    maintainers:
+    - email: frodenas@gmail.com
+      name: Ferran Rodenas
+    name: concourse
+    sources:
+    - https://github.com/concourse/bin
+    - https://github.com/kubernetes/charts
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/concourse-0.1.1.tgz
+    version: 0.1.1
+  - created: 2017-02-10T23:18:26.003782261Z
+    description: Concourse Helm chart for Kubernetes.
+    digest: 08e6b4c56357ce15dfd66b0fad8c2df37664877b16b4a0afcbaeb301ddcc7432
+    engine: gotpl
+    home: https://concourse.ci/
+    keywords:
+    - ci
+    - concourse
+    - concourse.ci
+    maintainers:
+    - email: frodenas@gmail.com
+      name: Ferran Rodenas
+    name: concourse
+    sources:
+    - https://github.com/concourse/bin
+    - https://github.com/kubernetes/charts
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/concourse-0.1.0.tgz
+    version: 0.1.0
+  consul:
+  - created: 2017-04-28T00:18:30.075038045Z
+    description: Highly available and distributed service discovery and key-value
+      store designed with support for the modern data center to make distributed systems
+      and configuration easy.
+    digest: 7e0093709abc7a2c475e4e8c14e856d9834f88683b4a9e8c6099f4e0ad7e434e
+    home: https://github.com/hashicorp/consul
+    icon: https://www.consul.io/assets/images/logo_large-475cebb0.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    name: consul
+    sources:
+    - https://github.com/kelseyhightower/consul-on-kubernetes
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/consul-0.2.2.tgz
+    version: 0.2.2
+  - created: 2017-04-26T14:48:28.225526691Z
+    description: Highly available and distributed service discovery and key-value
+      store designed with support for the modern data center to make distributed systems
+      and configuration easy.
+    digest: 03daa04827bf93627b7087001c1d2424337d268a5875a51d8db4bb4e53bbc7db
+    home: https://github.com/hashicorp/consul
+    icon: https://www.consul.io/assets/images/logo_large-475cebb0.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    name: consul
+    sources:
+    - https://github.com/kelseyhightower/consul-on-kubernetes
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/consul-0.2.0.tgz
+    version: 0.2.0
+  coredns:
+  - created: 2017-04-28T00:18:30.075393511Z
+    description: CoreDNS is a DNS server that chains middleware and provides Kubernetes
+      DNS Services
+    digest: adbdc4a8895f7c2e7cca64c2dcf36ddfffeff1115a3ade32011ec82b60be119b
+    home: https://coredns.io
+    icon: https://raw.githubusercontent.com/coredns/logo/master/Icon/CoreDNS_Colour_Icon.svg
+    keywords:
+    - coredns
+    - dns
+    - kubedns
+    maintainers:
+    - email: hello@acale.ph
+      name: Acaleph
+    - email: shashidhara.huawei@gmail.com
+      name: Shashidhara TD
+    name: coredns
+    sources:
+    - https://github.com/coredns/coredns
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/coredns-0.1.0.tgz
+    version: 0.1.0
+  datadog:
+  - created: 2017-04-28T00:18:30.075800677Z
+    description: DataDog Agent
+    digest: bc559f013b738704089c4964a268c447b22e82181e9fa9e8219d46d40b388709
+    home: https://www.datadoghq.com
+    icon: https://datadog-live.imgix.net/img/dd_logo_70x75.png
+    keywords:
+    - monitoring
+    - alerting
+    - metric
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: datadog
+    sources:
+    - https://app.datadoghq.com/account/settings#agent/kubernetes
+    - https://github.com/DataDog/docker-dd-agent
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/datadog-0.3.0.tgz
+    version: 0.3.0
+  - created: 2017-04-06T11:33:26.056402381Z
+    description: DataDog Agent
+    digest: b32c28e76004eedf5c160936ccf35adca3a150ae1d0b491df52d017725b5ee90
+    home: https://www.datadoghq.com
+    icon: https://datadog-live.imgix.net/img/dd_logo_70x75.png
+    keywords:
+    - monitoring
+    - alerting
+    - metric
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: datadog
+    sources:
+    - https://app.datadoghq.com/account/settings#agent/kubernetes
+    - https://github.com/DataDog/docker-dd-agent
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/datadog-0.2.1.tgz
+    version: 0.2.1
+  - created: 2017-02-11T03:18:26.518137684Z
+    description: DataDog Agent
+    digest: d534bdcf4644d88ebfa70c58e57aafed41b75da4264042d4975f70d091e2b493
+    keywords:
+    - monitoring
+    - alerting
+    - metric
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: datadog
+    sources:
+    - https://app.datadoghq.com/account/settings#agent/kubernetes
+    - https://github.com/DataDog/docker-dd-agent
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/datadog-0.2.0.tgz
+    version: 0.2.0
+  - created: 2017-01-04T00:48:19.731877862Z
+    description: DataDog Agent
+    digest: 694c1d036d92c8bb60638f7bd66144a991a807dc879bedacf8a5d32e9d72081a
+    keywords:
+    - monitoring
+    - alerting
+    - metric
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: datadog
+    sources:
+    - https://app.datadoghq.com/account/settings#agent/kubernetes
+    - https://github.com/DataDog/docker-dd-agent
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/datadog-0.1.0.tgz
+    version: 0.1.0
+  dokuwiki:
+  - created: 2017-04-28T00:18:30.076184541Z
+    description: DokuWiki is a standards-compliant, simple to use wiki optimized for
+      creating documentation. It is targeted at developer teams, workgroups, and small
+      companies. All data is stored in plain text files, so no database is required.
+    digest: 5cfff9542341a391abf9029dd9b42e7c44813c520ef0301ce62e9c08586ceca2
+    engine: gotpl
+    home: http://www.dokuwiki.org/
+    icon: https://bitnami.com/assets/stacks/dokuwiki/img/dokuwiki-stack-110x117.png
+    keywords:
+    - dokuwiki
+    - wiki
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: dokuwiki
+    sources:
+    - https://github.com/bitnami/bitnami-docker-dokuwiki
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/dokuwiki-0.1.4.tgz
+    version: 0.1.4
+  - created: 2017-04-13T05:18:28.897680481Z
+    description: DokuWiki is a standards-compliant, simple to use wiki optimized for
+      creating documentation. It is targeted at developer teams, workgroups, and small
+      companies. All data is stored in plain text files, so no database is required.
+    digest: 3c46f9d9196bbf975711b2bb7c889fd3df1976cc57c3c120c7374d721da0e240
+    engine: gotpl
+    home: http://www.dokuwiki.org/
+    icon: https://bitnami.com/assets/stacks/dokuwiki/img/dokuwiki-stack-110x117.png
+    keywords:
+    - dokuwiki
+    - wiki
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: dokuwiki
+    sources:
+    - https://github.com/bitnami/bitnami-docker-dokuwiki
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/dokuwiki-0.1.3.tgz
+    version: 0.1.3
+  - created: 2017-03-02T19:33:28.170205427Z
+    description: DokuWiki is a standards-compliant, simple to use wiki optimized for
+      creating documentation. It is targeted at developer teams, workgroups, and small
+      companies. All data is stored in plain text files, so no database is required.
+    digest: f533bc20e08179a49cca77b175f897087dc3f2c57e6c89ecbd7264ab5975d66a
+    engine: gotpl
+    home: http://www.dokuwiki.org/
+    icon: https://bitnami.com/assets/stacks/dokuwiki/img/dokuwiki-stack-110x117.png
+    keywords:
+    - dokuwiki
+    - wiki
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: dokuwiki
+    sources:
+    - https://github.com/bitnami/bitnami-docker-dokuwiki
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/dokuwiki-0.1.2.tgz
+    version: 0.1.2
+  - created: 2017-02-01T02:18:29.116555882Z
+    description: DokuWiki is a standards-compliant, simple to use wiki optimized for
+      creating documentation. It is targeted at developer teams, workgroups, and small
+      companies. All data is stored in plain text files, so no database is required.
+    digest: 34a926398cfafbf426ff468167ef49577252e260ebce5df33380e6e67b79fe59
+    engine: gotpl
+    home: http://www.dokuwiki.org/
+    icon: https://bitnami.com/assets/stacks/dokuwiki/img/dokuwiki-stack-110x117.png
+    keywords:
+    - dokuwiki
+    - wiki
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: dokuwiki
+    sources:
+    - https://github.com/bitnami/bitnami-docker-dokuwiki
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/dokuwiki-0.1.1.tgz
+    version: 0.1.1
+  - created: 2017-01-28T00:33:31.06436596Z
+    description: DokuWiki is a standards-compliant, simple to use wiki optimized for
+      creating documentation. It is targeted at developer teams, workgroups, and small
+      companies. All data is stored in plain text files, so no database is required.
+    digest: 6825fbacb709cf05901985561be10ba9473a379488d99b71d1590d33f5a81374
+    engine: gotpl
+    home: http://www.dokuwiki.org/
+    icon: https://bitnami.com/assets/stacks/dokuwiki/img/dokuwiki-stack-110x117.png
+    keywords:
+    - dokuwiki
+    - wiki
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: dokuwiki
+    sources:
+    - https://github.com/bitnami/bitnami-docker-dokuwiki
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/dokuwiki-0.1.0.tgz
+    version: 0.1.0
+  drupal:
+  - created: 2017-04-28T00:18:30.076853626Z
+    description: One of the most versatile open source content management systems.
+    digest: db95c255b19164c5051eb75a6860f3775a1011399a62b27e474cd9ebee0cb578
+    engine: gotpl
+    home: http://www.drupal.org/
+    icon: https://bitnami.com/assets/stacks/drupal/img/drupal-stack-220x234.png
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.5.1.tgz
+    version: 0.5.1
+  - created: 2017-04-24T19:18:29.642780033Z
+    description: One of the most versatile open source content management systems.
+    digest: 84c13154a9aeb7215dc0d98e9825207207e69ca870f3d54b273bfc2d34699f61
+    engine: gotpl
+    home: http://www.drupal.org/
+    icon: https://bitnami.com/assets/stacks/drupal/img/drupal-stack-220x234.png
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.5.0.tgz
+    version: 0.5.0
+  - created: 2017-04-11T17:18:28.883487907Z
+    description: One of the most versatile open source content management systems.
+    digest: 17d0bfdcdf5a1a650941343c76b6b928d76d3332fece127c502e91f9597f419e
+    engine: gotpl
+    home: http://www.drupal.org/
+    icon: https://bitnami.com/assets/stacks/drupal/img/drupal-stack-220x234.png
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.4.6.tgz
+    version: 0.4.6
+  - created: 2017-03-23T01:48:29.309045867Z
+    description: One of the most versatile open source content management systems.
+    digest: 317674c89762e0b54156b734203ee93638dd7a25df35120c5cab45546814d89b
+    engine: gotpl
+    home: http://www.drupal.org/
+    icon: https://bitnami.com/assets/stacks/drupal/img/drupal-stack-220x234.png
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-03-16T13:33:30.828606332Z
+    description: One of the most versatile open source content management systems.
+    digest: 24c4f187b50c0e961cc2cacf6e6b2ce6d6b225c73637c578e001bebd9b3f5d48
+    engine: gotpl
+    home: http://www.drupal.org/
+    icon: https://bitnami.com/assets/stacks/drupal/img/drupal-stack-220x234.png
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-03-02T19:33:28.170963773Z
+    description: One of the most versatile open source content management systems.
+    digest: 7fcea4684a3d520454aeaa10beb9f9b1789c09c097680fc484954084f283feb3
+    engine: gotpl
+    home: http://www.drupal.org/
+    icon: https://bitnami.com/assets/stacks/drupal/img/drupal-stack-220x234.png
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-02-27T17:03:27.765392204Z
+    description: One of the most versatile open source content management systems.
+    digest: adb23bc71125b9691b407a47dadf4298de3516805218813b56067967e39db7d8
+    engine: gotpl
+    home: http://www.drupal.org/
+    icon: https://bitnami.com/assets/stacks/drupal/img/drupal-stack-220x234.png
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-02-11T00:18:52.26723498Z
+    description: One of the most versatile open source content management systems.
+    digest: 5de529e25767e8a37b8d6f413daa0fe99f5c304e48ddcfa8adb4d8c7a0496aa7
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-01-28T00:33:31.065139372Z
+    description: One of the most versatile open source content management systems.
+    digest: a35dbf9d470972cc2461de3e0a8fcf2fec8d0adc04f5a0f1e924505f22c714d7
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.4.0.tgz
+    version: 0.4.0
+  - created: 2017-01-04T00:48:19.73297256Z
+    description: One of the most versatile open source content management systems.
+    digest: a62d686d6bd47643dfa489e395dda89286954f785123a43a88db7ef34f3ea48d
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.3.10.tgz
+    version: 0.3.10
+  - created: 2016-12-15T00:48:24.005322531Z
+    description: One of the most versatile open source content management systems.
+    digest: 2c189424bda94eeebb7e6370e96884f09bdfa81498cb93ac4723d24c92a3938e
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.3.9.tgz
+    version: 0.3.9
+  - created: 2016-12-09T18:48:20.182097412Z
+    description: One of the most versatile open source content management systems.
+    digest: 3596f47c5dcaa7a975d1c4cb7bf7ef6790c9ad8dda41a5a329e30c1ea8a40d11
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.3.8.tgz
+    version: 0.3.8
+  - created: 2016-11-21T19:48:21.904806991Z
+    description: One of the most versatile open source content management systems.
+    digest: 78b2bb3717be63dccb02ea06b711ca7cf7869848b296b880099c6264e86d86d3
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.3.7.tgz
+    version: 0.3.7
+  - created: 2016-11-08T15:03:20.739400722Z
+    description: One of the most versatile open source content management systems.
+    digest: 5508b29e20a5d609f76319869774f008dcc4bed13bbbc7ed40546bc9af8c7cd7
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.3.6.tgz
+    version: 0.3.6
+  - created: 2016-11-03T19:33:29.11780736Z
+    description: One of the most versatile open source content management systems.
+    digest: 023a282c93f8411fb81bb4fff7820c1337aad0586ccf7dae55bdbed515ad8b05
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.3.5.tgz
+    version: 0.3.5
+  - created: 2016-10-21T19:18:18.619010562Z
+    description: One of the most versatile open source content management systems.
+    digest: 9bdaa53f7a9e82c9b32c7ac9b34b84fd142671732a54423a2dcdc893c4162801
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.3.4.tgz
+    version: 0.3.4
+  - created: 2016-10-19T00:03:14.027652488Z
+    description: One of the most versatile open source content management systems.
+    digest: 25650526abc1036398dbb314d77a0062cbb644b2c5791a258fb863fdaad5093d
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.3.3.tgz
+    version: 0.3.3
+  - created: 2016-10-19T00:03:14.027073479Z
+    description: One of the most versatile open source content management systems.
+    digest: 13d5d32d316c08359221d230004dd2adc0152362e87abcc0d61ea191241fa69f
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.3.2.tgz
+    version: 0.3.2
+  - created: 2016-10-19T00:03:14.025451665Z
+    description: One of the most versatile open source content management systems.
+    digest: b3f09ecd191f8c06275c96d9af4d77a97c94355525864201e9baf151b17bd5a7
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.3.1.tgz
+    version: 0.3.1
+  - created: 2016-10-19T00:03:14.024557743Z
+    description: One of the most versatile open source content management systems.
+    digest: c56fc55b93b0dead65af7b81bbd54befd5115860698ca475baa5acb178a12e5a
+    engine: gotpl
+    home: http://www.drupal.org/
+    keywords:
+    - drupal
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: drupal
+    sources:
+    - https://github.com/bitnami/bitnami-docker-drupal
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/drupal-0.3.0.tgz
+    version: 0.3.0
+  etcd-operator:
+  - apiVersion: v1
+    created: 2017-04-28T00:18:30.077181321Z
+    description: CoreOS etcd-operator Helm chart for Kubernetes
+    digest: 1eb39b2f0ca26762eb13fc8cb577be741f7bb9d3162ab9c4547bb5176383bc2b
+    home: https://github.com/coreos/etcd-operator
+    icon: https://raw.githubusercontent.com/coreos/etcd/master/logos/etcd-horizontal-color.png
+    maintainers:
+    - email: chance.zibolski@coreos.com
+      name: Chance Zibolski
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    name: etcd-operator
+    sources:
+    - https://github.com/coreos/etcd-operator
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/etcd-operator-0.2.0.tgz
+    version: 0.2.0
+  - apiVersion: v1
+    created: 2017-03-08T19:18:29.84391993Z
+    description: CoreOS etcd-operator Helm chart for Kubernetes
+    digest: 4a65fe6c61e731b373395e524f160eb4ced32a22cbfb3ff5d406b1c8bc3ae3c7
+    home: https://github.com/coreos/etcd-operator
+    icon: https://raw.githubusercontent.com/coreos/etcd/master/logos/etcd-horizontal-color.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    name: etcd-operator
+    sources:
+    - https://github.com/coreos/etcd-operator
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/etcd-operator-0.1.1.tgz
+    version: 0.1.1
+  - apiVersion: v1
+    created: 2017-02-11T03:18:26.519796919Z
+    description: CoreOS etcd-operator Helm chart for Kubernetes
+    digest: 9bf72369082c4bad154171b3b68ad435331d6d07ae6d00e79e859f2a1599017b
+    icon: https://github.com/coreos/etcd/blob/master/logos/etcd-horizontal-color.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    name: etcd-operator
+    sources:
+    - https://github.com/coreos/etcd-operator
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/etcd-operator-0.1.0.tgz
+    version: 0.1.0
+  factorio:
+  - created: 2017-04-28T00:18:30.077542134Z
+    description: Factorio dedicated server.
+    digest: cdc44bc00d42020a7a4df154cdc5cc7ae148aa8d2a3f97b1e18ac1fc42853dc1
+    home: https://www.factorio.com/
+    icon: https://us1.factorio.com/assets/img/factorio-logo.png
+    keywords:
+    - game
+    - server
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: factorio
+    sources:
+    - https://github.com/games-on-k8s/docker-factorio
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/factorio-0.2.0.tgz
+    version: 0.2.0
+  - created: 2017-03-15T11:48:36.74226142Z
+    description: Factorio dedicated server.
+    digest: 5a60defdd8ac6f2276950662ba75f65d20c9e37edc85149012a2c84146eb6cff
+    home: https://www.factorio.com/
+    icon: https://us1.factorio.com/assets/img/factorio-logo.png
+    keywords:
+    - game
+    - server
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: factorio
+    sources:
+    - https://github.com/games-on-k8s/docker-factorio
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/factorio-0.1.4.tgz
+    version: 0.1.4
+  - created: 2017-02-13T04:18:31.530714209Z
+    description: Factorio dedicated server.
+    digest: 26244a5e1b5f992cdbef73ef9c7ffcaa52af538912fa299210f72275f2c756c9
+    keywords:
+    - game
+    - server
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: factorio
+    sources:
+    - https://github.com/games-on-k8s/docker-factorio
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/factorio-0.1.3.tgz
+    version: 0.1.3
+  - created: 2017-01-28T00:33:31.066072163Z
+    description: Factorio dedicated server.
+    digest: d6f4e42b82713c2da69e1ddcfce4a04fad31d4af915629d8e83e54b90a822f9a
+    keywords:
+    - game
+    - server
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: factorio
+    sources:
+    - https://github.com/games-on-k8s/docker-factorio
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/factorio-0.1.2.tgz
+    version: 0.1.2
+  - created: 2016-12-02T09:03:20.175832035Z
+    description: Factorio dedicated server.
+    digest: 3cc1f83669fd1d97eb96e76ba4821e8664350a4c310d3a14e62be18cc09e59b7
+    keywords:
+    - game
+    - server
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: factorio
+    sources:
+    - https://github.com/games-on-k8s/docker-factorio
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/factorio-0.1.1.tgz
+    version: 0.1.1
+  - created: 2016-11-07T18:33:21.243890443Z
+    description: Factorio dedicated server.
+    digest: 8edc1340cd99225a769b5843a677896c0d54a079133f9759211a1839bc7bb3eb
+    keywords:
+    - game
+    - server
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: factorio
+    sources:
+    - https://github.com/games-on-k8s/docker-factorio
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/factorio-0.1.0.tgz
+    version: 0.1.0
+  gcloud-endpoints:
+  - created: 2017-04-28T00:18:30.077956448Z
+    description: Develop, deploy, protect and monitor your APIs with Google Cloud
+      Endpoints.
+    digest: 172b56d0343c560f06e18858038e2096c910b37075a90f4303f77a79342b56fd
+    engine: gotpl
+    home: https://cloud.google.com/endpoints/
+    keywords:
+    - google
+    - endpoints
+    - nginx
+    - gcloud
+    - proxy
+    - authentication
+    - monitoring
+    - api
+    - swagger
+    - open api
+    maintainers:
+    - email: mtucker@deis.com
+      name: Matt Tucker
+    name: gcloud-endpoints
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/gcloud-endpoints-0.1.0.tgz
+    version: 0.1.0
+  gcloud-sqlproxy:
+  - created: 2017-04-28T00:18:30.078355277Z
+    description: Google Cloud SQL Proxy
+    digest: 1115afe0958f1ed01e568ec4c35b48ac0094704165b8808634ea5331c0d6da7d
+    engine: gotpl
+    home: https://cloud.google.com/sql/docs/postgres/sql-proxy
+    keywords:
+    - google
+    - cloud
+    - postgresql
+    - mysql
+    - sql
+    - sqlproxy
+    maintainers:
+    - email: rmocius@gmail.com
+      name: Rimas Mocevicius
+    name: gcloud-sqlproxy
+    sources:
+    - https://github.com/rimusz/charts
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/gcloud-sqlproxy-0.1.0.tgz
+    version: 0.1.0
+  ghost:
+  - created: 2017-04-28T00:18:30.079159648Z
+    description: A simple, powerful publishing platform that allows you to share your
+      stories with the world
+    digest: 91d195c99e00b2801eafef5c23fcf9ced218bb29c7097f08139e2bdc80e38a0f
+    engine: gotpl
+    home: http://www.ghost.org/
+    icon: https://bitnami.com/assets/stacks/ghost/img/ghost-stack-220x234.png
+    keywords:
+    - ghost
+    - blog
+    - http
+    - web
+    - application
+    - nodejs
+    - javascript
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: ghost
+    sources:
+    - https://github.com/bitnami/bitnami-docker-ghost
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/ghost-0.4.7.tgz
+    version: 0.4.7
+  - created: 2017-04-06T10:48:26.261677382Z
+    description: A simple, powerful publishing platform that allows you to share your
+      stories with the world
+    digest: 6342a95aeef40690430c2e80b167fbb116a632746cdca49cfac4cbd535eadb22
+    engine: gotpl
+    home: http://www.ghost.org/
+    icon: https://bitnami.com/assets/stacks/ghost/img/ghost-stack-220x234.png
+    keywords:
+    - ghost
+    - blog
+    - http
+    - web
+    - application
+    - nodejs
+    - javascript
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: ghost
+    sources:
+    - https://github.com/bitnami/bitnami-docker-ghost
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/ghost-0.4.6.tgz
+    version: 0.4.6
+  - created: 2017-03-08T19:03:31.719494672Z
+    description: A simple, powerful publishing platform that allows you to share your
+      stories with the world
+    digest: 8998a9a4e75e777edb6f06c05b45d461daebba09021161af3bef523efd193b15
+    engine: gotpl
+    home: http://www.ghost.org/
+    icon: https://bitnami.com/assets/stacks/ghost/img/ghost-stack-220x234.png
+    keywords:
+    - ghost
+    - blog
+    - http
+    - web
+    - application
+    - nodejs
+    - javascript
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: ghost
+    sources:
+    - https://github.com/bitnami/bitnami-docker-ghost
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/ghost-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-02-27T17:03:27.767416735Z
+    description: A simple, powerful publishing platform that allows you to share your
+      stories with the world
+    digest: e44c9a53355086ded1832f769dca515b863337ad118ba618ef97f37b3ef84030
+    engine: gotpl
+    home: http://www.ghost.org/
+    icon: https://bitnami.com/assets/stacks/ghost/img/ghost-stack-220x234.png
+    keywords:
+    - ghost
+    - blog
+    - http
+    - web
+    - application
+    - nodejs
+    - javascript
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: ghost
+    sources:
+    - https://github.com/bitnami/bitnami-docker-ghost
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/ghost-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-02-11T00:18:52.2688126Z
+    description: A simple, powerful publishing platform that allows you to share your
+      stories with the world
+    digest: b0c94a93c88fde68bb4fc78e92691d46cd2eb4d32cbac011e034565fbd35d46b
+    engine: gotpl
+    home: http://www.ghost.org/
+    keywords:
+    - ghost
+    - blog
+    - http
+    - web
+    - application
+    - nodejs
+    - javascript
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: ghost
+    sources:
+    - https://github.com/bitnami/bitnami-docker-ghost
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/ghost-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-01-29T22:48:35.944809746Z
+    description: A simple, powerful publishing platform that allows you to share your
+      stories with the world
+    digest: 791ccb42b62d56d50c72b37db3282eb3f2af75d667a25542d76c7991004eb822
+    engine: gotpl
+    home: http://www.ghost.org/
+    keywords:
+    - ghost
+    - blog
+    - http
+    - web
+    - application
+    - nodejs
+    - javascript
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: ghost
+    sources:
+    - https://github.com/bitnami/bitnami-docker-ghost
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/ghost-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-01-21T00:18:31.342008382Z
+    description: A simple, powerful publishing platform that allows you to share your
+      stories with the world
+    digest: 331a2b145bfdb39b626313cda7dc539f32dbda5149893957589c5406317fca53
+    engine: gotpl
+    home: http://www.ghost.org/
+    keywords:
+    - ghost
+    - blog
+    - http
+    - web
+    - application
+    - nodejs
+    - javascript
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: ghost
+    sources:
+    - https://github.com/bitnami/bitnami-docker-ghost
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/ghost-0.4.1.tgz
+    version: 0.4.1
+  - created: 2016-12-09T18:48:20.183434341Z
+    description: A simple, powerful publishing platform that allows you to share your
+      stories with the world
+    digest: 804227af037082a0f5c3c579feb9e24eb3682449e78876971c93a109bc716f40
+    engine: gotpl
+    home: http://www.ghost.org/
+    keywords:
+    - ghost
+    - blog
+    - http
+    - web
+    - application
+    - nodejs
+    - javascript
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: ghost
+    sources:
+    - https://github.com/bitnami/bitnami-docker-ghost
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/ghost-0.4.0.tgz
+    version: 0.4.0
+  gitlab-ce:
+  - created: 2017-04-28T00:18:30.080184798Z
+    description: GitLab Community Edition
+    digest: df5e36c64bf1b8e2b77609c1cd9c717df47c290777a005ebf0edbe42d1f0ac70
+    home: https://about.gitlab.com
+    icon: https://gitlab.com/uploads/group/avatar/6543/gitlab-logo-square.png
+    keywords:
+    - git
+    - ci
+    - deploy
+    - issue tracker
+    - code review
+    - wiki
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: gitlab-ce
+    sources:
+    - https://hub.docker.com/r/gitlab/gitlab-ce/
+    - https://docs.gitlab.com/omnibus/
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/gitlab-ce-0.1.7.tgz
+    version: 0.1.7
+  - created: 2017-04-11T16:33:29.173232912Z
+    description: GitLab Community Edition
+    digest: 80094520d1bee55c7e25ad740bbfe3740814f389e6221b2fa536f77aabba9b37
+    home: https://about.gitlab.com
+    icon: https://gitlab.com/uploads/group/avatar/6543/gitlab-logo-square.png
+    keywords:
+    - git
+    - ci
+    - deploy
+    - issue tracker
+    - code review
+    - wiki
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: gitlab-ce
+    sources:
+    - https://hub.docker.com/r/gitlab/gitlab-ce/
+    - https://docs.gitlab.com/omnibus/
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/gitlab-ce-0.1.6.tgz
+    version: 0.1.6
+  - created: 2017-03-23T20:48:32.107763732Z
+    description: GitLab Community Edition
+    digest: 20c0895dd3c5c1edbc0e3be4687f0d0874599cd0c53e49560f9f0a91506957ce
+    home: https://about.gitlab.com
+    icon: https://gitlab.com/uploads/group/avatar/6543/gitlab-logo-square.png
+    keywords:
+    - git
+    - ci
+    - deploy
+    - issue tracker
+    - code review
+    - wiki
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: gitlab-ce
+    sources:
+    - https://hub.docker.com/r/gitlab/gitlab-ce/
+    - https://docs.gitlab.com/omnibus/
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/gitlab-ce-0.1.5.tgz
+    version: 0.1.5
+  - created: 2017-02-14T02:48:28.88667289Z
+    description: GitLab Community Edition
+    digest: e05d4de559597760d59ca684fab107abcc0968b3260a77b16099d31e0b00cd74
+    keywords:
+    - git
+    - ci
+    - deploy
+    - issue tracker
+    - code review
+    - wiki
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: gitlab-ce
+    sources:
+    - https://hub.docker.com/r/gitlab/gitlab-ce/
+    - https://docs.gitlab.com/omnibus/
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/gitlab-ce-0.1.4.tgz
+    version: 0.1.4
+  - created: 2017-02-13T20:18:28.097071087Z
+    description: GitLab Community Edition
+    digest: a2fef3fd8d3187f8a4242d66435488bce4193ae3f2db8d3ec14da1c4373c2519
+    keywords:
+    - git
+    - ci
+    - deploy
+    - issue tracker
+    - code review
+    - wiki
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: gitlab-ce
+    sources:
+    - https://hub.docker.com/r/gitlab/gitlab-ce/
+    - https://docs.gitlab.com/omnibus/
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/gitlab-ce-0.1.3.tgz
+    version: 0.1.3
+  - created: 2017-01-26T03:18:35.336711333Z
+    description: GitLab Community Edition
+    digest: 3ca821c4e3bec2fe7541b95f94503875c508517e2f1200368268511e254df360
+    keywords:
+    - git
+    - ci
+    - deploy
+    - issue tracker
+    - code review
+    - wiki
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: gitlab-ce
+    sources:
+    - https://hub.docker.com/r/gitlab/gitlab-ce/
+    - https://docs.gitlab.com/omnibus/
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/gitlab-ce-0.1.2.tgz
+    version: 0.1.2
+  - created: 2017-01-13T20:48:31.520266166Z
+    description: GitLab Community Edition
+    digest: d78cfc8cc2e262c49e1aee3af046509b92b022a5cd4b522778e846ddcd808d9b
+    keywords:
+    - git
+    - ci
+    - deploy
+    - issue tracker
+    - code review
+    - wiki
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: gitlab-ce
+    sources:
+    - https://hub.docker.com/r/gitlab/gitlab-ce/
+    - https://docs.gitlab.com/omnibus/
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/gitlab-ce-0.1.1.tgz
+    version: 0.1.1
+  - created: 2016-12-15T21:18:24.667256782Z
+    description: GitLab Community Edition
+    digest: 2c84a056e3f6d66a6aed763b2f4a26c1f4275eb3f6ca64798962a070809c6272
+    keywords:
+    - git
+    - ci
+    - deploy
+    - issue tracker
+    - code review
+    - wiki
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: gitlab-ce
+    sources:
+    - https://hub.docker.com/r/gitlab/gitlab-ce/
+    - https://docs.gitlab.com/omnibus/
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/gitlab-ce-0.1.0.tgz
+    version: 0.1.0
+  gitlab-ee:
+  - created: 2017-04-28T00:18:30.081242553Z
+    description: GitLab Enterprise Edition
+    digest: 3fa791ba74b0e43c05178b6eb16fb21eede5bb046e9870b854db38654768de09
+    home: https://about.gitlab.com
+    icon: https://gitlab.com/uploads/group/avatar/6543/gitlab-logo-square.png
+    keywords:
+    - git
+    - ci
+    - deploy
+    - issue tracker
+    - code review
+    - wiki
+    maintainers:
+    - email: contact@quent.in
+      name: Quentin Rousseau
+    name: gitlab-ee
+    sources:
+    - https://hub.docker.com/r/gitlab/gitlab-ee/
+    - https://docs.gitlab.com/omnibus/
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/gitlab-ee-0.1.6.tgz
+    version: 0.1.6
+  grafana:
+  - created: 2017-04-28T00:18:30.082782593Z
+    description: The leading tool for querying and visualizing time series and metrics.
+    digest: 721c85c6407ef534dc0d2366af3092f63229d51158abb124496efbe1a224907b
+    engine: gotpl
+    home: https://grafana.net
+    icon: https://raw.githubusercontent.com/grafana/grafana/master/public/img/logo_transparent_400x.png
+    maintainers:
+    - email: zanhsieh@gmail.com
+      name: Ming Hsieh
+    name: grafana
+    sources:
+    - https://github.com/grafana/grafana
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/grafana-0.3.1.tgz
+    version: 0.3.1
+  - created: 2017-04-14T01:18:27.369088748Z
+    description: The leading tool for querying and visualizing time series and metrics.
+    digest: 8f1db00e769d13c2435841b9b89b2045653039ca377c4547f46b33ec566f60ef
+    engine: gotpl
+    home: https://grafana.net
+    icon: https://raw.githubusercontent.com/grafana/grafana/master/public/img/logo_transparent_400x.png
+    maintainers:
+    - email: zanhsieh@gmail.com
+      name: Ming Hsieh
+    name: grafana
+    sources:
+    - https://github.com/grafana/grafana
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/grafana-0.3.0.tgz
+    version: 0.3.0
+  - created: 2017-04-05T18:03:30.376700685Z
+    description: The leading tool for querying and visualizing time series and metrics.
+    digest: e428e33b249f2261882632cc658c36d50df81460c091fd29404a3b3d16886416
+    engine: gotpl
+    home: https://grafana.net
+    icon: https://raw.githubusercontent.com/grafana/grafana/master/public/img/logo_transparent_400x.png
+    maintainers:
+    - email: zanhsieh@gmail.com
+      name: Ming Hsieh
+    name: grafana
+    sources:
+    - https://github.com/grafana/grafana
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/grafana-0.2.5.tgz
+    version: 0.2.5
+  - created: 2017-03-16T23:33:31.578792832Z
+    description: The leading tool for querying and visualizing time series and metrics.
+    digest: 2fefc51028c411641e5bf85b799fc8e608c7646c7054cfaa2149d4e83610d60a
+    engine: gotpl
+    home: https://grafana.net
+    icon: https://raw.githubusercontent.com/grafana/grafana/master/public/img/logo_transparent_400x.png
+    maintainers:
+    - email: zanhsieh@gmail.com
+      name: Ming Hsieh
+    name: grafana
+    sources:
+    - https://github.com/grafana/grafana
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/grafana-0.2.4.tgz
+    version: 0.2.4
+  - created: 2017-03-14T23:48:31.886602615Z
+    description: The leading tool for querying and visualizing time series and metrics.
+    digest: 7fac33dcd25d8ac60071e56968db133ecfa4f796732f92044d1f7714495840fd
+    engine: gotpl
+    home: https://grafana.net
+    icon: https://raw.githubusercontent.com/grafana/grafana/master/public/img/logo_transparent_400x.png
+    maintainers:
+    - email: zanhsieh@gmail.com
+      name: Ming Hsieh
+    name: grafana
+    sources:
+    - https://github.com/grafana/grafana
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/grafana-0.2.3.tgz
+    version: 0.2.3
+  - created: 2017-02-13T22:33:28.777518221Z
+    description: The leading tool for querying and visualizing time series and metrics.
+    digest: 037158b80733838ab2ad84928c999997ab76b5383cbeb4cce6c174fe5bc5ae8d
+    engine: gotpl
+    home: https://grafana.net
+    icon: https://raw.githubusercontent.com/grafana/grafana/master/public/img/logo_transparent_400x.png
+    maintainers:
+    - email: zanhsieh@gmail.com
+      name: Ming Hsieh
+    name: grafana
+    sources:
+    - https://github.com/grafana/grafana
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/grafana-0.2.2.tgz
+    version: 0.2.2
+  - created: 2017-02-13T04:18:31.532928133Z
+    description: A Helm chart for Kubernetes
+    digest: e49f08bd26843eb0449304c72fd9be3e65de0d8647457f39807f9aa296ba9b6a
+    engine: gotpl
+    home: https://grafana.net
+    maintainers:
+    - email: zanhsieh@gmail.com
+      name: Ming Hsieh
+    name: grafana
+    sources:
+    - https://github.com/grafana/grafana
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/grafana-0.2.1.tgz
+    version: 0.2.1
+  - created: 2017-01-29T23:03:26.897254812Z
+    description: A Helm chart for Kubernetes
+    digest: 283be1abb811d005b3759f65761e4465e79f2031be8a47b3d87256e88888f047
+    engine: gotpl
+    home: https://grafana.net
+    maintainers:
+    - email: zanhsieh@gmail.com
+      name: Ming Hsieh
+    name: grafana
+    sources:
+    - https://github.com/grafana/grafana
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/grafana-0.2.0.tgz
+    version: 0.2.0
+  influxdb:
+  - created: 2017-04-28T00:18:30.083302575Z
+    description: Scalable datastore for metrics, events, and real-time analytics.
+    digest: c34d6d57a1c4f5cdf1d1eb869231b27d2c080c7d219ab330f43fd9fd795b8d40
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/influxdb/
+    keywords:
+    - influxdb
+    - database
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: influxdb
+    sources:
+    - https://github.com/influxdata/influxdb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/influxdb-0.4.0.tgz
+    version: 0.4.0
+  - created: 2017-03-23T01:19:01.442621577Z
+    description: Scalable datastore for metrics, events, and real-time analytics.
+    digest: 76522d9156e4939669344cc72a9674ce16ccc7049b06c03eaa0822ed4ce59254
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/influxdb/
+    keywords:
+    - influxdb
+    - database
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: influxdb
+    sources:
+    - https://github.com/influxdata/influxdb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/influxdb-0.3.0.tgz
+    version: 0.3.0
+  - created: 2017-03-17T05:33:29.077307939Z
+    description: Scalable datastore for metrics, events, and real-time analytics.
+    digest: 499e87e9a0cfb2452107eaabc5e81bb5382554731b12e20dac791d81d492044e
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/influxdb/
+    keywords:
+    - influxdb
+    - database
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: influxdb
+    sources:
+    - https://github.com/influxdata/influxdb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/influxdb-0.2.1.tgz
+    version: 0.2.1
+  - created: 2017-02-13T17:03:30.109119817Z
+    description: Scalable datastore for metrics, events, and real-time analytics.
+    digest: e78ce7b2aac9538e5f6087fc77e5e30ab41a2a54d9bb1381b02830dd3324f0a9
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/influxdb/
+    keywords:
+    - influxdb
+    - database
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: influxdb
+    sources:
+    - https://github.com/influxdata/influxdb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/influxdb-0.1.2.tgz
+    version: 0.1.2
+  - created: 2017-02-13T04:33:52.294695041Z
+    description: Chart for InfluxDB
+    digest: 3341f3cca2d60540b219390688ac600ec605a331975cd402d6489969a0346aec
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/influxdb/
+    keywords:
+    - influxdb
+    - database
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: influxdb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/influxdb-0.1.1.tgz
+    version: 0.1.1
+  - created: 2017-01-28T00:48:33.328518706Z
+    description: Chart for InfluxDB
+    digest: a64fad23b1d02c8f14955f652f60a36ca2bc9f01fb5f4d80cd88bcf9f96a7300
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/influxdb/
+    keywords:
+    - influxdb
+    - database
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: influxdb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/influxdb-0.1.0.tgz
+    version: 0.1.0
+  jasperreports:
+  - created: 2017-04-28T00:18:30.084006378Z
+    description: The JasperReports server can be used as a stand-alone or embedded
+      reporting and BI server that offers web-based reporting, analytic tools and
+      visualization, and a dashboard feature for compiling multiple custom views
+    digest: 8a649026f55b2fa1e743c93fd331e127e66b49c4d7f20116a2bb06e5937f4828
+    engine: gotpl
+    home: http://community.jaspersoft.com/project/jasperreports-server
+    icon: https://bitnami.com/assets/stacks/jasperserver/img/jasperserver-stack-110x117.png
+    keywords:
+    - business intelligence
+    - java
+    - jasper
+    - reporting
+    - analytic
+    - visualization
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: jasperreports
+    sources:
+    - https://github.com/bitnami/bitnami-docker-jasperreports
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jasperreports-0.1.5.tgz
+    version: 0.1.5
+  - created: 2017-04-06T10:18:27.580953879Z
+    description: The JasperReports server can be used as a stand-alone or embedded
+      reporting and BI server that offers web-based reporting, analytic tools and
+      visualization, and a dashboard feature for compiling multiple custom views
+    digest: d4a62f7ace55256852e5c650a56ccf671633c4f223180d304cfb03b9cd7993aa
+    engine: gotpl
+    home: http://community.jaspersoft.com/project/jasperreports-server
+    icon: https://bitnami.com/assets/stacks/jasperserver/img/jasperserver-stack-110x117.png
+    keywords:
+    - business intelligence
+    - java
+    - jasper
+    - reporting
+    - analytic
+    - visualization
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: jasperreports
+    sources:
+    - https://github.com/bitnami/bitnami-docker-jasperreports
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jasperreports-0.1.4.tgz
+    version: 0.1.4
+  - created: 2017-03-08T19:03:31.722665089Z
+    description: The JasperReports server can be used as a stand-alone or embedded
+      reporting and BI server that offers web-based reporting, analytic tools and
+      visualization, and a dashboard feature for compiling multiple custom views
+    digest: 99af0fca7ef1c475b239f2c8fc2dee6b040ea76b3c30bba1431f358df873aa49
+    engine: gotpl
+    home: http://community.jaspersoft.com/project/jasperreports-server
+    icon: https://bitnami.com/assets/stacks/jasperserver/img/jasperserver-stack-110x117.png
+    keywords:
+    - business intelligence
+    - java
+    - jasper
+    - reporting
+    - analytic
+    - visualization
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: jasperreports
+    sources:
+    - https://github.com/bitnami/bitnami-docker-jasperreports
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jasperreports-0.1.3.tgz
+    version: 0.1.3
+  - created: 2017-02-13T21:33:27.741967589Z
+    description: The JasperReports server can be used as a stand-alone or embedded
+      reporting and BI server that offers web-based reporting, analytic tools and
+      visualization, and a dashboard feature for compiling multiple custom views
+    digest: f01e53d1b89c4fb1fcd9702cd5f4e48d77607aed65f249e1f94b8b21f7eef3f4
+    engine: gotpl
+    home: http://community.jaspersoft.com/project/jasperreports-server
+    icon: https://bitnami.com/assets/stacks/jasperserver/img/jasperserver-stack-110x117.png
+    keywords:
+    - business intelligence
+    - java
+    - jasper
+    - reporting
+    - analytic
+    - visualization
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: jasperreports
+    sources:
+    - https://github.com/bitnami/bitnami-docker-jasperreports
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jasperreports-0.1.2.tgz
+    version: 0.1.2
+  - created: 2017-01-28T01:33:32.784491819Z
+    description: The JasperReports server can be used as a stand-alone or embedded
+      reporting and BI server that offers web-based reporting, analytic tools and
+      visualization, and a dashboard feature for compiling multiple custom views
+    digest: 5cc4af8c88691d7030602c97be2ccbc125ef11129b361da0aa236a127c31b965
+    engine: gotpl
+    home: http://community.jaspersoft.com/project/jasperreports-server
+    icon: https://bitnami.com/assets/stacks/jasperserver/img/jasperserver-stack-110x117.png
+    keywords:
+    - business intelligence
+    - java
+    - jasper
+    - reporting
+    - analytic
+    - visualization
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: jasperreports
+    sources:
+    - https://github.com/bitnami/bitnami-docker-jasperreports
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jasperreports-0.1.1.tgz
+    version: 0.1.1
+  jenkins:
+  - created: 2017-04-28T00:18:30.084552323Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: e8bb6edabe1af4db4f67e2939b88fa45416167612349a3a32bcf786c529a18e7
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.6.0.tgz
+    version: 0.6.0
+  - created: 2017-04-24T21:03:29.315054715Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: 0c962935ead654ed9422c75978195b9ec893b1e1909b38cdbc15e3dc24863f7e
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.5.1.tgz
+    version: 0.5.1
+  - created: 2017-04-19T16:48:30.580850385Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: 338a9265e567f75469c4e227f583de14b7ab38da137b1d4fd5eee24ddea05724
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.5.0.tgz
+    version: 0.5.0
+  - created: 2017-04-13T19:03:30.206806842Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: 66cb4ab56bdac82c98eea4ceaf0fbcd9bb7c5c446f21bb396c3ce4246a76f423
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-04-13T05:33:26.915479665Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: 109c67f85696136b5629126952d5eb4196ca3cf36524976adf7babd3b8631782
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.4.0.tgz
+    version: 0.4.0
+  - created: 2017-04-13T05:18:28.907645759Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: afa4583548e2e89617e21b91ef014285f060ad4a5355741260d72e27bb8eb4d3
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.3.1.tgz
+    version: 0.3.1
+  - created: 2017-03-30T07:48:56.453711055Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: e9c5280a7cc57b16c51e70af9e4bf8b10f6525daf191c22a3a050a1791e5f7c7
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.3.0.tgz
+    version: 0.3.0
+  - created: 2017-03-22T22:18:33.707478335Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: f5cf5bafd797d65bbbb55ff0b31935123d3f7ac283e703ac0b9df73b016edf59
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.2.0.tgz
+    version: 0.2.0
+  - created: 2017-03-15T09:48:31.97803944Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: f8167252e615a10eb155087d6666985e8eb083781faa0485c0413de8c13deeb8
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.15.tgz
+    version: 0.1.15
+  - created: 2017-03-14T13:33:36.105867963Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: 6c5039f7ab62e7f74bb902f5804814f66733c535908b4ffae1cf759efa3c6f24
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.14.tgz
+    version: 0.1.14
+  - created: 2017-02-13T22:18:28.949796594Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: 90aa0fe9bac319690c871327dff6fee85e7de117e961dfa95ba12abedec4e99b
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.13.tgz
+    version: 0.1.13
+  - created: 2017-02-13T21:48:52.587710548Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: 92224a4dcf96772652e91cee6369a08f21f4ba7d1513ee458b5724720f7045ca
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.12.tgz
+    version: 0.1.12
+  - created: 2017-02-13T21:03:28.21318035Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: c75cadf6bc32c90cfc8a61c1f233884004670c8583edefcfcaa43b5573422923
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.10.tgz
+    version: 0.1.10
+  - created: 2017-02-13T17:03:30.11276321Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: 47f32f975f942607a4b4ca05bd804ece5e2381840508d049251ca692e83080c0
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.9.tgz
+    version: 0.1.9
+  - created: 2017-02-13T04:18:31.534794405Z
+    description: Open source continuous integration server. It supports multiple SCM
+      tools including CVS, Subversion and Git. It can execute Apache Ant and Apache
+      Maven-based projects as well as arbitrary scripts.
+    digest: 0764541a4165016e68bef6de1f405964b58ebb2b43b4d738f4bbbbad794b5df8
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.8.tgz
+    version: 0.1.8
+  - created: 2017-01-27T21:48:32.069740444Z
+    description: A Jenkins Helm chart for Kubernetes.
+    digest: c29819a435e9474277846492930e910c9f7c0605717421c4efe411ce476283ab
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.7.tgz
+    version: 0.1.7
+  - created: 2017-01-04T00:48:19.7378014Z
+    description: A Jenkins Helm chart for Kubernetes.
+    digest: 58ddd6442c8534de79a8d5eaca48263c744ca9fa6e9af7ceb28d1fda9b88ddb5
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.6.tgz
+    version: 0.1.6
+  - created: 2016-12-19T22:03:51.103057889Z
+    description: A Jenkins Helm chart for Kubernetes.
+    digest: 2c8dff77b7ad736ac54e5335f5d52bfacaf7ea2ad97558da507b7f5bb9f4d549
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.5.tgz
+    version: 0.1.5
+  - created: 2016-12-09T18:48:20.183887307Z
+    description: A Jenkins Helm chart for Kubernetes.
+    digest: 0b7016624acec8d66f6d919611e8f1c9853a5475c9801c3da6e50b7ce044ed57
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.4.tgz
+    version: 0.1.4
+  - created: 2016-12-05T18:33:22.028569484Z
+    description: A Jenkins Helm chart for Kubernetes.
+    digest: 82b53a4c90ac2cf71bb41d870939ce1e980192e1407ba8825051c0ed98c04906
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.1.tgz
+    version: 0.1.1
+  - created: 2016-10-19T00:03:14.028672648Z
+    description: A Jenkins Helm chart for Kubernetes.
+    digest: ea97fbfeaf9b9701d71dbc2b6fa50bff25a33f0565233d81170a6ac225d22ab4
+    home: https://jenkins.io/
+    icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
+    maintainers:
+    - email: lachlan@deis.com
+      name: Lachlan Evenson
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: jenkins
+    sources:
+    - https://github.com/jenkinsci/jenkins
+    - https://github.com/jenkinsci/docker-jnlp-slave
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/jenkins-0.1.0.tgz
+    version: 0.1.0
+  joomla:
+  - created: 2017-04-28T00:18:30.085219154Z
+    description: PHP content management system (CMS) for publishing web content
+    digest: 6f9934487533f325515f4877b3af1306c87d64bf3ece9d4bd875289cd73b340d
+    engine: gotpl
+    home: http://www.joomla.org/
+    icon: https://bitnami.com/assets/stacks/joomla/img/joomla-stack-220x234.png
+    keywords:
+    - joomla
+    - cms
+    - blog
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: joomla
+    sources:
+    - https://github.com/bitnami/bitnami-docker-joomla
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/joomla-0.4.6.tgz
+    version: 0.4.6
+  - created: 2017-04-06T11:03:25.397962583Z
+    description: PHP content management system (CMS) for publishing web content
+    digest: f9dedab2fc2dbf170cf45b2c230baa6d20aad9a6f8ccfcb09c459602fc5213dc
+    engine: gotpl
+    home: http://www.joomla.org/
+    icon: https://bitnami.com/assets/stacks/joomla/img/joomla-stack-220x234.png
+    keywords:
+    - joomla
+    - cms
+    - blog
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: joomla
+    sources:
+    - https://github.com/bitnami/bitnami-docker-joomla
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/joomla-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-03-02T19:33:28.178324258Z
+    description: PHP content management system (CMS) for publishing web content
+    digest: 1e067e459873ae832d54ff516a3420f7f0e16ecd8f72f4c4f02be22e47702077
+    engine: gotpl
+    home: http://www.joomla.org/
+    icon: https://bitnami.com/assets/stacks/joomla/img/joomla-stack-220x234.png
+    keywords:
+    - joomla
+    - cms
+    - blog
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: joomla
+    sources:
+    - https://github.com/bitnami/bitnami-docker-joomla
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/joomla-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-02-27T16:48:32.159029074Z
+    description: PHP content management system (CMS) for publishing web content
+    digest: 9a99b15e83e18955eb364985cd545659f1176ef203ac730876dfe39499edfb18
+    engine: gotpl
+    home: http://www.joomla.org/
+    icon: https://bitnami.com/assets/stacks/joomla/img/joomla-stack-220x234.png
+    keywords:
+    - joomla
+    - cms
+    - blog
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: joomla
+    sources:
+    - https://github.com/bitnami/bitnami-docker-joomla
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/joomla-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-02-11T00:18:52.272598223Z
+    description: PHP content management system (CMS) for publishing web content
+    digest: 07c3a16eb674ffc74fe5b2b16191b8bb24c63bdae9bce9710bda1999920c46fc
+    engine: gotpl
+    home: http://www.joomla.org/
+    keywords:
+    - joomla
+    - cms
+    - blog
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: joomla
+    sources:
+    - https://github.com/bitnami/bitnami-docker-joomla
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/joomla-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-01-21T00:18:31.345952551Z
+    description: PHP content management system (CMS) for publishing web content
+    digest: 95fbe272015941544609eee90b3bffd5172bfdec10be13636510caa8478a879e
+    engine: gotpl
+    home: http://www.joomla.org/
+    keywords:
+    - joomla
+    - cms
+    - blog
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: joomla
+    sources:
+    - https://github.com/bitnami/bitnami-docker-joomla
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/joomla-0.4.1.tgz
+    version: 0.4.1
+  - created: 2016-12-09T18:48:20.18539038Z
+    description: PHP content management system (CMS) for publishing web content
+    digest: 0a01ea051ec15274932c8d82076c1a9fd62584b0fb916a81372319bef223c20e
+    engine: gotpl
+    home: http://www.joomla.org/
+    keywords:
+    - joomla
+    - cms
+    - blog
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: joomla
+    sources:
+    - https://github.com/bitnami/bitnami-docker-joomla
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/joomla-0.4.0.tgz
+    version: 0.4.0
+  kapacitor:
+  - created: 2017-04-28T00:18:30.085544137Z
+    description: InfluxDB's native data processing engine. It can process both stream
+      and batch data from InfluxDB.
+    digest: f484ef5acbc3ad68bb765adb1fd6c74920b9265371d3379e43a47ec266dc8449
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/kapacitor/
+    keywords:
+    - kapacitor
+    - stream
+    - etl
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: kapacitor
+    sources:
+    - https://github.com/influxdata/kapacitor
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kapacitor-0.2.2.tgz
+    version: 0.2.2
+  - created: 2017-03-22T21:33:33.841225941Z
+    description: InfluxDB's native data processing engine. It can process both stream
+      and batch data from InfluxDB.
+    digest: c592b3bf2dec92c2273057b984b7289c17032dc578ea0f2ec86aeb5e838a7047
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/kapacitor/
+    keywords:
+    - kapacitor
+    - stream
+    - etl
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: kapacitor
+    sources:
+    - https://github.com/influxdata/kapacitor
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kapacitor-0.2.1.tgz
+    version: 0.2.1
+  - created: 2017-02-13T21:48:52.58883187Z
+    description: InfluxDB's native data processing engine. It can process both stream
+      and batch data from InfluxDB.
+    digest: 18971c9c5b3805830f72fdfacd6c1dfc173db4797994f61b3666296b67abe70a
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/kapacitor/
+    keywords:
+    - kapacitor
+    - stream
+    - etl
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: kapacitor
+    sources:
+    - https://github.com/influxdata/kapacitor
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kapacitor-0.1.2.tgz
+    version: 0.1.2
+  - created: 2017-02-13T21:03:28.215149313Z
+    description: Chart for Chronograf
+    digest: e0d29608602df25a9352629afd3fd7615e01a23549e1d1eba8101ee1b725e528
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/kapacitor/
+    keywords:
+    - kapacitor
+    - stream
+    - etl
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: kapacitor
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kapacitor-0.1.1.tgz
+    version: 0.1.1
+  - created: 2017-01-28T01:33:32.786133788Z
+    description: Chart for Chronograf
+    digest: efde65696634d3bf1dc4c9caae44e68f7ed8c7599aab809c8cdd0fde7e4f9efc
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/kapacitor/
+    keywords:
+    - kapacitor
+    - stream
+    - etl
+    - timeseries
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: kapacitor
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kapacitor-0.1.0.tgz
+    version: 0.1.0
+  kube-lego:
+  - apiVersion: v1
+    created: 2017-04-28T00:18:30.085897046Z
+    description: Automatically requests certificates from Let's Encrypt
+    digest: adc8f0fe1c244e5abda2d918afe9153d47648b2acb779adaf796fa5a7266ea6b
+    engine: gotpl
+    keywords:
+    - kube-lego
+    - letsencrypt
+    maintainers:
+    - email: jack.zampolin@gmail.com
+      name: Jack Zampolin
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: kube-lego
+    sources:
+    - https://github.com/jetstack/kube-lego/tree/master/examples/nginx
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kube-lego-0.1.8.tgz
+    version: 0.1.8
+  - apiVersion: v1
+    created: 2017-03-20T20:03:37.426644363Z
+    description: Automatically requests certificates from Let's Encrypt
+    digest: 0110b8c36f6ad016684ef904b5e514751ffa7a89ba7b88cf4a8376c889e03693
+    engine: gotpl
+    keywords:
+    - kube-lego
+    - letsencrypt
+    maintainers:
+    - email: jack.zampolin@gmail.com
+      name: Jack Zampolin
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: kube-lego
+    sources:
+    - https://github.com/jetstack/kube-lego/tree/master/examples/nginx
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kube-lego-0.1.7.tgz
+    version: 0.1.7
+  - apiVersion: v1
+    created: 2017-03-02T19:33:28.179029307Z
+    description: Automatically requests certificates from Let's Encrypt
+    digest: 275265fda80ccc62376ebd3a200bbea94b105cbf3481efcc726d6a33d73da8d0
+    engine: gotpl
+    keywords:
+    - kube-lego
+    - letsencrypt
+    maintainers:
+    - email: jack.zampolin@gmail.com
+      name: Jack Zampolin
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: kube-lego
+    sources:
+    - https://github.com/jetstack/kube-lego/tree/master/examples/nginx
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kube-lego-0.1.6.tgz
+    version: 0.1.6
+  - apiVersion: v1
+    created: 2017-02-27T17:33:27.264070807Z
+    description: Automatically requests certificates from Let's Encrypt
+    digest: 62de296cc21c6b286097de9ac389033e18a4cd3cf414cd97b7a02d4c3be14d6d
+    engine: gotpl
+    keywords:
+    - kube-lego
+    - letsencrypt
+    maintainers:
+    - email: jack.zampolin@gmail.com
+      name: Jack Zampolin
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: kube-lego
+    sources:
+    - https://github.com/jetstack/kube-lego/tree/master/examples/nginx
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kube-lego-0.1.5.tgz
+    version: 0.1.5
+  - apiVersion: v1
+    created: 2017-02-14T15:48:28.578398517Z
+    description: Automatically requests certificates from Let's Encrypt
+    digest: 1bc993b68eb51fb00e4eb18a65df9e2182f895bd46134d6ddfdc0dd3b6432a98
+    engine: gotpl
+    keywords:
+    - kube-lego
+    - letsencrypt
+    maintainers:
+    - email: jack.zampolin@gmail.com
+      name: Jack Zampolin
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: kube-lego
+    sources:
+    - https://github.com/jetstack/kube-lego/tree/master/examples/nginx
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kube-lego-0.1.4.tgz
+    version: 0.1.4
+  - apiVersion: v1
+    created: 2017-02-11T00:48:25.354730418Z
+    description: Automatically requests certificates from Let's Encrypt
+    digest: d4b3694951c2bb42b356217a8f12870bd3806dac4de3390056279998fd634c34
+    engine: gotpl
+    keywords:
+    - kube-lego
+    - letsencrypt
+    maintainers:
+    - email: jack.zampolin@gmail.com
+      name: Jack Zampolin
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: kube-lego
+    sources:
+    - https://github.com/jetstack/kube-lego/tree/master/examples/nginx
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kube-lego-0.1.3.tgz
+    version: 0.1.3
+  kube-ops-view:
+  - created: 2017-04-28T00:18:30.086143954Z
+    description: Kubernetes Operational View - read-only system dashboard for multiple
+      K8s clusters
+    digest: 9e7b62f2d781aaacee801e91efe4d6b6ef6df9d511c0d6fb2d6e7977c8d0a06e
+    home: https://github.com/hjacobs/kube-ops-view
+    icon: https://raw.githubusercontent.com/hjacobs/kube-ops-view/master/kube-ops-view-logo.png
+    keywords:
+    - kubernetes
+    - dashboard
+    - operations
+    maintainers:
+    - email: henning@jacobs1.de
+      name: Henning Jacobs
+    name: kube-ops-view
+    sources:
+    - https://github.com/hjacobs/kube-ops-view
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kube-ops-view-0.2.0.tgz
+    version: 0.2.0
+  kube2iam:
+  - created: 2017-04-28T00:18:30.086423576Z
+    description: Provide IAM credentials to pods based on annotations.
+    digest: 2035d8dfae5733fa475914694cd060e28954b1f5c930b6c4800ee165d23abc46
+    engine: gotpl
+    keywords:
+    - kube2iam
+    - aws
+    - iam
+    - security
+    maintainers:
+    - email: jm.carp@gmail.com
+      name: Josh Carp
+    - email: michael.haselton@gmail.com
+      name: Michael Haselton
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: kube2iam
+    sources:
+    - https://github.com/jtblin/kube2iam
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kube2iam-0.2.1.tgz
+    version: 0.2.1
+  - created: 2017-03-02T18:48:30.431985789Z
+    description: Provide IAM credentials to pods based on annotations.
+    digest: 5d2226fb101b800fc5a6edb5566d329880c604d75f4245da55f47027bcf5546e
+    engine: gotpl
+    keywords:
+    - kube2iam
+    - aws
+    - iam
+    - security
+    maintainers:
+    - email: jm.carp@gmail.com
+      name: Josh Carp
+    - email: michael.haselton@gmail.com
+      name: Michael Haselton
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: kube2iam
+    sources:
+    - https://github.com/jtblin/kube2iam
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kube2iam-0.2.0.tgz
+    version: 0.2.0
+  - created: 2017-02-13T17:03:30.115672844Z
+    description: Provide IAM credentials to containers running inside a kubernetes
+      cluster based on annotations.
+    digest: 63d913fb8f31c287b1f1d45d310517c0b22597ecdaef19d7ad2520bff990969a
+    engine: gotpl
+    keywords:
+    - kube2iam
+    - aws
+    - iam
+    - security
+    maintainers:
+    - email: jm.carp@gmail.com
+      name: Josh Carp
+    - email: michael.haselton@gmail.com
+      name: Michael Haselton
+    name: kube2iam
+    sources:
+    - https://github.com/jtblin/kube2iam
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kube2iam-0.1.1.tgz
+    version: 0.1.1
+  - created: 2017-01-19T00:33:27.789172853Z
+    description: Provide IAM credentials to containers running inside a kubernetes
+      cluster based on annotations.
+    digest: b4de5bddfa0af6737ea91d9b3a9bcfc3a0e5a656045e06038505613b214120fc
+    engine: gotpl
+    keywords:
+    - kube2iam
+    - aws
+    - iam
+    - security
+    maintainers:
+    - email: jm.carp@gmail.com
+      name: Josh Carp
+    - email: michael.haselton@gmail.com
+      name: Michael Haselton
+    name: kube2iam
+    sources:
+    - https://github.com/jtblin/kube2iam
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/kube2iam-0.1.0.tgz
+    version: 0.1.0
+  linkerd:
+  - apiVersion: v1
+    created: 2017-04-28T00:18:30.086763621Z
+    description: Service mesh for cloud native apps
+    digest: 9341ea67647129999beadb49f1a33131a187569581095907f902daffa73dd73b
+    home: https://linkerd.io/
+    icon: https://pbs.twimg.com/profile_images/690258997237014528/KNgQd9GL_400x400.png
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: linkerd
+    sources:
+    - https://github.com/BuoyantIO/linkerd
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/linkerd-0.2.0.tgz
+    version: 0.2.0
+  - apiVersion: v1
+    created: 2017-03-27T13:18:34.232799345Z
+    description: Service mesh for cloud native apps
+    digest: f9f2287d026c6de3a522bdcffdff061f81a8e64274da4acefdc9d2177b603570
+    home: https://linkerd.io/
+    icon: https://pbs.twimg.com/profile_images/690258997237014528/KNgQd9GL_400x400.png
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: linkerd
+    sources:
+    - https://github.com/BuoyantIO/linkerd
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/linkerd-0.1.1.tgz
+    version: 0.1.1
+  - apiVersion: v1
+    created: 2017-02-13T04:33:52.299092507Z
+    description: Service mesh for cloud native apps
+    digest: 147759e4982f1dffce894e0d4242fb914d21014700a7d9891e8dc352318633fa
+    home: https://linkerd.io/
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: linkerd
+    sources:
+    - https://github.com/BuoyantIO/linkerd
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/linkerd-0.1.0.tgz
+    version: 0.1.0
+  locust:
+  - created: 2017-04-28T00:18:30.087097677Z
+    description: A modern load testing framework
+    digest: eb91b0e3c0b618cf5ad0f24d2685fe4086bc6f497685e58ad8a64032c4e82b7a
+    home: http://locust.io
+    icon: https://pbs.twimg.com/profile_images/1867636195/locust-logo-orignal.png
+    maintainers:
+    - email: vincent.drl@gmail.com
+      name: Vincent De Smet
+    name: locust
+    sources:
+    - https://github.com/honestbee/distributed-load-testing
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/locust-0.1.2.tgz
+    version: 0.1.2
+  - created: 2017-04-20T16:18:33.345004534Z
+    description: A chart for locust distributed load testing
+    digest: 40a353b38823eaa4954dcb70ae92858671a16fb8d00ac9677a36912aab6b629a
+    name: locust
+    sources:
+    - https://github.com/honestbee/distributed-load-testing
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/locust-0.1.1.tgz
+    version: 0.1.1
+  - created: 2017-04-11T16:03:29.689097384Z
+    description: A chart for locust distributed load testing
+    digest: 2cd175e8c8d66625ca3608046d5764662b53e3760aa260a934d3d2ee35148c49
+    name: locust
+    sources:
+    - https://github.com/honestbee/distributed-load-testing
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/locust-0.1.0.tgz
+    version: 0.1.0
+  magento:
+  - created: 2017-04-28T00:18:30.087794886Z
+    description: A feature-rich flexible e-commerce solution. It includes transaction
+      options, multi-store functionality, loyalty programs, product categorization
+      and shopper filtering, promotion rules, and more.
+    digest: 2d7ebf934ca0e742e248753da6502f05929b51329a42d0d4b3db4e1824381f11
+    engine: gotpl
+    home: https://magento.com/
+    icon: https://bitnami.com/assets/stacks/magento/img/magento-stack-110x117.png
+    keywords:
+    - magento
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: magento
+    sources:
+    - https://github.com/bitnami/bitnami-docker-magento
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/magento-0.4.6.tgz
+    version: 0.4.6
+  - created: 2017-03-31T19:33:30.42890495Z
+    description: A feature-rich flexible e-commerce solution. It includes transaction
+      options, multi-store functionality, loyalty programs, product categorization
+      and shopper filtering, promotion rules, and more.
+    digest: a289a051d6d2e8cf833398d7d63fcb1fd953d202f0755800eebe568804fce525
+    engine: gotpl
+    home: https://magento.com/
+    icon: https://bitnami.com/assets/stacks/magento/img/magento-stack-110x117.png
+    keywords:
+    - magento
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: magento
+    sources:
+    - https://github.com/bitnami/bitnami-docker-magento
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/magento-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-03-09T19:33:31.142591331Z
+    description: A feature-rich flexible e-commerce solution. It includes transaction
+      options, multi-store functionality, loyalty programs, product categorization
+      and shopper filtering, promotion rules, and more.
+    digest: 311a98182281b981f60fbd446b42f6af4b86e0bac9445bf2248b1b47dfce5933
+    engine: gotpl
+    home: https://magento.com/
+    icon: https://bitnami.com/assets/stacks/magento/img/magento-stack-110x117.png
+    keywords:
+    - magento
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: magento
+    sources:
+    - https://github.com/bitnami/bitnami-docker-magento
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/magento-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-03-02T19:33:28.180428252Z
+    description: A feature-rich flexible e-commerce solution. It includes transaction
+      options, multi-store functionality, loyalty programs, product categorization
+      and shopper filtering, promotion rules, and more.
+    digest: fccfa89493a977a2f898a5e6d3c6fa4fda15faf0dc0a9e48772744a32c2b1d24
+    engine: gotpl
+    home: https://magento.com/
+    icon: https://bitnami.com/assets/stacks/magento/img/magento-stack-110x117.png
+    keywords:
+    - magento
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: magento
+    sources:
+    - https://github.com/bitnami/bitnami-docker-magento
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/magento-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-02-27T16:48:32.161186722Z
+    description: A feature-rich flexible e-commerce solution. It includes transaction
+      options, multi-store functionality, loyalty programs, product categorization
+      and shopper filtering, promotion rules, and more.
+    digest: fb33cafa4874855419ea3178dc0660a856ed6f8b581b984f38e86701d54e54a6
+    engine: gotpl
+    home: https://magento.com/
+    icon: https://bitnami.com/assets/stacks/magento/img/magento-stack-110x117.png
+    keywords:
+    - magento
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: magento
+    sources:
+    - https://github.com/bitnami/bitnami-docker-magento
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/magento-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-01-21T00:18:31.349108265Z
+    description: A feature-rich flexible e-commerce solution. It includes transaction
+      options, multi-store functionality, loyalty programs, product categorization
+      and shopper filtering, promotion rules, and more.
+    digest: c597107a5cf512d616e5e4134e562f8fcc6e79ad1f78241e9a40ded77e77ef62
+    engine: gotpl
+    home: https://magento.com/
+    icon: https://bitnami.com/assets/stacks/magento/img/magento-stack-110x117.png
+    keywords:
+    - magento
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: magento
+    sources:
+    - https://github.com/bitnami/bitnami-docker-magento
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/magento-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-01-04T00:48:19.74048297Z
+    description: A feature-rich flexible e-commerce solution. It includes transaction
+      options, multi-store functionality, loyalty programs, product categorization
+      and shopper filtering, promotion rules, and more.
+    digest: 526115583b8ae741f6819c2a0d3e719a6622a63a0a2e9918e56d2ebaa6ad498b
+    engine: gotpl
+    home: https://magento.com/
+    icon: https://bitnami.com/assets/stacks/magento/img/magento-stack-110x117.png
+    keywords:
+    - magento
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: magento
+    sources:
+    - https://github.com/bitnami/bitnami-docker-magento
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/magento-0.4.0.tgz
+    version: 0.4.0
+  mariadb:
+  - created: 2017-04-28T00:18:30.088188975Z
+    description: Fast, reliable, scalable, and easy to use open-source relational
+      database system. MariaDB Server is intended for mission-critical, heavy-load
+      production systems as well as for embedding into mass-deployed software.
+    digest: bc13b8aa3728de5595bb83ea8a5c21f9234e169352739d8e72f04d1ed2558508
+    engine: gotpl
+    home: https://mariadb.org
+    icon: https://bitnami.com/assets/stacks/mariadb/img/mariadb-stack-220x234.png
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.6.0.tgz
+    version: 0.6.0
+  - created: 2017-04-03T22:33:26.672780802Z
+    description: Fast, reliable, scalable, and easy to use open-source relational
+      database system. MariaDB Server is intended for mission-critical, heavy-load
+      production systems as well as for embedding into mass-deployed software.
+    digest: 23b81e8bc8cd8577a47a73578b56f68a2a3c15640e0a0fb0ac7f1646845bc0b0
+    engine: gotpl
+    home: https://mariadb.org
+    icon: https://bitnami.com/assets/stacks/mariadb/img/mariadb-stack-220x234.png
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.14.tgz
+    version: 0.5.14
+  - created: 2017-03-23T19:18:29.910295788Z
+    description: Fast, reliable, scalable, and easy to use open-source relational
+      database system. MariaDB Server is intended for mission-critical, heavy-load
+      production systems as well as for embedding into mass-deployed software.
+    digest: a4c8e19714e2a3d29eae03c63a63a7343b3e4f62df2956603acca7eb42ab15de
+    engine: gotpl
+    home: https://mariadb.org
+    icon: https://bitnami.com/assets/stacks/mariadb/img/mariadb-stack-220x234.png
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.13.tgz
+    version: 0.5.13
+  - created: 2017-03-17T22:48:29.250381078Z
+    description: Fast, reliable, scalable, and easy to use open-source relational
+      database system. MariaDB Server is intended for mission-critical, heavy-load
+      production systems as well as for embedding into mass-deployed software.
+    digest: 8d5cd0e79d675baa79ab4f999da8e10037ae4c2158e434b7b60d4ff345f1d976
+    engine: gotpl
+    home: https://mariadb.org
+    icon: https://bitnami.com/assets/stacks/mariadb/img/mariadb-stack-220x234.png
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.12.tgz
+    version: 0.5.12
+  - created: 2017-03-16T13:33:30.840089178Z
+    description: Fast, reliable, scalable, and easy to use open-source relational
+      database system. MariaDB Server is intended for mission-critical, heavy-load
+      production systems as well as for embedding into mass-deployed software.
+    digest: 0841b64dbe2fe499bd3554fa9b2074be0ed6535e9f87d3ea2c13bcfc2616717b
+    engine: gotpl
+    home: https://mariadb.org
+    icon: https://bitnami.com/assets/stacks/mariadb/img/mariadb-stack-220x234.png
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.11.tgz
+    version: 0.5.11
+  - created: 2017-03-15T23:03:34.130536152Z
+    description: Fast, reliable, scalable, and easy to use open-source relational
+      database system. MariaDB Server is intended for mission-critical, heavy-load
+      production systems as well as for embedding into mass-deployed software.
+    digest: 587d7ef318ee1229d14e3b783c3e825f90f274f56b2eb62f1c7126f69fec6fc2
+    engine: gotpl
+    home: https://mariadb.org
+    icon: https://bitnami.com/assets/stacks/mariadb/img/mariadb-stack-220x234.png
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.10.tgz
+    version: 0.5.10
+  - created: 2017-03-08T19:03:31.728285865Z
+    description: Fast, reliable, scalable, and easy to use open-source relational
+      database system. MariaDB Server is intended for mission-critical, heavy-load
+      production systems as well as for embedding into mass-deployed software.
+    digest: cfec18e7be68a616a5e4944c21ed0b65dab1701cf7182d0d1bdea83df6a77ab1
+    engine: gotpl
+    home: https://mariadb.org
+    icon: https://bitnami.com/assets/stacks/mariadb/img/mariadb-stack-220x234.png
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.9.tgz
+    version: 0.5.9
+  - created: 2017-02-11T00:18:52.27620633Z
+    description: Chart for MariaDB
+    digest: 33990fb57b2fafb4396498e02a8083f6a476cf0b465a4a52905a67aab73f3f43
+    engine: gotpl
+    home: https://mariadb.org
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.8.tgz
+    version: 0.5.8
+  - created: 2017-01-31T01:03:26.972704179Z
+    description: Chart for MariaDB
+    digest: 177a882b4248d6ebb2e72e125a3be775085bf082e4eb8f4359fee9e8640ede50
+    engine: gotpl
+    home: https://mariadb.org
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.7.tgz
+    version: 0.5.7
+  - created: 2017-01-27T22:33:30.411626628Z
+    description: Chart for MariaDB
+    digest: 730d179ab0d5922494e3c21594ce7b4f118f7fe796071dfcfdbbc2714ada7d15
+    engine: gotpl
+    home: https://mariadb.org
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.6.tgz
+    version: 0.5.6
+  - created: 2016-12-15T23:18:25.557355931Z
+    description: Chart for MariaDB
+    digest: c7811fad8165eb5d57eb55ad4e58d63e949d2f710c0fbbcd28cca11bb6af6de6
+    engine: gotpl
+    home: https://mariadb.org
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.5.tgz
+    version: 0.5.5
+  - created: 2016-12-09T18:48:20.185787408Z
+    description: Chart for MariaDB
+    digest: c6b73c5146d085a202f838741526fe5fdc2fae55b8f5f17c0c42fd195c65311f
+    engine: gotpl
+    home: https://mariadb.org
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.4.tgz
+    version: 0.5.4
+  - created: 2016-11-23T00:33:20.016012859Z
+    description: Chart for MariaDB
+    digest: 38786f4f6fe4fb7a2dcbc38aa0bfea72e40e4d9766e1679942af60e25b5ba9bd
+    engine: gotpl
+    home: https://mariadb.org
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.3.tgz
+    version: 0.5.3
+  - created: 2016-11-03T19:33:29.120356141Z
+    description: Chart for MariaDB
+    digest: 8eb24c65fbdb75711a8ffd8f8f6ed206951cdc3a24d74a355121bc11c6c02f3b
+    engine: gotpl
+    home: https://mariadb.org
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.2.tgz
+    version: 0.5.2
+  - created: 2016-10-19T00:03:14.031007257Z
+    description: Chart for MariaDB
+    digest: 6544dbf62586f570762a3a469f0086fe595379454fb46a53d001206a0e282268
+    engine: gotpl
+    home: https://mariadb.org
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.1.tgz
+    version: 0.5.1
+  - created: 2016-10-19T00:03:14.030598543Z
+    description: Chart for MariaDB
+    digest: c9f67f8140b3e7243d479f819d4ec8b2e992ee462b8fa579b920e86066955312
+    engine: gotpl
+    home: https://mariadb.org
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.5.0.tgz
+    version: 0.5.0
+  - created: 2016-10-19T00:03:14.03012509Z
+    description: Chart for MariaDB
+    digest: fe8adb0730567ad8cd63501ac18b178ec2a9a590d43dd7ad91fd2d5fcf6114be
+    engine: gotpl
+    home: https://mariadb.org
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.4.0.tgz
+    version: 0.4.0
+  - created: 2016-10-19T00:03:14.029775557Z
+    description: Chart for MariaDB
+    digest: 47fe08909187da025e7e86e9534a736df11e2629c5c123178113fe776992e9e7
+    engine: gotpl
+    home: https://mariadb.org
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.3.1.tgz
+    version: 0.3.1
+  - created: 2016-10-19T00:03:14.02942396Z
+    description: Chart for MariaDB
+    digest: 7354d2672b3983e98fe5c31d96d2c3d9c73edefe642eb5e1981484804315c4bc
+    engine: gotpl
+    home: https://mariadb.org
+    keywords:
+    - mariadb
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mariadb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mariadb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mariadb-0.3.0.tgz
+    version: 0.3.0
+  mediawiki:
+  - created: 2017-04-28T00:18:30.088860566Z
+    description: Extremely powerful, scalable software and a feature-rich wiki implementation
+      that uses PHP to process and display data stored in a database.
+    digest: 0e51822c5547895109a5b41ce426c77f62d0434b40f3021afee8471ab976a6f5
+    engine: gotpl
+    home: http://www.mediawiki.org/
+    icon: https://bitnami.com/assets/stacks/mediawiki/img/mediawiki-stack-220x234.png
+    keywords:
+    - mediawiki
+    - wiki
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mediawiki
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mediawiki
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mediawiki-0.4.6.tgz
+    version: 0.4.6
+  - created: 2017-04-06T10:18:27.586263816Z
+    description: Extremely powerful, scalable software and a feature-rich wiki implementation
+      that uses PHP to process and display data stored in a database.
+    digest: 0e419c2c5d87997f94a32da6597af3f3b52120dc1ec682dcbb6b238fb4825e06
+    engine: gotpl
+    home: http://www.mediawiki.org/
+    icon: https://bitnami.com/assets/stacks/mediawiki/img/mediawiki-stack-220x234.png
+    keywords:
+    - mediawiki
+    - wiki
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mediawiki
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mediawiki
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mediawiki-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-03-08T19:03:31.729226516Z
+    description: Extremely powerful, scalable software and a feature-rich wiki implementation
+      that uses PHP to process and display data stored in a database.
+    digest: 6f4dde26737f7f1aa63ffda6c259ce388e3a3509225f90f334bfc3f0f7617bc1
+    engine: gotpl
+    home: http://www.mediawiki.org/
+    icon: https://bitnami.com/assets/stacks/mediawiki/img/mediawiki-stack-220x234.png
+    keywords:
+    - mediawiki
+    - wiki
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mediawiki
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mediawiki
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mediawiki-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-02-13T04:18:31.539427547Z
+    description: Extremely powerful, scalable software and a feature-rich wiki implementation
+      that uses PHP to process and display data stored in a database.
+    digest: 0ba52b8c4c9e0bee3eb76fe625d2dc88729a1cdf41ace9d13cd4abc5b477cfb8
+    engine: gotpl
+    home: http://www.mediawiki.org/
+    keywords:
+    - mediawiki
+    - wiki
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mediawiki
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mediawiki
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mediawiki-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-01-21T00:18:31.350311075Z
+    description: Extremely powerful, scalable software and a feature-rich wiki implementation
+      that uses PHP to process and display data stored in a database.
+    digest: f49df3e17f97b238743aad0376eb9db7e4a9bca3829a3a65d7bbb349344a73be
+    engine: gotpl
+    home: http://www.mediawiki.org/
+    keywords:
+    - mediawiki
+    - wiki
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mediawiki
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mediawiki
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mediawiki-0.4.2.tgz
+    version: 0.4.2
+  - created: 2016-12-15T21:18:24.670966268Z
+    description: Extremely powerful, scalable software and a feature-rich wiki implementation
+      that uses PHP to process and display data stored in a database.
+    digest: 339a90050d5cf4216140409349a356aa7cd8dc95e2cbdca06e4fdd11e87aa963
+    engine: gotpl
+    home: http://www.mediawiki.org/
+    keywords:
+    - mediawiki
+    - wiki
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mediawiki
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mediawiki
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mediawiki-0.4.1.tgz
+    version: 0.4.1
+  - created: 2016-12-09T18:48:20.186416136Z
+    description: Extremely powerful, scalable software and a feature-rich wiki implementation
+      that uses PHP to process and display data stored in a database.
+    digest: 9617f13f51f5bb016a072f2a026c627420721a1c5b7cd22f32d6cd0c90f34eda
+    engine: gotpl
+    home: http://www.mediawiki.org/
+    keywords:
+    - mediawiki
+    - wiki
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mediawiki
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mediawiki
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mediawiki-0.4.0.tgz
+    version: 0.4.0
+  memcached:
+  - created: 2017-04-28T00:18:30.090586195Z
+    description: Free & open source, high-performance, distributed memory object caching
+      system.
+    digest: 36ceb2767094598171b2851ecda54bd43d862b9b81aa4b294f3d8c8d59ddd79c
+    engine: gotpl
+    home: http://memcached.org/
+    icon: https://upload.wikimedia.org/wikipedia/en/thumb/2/27/Memcached.svg/1024px-Memcached.svg.png
+    keywords:
+    - memcached
+    - cache
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: memcached
+    sources:
+    - https://github.com/docker-library/memcached
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/memcached-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-02-13T04:18:31.539713999Z
+    description: Chart for Memcached
+    digest: 2b918dd8129a9d706e58b3de459004e3367c05a162d3e3cdb031cb6818d5f820
+    engine: gotpl
+    home: http://memcached.org/
+    keywords:
+    - memcached
+    - cache
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: memcached
+    sources:
+    - https://github.com/docker-library/memcached
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/memcached-0.4.0.tgz
+    version: 0.4.0
+  minecraft:
+  - created: 2017-04-28T00:18:30.09103508Z
+    description: Minecraft server
+    digest: bc18a8356092c19f39ce94ff34b2160650a7bebca5723fd2e2f4e350c38793c0
+    keywords:
+    - game
+    - server
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: minecraft
+    sources:
+    - https://hub.docker.com/r/itzg/minecraft-server/~/dockerfile/
+    - https://github.com/itzg/dockerfiles
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/minecraft-0.1.3.tgz
+    version: 0.1.3
+  - created: 2017-03-16T23:33:31.588714127Z
+    description: Minecraft server
+    digest: 5a42451d7c2f69b7b77c40e91ef60ca284798bcab8aa5b97b1f3f2559612d443
+    keywords:
+    - game
+    - server
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: minecraft
+    sources:
+    - https://hub.docker.com/r/itzg/minecraft-server/~/dockerfile/
+    - https://github.com/itzg/dockerfiles
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/minecraft-0.1.2.tgz
+    version: 0.1.2
+  - created: 2017-01-30T23:33:28.437640114Z
+    description: Minecraft server
+    digest: 87c2ef91c8feaee680bb26ba16362c6b366429e0f54119c40dbf7a5ce3f22553
+    keywords:
+    - game
+    - server
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: minecraft
+    sources:
+    - https://hub.docker.com/r/itzg/minecraft-server/~/dockerfile/
+    - https://github.com/itzg/dockerfiles
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/minecraft-0.1.1.tgz
+    version: 0.1.1
+  - created: 2016-12-05T21:03:20.22190695Z
+    description: Minecraft server
+    digest: 2cd423a28eb8a0186fba171cc17dcbe6f5a53d1a99e4078f9713afed3b61cce6
+    keywords:
+    - game
+    - server
+    maintainers:
+    - email: gtaylor@gc-taylor.com
+      name: Greg Taylor
+    name: minecraft
+    sources:
+    - https://hub.docker.com/r/itzg/minecraft-server/~/dockerfile/
+    - https://github.com/itzg/dockerfiles
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/minecraft-0.1.0.tgz
+    version: 0.1.0
+  minio:
+  - apiVersion: v1
+    created: 2017-04-28T00:18:30.091526674Z
+    description: Distributed object storage server built for cloud applications and
+      devops.
+    digest: 12eb77d0d25971c86a4df25297eea8d579b4b5dc6599d16f340f553977c53914
+    home: https://minio.io
+    icon: https://www.minio.io/logo/img/logo-dark.svg
+    keywords:
+    - storage
+    - object-storage
+    - S3
+    maintainers:
+    - email: hello@acale.ph
+      name: Acaleph
+    - email: hello@minio.io
+      name: Minio
+    name: minio
+    sources:
+    - https://github.com/minio/minio
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/minio-0.1.0.tgz
+    version: 0.1.0
+  - apiVersion: v1
+    created: 2017-03-16T23:48:28.876000842Z
+    description: Distributed object storage server built for cloud applications and
+      devops.
+    digest: d19b721fcb5f0566cce4a259e296b957ba982e87343947e1cbdbe979c770378d
+    home: https://minio.io
+    icon: https://www.minio.io/logo/img/logo-dark.svg
+    keywords:
+    - storage
+    - object-storage
+    - S3
+    maintainers:
+    - email: hello@acale.ph
+      name: Acaleph
+    - email: hello@minio.io
+      name: Minio
+    name: minio
+    sources:
+    - https://github.com/minio/minio
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/minio-0.0.4.tgz
+    version: 0.0.4
+  - apiVersion: v1
+    created: 2017-02-13T04:33:52.302413618Z
+    description: A Minio Helm chart for Kubernetes
+    digest: cd58148df0776329fe5f518c542759565cab29dbefbc43f6b0ffdac86c9b31a9
+    home: https://minio.io
+    keywords:
+    - storage
+    - object-storage
+    - S3
+    maintainers:
+    - email: hello@acale.ph
+      name: Acaleph
+    - email: hello@minio.io
+      name: Minio
+    name: minio
+    sources:
+    - https://github.com/minio/minio
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/minio-0.0.3.tgz
+    version: 0.0.3
+  - apiVersion: v1
+    created: 2017-02-03T20:18:29.15659791Z
+    description: A Minio Helm chart for Kubernetes
+    digest: 699003bf2ef4cbb570580887da980412c1b9d6d173636de5def6053c7ba29a2a
+    home: https://minio.io
+    keywords:
+    - storage
+    - object-storage
+    - S3
+    maintainers:
+    - email: hello@acale.ph
+      name: Acaleph
+    - email: hello@minio.io
+      name: Minio
+    name: minio
+    sources:
+    - https://github.com/minio/minio
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/minio-0.0.2.tgz
+    version: 0.0.2
+  - apiVersion: v1
+    created: 2017-01-12T02:36:05.500400572Z
+    description: A Minio Helm chart for Kubernetes
+    digest: aed17de3622988f8366126e158c740535c8d3bc55a0a85a3dcfabf07ac1395e9
+    home: https://minio.io
+    keywords:
+    - storage
+    - object-storage
+    - S3
+    maintainers:
+    - email: hello@acale.ph
+      name: Acaleph
+    name: minio
+    sources:
+    - https://github.com/minio/minio
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/minio-0.0.1.tgz
+    version: 0.0.1
+  mongodb:
+  - created: 2017-04-28T00:18:30.091865909Z
+    description: NoSQL document-oriented database that stores JSON-like documents
+      with dynamic schemas, simplifying the integration of data in content-driven
+      applications.
+    digest: 979d36b208be9b266c70860d4fe1f9e5130d9d60b3bcbd893132452648dfe27f
+    engine: gotpl
+    home: https://mongodb.org
+    icon: https://bitnami.com/assets/stacks/mongodb/img/mongodb-stack-220x234.png
+    keywords:
+    - mongodb
+    - database
+    - nosql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mongodb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mongodb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mongodb-0.4.9.tgz
+    version: 0.4.9
+  - created: 2017-04-06T10:33:26.324740815Z
+    description: NoSQL document-oriented database that stores JSON-like documents
+      with dynamic schemas, simplifying the integration of data in content-driven
+      applications.
+    digest: cdc9fc28ff9139fcc6be015177e481f9d3765d6af284dce1999fc334cd7ef3a4
+    engine: gotpl
+    home: https://mongodb.org
+    icon: https://bitnami.com/assets/stacks/mongodb/img/mongodb-stack-220x234.png
+    keywords:
+    - mongodb
+    - database
+    - nosql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mongodb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mongodb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mongodb-0.4.8.tgz
+    version: 0.4.8
+  - created: 2017-03-08T19:03:31.731176002Z
+    description: NoSQL document-oriented database that stores JSON-like documents
+      with dynamic schemas, simplifying the integration of data in content-driven
+      applications.
+    digest: 7d334e12acf9327f58f9a890e884a61ad760da2b1081d4a79b5680bee055cdbd
+    engine: gotpl
+    home: https://mongodb.org
+    icon: https://bitnami.com/assets/stacks/mongodb/img/mongodb-stack-220x234.png
+    keywords:
+    - mongodb
+    - database
+    - nosql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mongodb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mongodb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mongodb-0.4.7.tgz
+    version: 0.4.7
+  - created: 2017-02-14T03:48:27.566728756Z
+    description: NoSQL document-oriented database that stores JSON-like documents
+      with dynamic schemas, simplifying the integration of data in content-driven
+      applications.
+    digest: 27f9071cb81e9d3745776861f453db80b6ab6bf4507809f2e5c59e8a34d44939
+    engine: gotpl
+    home: https://mongodb.org
+    icon: https://bitnami.com/assets/stacks/mongodb/img/mongodb-stack-220x234.png
+    keywords:
+    - mongodb
+    - database
+    - nosql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mongodb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mongodb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mongodb-0.4.6.tgz
+    version: 0.4.6
+  - created: 2017-02-10T23:18:26.017406698Z
+    description: Chart for MongoDB
+    digest: 27a78b0c6300f4567975af18a3ca145940a716a53de42ed89c75872788d2848b
+    engine: gotpl
+    home: https://mongodb.org
+    keywords:
+    - mongodb
+    - database
+    - nosql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mongodb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mongodb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mongodb-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-01-30T23:33:28.438574863Z
+    description: Chart for MongoDB
+    digest: 9bcc0e2aa1d7d8f8c2ce43ef9284af39e5794214d185577ed1baff07c1a019f4
+    engine: gotpl
+    home: https://mongodb.org
+    keywords:
+    - mongodb
+    - database
+    - nosql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mongodb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mongodb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mongodb-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-01-13T20:48:31.52900213Z
+    description: Chart for MongoDB
+    digest: be548ec183b8c44f031504864b85b7a0d48d745fa450bf733f89646c9cbbda44
+    engine: gotpl
+    home: https://mongodb.org
+    keywords:
+    - mongodb
+    - database
+    - nosql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mongodb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mongodb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mongodb-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-01-03T17:48:20.740456601Z
+    description: Chart for MongoDB
+    digest: 027dd50ff545309506daa0636a62d633071379040f8be080a403cb6d67399b0d
+    engine: gotpl
+    home: https://mongodb.org
+    keywords:
+    - mongodb
+    - database
+    - nosql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mongodb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mongodb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mongodb-0.4.2.tgz
+    version: 0.4.2
+  - created: 2016-12-15T00:48:24.012807516Z
+    description: Chart for MongoDB
+    digest: 42e8e56c715ea3bd2b8f9c188f5a9aec48a87654fb5215c35728ddf6c33c7437
+    engine: gotpl
+    home: https://mongodb.org
+    keywords:
+    - mongodb
+    - database
+    - nosql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mongodb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mongodb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mongodb-0.4.1.tgz
+    version: 0.4.1
+  - created: 2016-12-09T18:48:20.187403991Z
+    description: Chart for MongoDB
+    digest: d5eabbe99b03b4f7f71c461580564e3d965c2602bfd1be4dd09f1c54c8e7e9db
+    engine: gotpl
+    home: https://mongodb.org
+    keywords:
+    - mongodb
+    - database
+    - nosql
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: mongodb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-mongodb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mongodb-0.4.0.tgz
+    version: 0.4.0
+  mongodb-replicaset:
+  - created: 2017-04-28T00:18:30.092344824Z
+    description: NoSQL document-oriented database that stores JSON-like documents
+      with dynamic schemas, simplifying the integration of data in content-driven
+      applications.
+    digest: 98592fbb471eb98d3c59deb83ed9bd2a808e8df972b21ff183d04fa4659e9a39
+    home: https://github.com/mongodb/mongo
+    icon: https://webassets.mongodb.com/_com_assets/cms/mongodb-logo-rgb-j6w271g1xn.jpg
+    maintainers:
+    - email: ramanathana@google.com
+      name: Anirudh Ramanathan
+    name: mongodb-replicaset
+    sources:
+    - https://github.com/mongodb/mongo
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mongodb-replicaset-1.0.0.tgz
+    version: 1.0.0
+  moodle:
+  - created: 2017-04-28T00:18:30.093014917Z
+    description: Moodle is a learning platform designed to provide educators, administrators
+      and learners with a single robust, secure and integrated system to create personalised
+      learning environments
+    digest: 386bff8ce61cf61961daf8ed6d68a76cd3a360560a08c1fca80bcbd897f11270
+    engine: gotpl
+    home: http://www.moodle.org/
+    icon: https://bitnami.com/assets/stacks/moodle/img/moodle-stack-110x117.png
+    keywords:
+    - moodle
+    - learning
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: moodle
+    sources:
+    - https://github.com/bitnami/bitnami-docker-moodle
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/moodle-0.1.4.tgz
+    version: 0.1.4
+  - created: 2017-03-31T19:33:30.433327839Z
+    description: Moodle is a learning platform designed to provide educators, administrators
+      and learners with a single robust, secure and integrated system to create personalised
+      learning environments
+    digest: bd85420a7cefd82e9d96088591601f832ecc60016d6389dbcde51a2050327a66
+    engine: gotpl
+    home: http://www.moodle.org/
+    icon: https://bitnami.com/assets/stacks/moodle/img/moodle-stack-110x117.png
+    keywords:
+    - moodle
+    - learning
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: moodle
+    sources:
+    - https://github.com/bitnami/bitnami-docker-moodle
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/moodle-0.1.3.tgz
+    version: 0.1.3
+  - created: 2017-03-26T18:03:33.791615833Z
+    description: Moodle is a learning platform designed to provide educators, administrators
+      and learners with a single robust, secure and integrated system to create personalised
+      learning environments
+    digest: 8656c544a71fa8cc4ac23380e999e072740ec8e481a22aff86517d8362e70121
+    engine: gotpl
+    home: http://www.moodle.org/
+    icon: https://bitnami.com/assets/stacks/moodle/img/moodle-stack-110x117.png
+    keywords:
+    - moodle
+    - learning
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: moodle
+    sources:
+    - https://github.com/bitnami/bitnami-docker-moodle
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/moodle-0.1.2.tgz
+    version: 0.1.2
+  mysql:
+  - created: 2017-04-28T00:18:30.093353908Z
+    description: Fast, reliable, scalable, and easy to use open-source relational
+      database system.
+    digest: 2de7736158326da89faed2e5af952b4c7288f61bd96377ef345a99b4b271a3e7
+    engine: gotpl
+    home: https://www.mysql.com/
+    icon: https://www.mysql.com/common/logos/logo-mysql-170x115.png
+    keywords:
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: mysql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mysql-0.2.6.tgz
+    version: 0.2.6
+  - created: 2017-04-13T05:18:28.91694371Z
+    description: Fast, reliable, scalable, and easy to use open-source relational
+      database system.
+    digest: 66b9a6787a36c72095c24499a45f2d3bfc700e31420a8926d09c029604ac4c98
+    engine: gotpl
+    home: https://www.mysql.com/
+    icon: https://www.mysql.com/common/logos/logo-mysql-170x115.png
+    keywords:
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: mysql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mysql-0.2.5.tgz
+    version: 0.2.5
+  - created: 2017-02-13T04:18:31.541320579Z
+    description: Chart for MySQL
+    digest: 3653a2d111ca60287ffbf10cbbb3c268dcb8666422bf5518d37adb9b2f131f7c
+    engine: gotpl
+    home: https://www.mysql.com/
+    keywords:
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: mysql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mysql-0.2.4.tgz
+    version: 0.2.4
+  - created: 2017-01-27T22:33:30.41494884Z
+    description: Chart for MySQL
+    digest: 1244814f3490d23172a923e52339ad8b126f3037483db462591405863884e7ce
+    engine: gotpl
+    home: https://www.mysql.com/
+    keywords:
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: mysql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mysql-0.2.3.tgz
+    version: 0.2.3
+  - created: 2016-12-21T19:33:19.335178436Z
+    description: Chart for MySQL
+    digest: 5dfdd6301aa5c7424c5ecc649ac3038ea72afd0e25d4c350c79e8ba84fe15faf
+    engine: gotpl
+    home: https://www.mysql.com/
+    keywords:
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: mysql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mysql-0.2.2.tgz
+    version: 0.2.2
+  - created: 2016-12-09T18:48:20.187750412Z
+    description: Chart for MySQL
+    digest: 3dd20c2ed2faf64b9f940e813b18d7fa1c18c1b86101de453c7c836940e05680
+    engine: gotpl
+    home: https://www.mysql.com/
+    keywords:
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: mysql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mysql-0.2.1.tgz
+    version: 0.2.1
+  - created: 2016-11-04T14:18:20.013918541Z
+    description: Chart for MySQL
+    digest: 9723417e4d71713ed87b701eff52a1a74abea64c3cf852833b1e9bb96ff6fd55
+    engine: gotpl
+    home: https://www.mysql.com/
+    keywords:
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: mysql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mysql-0.2.0.tgz
+    version: 0.2.0
+  - created: 2016-11-03T03:18:19.715713217Z
+    description: Chart for MySQL
+    digest: fef93423760265f8bb3aedf9a922ed0169e018071ea467f22c17527006ae6a60
+    engine: gotpl
+    home: https://www.mysql.com/
+    keywords:
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: mysql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mysql-0.1.2.tgz
+    version: 0.1.2
+  - created: 2016-10-19T18:33:14.866729383Z
+    description: Chart for MySQL
+    digest: 3cb4495336e12d4fea28a1f7e3f02bbb18249582227866088cf6ac89587a2527
+    engine: gotpl
+    home: https://www.mysql.com/
+    keywords:
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: mysql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mysql-0.1.1.tgz
+    version: 0.1.1
+  - created: 2016-10-19T00:03:14.031801762Z
+    description: Chart for MySQL
+    digest: cba3eff1710520dbfbbeca2b0f9a754e0ddc172eb83ce51211606387955a6572
+    engine: gotpl
+    home: https://www.mysql.com/
+    keywords:
+    - mysql
+    - database
+    - sql
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: mysql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/mysql-0.1.0.tgz
+    version: 0.1.0
+  namerd:
+  - apiVersion: v1
+    created: 2017-04-28T00:18:30.093626863Z
+    description: Service that manages routing for multiple linkerd instances
+    digest: 52164352b00a196135a608198d12748d063965cfde016dc8a4fdc9021587bbeb
+    home: https://linkerd.io/in-depth/namerd/
+    icon: https://pbs.twimg.com/profile_images/690258997237014528/KNgQd9GL_400x400.png
+    maintainers:
+    - email: knoxville@gmail.com
+      name: Sean Knox
+    name: namerd
+    sources:
+    - https://github.com/linkerd/linkerd
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/namerd-0.1.0.tgz
+    version: 0.1.0
+  nginx-ingress:
+  - created: 2017-04-28T00:18:30.094151336Z
+    description: An nginx Ingress controller that uses ConfigMap to store the nginx
+      configuration.
+    digest: 2d6183d368b3993b4fdfd7108531067b928083b3db6dc30eab3f9c3a8212df9b
+    engine: gotpl
+    icon: https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Nginx_logo.svg/500px-Nginx_logo.svg.png
+    keywords:
+    - ingress
+    - nginx
+    maintainers:
+    - email: jack.zampolin@gmail.com
+      name: Jack Zampolin
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    - email: chance.zibolski@coreos.com
+      name: Chance Zibolski
+    name: nginx-ingress
+    sources:
+    - https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/nginx-ingress-0.3.2.tgz
+    version: 0.3.2
+  - created: 2017-04-03T22:33:26.678796256Z
+    description: An nginx Ingress controller that uses ConfigMap to store the nginx
+      configuration.
+    digest: 4e4632273eb5db95e525a8899b9f6f1697db241c2ff1ccb7456e0fc916bb75c2
+    engine: gotpl
+    icon: https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Nginx_logo.svg/500px-Nginx_logo.svg.png
+    keywords:
+    - ingress
+    - nginx
+    maintainers:
+    - email: jack.zampolin@gmail.com
+      name: Jack Zampolin
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    - email: chance.zibolski@coreos.com
+      name: Chance Zibolski
+    name: nginx-ingress
+    sources:
+    - https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/nginx-ingress-0.3.1.tgz
+    version: 0.3.1
+  - created: 2017-03-10T17:03:37.208481141Z
+    description: An nginx Ingress controller that uses ConfigMap to store the nginx
+      configuration.
+    digest: 731823c88a849f945f405c192d92daf27afad37af76befb1eb92251240de29d7
+    engine: gotpl
+    icon: https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Nginx_logo.svg/500px-Nginx_logo.svg.png
+    keywords:
+    - ingress
+    - nginx
+    maintainers:
+    - email: jack.zampolin@gmail.com
+      name: Jack Zampolin
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: nginx-ingress
+    sources:
+    - https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/nginx-ingress-0.3.0.tgz
+    version: 0.3.0
+  nginx-lego:
+  - created: 2017-04-28T00:18:30.094506147Z
+    description: Chart for nginx-ingress-controller and kube-lego
+    digest: da173cc1a9313ea0b11f5fb7aa67a20a2ac797b2f129a079c06284e8a9765f21
+    engine: gotpl
+    keywords:
+    - kube-lego
+    - nginx-ingress-controller
+    - nginx
+    - letsencrypt
+    maintainers:
+    - email: jack.zampolin@gmail.com
+      name: Jack Zampolin
+    name: nginx-lego
+    sources:
+    - https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx
+    - https://github.com/jetstack/kube-lego/tree/master/examples/nginx
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/nginx-lego-0.2.1.tgz
+    version: 0.2.1
+  - created: 2017-03-02T18:48:30.43738595Z
+    description: Chart for nginx-ingress-controller and kube-lego
+    digest: 9a8ea81371900d2c7931b0143f991ef0fde41038d26a968628008aef14ec08ef
+    engine: gotpl
+    keywords:
+    - kube-lego
+    - nginx-ingress-controller
+    - nginx
+    - letsencrypt
+    maintainers:
+    - email: jack.zampolin@gmail.com
+      name: Jack Zampolin
+    name: nginx-lego
+    sources:
+    - https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx
+    - https://github.com/jetstack/kube-lego/tree/master/examples/nginx
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/nginx-lego-0.2.0.tgz
+    version: 0.2.0
+  - created: 2017-01-12T02:52:37.835917781Z
+    description: Chart for nginx-ingress-controller and kube-lego
+    digest: 2dee942e546940beb8301a94a1a51e22c7a38b4c5592701528149dfaa83e1bb6
+    engine: gotpl
+    keywords:
+    - kube-lego
+    - nginx-ingress-controller
+    - nginx
+    - letsencrypt
+    maintainers:
+    - email: jack.zampolin@gmail.com
+      name: Jack Zampolin
+    name: nginx-lego
+    sources:
+    - https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx
+    - https://github.com/jetstack/kube-lego/tree/master/examples/nginx
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/nginx-lego-0.1.0.tgz
+    version: 0.1.0
+  odoo:
+  - created: 2017-04-28T00:18:30.095144247Z
+    description: A suite of web based open source business apps.
+    digest: 439b9160c3226a0cf6b848a5ac921307e5100ffa36e03e3697619a6c968eec3b
+    engine: gotpl
+    home: https://www.odoo.com/
+    icon: https://bitnami.com/assets/stacks/odoo/img/odoo-stack-110x117.png
+    keywords:
+    - odoo
+    - crm
+    - www
+    - http
+    - web
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: odoo
+    sources:
+    - https://github.com/bitnami/bitnami-docker-odoo
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/odoo-0.5.0.tgz
+    version: 0.5.0
+  - created: 2017-04-20T11:48:30.777572861Z
+    description: A suite of web based open source business apps.
+    digest: 4aeba5cf600c9552d3a0ace00b4880aa27d8b2c2aec1b7dc9ebad04f2152d165
+    engine: gotpl
+    home: https://www.odoo.com/
+    icon: https://bitnami.com/assets/stacks/odoo/img/odoo-stack-110x117.png
+    keywords:
+    - odoo
+    - crm
+    - www
+    - http
+    - web
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: odoo
+    sources:
+    - https://github.com/bitnami/bitnami-docker-odoo
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/odoo-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-04-19T19:48:30.479799003Z
+    description: A suite of web based open source business apps.
+    digest: 74dff526f84c50445e0cc0fb602679c68941e9b93d9410ce66a6f3713a71f39d
+    engine: gotpl
+    home: https://www.odoo.com/
+    icon: https://bitnami.com/assets/stacks/odoo/img/odoo-stack-110x117.png
+    keywords:
+    - odoo
+    - crm
+    - www
+    - http
+    - web
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: odoo
+    sources:
+    - https://github.com/bitnami/bitnami-docker-odoo
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/odoo-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-03-23T21:18:31.859026332Z
+    description: A suite of web based open source business apps.
+    digest: 6bdd86f83c41f079218105162f1e86cf572d005174c0688a2201c59d20cf1e55
+    engine: gotpl
+    home: https://www.odoo.com/
+    icon: https://bitnami.com/assets/stacks/odoo/img/odoo-stack-110x117.png
+    keywords:
+    - odoo
+    - crm
+    - www
+    - http
+    - web
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: odoo
+    sources:
+    - https://github.com/bitnami/bitnami-docker-odoo
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/odoo-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-03-23T00:18:30.533565303Z
+    description: A suite of web based open source business apps.
+    digest: 9a7723d94d17ff18347074d5a1d6b42530466a8a4882981178f4856138f44072
+    engine: gotpl
+    home: https://www.odoo.com/
+    icon: https://bitnami.com/assets/stacks/odoo/img/odoo-stack-110x117.png
+    keywords:
+    - odoo
+    - crm
+    - www
+    - http
+    - web
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: odoo
+    sources:
+    - https://github.com/bitnami/bitnami-docker-odoo
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/odoo-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-03-17T22:48:29.256461745Z
+    description: A suite of web based open source business apps.
+    digest: 1339b6efbc6b4df849c460ddbcade9f81ede3a6a800e9566f54acc1c52dccb4b
+    engine: gotpl
+    home: https://www.odoo.com/
+    icon: https://bitnami.com/assets/stacks/odoo/img/odoo-stack-110x117.png
+    keywords:
+    - odoo
+    - crm
+    - www
+    - http
+    - web
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: odoo
+    sources:
+    - https://github.com/bitnami/bitnami-docker-odoo
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/odoo-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-03-08T19:03:31.734764598Z
+    description: A suite of web based open source business apps.
+    digest: 15b1d5339086427990fb3d0ee8f65e768b398195f2db63b0356e6c79f4d4b981
+    engine: gotpl
+    home: https://www.odoo.com/
+    icon: https://bitnami.com/assets/stacks/odoo/img/odoo-stack-110x117.png
+    keywords:
+    - odoo
+    - crm
+    - www
+    - http
+    - web
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: odoo
+    sources:
+    - https://github.com/bitnami/bitnami-docker-odoo
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/odoo-0.4.0.tgz
+    version: 0.4.0
+  opencart:
+  - created: 2017-04-28T00:18:30.095906073Z
+    description: A free and open source e-commerce platform for online merchants.
+      It provides a professional and reliable foundation for a successful online store.
+    digest: a22a7ee46a419b2bc4dd0ba66c3fa294e15f86722944a7bc3cc56cb24f3fa737
+    engine: gotpl
+    home: https://opencart.com/
+    icon: https://bitnami.com/assets/stacks/opencart/img/opencart-stack-110x117.png
+    keywords:
+    - opencart
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: opencart
+    sources:
+    - https://github.com/bitnami/bitnami-docker-opencart
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/opencart-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-04-06T11:18:27.44256999Z
+    description: A free and open source e-commerce platform for online merchants.
+      It provides a professional and reliable foundation for a successful online store.
+    digest: 0abb5c30e0eef2a06b36b83b0c11f4bcf3df14ea416c5e49cb821c78e6783bce
+    engine: gotpl
+    home: https://opencart.com/
+    icon: https://bitnami.com/assets/stacks/opencart/img/opencart-stack-110x117.png
+    keywords:
+    - opencart
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: opencart
+    sources:
+    - https://github.com/bitnami/bitnami-docker-opencart
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/opencart-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-03-02T19:33:28.187180475Z
+    description: A free and open source e-commerce platform for online merchants.
+      It provides a professional and reliable foundation for a successful online store.
+    digest: 1a80dfcec98c190b8710d7db47c22c3882a05a046b3d767c84094cef983a1556
+    engine: gotpl
+    home: https://opencart.com/
+    icon: https://bitnami.com/assets/stacks/opencart/img/opencart-stack-110x117.png
+    keywords:
+    - opencart
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: opencart
+    sources:
+    - https://github.com/bitnami/bitnami-docker-opencart
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/opencart-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-02-23T02:33:30.963491381Z
+    description: A free and open source e-commerce platform for online merchants.
+      It provides a professional and reliable foundation for a successful online store.
+    digest: d3092c4ed82db569937e435d3dc6bcddce420540bf340dd54a554a57b62c6aaa
+    engine: gotpl
+    home: https://opencart.com/
+    icon: https://bitnami.com/assets/stacks/opencart/img/opencart-stack-110x117.png
+    keywords:
+    - opencart
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: opencart
+    sources:
+    - https://github.com/bitnami/bitnami-docker-opencart
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/opencart-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-01-21T00:18:31.354317974Z
+    description: A free and open source e-commerce platform for online merchants.
+      It provides a professional and reliable foundation for a successful online store.
+    digest: afbaa2517e811990bc4b31495a4634b6399615493cf344215a5658de2f33575b
+    engine: gotpl
+    home: https://opencart.com/
+    icon: https://bitnami.com/assets/stacks/opencart/img/opencart-stack-110x117.png
+    keywords:
+    - opencart
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: opencart
+    sources:
+    - https://github.com/bitnami/bitnami-docker-opencart
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/opencart-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-01-04T00:48:19.745672724Z
+    description: A free and open source e-commerce platform for online merchants.
+      It provides a professional and reliable foundation for a successful online store.
+    digest: f0e46cf67f8594c6d92f02fad4a23fdf7aa94bdb145bfde39436e17f0a8930f5
+    engine: gotpl
+    home: https://opencart.com/
+    icon: https://bitnami.com/assets/stacks/opencart/img/opencart-stack-110x117.png
+    keywords:
+    - opencart
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: opencart
+    sources:
+    - https://github.com/bitnami/bitnami-docker-opencart
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/opencart-0.4.0.tgz
+    version: 0.4.0
+  openvpn:
+  - apiVersion: v1
+    created: 2017-04-28T00:18:30.096266269Z
+    description: A Helm chart to install an openvpn server inside a kubernetes cluster.  Certificate
+      generation is also part of the deployment, and this chart will generate client
+      keys as needed.
+    digest: 403a80ed3f204442afe4236e275035bf39f9e1f6af8d48153d6698f51efeb16d
+    home: https://openvpn.net/index.php/open-source.html
+    icon: https://forums.openvpn.net/styles/openvpn/theme/images/ovpnlogo.png
+    keywords:
+    - openvpn
+    - vpn
+    - tunnel
+    - network
+    - service
+    - connectivity
+    - encryption
+    maintainers:
+    - email: john.felten@gmail.com
+      name: John Felten
+    name: openvpn
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/openvpn-1.0.2.tgz
+    version: 1.0.2
+  - apiVersion: v1
+    created: 2017-04-06T10:18:27.592699587Z
+    description: A Helm chart to install an openvpn server inside a kubernetes cluster.  Certificate
+      generation is also part of the deployment, and this chart will generate client
+      keys as needed.
+    digest: c92674b7c6391e412864a3aa73af1a2d89f3b4e768bb459118b8e75b9750fc10
+    home: https://openvpn.net/index.php/open-source.html
+    icon: https://forums.openvpn.net/styles/openvpn/theme/images/ovpnlogo.png
+    keywords:
+    - openvpn
+    - vpn
+    - tunnel
+    - network
+    - service
+    - connectivity
+    - encryption
+    maintainers:
+    - email: john.felten@gmail.com
+      name: John Felten
+    name: openvpn
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/openvpn-1.0.1.tgz
+    version: 1.0.1
+  - apiVersion: v1
+    created: 2017-01-27T21:48:32.078827588Z
+    description: A Helm chart to install an openvpn server inside a kubernetes cluster.  Certificate
+      generation is also part of the deployment, and this chart will generate client
+      keys as needed.
+    digest: a12cfddce900c8a4ef6cea0cef5426d5fb23c657cdab433f9307f6d048273f6b
+    home: https://openvpn.net/index.php/open-source.html
+    icon: https://forums.openvpn.net/styles/openvpn/theme/images/ovpnlogo.png
+    keywords:
+    - openvpn
+    - vpn
+    - tunnel
+    - network
+    - service
+    - connectivity
+    - encryption
+    maintainers:
+    - email: john.felten@gmail.com
+      name: John Felten
+    name: openvpn
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/openvpn-1.0.0.tgz
+    version: 1.0.0
+  orangehrm:
+  - created: 2017-04-28T00:18:30.097427186Z
+    description: OrangeHRM is a free HR management system that offers a wealth of
+      modules to suit the needs of your business.
+    digest: d796649de3610a41a9f92b0ee3f5ce327a250d1b86d7a4c76fd46a31144c59e5
+    engine: gotpl
+    home: https://www.orangehrm.com
+    icon: https://bitnami.com/assets/stacks/orangehrm/img/orangehrm-stack-110x117.png
+    keywords:
+    - orangehrm
+    - http
+    - https
+    - web
+    - application
+    - php
+    - human resources
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: orangehrm
+    sources:
+    - https://github.com/bitnami/bitnami-docker-orangehrm
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/orangehrm-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-04-12T21:03:28.668395677Z
+    description: OrangeHRM is a free HR management system that offers a wealth of
+      modules to suit the needs of your business.
+    digest: 9c954806dfd415ee07cbcc6ee5e82eeeebeb765ecfe173ba80c0003b1d0be504
+    engine: gotpl
+    home: https://www.orangehrm.com
+    icon: https://bitnami.com/assets/stacks/orangehrm/img/orangehrm-stack-110x117.png
+    keywords:
+    - orangehrm
+    - http
+    - https
+    - web
+    - application
+    - php
+    - human resources
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: orangehrm
+    sources:
+    - https://github.com/bitnami/bitnami-docker-orangehrm
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/orangehrm-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-03-18T18:33:36.171180792Z
+    description: OrangeHRM is a free HR management system that offers a wealth of
+      modules to suit the needs of your business.
+    digest: 87483fe0c39f63c61549a85103b9423b30ac4bfe2b19a7af083eaf7dd3491ce2
+    engine: gotpl
+    home: https://www.orangehrm.com
+    icon: https://bitnami.com/assets/stacks/orangehrm/img/orangehrm-stack-110x117.png
+    keywords:
+    - orangehrm
+    - http
+    - https
+    - web
+    - application
+    - php
+    - human resources
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: orangehrm
+    sources:
+    - https://github.com/bitnami/bitnami-docker-orangehrm
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/orangehrm-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-03-02T19:33:28.188778055Z
+    description: OrangeHRM is a free HR management system that offers a wealth of
+      modules to suit the needs of your business.
+    digest: d03e9f261dd50212f6c2c0ecc3a84cbabda89493d8bfc28ad95c6c9a6a195af9
+    engine: gotpl
+    home: https://www.orangehrm.com
+    icon: https://bitnami.com/assets/stacks/orangehrm/img/orangehrm-stack-110x117.png
+    keywords:
+    - orangehrm
+    - http
+    - https
+    - web
+    - application
+    - php
+    - human resources
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: orangehrm
+    sources:
+    - https://github.com/bitnami/bitnami-docker-orangehrm
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/orangehrm-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-02-23T02:33:30.964778113Z
+    description: OrangeHRM is a free HR management system that offers a wealth of
+      modules to suit the needs of your business.
+    digest: b5e5ed301b5321a99a7147173ec6fa7cb471879a585b9af0e8ac2741f0409e48
+    engine: gotpl
+    home: https://www.orangehrm.com
+    icon: https://bitnami.com/assets/stacks/orangehrm/img/orangehrm-stack-110x117.png
+    keywords:
+    - orangehrm
+    - http
+    - https
+    - web
+    - application
+    - php
+    - human resources
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: orangehrm
+    sources:
+    - https://github.com/bitnami/bitnami-docker-orangehrm
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/orangehrm-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-02-01T00:48:29.581953712Z
+    description: OrangeHRM is a free HR management system that offers a wealth of
+      modules to suit the needs of your business.
+    digest: 4ca6ccafc5bc408cb9e61139b8914468e0d8eeed7bffb62eea51c6e40697e8dd
+    engine: gotpl
+    home: https://www.orangehrm.com
+    icon: https://bitnami.com/assets/stacks/orangehrm/img/orangehrm-stack-110x117.png
+    keywords:
+    - orangehrm
+    - http
+    - https
+    - web
+    - application
+    - php
+    - human resources
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: orangehrm
+    sources:
+    - https://github.com/bitnami/bitnami-docker-orangehrm
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/orangehrm-0.4.0.tgz
+    version: 0.4.0
+  osclass:
+  - created: 2017-04-28T00:18:30.098620601Z
+    description: Osclass is a php script that allows you to quickly create and manage
+      your own free classifieds site.
+    digest: 23472bb37c094dad3122a96f6fd6a3967f1d41547121ecf2622b557f2fc5da8b
+    engine: gotpl
+    home: https://osclass.org/
+    icon: https://bitnami.com/assets/stacks/osclass/img/osclass-stack-110x117.png
+    keywords:
+    - osclass
+    - classifieds
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: osclass
+    sources:
+    - https://github.com/bitnami/bitnami-docker-osclass
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/osclass-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-02-23T02:33:30.965596248Z
+    description: Osclass is a php script that allows you to quickly create and manage
+      your own free classifieds site.
+    digest: 7c21cef0b281e3da5b3c9b60940c1b010c34fe866c95615b7d0afd10c480178c
+    engine: gotpl
+    home: https://osclass.org/
+    icon: https://bitnami.com/assets/stacks/osclass/img/osclass-stack-110x117.png
+    keywords:
+    - osclass
+    - classifieds
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: osclass
+    sources:
+    - https://github.com/bitnami/bitnami-docker-osclass
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/osclass-0.4.0.tgz
+    version: 0.4.0
+  owncloud:
+  - created: 2017-04-28T00:18:30.099329236Z
+    description: A file sharing server that puts the control and security of your
+      own data back into your hands.
+    digest: 9beee22ffa4b4eae5e6f8da5734e08a9455a063299b33d4350dea91050ae9a25
+    engine: gotpl
+    home: https://owncloud.org/
+    icon: https://bitnami.com/assets/stacks/owncloud/img/owncloud-stack-220x234.png
+    keywords:
+    - owncloud
+    - storage
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: owncloud
+    sources:
+    - https://github.com/bitnami/bitnami-docker-owncloud
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/owncloud-0.4.7.tgz
+    version: 0.4.7
+  - created: 2017-04-20T16:18:33.358391215Z
+    description: A file sharing server that puts the control and security of your
+      own data back into your hands.
+    digest: 97b3574369c1d690ce8787588668070451c559ac06b6b69942e9905cb6ec94ad
+    engine: gotpl
+    home: https://owncloud.org/
+    icon: https://bitnami.com/assets/stacks/owncloud/img/owncloud-stack-220x234.png
+    keywords:
+    - owncloud
+    - storage
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: owncloud
+    sources:
+    - https://github.com/bitnami/bitnami-docker-owncloud
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/owncloud-0.4.6.tgz
+    version: 0.4.6
+  - created: 2017-03-23T21:18:31.86258413Z
+    description: A file sharing server that puts the control and security of your
+      own data back into your hands.
+    digest: fb78c2ea47996c6781ddfe2dca6aea87cbb8b895e1fc5fea404aa28735d4a2ec
+    engine: gotpl
+    home: https://owncloud.org/
+    icon: https://bitnami.com/assets/stacks/owncloud/img/owncloud-stack-220x234.png
+    keywords:
+    - owncloud
+    - storage
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: owncloud
+    sources:
+    - https://github.com/bitnami/bitnami-docker-owncloud
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/owncloud-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-03-08T19:03:31.738784117Z
+    description: A file sharing server that puts the control and security of your
+      own data back into your hands.
+    digest: 07e18bccf9dc0a8fcff42e97c422520530c2c5057c2a9c14767842609bcaa7ac
+    engine: gotpl
+    home: https://owncloud.org/
+    icon: https://bitnami.com/assets/stacks/owncloud/img/owncloud-stack-220x234.png
+    keywords:
+    - owncloud
+    - storage
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: owncloud
+    sources:
+    - https://github.com/bitnami/bitnami-docker-owncloud
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/owncloud-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-02-11T03:18:26.536480213Z
+    description: A file sharing server that puts the control and security of your
+      own data back into your hands.
+    digest: 4e534bdc4be184c59fbcbcff4641f2bfa341cd7f4ed3668912cd47c1336f5dea
+    engine: gotpl
+    home: https://owncloud.org/
+    keywords:
+    - owncloud
+    - storage
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: owncloud
+    sources:
+    - https://github.com/bitnami/bitnami-docker-owncloud
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/owncloud-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-01-30T23:48:29.172608299Z
+    description: A file sharing server that puts the control and security of your
+      own data back into your hands.
+    digest: b41eb1fc1eea6311f3ad15b459f99b77e96b944b81ea50ebccc941191d496141
+    engine: gotpl
+    home: https://owncloud.org/
+    keywords:
+    - owncloud
+    - storage
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: owncloud
+    sources:
+    - https://github.com/bitnami/bitnami-docker-owncloud
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/owncloud-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-01-21T00:18:31.35624854Z
+    description: A file sharing server that puts the control and security of your
+      own data back into your hands.
+    digest: 89901fc256d6a4f878d77b51bf23eb77358dedb040052b34a09cbe9ca607487f
+    engine: gotpl
+    home: https://owncloud.org/
+    keywords:
+    - owncloud
+    - storage
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: owncloud
+    sources:
+    - https://github.com/bitnami/bitnami-docker-owncloud
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/owncloud-0.4.1.tgz
+    version: 0.4.1
+  - created: 2016-12-21T18:33:20.278724682Z
+    description: A file sharing server that puts the control and security of your
+      own data back into your hands.
+    digest: 7ec2dfe27bf42e8ee2e0672964decc2fbec94ec4fb60af2f3e9e91e13fdae08a
+    engine: gotpl
+    home: https://owncloud.org/
+    keywords:
+    - owncloud
+    - storage
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: owncloud
+    sources:
+    - https://github.com/bitnami/bitnami-docker-owncloud
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/owncloud-0.4.0.tgz
+    version: 0.4.0
+  percona:
+  - created: 2017-04-28T00:18:30.099763589Z
+    description: free, fully compatible, enhanced, open source drop-in replacement
+      for MySQL
+    digest: b10837a3de2492c2826aaf9ab740314ffa3f8c6110568b0a88e142791abb0e96
+    engine: gotpl
+    home: https://www.percona.com/
+    icon: https://www.percona.com/sites/all/themes/percona2015/logo.png
+    keywords:
+    - mysql
+    - percona
+    - database
+    - sql
+    maintainers:
+    - email: patg@patg.net
+      name: Patrick Galbraith
+    name: percona
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/percona
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/percona-0.1.0.tgz
+    version: 0.1.0
+  phabricator:
+  - created: 2017-04-28T00:18:30.100508372Z
+    description: Collection of open source web applications that help software companies
+      build better software.
+    digest: 6c53fef9ac9c246983a26d2e8b9e8f032b87706c09667edb9f9bb62dfa822e88
+    engine: gotpl
+    home: https://www.phacility.com/phabricator/
+    icon: https://bitnami.com/assets/stacks/phabricator/img/phabricator-stack-110x117.png
+    keywords:
+    - phabricator
+    - http
+    - https
+    - web
+    - application
+    - collaboration
+    - project management
+    - bug tracking
+    - code review
+    - wiki
+    - git
+    - mercurial
+    - subversion
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phabricator
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phabricator
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phabricator-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-04-06T10:33:26.333625406Z
+    description: Collection of open source web applications that help software companies
+      build better software.
+    digest: ef626563185a4b41ff7da03a9bd5548903061c6140d2d65300e4b1c1d39a2f28
+    engine: gotpl
+    home: https://www.phacility.com/phabricator/
+    icon: https://bitnami.com/assets/stacks/phabricator/img/phabricator-stack-110x117.png
+    keywords:
+    - phabricator
+    - http
+    - https
+    - web
+    - application
+    - collaboration
+    - project management
+    - bug tracking
+    - code review
+    - wiki
+    - git
+    - mercurial
+    - subversion
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phabricator
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phabricator
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phabricator-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-03-02T19:33:28.191377992Z
+    description: Collection of open source web applications that help software companies
+      build better software.
+    digest: 544373e984918da349351f05fdb7a8cf0c695726890bcd4cc348e786e1c55d57
+    engine: gotpl
+    home: https://www.phacility.com/phabricator/
+    icon: https://bitnami.com/assets/stacks/phabricator/img/phabricator-stack-110x117.png
+    keywords:
+    - phabricator
+    - http
+    - https
+    - web
+    - application
+    - collaboration
+    - project management
+    - bug tracking
+    - code review
+    - wiki
+    - git
+    - mercurial
+    - subversion
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phabricator
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phabricator
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phabricator-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-02-23T02:33:30.967143259Z
+    description: Collection of open source web applications that help software companies
+      build better software.
+    digest: 657b118031c1513b95268915ef4f68f5453f2b21ca5a919e9a370facb439dfe5
+    engine: gotpl
+    home: https://www.phacility.com/phabricator/
+    icon: https://bitnami.com/assets/stacks/phabricator/img/phabricator-stack-110x117.png
+    keywords:
+    - phabricator
+    - http
+    - https
+    - web
+    - application
+    - collaboration
+    - project management
+    - bug tracking
+    - code review
+    - wiki
+    - git
+    - mercurial
+    - subversion
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phabricator
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phabricator
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phabricator-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-01-21T00:18:31.358403062Z
+    description: Collection of open source web applications that help software companies
+      build better software.
+    digest: 77603dd383c0674e829fa4aa2ca0d33ce61884df6a3ce68f9e165e7802e7eacc
+    engine: gotpl
+    home: https://www.phacility.com/phabricator/
+    icon: https://bitnami.com/assets/stacks/phabricator/img/phabricator-stack-110x117.png
+    keywords:
+    - phabricator
+    - http
+    - https
+    - web
+    - application
+    - collaboration
+    - project management
+    - bug tracking
+    - code review
+    - wiki
+    - git
+    - mercurial
+    - subversion
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phabricator
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phabricator
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phabricator-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-01-04T00:48:19.747640048Z
+    description: Collection of open source web applications that help software companies
+      build better software.
+    digest: e4f0f5322bac2a2bed822eb8065eec6e29716310af1623975f1ad0ef2b448c66
+    engine: gotpl
+    home: https://www.phacility.com/phabricator/
+    icon: https://bitnami.com/assets/stacks/phabricator/img/phabricator-stack-110x117.png
+    keywords:
+    - phabricator
+    - http
+    - https
+    - web
+    - application
+    - collaboration
+    - project management
+    - bug tracking
+    - code review
+    - wiki
+    - git
+    - mercurial
+    - subversion
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phabricator
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phabricator
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phabricator-0.4.0.tgz
+    version: 0.4.0
+  phpbb:
+  - created: 2017-04-28T00:18:30.10119319Z
+    description: Community forum that supports the notion of users and groups, file
+      attachments, full-text search, notifications and more.
+    digest: d4e97de68d28acd69cb655c7fa44cb8829367ce3a7b20ecbf151f1bb2b10d1cb
+    engine: gotpl
+    home: https://www.phpbb.com/
+    icon: https://bitnami.com/assets/stacks/phpbb/img/phpbb-stack-220x234.png
+    keywords:
+    - phpbb
+    - forum
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phpbb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phpbb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phpbb-0.4.7.tgz
+    version: 0.4.7
+  - created: 2017-04-13T05:18:28.926003844Z
+    description: Community forum that supports the notion of users and groups, file
+      attachments, full-text search, notifications and more.
+    digest: 30732d5c200ef312a50f5a89a222a959c99b0a08af87f0c312c3699bb2c56082
+    engine: gotpl
+    home: https://www.phpbb.com/
+    icon: https://bitnami.com/assets/stacks/phpbb/img/phpbb-stack-220x234.png
+    keywords:
+    - phpbb
+    - forum
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phpbb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phpbb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phpbb-0.4.6.tgz
+    version: 0.4.6
+  - created: 2017-03-02T19:33:28.19218227Z
+    description: Community forum that supports the notion of users and groups, file
+      attachments, full-text search, notifications and more.
+    digest: ed994a70f454f325cf677bdcc0a09aa66b01c7343a624a3304b88148eafa0dd4
+    engine: gotpl
+    home: https://www.phpbb.com/
+    icon: https://bitnami.com/assets/stacks/phpbb/img/phpbb-stack-220x234.png
+    keywords:
+    - phpbb
+    - forum
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phpbb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phpbb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phpbb-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-02-23T02:33:30.967854461Z
+    description: Community forum that supports the notion of users and groups, file
+      attachments, full-text search, notifications and more.
+    digest: f50e4b1eb4bf8b2e6815b664e3cfff4bfd7979b650bf1efa709b79c92a8e5dd0
+    engine: gotpl
+    home: https://www.phpbb.com/
+    icon: https://bitnami.com/assets/stacks/phpbb/img/phpbb-stack-220x234.png
+    keywords:
+    - phpbb
+    - forum
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phpbb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phpbb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phpbb-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-02-13T17:03:30.134235119Z
+    description: Community forum that supports the notion of users and groups, file
+      attachments, full-text search, notifications and more.
+    digest: c41705e34490d1941adda128b166ef1a327cceb7a447113d2633652f3c85363a
+    engine: gotpl
+    home: https://www.phpbb.com/
+    icon: https://bitnami.com/assets/stacks/phpbb/img/phpbb-stack-220x234.png
+    keywords:
+    - phpbb
+    - forum
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phpbb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phpbb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phpbb-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-02-13T04:18:31.547850917Z
+    description: Community forum that supports the notion of users and groups, file
+      attachments, full-text search, notifications and more.
+    digest: 77f6dfa8f277b003ba0b8e2ca6d046f6b6526ee7db05e304cbb9924c9fd7d194
+    engine: gotpl
+    home: https://www.phpbb.com/
+    keywords:
+    - phpbb
+    - forum
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phpbb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phpbb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phpbb-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-01-31T00:03:26.18262303Z
+    description: Community forum that supports the notion of users and groups, file
+      attachments, full-text search, notifications and more.
+    digest: cd6dde525898d91f5f39541ee205e79ba5b8eb7a5b99585141cc88c3a63f5aed
+    engine: gotpl
+    home: https://www.phpbb.com/
+    keywords:
+    - phpbb
+    - forum
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phpbb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phpbb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phpbb-0.4.1.tgz
+    version: 0.4.1
+  - created: 2016-12-09T18:48:20.188802837Z
+    description: Community forum that supports the notion of users and groups, file
+      attachments, full-text search, notifications and more.
+    digest: 7e5e8828fdbba9ebc83c95baac4937e569e881d8b68bc79974a0f5d8a2883e13
+    engine: gotpl
+    home: https://www.phpbb.com/
+    keywords:
+    - phpbb
+    - forum
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: phpbb
+    sources:
+    - https://github.com/bitnami/bitnami-docker-phpbb
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/phpbb-0.4.0.tgz
+    version: 0.4.0
+  postgresql:
+  - created: 2017-04-28T00:18:30.101575321Z
+    description: Object-relational database management system (ORDBMS) with an emphasis
+      on extensibility and on standards-compliance.
+    digest: 60224116f1e803bbf744cb2b3c2d621cfadef709ef0a8c6ed08cbed0f5415915
+    engine: gotpl
+    home: https://www.postgresql.org/
+    icon: https://www.postgresql.org/media/img/about/press/elephant.png
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    - name: databus23
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.6.0.tgz
+    version: 0.6.0
+  - created: 2017-03-16T23:33:31.598678756Z
+    description: Object-relational database management system (ORDBMS) with an emphasis
+      on extensibility and on standards-compliance.
+    digest: abfc2c516cce613f9042eb5d202b01f6766240f54bb3632df9378be033711b30
+    engine: gotpl
+    home: https://www.postgresql.org/
+    icon: https://www.postgresql.org/media/img/about/press/elephant.png
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    - name: databus23
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.5.1.tgz
+    version: 0.5.1
+  - created: 2017-03-15T11:18:31.676836517Z
+    description: Object-relational database management system (ORDBMS) with an emphasis
+      on extensibility and on standards-compliance.
+    digest: 29a90e1b52577e04a42da3ac7464b1b1cf9572b359d7825a375aad122659db55
+    engine: gotpl
+    home: https://www.postgresql.org/
+    icon: https://www.postgresql.org/media/img/about/press/elephant.png
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    - name: databus23
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.5.0.tgz
+    version: 0.5.0
+  - created: 2017-03-15T09:48:31.994004661Z
+    description: Object-relational database management system (ORDBMS) with an emphasis
+      on extensibility and on standards-compliance.
+    digest: 0ca09fbfd539d5258026fcaf7b640f88295271f88773acfa540dcd55cfaf6036
+    engine: gotpl
+    home: https://www.postgresql.org/
+    icon: https://www.postgresql.org/media/img/about/press/elephant.png
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    - name: databus23
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.4.0.tgz
+    version: 0.4.0
+  - created: 2017-02-13T21:33:27.762374795Z
+    description: Object-relational database management system (ORDBMS) with an emphasis
+      on extensibility and on standards-compliance.
+    digest: b07b7c12f13731ebc3019c11601351863030ad3933f72fb7925f3c0de39e23f4
+    engine: gotpl
+    home: https://www.postgresql.org/
+    icon: https://www.postgresql.org/media/img/about/press/elephant.png
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    - name: databus23
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.3.4.tgz
+    version: 0.3.4
+  - created: 2017-02-13T04:18:31.548242286Z
+    description: Chart for PostgreSQL
+    digest: 80685774a539b9efa27ea82337e9dd9fccd436688a84e2609d59a68a336d8f18
+    engine: gotpl
+    home: https://www.postgresql.org/
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    - name: databus23
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.3.3.tgz
+    version: 0.3.3
+  - created: 2017-02-06T17:48:28.059659169Z
+    description: Chart for PostgreSQL
+    digest: d8306a710181a440672795d0b5850e6851ae28b3ecb4cf5f92126c9f533700d5
+    engine: gotpl
+    home: https://www.postgresql.org/
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    - name: databus23
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.3.2.tgz
+    version: 0.3.2
+  - created: 2017-01-28T00:18:32.756495622Z
+    description: Chart for PostgreSQL
+    digest: 7b4e2b838ccb2e96c26f0b18d75b2cba224a634925abacaeee1b053a3db40f72
+    engine: gotpl
+    home: https://www.postgresql.org/
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    - name: databus23
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.3.1.tgz
+    version: 0.3.1
+  - created: 2017-01-26T17:18:33.808053693Z
+    description: Chart for PostgreSQL
+    digest: b8e412ddd2f2648efbaa84f85c924e5b94cba0393fb93ea607fdcab3132b7d2e
+    engine: gotpl
+    home: https://www.postgresql.org/
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    - name: databus23
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.3.0.tgz
+    version: 0.3.0
+  - created: 2016-12-21T18:33:20.280731983Z
+    description: Chart for PostgreSQL
+    digest: a0516b4e5b83d9dd4af936859582878683183c6f72e9dddb73c9ff0fd280b972
+    engine: gotpl
+    home: https://www.postgresql.org/
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.2.2.tgz
+    version: 0.2.2
+  - created: 2016-12-19T22:48:20.03810957Z
+    description: Chart for PostgreSQL
+    digest: 8d79ed44bb8477cdbbf8a3eb5a08eef787a147334b30d35a81f8ee43d07eb9ee
+    engine: gotpl
+    home: https://www.postgresql.org/
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.2.1.tgz
+    version: 0.2.1
+  - created: 2016-12-05T20:48:21.242600076Z
+    description: Chart for PostgreSQL
+    digest: 713d7ee250af7f914188d889ba3cb3065b4c36565b6f68ca8f55cd5340bda213
+    engine: gotpl
+    home: https://www.postgresql.org/
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.2.0.tgz
+    version: 0.2.0
+  - created: 2016-11-08T15:03:20.745475633Z
+    description: Chart for PostgreSQL
+    digest: c79411d63ad872d0f6d034de9818cef565dbde3ac5f018ee8349305f286031a8
+    engine: gotpl
+    home: https://www.postgresql.org/
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.1.1.tgz
+    version: 0.1.1
+  - created: 2016-11-04T14:18:20.014925806Z
+    description: Chart for PostgreSQL
+    digest: c984e3efb97da1b841c6a07b1e8fd32638b59de42e5b062690b8c9956be58959
+    engine: gotpl
+    home: https://www.postgresql.org/
+    keywords:
+    - postgresql
+    - postgres
+    - database
+    - sql
+    maintainers:
+    - name: swordbeta
+    name: postgresql
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/docker-library/postgres
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/postgresql-0.1.0.tgz
+    version: 0.1.0
+  prestashop:
+  - created: 2017-04-28T00:18:30.102289986Z
+    description: A popular open source ecommerce solution. Professional tools are
+      easily accessible to increase online sales including instant guest checkout,
+      abandoned cart reminders and automated Email marketing.
+    digest: fd575ef671455aa2c85ed91643419219bad86f8766b5775c1e869837cfbef6e5
+    engine: gotpl
+    home: https://prestashop.com/
+    icon: https://bitnami.com/assets/stacks/prestashop/img/prestashop-stack-110x117.png
+    keywords:
+    - prestashop
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: prestashop
+    sources:
+    - https://github.com/bitnami/bitnami-docker-prestashop
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prestashop-0.4.6.tgz
+    version: 0.4.6
+  - created: 2017-04-06T11:03:25.414976585Z
+    description: A popular open source ecommerce solution. Professional tools are
+      easily accessible to increase online sales including instant guest checkout,
+      abandoned cart reminders and automated Email marketing.
+    digest: 17eb689a1b04c31c1c78fa1b411f938eaad74bbd1ae78e4eecd0755770156043
+    engine: gotpl
+    home: https://prestashop.com/
+    icon: https://bitnami.com/assets/stacks/prestashop/img/prestashop-stack-110x117.png
+    keywords:
+    - prestashop
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: prestashop
+    sources:
+    - https://github.com/bitnami/bitnami-docker-prestashop
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prestashop-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-03-23T01:19:01.462007867Z
+    description: A popular open source ecommerce solution. Professional tools are
+      easily accessible to increase online sales including instant guest checkout,
+      abandoned cart reminders and automated Email marketing.
+    digest: ff84426385c8abb40d0f4f7e2cfc7fec70b0ae38ca32de832ccbb2b26f74787b
+    engine: gotpl
+    home: https://prestashop.com/
+    icon: https://bitnami.com/assets/stacks/prestashop/img/prestashop-stack-110x117.png
+    keywords:
+    - prestashop
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: prestashop
+    sources:
+    - https://github.com/bitnami/bitnami-docker-prestashop
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prestashop-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-03-08T19:03:31.741573757Z
+    description: A popular open source ecommerce solution. Professional tools are
+      easily accessible to increase online sales including instant guest checkout,
+      abandoned cart reminders and automated Email marketing.
+    digest: 4beeb9d17c713b8065f9167d11672862fe2d1eeb5fded4d4ecd395a379825bbc
+    engine: gotpl
+    home: https://prestashop.com/
+    icon: https://bitnami.com/assets/stacks/prestashop/img/prestashop-stack-110x117.png
+    keywords:
+    - prestashop
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: prestashop
+    sources:
+    - https://github.com/bitnami/bitnami-docker-prestashop
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prestashop-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-02-13T17:03:30.136404798Z
+    description: A popular open source ecommerce solution. Professional tools are
+      easily accessible to increase online sales including instant guest checkout,
+      abandoned cart reminders and automated Email marketing.
+    digest: fd8c2be6fd9348d2c5bda428ac61f0745974ebd7a4b58ad5d975d8d21888f1c4
+    engine: gotpl
+    home: https://prestashop.com/
+    icon: https://bitnami.com/assets/stacks/prestashop/img/prestashop-stack-110x117.png
+    keywords:
+    - prestashop
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: prestashop
+    sources:
+    - https://github.com/bitnami/bitnami-docker-prestashop
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prestashop-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-01-21T00:18:31.360326923Z
+    description: A popular open source ecommerce solution. Professional tools are
+      easily accessible to increase online sales including instant guest checkout,
+      abandoned cart reminders and automated Email marketing.
+    digest: eba227b32cb9f503c4fd41609d705019372f7936c69febaf2c4200735910e333
+    engine: gotpl
+    home: https://prestashop.com/
+    icon: https://bitnami.com/assets/stacks/prestashop/img/prestashop-stack-110x117.png
+    keywords:
+    - prestashop
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: prestashop
+    sources:
+    - https://github.com/bitnami/bitnami-docker-prestashop
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prestashop-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-01-04T00:48:19.749415831Z
+    description: A popular open source ecommerce solution. Professional tools are
+      easily accessible to increase online sales including instant guest checkout,
+      abandoned cart reminders and automated Email marketing.
+    digest: dd80da4612c962f5d02e2f52f7e0facf42a661d6d6f5eec36d7a3980e2a685d3
+    engine: gotpl
+    home: https://prestashop.com/
+    icon: https://bitnami.com/assets/stacks/prestashop/img/prestashop-stack-110x117.png
+    keywords:
+    - prestashop
+    - e-commerce
+    - http
+    - web
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: prestashop
+    sources:
+    - https://github.com/bitnami/bitnami-docker-prestashop
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prestashop-0.4.0.tgz
+    version: 0.4.0
+  prometheus:
+  - created: 2017-04-28T00:18:30.103009703Z
+    description: Prometheus is a monitoring system and time series database.
+    digest: 54cd97a780b0af5cd86d84455a29ec2f30765cfbf5c56f9eedf0c30539e325ec
+    engine: gotpl
+    home: https://prometheus.io/
+    icon: https://raw.githubusercontent.com/prometheus/prometheus.github.io/master/assets/prometheus_logo-cb55bb5c346.png
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: prometheus
+    sources:
+    - https://github.com/prometheus/alertmanager
+    - https://github.com/prometheus/prometheus
+    - https://github.com/kubernetes/kube-state-metrics
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prometheus-3.0.2.tgz
+    version: 3.0.2
+  - created: 2017-04-14T01:18:27.389282119Z
+    description: Prometheus is a monitoring system and time series database.
+    digest: 8240b1319bb4b1382f69e3ae753fce599185a7f21a399c7ed15108138cb6e793
+    engine: gotpl
+    home: https://prometheus.io/
+    icon: https://raw.githubusercontent.com/prometheus/prometheus.github.io/master/assets/prometheus_logo-cb55bb5c346.png
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: prometheus
+    sources:
+    - https://github.com/prometheus/alertmanager
+    - https://github.com/prometheus/prometheus
+    - https://github.com/kubernetes/kube-state-metrics
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prometheus-3.0.1.tgz
+    version: 3.0.1
+  - created: 2017-03-23T19:03:32.048982259Z
+    description: Prometheus is a monitoring system and time series database.
+    digest: a6a49f3aaf7768dd84acfec96f95cab74a4ed1b68f95f23a9248d6926e8a2ba7
+    engine: gotpl
+    home: https://prometheus.io/
+    icon: https://raw.githubusercontent.com/prometheus/prometheus.github.io/master/assets/prometheus_logo-cb55bb5c346.png
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: prometheus
+    sources:
+    - https://github.com/prometheus/alertmanager
+    - https://github.com/prometheus/prometheus
+    - https://github.com/kubernetes/kube-state-metrics
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prometheus-3.0.0.tgz
+    version: 3.0.0
+  - created: 2017-03-20T20:18:33.636286259Z
+    description: A Prometheus Helm chart for Kubernetes. Prometheus is a monitoring
+      system and time series database.
+    digest: 0bbefe8b7732b400320007e4f8898518ffcafd3371114be24ca8ded424fe60b3
+    engine: gotpl
+    home: https://prometheus.io/
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: prometheus
+    sources:
+    - https://github.com/prometheus/alertmanager
+    - https://github.com/prometheus/prometheus
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prometheus-2.0.4.tgz
+    version: 2.0.4
+  - created: 2017-02-13T04:18:31.549501389Z
+    description: A Prometheus Helm chart for Kubernetes. Prometheus is a monitoring
+      system and time series database.
+    digest: 0f54774b8b258a8e126f09a66749b15c0691e0a330b65f397d58418b0fa0210c
+    engine: gotpl
+    home: https://prometheus.io/
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: prometheus
+    sources:
+    - https://github.com/prometheus/alertmanager
+    - https://github.com/prometheus/prometheus
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prometheus-2.0.3.tgz
+    version: 2.0.3
+  - created: 2017-02-03T20:18:29.168136057Z
+    description: A Prometheus Helm chart for Kubernetes. Prometheus is a monitoring
+      system and time series database.
+    digest: f1f457be370a944f3c703ceecc35664aa00f7a243730ca9e110bc18f1ed3ab9a
+    engine: gotpl
+    home: https://prometheus.io/
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: prometheus
+    sources:
+    - https://github.com/prometheus/alertmanager
+    - https://github.com/prometheus/prometheus
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prometheus-2.0.2.tgz
+    version: 2.0.2
+  - created: 2017-02-01T02:18:29.14318599Z
+    description: A Prometheus Helm chart for Kubernetes. Prometheus is a monitoring
+      system and time series database.
+    digest: eebea40b9e86c6dfb92048b0f63d47b11021ab0df437e2b13bc0fd1fc121e8d6
+    engine: gotpl
+    home: https://prometheus.io/
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: prometheus
+    sources:
+    - https://github.com/prometheus/alertmanager
+    - https://github.com/prometheus/prometheus
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prometheus-2.0.1.tgz
+    version: 2.0.1
+  - created: 2017-01-19T19:18:27.372125459Z
+    description: A Prometheus Helm chart for Kubernetes. Prometheus is a monitoring
+      system and time series database.
+    digest: 0ae9e1c2ec6e3a6e2148f01e174bbbdd02a5797b4136e5de784383bca9bff938
+    engine: gotpl
+    home: https://prometheus.io/
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: prometheus
+    sources:
+    - https://github.com/prometheus/alertmanager
+    - https://github.com/prometheus/prometheus
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prometheus-2.0.0.tgz
+    version: 2.0.0
+  - created: 2017-01-12T02:52:37.843602967Z
+    description: A Prometheus Helm chart for Kubernetes. Prometheus is a monitoring
+      system and time series database.
+    digest: cd8d763bdfe5d7c3c0e9a38f9741a2ef5de1c7c57a0c43a4407e70e2f6232dc9
+    engine: gotpl
+    home: https://prometheus.io/
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: prometheus
+    sources:
+    - https://github.com/prometheus/alertmanager
+    - https://github.com/prometheus/prometheus
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prometheus-1.4.2.tgz
+    version: 1.4.2
+  - created: 2017-01-04T00:48:19.750279814Z
+    description: A Prometheus Helm chart for Kubernetes. Prometheus is a monitoring
+      system and time series database.
+    digest: 7209dafe19488487a8a151129deff24fe174d9734ea2c1629dd52bee183a8ad2
+    engine: gotpl
+    home: https://prometheus.io/
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: prometheus
+    sources:
+    - https://github.com/prometheus/alertmanager
+    - https://github.com/prometheus/prometheus
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prometheus-1.4.1.tgz
+    version: 1.4.1
+  - created: 2016-12-09T18:48:20.189907856Z
+    description: A Prometheus Helm chart for Kubernetes. Prometheus is a monitoring
+      system and time series database.
+    digest: f6b4c948e408471b51ff6361e0d0f5afc801ee8141aae5002111ffbc12c68895
+    engine: gotpl
+    home: https://prometheus.io/
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: prometheus
+    sources:
+    - https://github.com/prometheus/alertmanager
+    - https://github.com/prometheus/prometheus
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/prometheus-1.3.1.tgz
+    version: 1.3.1
+  rabbitmq:
+  - created: 2017-04-28T00:18:30.103417484Z
+    description: Open source message broker software that implements the Advanced
+      Message Queuing Protocol (AMQP)
+    digest: 1b4339d3f866cdc57072ce60fc3a579a5f4233aa6a4cb81254dcb9ddc0fabc33
+    engine: gotpl
+    home: https://www.rabbitmq.com
+    icon: https://bitnami.com/assets/stacks/rabbitmq/img/rabbitmq-stack-220x234.png
+    keywords:
+    - rabbitmq
+    - message queue
+    - AMQP
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: rabbitmq
+    sources:
+    - https://github.com/bitnami/bitnami-docker-rabbitmq
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/rabbitmq-0.5.1.tgz
+    version: 0.5.1
+  - created: 2017-04-06T10:33:26.336868116Z
+    description: Open source message broker software that implements the Advanced
+      Message Queuing Protocol (AMQP)
+    digest: 60c103b6cd7c57d5bf25588c0d1fcbbe0790ad50968d1947ce11e4b7ae1b2e6e
+    engine: gotpl
+    home: https://www.rabbitmq.com
+    icon: https://bitnami.com/assets/stacks/rabbitmq/img/rabbitmq-stack-220x234.png
+    keywords:
+    - rabbitmq
+    - message queue
+    - AMQP
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: rabbitmq
+    sources:
+    - https://github.com/bitnami/bitnami-docker-rabbitmq
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/rabbitmq-0.5.0.tgz
+    version: 0.5.0
+  - created: 2017-04-03T22:33:26.690098498Z
+    description: Open source message broker software that implements the Advanced
+      Message Queuing Protocol (AMQP)
+    digest: 2f9b4afaffbe72c99c640de71b33e161e9d11386c287bab9028af19d1548bfa8
+    engine: gotpl
+    home: https://www.rabbitmq.com
+    icon: https://bitnami.com/assets/stacks/rabbitmq/img/rabbitmq-stack-220x234.png
+    keywords:
+    - rabbitmq
+    - message queue
+    - AMQP
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: rabbitmq
+    sources:
+    - https://github.com/bitnami/bitnami-docker-rabbitmq
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/rabbitmq-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-03-18T18:33:36.178174406Z
+    description: Open source message broker software that implements the Advanced
+      Message Queuing Protocol (AMQP)
+    digest: 833f7c8b0db5eeee50005fe88db8f1aaa899e5cc7875e18473a77162425756be
+    engine: gotpl
+    home: https://www.rabbitmq.com
+    icon: https://bitnami.com/assets/stacks/rabbitmq/img/rabbitmq-stack-220x234.png
+    keywords:
+    - rabbitmq
+    - message queue
+    - AMQP
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: rabbitmq
+    sources:
+    - https://github.com/bitnami/bitnami-docker-rabbitmq
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/rabbitmq-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-03-16T13:33:30.85508759Z
+    description: Open source message broker software that implements the Advanced
+      Message Queuing Protocol (AMQP)
+    digest: bcfcbfa446f75dc1ca93f9a7d2ccc36731ef41f1dd5615e251344af0d6a1ba83
+    engine: gotpl
+    home: https://www.rabbitmq.com
+    icon: https://bitnami.com/assets/stacks/rabbitmq/img/rabbitmq-stack-220x234.png
+    keywords:
+    - rabbitmq
+    - message queue
+    - AMQP
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: rabbitmq
+    sources:
+    - https://github.com/bitnami/bitnami-docker-rabbitmq
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/rabbitmq-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-03-08T19:03:31.743135112Z
+    description: Open source message broker software that implements the Advanced
+      Message Queuing Protocol (AMQP)
+    digest: 7ad8ba0ff9d1b57778ffe60812be9087ad4fac27e8696fad4c9eba9a2529fdba
+    engine: gotpl
+    home: https://www.rabbitmq.com
+    icon: https://bitnami.com/assets/stacks/rabbitmq/img/rabbitmq-stack-220x234.png
+    keywords:
+    - rabbitmq
+    - message queue
+    - AMQP
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: rabbitmq
+    sources:
+    - https://github.com/bitnami/bitnami-docker-rabbitmq
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/rabbitmq-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-02-13T04:18:31.549853753Z
+    description: Open source message broker software that implements the Advanced
+      Message Queuing Protocol (AMQP)
+    digest: 323ca950152028ecfa421b78ba0b9282265f39b934b07649b239be4d9f2dc10a
+    engine: gotpl
+    home: https://www.rabbitmq.com
+    keywords:
+    - rabbitmq
+    - message queue
+    - AMQP
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: rabbitmq
+    sources:
+    - https://github.com/bitnami/bitnami-docker-rabbitmq
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/rabbitmq-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-01-31T00:03:26.184733426Z
+    description: Open source message broker software that implements the Advanced
+      Message Queuing Protocol (AMQP)
+    digest: 9bd9655f974dc3b2666c141718b65c7786e91c533ffee1784428a6d48cb458ca
+    engine: gotpl
+    home: https://www.rabbitmq.com
+    keywords:
+    - rabbitmq
+    - message queue
+    - AMQP
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: rabbitmq
+    sources:
+    - https://github.com/bitnami/bitnami-docker-rabbitmq
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/rabbitmq-0.4.0.tgz
+    version: 0.4.0
+  redis:
+  - created: 2017-04-28T00:18:30.103747837Z
+    description: Open source, advanced key-value store. It is often referred to as
+      a data structure server since keys can contain strings, hashes, lists, sets
+      and sorted sets.
+    digest: 72af23bdc2aee61a6cc75e6b7fe3677d1f08ec98afbf8b6fccb3922c9bde47aa
+    engine: gotpl
+    home: http://redis.io/
+    icon: https://bitnami.com/assets/stacks/redis/img/redis-stack-220x234.png
+    keywords:
+    - redis
+    - keyvalue
+    - database
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redis
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redis
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redis-0.5.1.tgz
+    version: 0.5.1
+  - created: 2017-04-03T22:18:27.809077961Z
+    description: Open source, advanced key-value store. It is often referred to as
+      a data structure server since keys can contain strings, hashes, lists, sets
+      and sorted sets.
+    digest: 84fdd07b6f56e7771696e7a707456808cb925f2a6311bf85e1bd027e5b2d364d
+    engine: gotpl
+    home: http://redis.io/
+    icon: https://bitnami.com/assets/stacks/redis/img/redis-stack-220x234.png
+    keywords:
+    - redis
+    - keyvalue
+    - database
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redis
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redis
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redis-0.5.0.tgz
+    version: 0.5.0
+  - created: 2017-03-23T15:48:30.415372004Z
+    description: Open source, advanced key-value store. It is often referred to as
+      a data structure server since keys can contain strings, hashes, lists, sets
+      and sorted sets.
+    digest: 83ace7583e93e763b781d74c940d0966d7317d2b1665eaed35be9ca73dcace5e
+    engine: gotpl
+    home: http://redis.io/
+    icon: https://bitnami.com/assets/stacks/redis/img/redis-stack-220x234.png
+    keywords:
+    - redis
+    - keyvalue
+    - database
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redis
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redis
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redis-0.4.6.tgz
+    version: 0.4.6
+  - created: 2017-03-02T19:33:28.196397881Z
+    description: Open source, advanced key-value store. It is often referred to as
+      a data structure server since keys can contain strings, hashes, lists, sets
+      and sorted sets.
+    digest: 7891aef2647fd00ca93cd6894720a6307d3fdd275f912eb6a05fcbb6b7009c13
+    engine: gotpl
+    home: http://redis.io/
+    icon: https://bitnami.com/assets/stacks/redis/img/redis-stack-220x234.png
+    keywords:
+    - redis
+    - keyvalue
+    - database
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redis
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redis
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redis-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-02-13T20:18:28.115940614Z
+    description: Open source, advanced key-value store. It is often referred to as
+      a data structure server since keys can contain strings, hashes, lists, sets
+      and sorted sets.
+    digest: e8cf2f96a6931397adf372857a6a0da161e7e9eb0cf91f565399d20b26144be1
+    engine: gotpl
+    home: http://redis.io/
+    icon: https://bitnami.com/assets/stacks/redis/img/redis-stack-220x234.png
+    keywords:
+    - redis
+    - keyvalue
+    - database
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redis
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redis
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redis-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-02-13T04:18:31.550184203Z
+    description: Chart for Redis
+    digest: b4cb9b2e0811a83ce269dc06c25a05fe31deb799018eba418232b2c3f4b18b12
+    engine: gotpl
+    home: http://redis.io/
+    keywords:
+    - redis
+    - keyvalue
+    - database
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redis
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redis
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redis-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-01-28T02:03:32.495597111Z
+    description: Chart for Redis
+    digest: 160dab504021716867790c3b1ea5c6e4afcaf865d9b8569707e123bc4d1536dc
+    engine: gotpl
+    home: http://redis.io/
+    keywords:
+    - redis
+    - keyvalue
+    - database
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redis
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redis
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redis-0.4.2.tgz
+    version: 0.4.2
+  - created: 2016-12-09T18:48:20.191261198Z
+    description: Chart for Redis
+    digest: 7132d9ddecaf4a890e5177c401228fa031f52e927393063f8d6c5a0881b281a3
+    engine: gotpl
+    home: http://redis.io/
+    keywords:
+    - redis
+    - keyvalue
+    - database
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redis
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redis
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redis-0.4.1.tgz
+    version: 0.4.1
+  - created: 2016-10-31T16:33:19.644247028Z
+    description: Chart for Redis
+    digest: cef59b98a3607bf0f40560c724fd36a84e5f29498031a36c0f2f80369c35d9c4
+    engine: gotpl
+    home: http://redis.io/
+    keywords:
+    - redis
+    - keyvalue
+    - database
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redis
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redis
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redis-0.4.0.tgz
+    version: 0.4.0
+  redmine:
+  - created: 2017-04-28T00:18:30.104404263Z
+    description: A flexible project management web application.
+    digest: 65419e8af0bff73d1c4da279cbb4d2abdaf99a714dabae01b27f67b917d4efc1
+    engine: gotpl
+    home: http://www.redmine.org/
+    icon: https://bitnami.com/assets/stacks/redmine/img/redmine-stack-220x234.png
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-04-13T05:18:28.930142135Z
+    description: A flexible project management web application.
+    digest: 3edad0332b7aa4ff2c33729f0e49e7c58c0ad06108d66774d1f1583b8e4ccddf
+    engine: gotpl
+    home: http://www.redmine.org/
+    icon: https://bitnami.com/assets/stacks/redmine/img/redmine-stack-220x234.png
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-03-31T19:33:30.446728632Z
+    description: A flexible project management web application.
+    digest: facd552d60b39c5f6d37e8cf88f453bcae418a08eee0c401f15d15872e1e3601
+    engine: gotpl
+    home: http://www.redmine.org/
+    icon: https://bitnami.com/assets/stacks/redmine/img/redmine-stack-220x234.png
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.4.0.tgz
+    version: 0.4.0
+  - created: 2017-03-14T23:48:31.907843022Z
+    description: A flexible project management web application.
+    digest: a21733ee877ad579f8b5be03d5a35008816d64dd56e0ca6482a7c0686fcdfe09
+    engine: gotpl
+    home: http://www.redmine.org/
+    icon: https://bitnami.com/assets/stacks/redmine/img/redmine-stack-220x234.png
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.3.11.tgz
+    version: 0.3.11
+  - created: 2017-03-08T19:03:31.745197966Z
+    description: A flexible project management web application.
+    digest: 30253b618b47801a076c6cdd8a9ff93e1e4401e0189e88576553802b224e2775
+    engine: gotpl
+    home: http://www.redmine.org/
+    icon: https://bitnami.com/assets/stacks/redmine/img/redmine-stack-220x234.png
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.3.10.tgz
+    version: 0.3.10
+  - created: 2017-02-13T21:33:27.767502945Z
+    description: A flexible project management web application.
+    digest: aa8a3b1be968e99c7a61ad0b7c1d13934562b9c30eeec0b3a3683063b9d38c7b
+    engine: gotpl
+    home: http://www.redmine.org/
+    icon: https://bitnami.com/assets/stacks/redmine/img/redmine-stack-220x234.png
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.3.9.tgz
+    version: 0.3.9
+  - created: 2017-02-10T23:18:26.028438027Z
+    description: A flexible project management web application.
+    digest: 51f4e834b5d2eb4ab66468e6996419bb20aa4d96ebe35a3663bc8b2c494694e6
+    engine: gotpl
+    home: http://www.redmine.org/
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.3.8.tgz
+    version: 0.3.8
+  - created: 2017-01-31T00:18:28.517014253Z
+    description: A flexible project management web application.
+    digest: d9e7c4c47c853413107330d4fc0ad44e9bc3be90057ca722d28042b73f244fe5
+    engine: gotpl
+    home: http://www.redmine.org/
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.3.7.tgz
+    version: 0.3.7
+  - created: 2016-12-15T21:18:24.678305914Z
+    description: A flexible project management web application.
+    digest: 98d9c8c7f241a9418bed6862f7c82295d5d8158cd1702907ced7150e46530768
+    engine: gotpl
+    home: http://www.redmine.org/
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.3.6.tgz
+    version: 0.3.6
+  - created: 2016-12-05T21:03:20.228049572Z
+    description: A flexible project management web application.
+    digest: ae1c2ced129d05cdae28e1fe9c2bed53ded35cd77d96fc1b26f810d334c601e3
+    engine: gotpl
+    home: http://www.redmine.org/
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.3.5.tgz
+    version: 0.3.5
+  - created: 2016-11-03T19:33:29.122956769Z
+    description: A flexible project management web application.
+    digest: c591dea135ef93f4af1a05961333125167ae551cf2b666363fe76b5a7ad9f806
+    engine: gotpl
+    home: http://www.redmine.org/
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.3.4.tgz
+    version: 0.3.4
+  - created: 2016-10-21T19:18:18.621573514Z
+    description: A flexible project management web application.
+    digest: da6a8cb8c355a93ae11d9312be9eca51966d2288eafe96b6724e6154d000b8c3
+    engine: gotpl
+    home: http://www.redmine.org/
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.3.3.tgz
+    version: 0.3.3
+  - created: 2016-10-19T00:03:14.035726608Z
+    description: A flexible project management web application.
+    digest: 052a0a97ff279db43f06c5ceeabfc5bd26f2e5f4f7ce7c24fdbcf761f97af84e
+    engine: gotpl
+    home: http://www.redmine.org/
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.3.2.tgz
+    version: 0.3.2
+  - created: 2016-10-19T00:03:14.034750035Z
+    description: A flexible project management web application.
+    digest: 88cf358644be274866ec5e88199c257e18a35fc8bbe97417658b9a0ea1e4a260
+    engine: gotpl
+    home: http://www.redmine.org/
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.3.1.tgz
+    version: 0.3.1
+  - created: 2016-10-19T00:03:14.033766322Z
+    description: A flexible project management web application.
+    digest: f4815d35cbf9f8bb72c051ee528958b9c6f48b1f3bf8b3fdceaadd90d1b88068
+    engine: gotpl
+    home: http://www.redmine.org/
+    keywords:
+    - redmine
+    - project management
+    - www
+    - http
+    - web
+    - application
+    - ruby
+    - rails
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: redmine
+    sources:
+    - https://github.com/bitnami/bitnami-docker-redmine
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/redmine-0.3.0.tgz
+    version: 0.3.0
+  sapho:
+  - apiVersion: v1
+    created: 2017-04-28T00:18:30.105942339Z
+    description: A micro application development and integration platform that enables
+      organizations to create and deliver secure micro applications that tie into
+      existing business systems and track changes to key business data.
+    digest: 6c499f9875c07b508d23b081ffd991a5737a0acaf1c75def55dbb2dc07bf40ea
+    engine: gotpl
+    home: http://www.sapho.com
+    icon: https://www.sapho.com/wp-content/uploads/2016/04/sapho-logotype.svg
+    maintainers:
+    - email: support@sapho.com
+      name: Sapho
+    name: sapho
+    sources:
+    - https://bitbucket.org/sapho/ops-docker-tomcat/src
+    - https://hub.docker.com/r/sapho/ops-docker-tomcat
+    - https://github.com/kubernetes/charts/tree/master/stable/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/sapho-0.1.5.tgz
+    version: 0.1.5
+  - apiVersion: v1
+    created: 2017-02-13T04:33:52.314506112Z
+    description: A micro application development and integration platform that enables
+      organizations to create and deliver secure micro applications that tie into
+      existing business systems and track changes to key business data.
+    digest: abe8e15b8e51369d6d05033177efb524139d3352794e201003d2e3fce3d0669d
+    engine: gotpl
+    maintainers:
+    - email: support@sapho.com
+      name: Sapho
+    name: sapho
+    sources:
+    - https://bitbucket.org/sapho/ops-docker-tomcat/src
+    - https://hub.docker.com/r/sapho/ops-docker-tomcat
+    - https://github.com/kubernetes/charts/tree/master/stable/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/sapho-0.1.4.tgz
+    version: 0.1.4
+  - apiVersion: v1
+    created: 2017-01-31T00:18:28.518904Z
+    description: A micro application development and integration platform that enables
+      organizations to create and deliver secure micro applications that tie into
+      existing business systems and track changes to key business data.
+    digest: d93ff20d61a35de8ab23d5d118c177184a6b8b0578a39ba7d101f818a8742851
+    engine: gotpl
+    maintainers:
+    - email: support@sapho.com
+      name: Sapho
+    name: sapho
+    sources:
+    - https://bitbucket.org/sapho/ops-docker-tomcat/src
+    - https://hub.docker.com/r/sapho/ops-docker-tomcat
+    - https://github.com/kubernetes/charts/tree/master/stable/mysql
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/sapho-0.1.3.tgz
+    version: 0.1.3
+  selenium:
+  - created: 2017-04-28T00:18:30.106455441Z
+    description: Chart for selenium grid
+    digest: 0e03cf36738e83b3e6ae7384c0ffdeb4ee4b694f0c0a025eb15106acb189b8d2
+    engine: gotpl
+    home: http://www.seleniumhq.org/
+    icon: http://docs.seleniumhq.org/images/big-logo.png
+    keywords:
+    - qa
+    maintainers:
+    - email: techops@adaptly.com
+      name: Philip Champon (flah00)
+    name: selenium
+    sources:
+    - https://github.com/SeleniumHQ/docker-selenium
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/selenium-0.1.0.tgz
+    version: 0.1.0
+  sensu:
+  - apiVersion: v1
+    created: 2017-04-28T00:18:30.107064065Z
+    description: Sensu monitoring framework backed by the Redis transport
+    digest: 56c74a8de76074cfb021057112cf46d11d8b77f9ef5f6ec5d0877698c9931dfa
+    engine: gotpl
+    home: https://sensuapp.org/
+    icon: https://raw.githubusercontent.com/sensu/sensu/master/sensu-logo.png
+    keywords:
+    - sensu
+    - monitoring
+    maintainers:
+    - email: shane.starcher@gmail.com
+      name: Shane Starcher
+    name: sensu
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/sstarcher/docker-sensu
+    - https://github.com/sensu/sensu
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/sensu-0.1.2.tgz
+    version: 0.1.2
+  - apiVersion: v1
+    created: 2017-03-17T05:18:29.12808256Z
+    description: Sensu monitoring framework backed by the Redis transport
+    digest: bb8781a9693f3b6df9389b3098a6298658127df2e86ad8156788602f541f33c3
+    engine: gotpl
+    home: https://sensuapp.org/
+    icon: https://raw.githubusercontent.com/sensu/sensu/master/sensu-logo.png
+    keywords:
+    - sensu
+    - monitoring
+    maintainers:
+    - email: shane.starcher@gmail.com
+      name: Shane Starcher
+    name: sensu
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/sstarcher/docker-sensu
+    - https://github.com/sensu/sensu
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/sensu-0.1.1.tgz
+    version: 0.1.1
+  - apiVersion: v1
+    created: 2016-12-21T23:33:22.277352049Z
+    description: Sensu monitoring framework backed by the Redis transport
+    digest: 4592387df52c4110a3a313820dbea81e8bf0252845e8c08ad7c71bce9a92831c
+    engine: gotpl
+    home: https://sensuapp.org/
+    icon: https://raw.githubusercontent.com/sensu/sensu/master/sensu-logo.png
+    keywords:
+    - sensu
+    - monitoring
+    maintainers:
+    - email: shane.starcher@gmail.com
+      name: Shane Starcher
+    name: sensu
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/sstarcher/docker-sensu
+    - https://github.com/sensu/sensu
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/sensu-0.1.0.tgz
+    version: 0.1.0
+  spark:
+  - created: 2017-04-28T00:18:30.107369986Z
+    description: Fast and general-purpose cluster computing system.
+    digest: d37ec7d7530a5836eeeb5ff54110d594efe188ce8175a7c2e3b50e5d9f5af9bc
+    home: http://spark.apache.org
+    icon: http://spark.apache.org/images/spark-logo-trademark.png
+    maintainers:
+    - email: lachlan.evenson@gmail.com
+      name: Lachlan Evenson
+    name: spark
+    sources:
+    - https://github.com/kubernetes/kubernetes/tree/master/examples/spark
+    - https://github.com/apache/spark
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/spark-0.1.4.tgz
+    version: 0.1.4
+  - created: 2017-03-09T19:03:32.57258203Z
+    description: Fast and general-purpose cluster computing system.
+    digest: 1cea71eb812c7ea6d566ad34247ad8d1c7b2a460b908748372618a94f035d974
+    home: http://spark.apache.org
+    icon: http://spark.apache.org/images/spark-logo-trademark.png
+    maintainers:
+    - email: lachlan.evenson@gmail.com
+      name: Lachlan Evenson
+    name: spark
+    sources:
+    - https://github.com/kubernetes/kubernetes/tree/master/examples/spark
+    - https://github.com/apache/spark
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/spark-0.1.3.tgz
+    version: 0.1.3
+  - created: 2017-02-13T04:33:52.317122021Z
+    description: A Apache Spark Helm chart for Kubernetes. Apache Spark is a fast
+      and general-purpose cluster computing system
+    digest: fd5559299116691e56c85f60be46e3b1d1a647973f4dfd6c0d87d0b0274a349b
+    home: http://spark.apache.org/
+    maintainers:
+    - email: lachlan.evenson@gmail.com
+      name: Lachlan Evenson
+    name: spark
+    sources:
+    - https://github.com/kubernetes/kubernetes/tree/master/examples/spark
+    - https://github.com/apache/spark
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/spark-0.1.2.tgz
+    version: 0.1.2
+  - created: 2017-01-27T21:48:32.088621169Z
+    description: A Apache Spark Helm chart for Kubernetes. Apache Spark is a fast
+      and general-purpose cluster computing system
+    digest: 884cc07e4710011476db63017b48504cc00b00faf461cdfe83aac40f0fd33e49
+    home: http://spark.apache.org/
+    maintainers:
+    - email: lachlan.evenson@gmail.com
+      name: Lachlan Evenson
+    name: spark
+    sources:
+    - https://github.com/kubernetes/kubernetes/tree/master/examples/spark
+    - https://github.com/apache/spark
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/spark-0.1.1.tgz
+    version: 0.1.1
+  spartakus:
+  - created: 2017-04-28T00:18:30.107681212Z
+    description: Collect information about Kubernetes clusters to help improve the
+      project.
+    digest: 7db8a6ac7280c8d112b533b2653cfa8ed43d8517a4cf31d28e24d5761d8c6b80
+    engine: gotpl
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: spartakus
+    sources:
+    - https://github.com/kubernetes-incubator/spartakus
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/spartakus-1.1.1.tgz
+    version: 1.1.1
+  - created: 2017-03-02T18:48:30.451198217Z
+    description: Collect information about Kubernetes clusters to help improve the
+      project.
+    digest: 84720960919addcce5b608717eca0218b7f6cd9edbf77a52ddc0747e51037936
+    engine: gotpl
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: spartakus
+    sources:
+    - https://github.com/kubernetes-incubator/spartakus
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/spartakus-1.1.0.tgz
+    version: 1.1.0
+  - created: 2017-02-13T17:03:30.144830851Z
+    description: A Spartakus Helm chart for Kubernetes. Spartakus aims to collect
+      information about Kubernetes clusters.
+    digest: 1c202628cd57e01cb324ee6e9457b52d1e1a5fd665f99d4bb25bd17c92c438e9
+    engine: gotpl
+    maintainers:
+    - email: mgoodness@gmail.com
+      name: Michael Goodness
+    name: spartakus
+    sources:
+    - https://github.com/kubernetes-incubator/spartakus
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/spartakus-1.0.0.tgz
+    version: 1.0.0
+  spinnaker:
+  - apiVersion: v1
+    created: 2017-04-28T00:18:30.109150773Z
+    description: Open source, multi-cloud continuous delivery platform for releasing
+      software changes with high velocity and confidence.
+    digest: a06ae1d7452e19824110cbb3270c5b7bfc4acf10af23e072e442b81fe26b1dc5
+    home: http://spinnaker.io/
+    icon: https://pbs.twimg.com/profile_images/669205226994319362/O7OjwPrh_400x400.png
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: spinnaker
+    sources:
+    - https://github.com/spinnaker
+    - https://github.com/viglesiasce/images
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/spinnaker-0.1.1.tgz
+    version: 0.1.1
+  - apiVersion: v1
+    created: 2017-02-13T20:48:27.29021219Z
+    description: A Helm chart for Kubernetes
+    digest: cc44efeace9d645b2ea824b017986d86b6b3a50fcd94e86199e0e6849eb02731
+    home: http://spinnaker.io/
+    maintainers:
+    - email: viglesias@google.com
+      name: Vic Iglesias
+    name: spinnaker
+    sources:
+    - https://github.com/spinnaker
+    - https://github.com/viglesiasce/images
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/spinnaker-0.1.0.tgz
+    version: 0.1.0
+  sumokube:
+  - created: 2017-04-28T00:18:30.109952763Z
+    description: Sumologic Log Collector
+    digest: 2f4f5cfc4c1d40cd24085497041fd701f72d4f15cb55241bfb998da82b05c7b9
+    keywords:
+    - monitoring
+    - logging
+    maintainers:
+    - email: jdumars+github@gmail.com
+      name: Jason DuMars
+    - email: knoxville+github@gmail.com
+      name: Sean Knox
+    name: sumokube
+    sources:
+    - https://github.com/SumoLogic/sumologic-collector-docker
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/sumokube-0.1.1.tgz
+    version: 0.1.1
+  - created: 2017-01-27T21:48:32.092039665Z
+    description: Sumologic Log Collector
+    digest: 5b173be9b7dc0e1d48a7cd11015b9c405666a40420a290c5fb54e4f8718b4fc0
+    keywords:
+    - monitoring
+    - logging
+    maintainers:
+    - email: jdumars+github@gmail.com
+      name: Jason DuMars
+    - email: knoxville+github@gmail.com
+      name: Sean Knox
+    name: sumokube
+    sources:
+    - https://github.com/SumoLogic/sumologic-collector-docker
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/sumokube-0.1.0.tgz
+    version: 0.1.0
+  telegraf:
+  - created: 2017-04-28T00:18:30.110460492Z
+    description: Telegraf is an agent written in Go for collecting, processing, aggregating,
+      and writing metrics.
+    digest: 850b4b7543a3dd7f5d33ba65d9098fe4f361981f49452a40ce9774850b4285e3
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/telegraf/
+    keywords:
+    - telegraf
+    - collector
+    - timeseries
+    - influxdata
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: telegraf
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/telegraf-0.2.0.tgz
+    version: 0.2.0
+  - created: 2017-02-13T21:48:52.617397285Z
+    description: Telegraf is an agent written in Go for collecting, processing, aggregating,
+      and writing metrics.
+    digest: 1f74106455808d45d16742f6d7d02164eb328a40dd9699dfa4511b33efaf14e9
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/telegraf/
+    keywords:
+    - telegraf
+    - collector
+    - timeseries
+    - influxdata
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: telegraf
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/telegraf-0.1.1.tgz
+    version: 0.1.1
+  - created: 2017-02-11T03:18:26.54678474Z
+    description: Chart for Telegraf Kubernetes deployments
+    digest: 52fa68fd948ee675a5d1a5ffff22d98e293ee37569a8fa56a4022f51e9507184
+    engine: gotpl
+    home: https://www.influxdata.com/time-series-platform/telegraf/
+    keywords:
+    - telegraf
+    - collector
+    - timeseries
+    - influxdata
+    maintainers:
+    - email: jack@influxdb.com
+      name: Jack Zampolin
+    name: telegraf
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/telegraf-0.1.0.tgz
+    version: 0.1.0
+  testlink:
+  - created: 2017-04-28T00:18:30.111130012Z
+    description: Web-based test management system that facilitates software quality
+      assurance.
+    digest: 8cffc761a9e6618bc015cec3721964192e909dfaae92a9bb79c4471424c74128
+    engine: gotpl
+    home: http://www.testlink.org/
+    icon: https://bitnami.com/assets/stacks/testlink/img/testlink-stack-220x234.png
+    keywords:
+    - testlink
+    - testing
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: testlink
+    sources:
+    - https://github.com/bitnami/bitnami-docker-testlink
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/testlink-0.4.6.tgz
+    version: 0.4.6
+  - created: 2017-03-23T18:18:30.028234531Z
+    description: Web-based test management system that facilitates software quality
+      assurance.
+    digest: 08f7104671364ff6bd43270659733ea97a4adc06181f8a5c3027ac3d0078e51c
+    engine: gotpl
+    home: http://www.testlink.org/
+    icon: https://bitnami.com/assets/stacks/testlink/img/testlink-stack-220x234.png
+    keywords:
+    - testlink
+    - testing
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: testlink
+    sources:
+    - https://github.com/bitnami/bitnami-docker-testlink
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/testlink-0.4.5.tgz
+    version: 0.4.5
+  - created: 2017-03-08T19:03:31.751542723Z
+    description: Web-based test management system that facilitates software quality
+      assurance.
+    digest: 7861921ff159f1be6834acfc3e5c139382a8c6461b20a45c4b1561985827c865
+    engine: gotpl
+    home: http://www.testlink.org/
+    icon: https://bitnami.com/assets/stacks/testlink/img/testlink-stack-220x234.png
+    keywords:
+    - testlink
+    - testing
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: testlink
+    sources:
+    - https://github.com/bitnami/bitnami-docker-testlink
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/testlink-0.4.4.tgz
+    version: 0.4.4
+  - created: 2017-02-11T03:18:26.547570032Z
+    description: Web-based test management system that facilitates software quality
+      assurance.
+    digest: 2c7188d5f1a9fb03c71b2e2d693dfbef9a739ae8889d9eb38854900cf066077b
+    engine: gotpl
+    home: http://www.testlink.org/
+    keywords:
+    - testlink
+    - testing
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: testlink
+    sources:
+    - https://github.com/bitnami/bitnami-docker-testlink
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/testlink-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-01-21T00:18:31.369288453Z
+    description: Web-based test management system that facilitates software quality
+      assurance.
+    digest: 78f6a9cfe1843b8ea99489d8b4c801f84271ee25827ad044989ed0df21ac086b
+    engine: gotpl
+    home: http://www.testlink.org/
+    keywords:
+    - testlink
+    - testing
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: testlink
+    sources:
+    - https://github.com/bitnami/bitnami-docker-testlink
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/testlink-0.4.2.tgz
+    version: 0.4.2
+  - created: 2016-12-15T21:18:24.679744308Z
+    description: Web-based test management system that facilitates software quality
+      assurance.
+    digest: 9edb2777c6db4794885a2c7531a28436774edc248aad3a26007bca4076058143
+    engine: gotpl
+    home: http://www.testlink.org/
+    keywords:
+    - testlink
+    - testing
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: testlink
+    sources:
+    - https://github.com/bitnami/bitnami-docker-testlink
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/testlink-0.4.1.tgz
+    version: 0.4.1
+  - created: 2016-12-09T18:48:20.193151472Z
+    description: Web-based test management system that facilitates software quality
+      assurance.
+    digest: df216a31082cdf15867ee9a17b107e4006e9e0a20b79425889b695c4c46fb0c1
+    engine: gotpl
+    home: http://www.testlink.org/
+    keywords:
+    - testlink
+    - testing
+    - http
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: testlink
+    sources:
+    - https://github.com/bitnami/bitnami-docker-testlink
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/testlink-0.4.0.tgz
+    version: 0.4.0
+  traefik:
+  - apiVersion: v1
+    created: 2017-04-28T00:18:30.111646123Z
+    description: A Traefik based Kubernetes ingress controller with Let's Encrypt
+      support
+    digest: 4019610a5fb1defcc5bc90532cb19c986999114f7de4aef3f0272e6c7ed1b914
+    engine: gotpl
+    home: http://traefik.io/
+    icon: http://traefik.io/traefik.logo.png
+    keywords:
+    - traefik
+    - ingress
+    - acme
+    - letsencrypt
+    maintainers:
+    - email: engineering@deis.com
+      name: Deis
+    name: traefik
+    sources:
+    - https://github.com/containous/traefik
+    - https://github.com/krancour/charts/tree/master/traefik
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/traefik-1.2.1-a.tgz
+    version: 1.2.1-a
+  - apiVersion: v1
+    created: 2017-03-31T19:33:30.456523182Z
+    description: A Traefik based Kubernetes ingress controller with Let's Encrypt
+      support
+    digest: ba0ade25b34f419ad0790b220fb7277a046d48bc76e1c726f66ba535b51d4f63
+    engine: gotpl
+    home: http://traefik.io/
+    icon: http://traefik.io/traefik.logo.png
+    keywords:
+    - traefik
+    - ingress
+    - acme
+    - letsencrypt
+    maintainers:
+    - email: engineering@deis.com
+      name: Deis
+    name: traefik
+    sources:
+    - https://github.com/containous/traefik
+    - https://github.com/krancour/charts/tree/master/traefik
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/traefik-1.1.2-h.tgz
+    version: 1.1.2-h
+  - apiVersion: v1
+    created: 2017-03-16T23:33:31.610346236Z
+    description: A Traefik based Kubernetes ingress controller with Let's Encrypt
+      support
+    digest: 9aa401aee6da3b4afc5cc3f8be7ff9f74bf424743ca72a7a7b91a7105d9781b6
+    engine: gotpl
+    home: http://traefik.io/
+    icon: http://traefik.io/traefik.logo.png
+    keywords:
+    - traefik
+    - ingress
+    - acme
+    - letsencrypt
+    maintainers:
+    - email: engineering@deis.com
+      name: Deis
+    name: traefik
+    sources:
+    - https://github.com/containous/traefik
+    - https://github.com/krancour/charts/tree/master/traefik
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/traefik-1.1.2-g.tgz
+    version: 1.1.2-g
+  - apiVersion: v1
+    created: 2017-02-27T17:18:28.185706737Z
+    description: A Traefik based Kubernetes ingress controller with Let's Encrypt
+      support
+    digest: 5bb7b98b962098808e3b73f604592bc4c6e6245e0074fa0c99308fc04bf766b8
+    engine: gotpl
+    home: http://traefik.io/
+    icon: http://traefik.io/traefik.logo.png
+    keywords:
+    - traefik
+    - ingress
+    - acme
+    - letsencrypt
+    maintainers:
+    - email: engineering@deis.com
+      name: Deis
+    name: traefik
+    sources:
+    - https://github.com/containous/traefik
+    - https://github.com/krancour/charts/tree/master/traefik
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/traefik-1.1.2-f.tgz
+    version: 1.1.2-f
+  - apiVersion: v1
+    created: 2017-02-13T22:18:28.973464794Z
+    description: A Traefik based Kubernetes ingress controller with Let's Encrypt
+      support
+    digest: ae467c4bee7364d17de2583d33031d0eeb2ef55e7962a7db0245d692e65479e1
+    engine: gotpl
+    home: http://traefik.io/
+    icon: http://traefik.io/traefik.logo.png
+    keywords:
+    - traefik
+    - ingress
+    - acme
+    - letsencrypt
+    maintainers:
+    - email: engineering@deis.com
+      name: Deis
+    name: traefik
+    sources:
+    - https://github.com/containous/traefik
+    - https://github.com/krancour/charts/tree/master/traefik
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/traefik-1.1.2-e.tgz
+    version: 1.1.2-e
+  - apiVersion: v1
+    created: 2017-02-13T21:33:27.776086791Z
+    description: A Traefik based Kubernetes ingress controller with Let's Encrypt
+      support
+    digest: 399d74bcd8ab26f2de10894d83b59d413752797789b9fe9568e17f7b564f5f75
+    engine: gotpl
+    home: http://traefik.io/
+    icon: http://traefik.io/traefik.logo.png
+    keywords:
+    - traefik
+    - ingress
+    - acme
+    - letsencrypt
+    maintainers:
+    - email: engineering@deis.com
+      name: Deis
+    name: traefik
+    sources:
+    - https://github.com/containous/traefik
+    - https://github.com/krancour/charts/tree/master/traefik
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/traefik-1.1.2-d.tgz
+    version: 1.1.2-d
+  - apiVersion: v1
+    created: 2017-02-03T19:33:30.806247527Z
+    description: A Traefik based Kubernetes ingress controller with Let's Encrypt
+      support
+    digest: e225511060509d9cf3e38eaafd93af9ee994f8ed99c40a25500f4a1d06851841
+    engine: gotpl
+    home: http://traefik.io/
+    icon: http://traefik.io/traefik.logo.png
+    keywords:
+    - traefik
+    - ingress
+    - acme
+    - letsencrypt
+    maintainers:
+    - email: engineering@deis.com
+      name: Deis
+    name: traefik
+    sources:
+    - https://github.com/containous/traefik
+    - https://github.com/krancour/charts/tree/master/traefik
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/traefik-1.1.2-c.tgz
+    version: 1.1.2-c
+  - apiVersion: v1
+    created: 2017-02-01T02:18:29.153394653Z
+    description: A Traefik based Kubernetes ingress controller with Let's Encrypt
+      support
+    digest: 9cc02b2e43c901c92aa560b4f85e325f04635d052035418f3b27b06bdd571ae9
+    engine: gotpl
+    home: http://traefik.io/
+    icon: http://traefik.io/traefik.logo.png
+    keywords:
+    - traefik
+    - ingress
+    - acme
+    - letsencrypt
+    maintainers:
+    - email: engineering@deis.com
+      name: Deis
+    name: traefik
+    sources:
+    - https://github.com/containous/traefik
+    - https://github.com/krancour/charts/tree/master/traefik
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/traefik-1.1.2-b.tgz
+    version: 1.1.2-b
+  - apiVersion: v1
+    created: 2017-01-28T00:18:32.767314879Z
+    description: A Traefik based Kubernetes ingress controller with Let's Encrypt
+      support
+    digest: 9bae960964d5062dd4c412ad7daf6f6f9e8dd070264aa3f44c831c817fc26b7d
+    engine: gotpl
+    home: http://traefik.io/
+    icon: http://traefik.io/traefik.logo.png
+    keywords:
+    - traefik
+    - ingress
+    - acme
+    - letsencrypt
+    maintainers:
+    - email: engineering@deis.com
+      name: Deis
+    name: traefik
+    sources:
+    - https://github.com/containous/traefik
+    - https://github.com/krancour/charts/tree/master/traefik
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/traefik-1.1.2-a.tgz
+    version: 1.1.2-a
+  - apiVersion: v1
+    created: 2017-01-03T17:48:20.753425335Z
+    description: A Traefik based Kubernetes ingress controller with Let's Encrypt
+      support
+    digest: e8ab4576505091785b27084e4f4e4f02f1ee3f1744d9842ec086457baabe8b85
+    engine: gotpl
+    home: http://traefik.io/
+    icon: http://traefik.io/traefik.logo.png
+    keywords:
+    - traefik
+    - ingress
+    - acme
+    - letsencrypt
+    maintainers:
+    - email: engineering@deis.com
+      name: Deis
+    name: traefik
+    sources:
+    - https://github.com/containous/traefik
+    - https://github.com/krancour/charts/tree/master/traefik
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/traefik-1.1.1-a.tgz
+    version: 1.1.1-a
+  - apiVersion: v1
+    created: 2016-11-23T00:33:20.024479934Z
+    description: A Traefik based Kubernetes ingress controller with Let's Encrypt
+      support
+    digest: 6664534aab03a22531602a415ca14a72e932b08fe1feab8866cc55ba18b77dc8
+    engine: gotpl
+    home: http://traefik.io/
+    icon: http://traefik.io/traefik.logo.png
+    keywords:
+    - traefik
+    - ingress
+    - acme
+    - letsencrypt
+    maintainers:
+    - email: engineering@deis.com
+      name: Deis
+    name: traefik
+    sources:
+    - https://github.com/containous/traefik
+    - https://github.com/krancour/charts/tree/master/traefik
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/traefik-1.1.0-rc3-a.tgz
+    version: 1.1.0-rc3-a
+  - apiVersion: v1
+    created: 2016-11-30T22:03:20.721274307Z
+    description: A Traefik based Kubernetes ingress controller with Let's Encrypt
+      support
+    digest: 2828d7284839baee1fb36f823ce4e2574a4b675b7f4f74e921a4685f4cee28c2
+    engine: gotpl
+    home: http://traefik.io/
+    icon: http://traefik.io/traefik.logo.png
+    keywords:
+    - traefik
+    - ingress
+    - acme
+    - letsencrypt
+    maintainers:
+    - email: engineering@deis.com
+      name: Deis
+    name: traefik
+    sources:
+    - https://github.com/containous/traefik
+    - https://github.com/krancour/charts/tree/master/traefik
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/traefik-1.1.0-a.tgz
+    version: 1.1.0-a
+  uchiwa:
+  - apiVersion: v1
+    created: 2017-04-28T00:18:30.112528335Z
+    description: Dashboard for the Sensu monitoring framework
+    digest: b9b7186c2e53d4049c4b0ef9ba9c89ded7de36bf920653b63f6ea725253354d6
+    engine: gotpl
+    home: https://uchiwa.io/
+    icon: https://uchiwa.io/img/favicon.png
+    keywords:
+    - uchiwa
+    - sensu
+    - monitoring
+    maintainers:
+    - email: shane.starcher@gmail.com
+      name: Shane Starcher
+    name: uchiwa
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/sstarcher/docker-uchiwa
+    - https://github.com/sensu/uchiwa
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/uchiwa-0.2.1.tgz
+    version: 0.2.1
+  - apiVersion: v1
+    created: 2017-03-17T06:03:29.101091523Z
+    description: Dashboard for the Sensu monitoring framework
+    digest: 9bee21cd61e56e08f58c1ba130e0a4af1a1d62a8d7921f9408509bd501494403
+    engine: gotpl
+    home: https://uchiwa.io/
+    icon: https://uchiwa.io/img/favicon.png
+    keywords:
+    - uchiwa
+    - sensu
+    - monitoring
+    maintainers:
+    - email: shane.starcher@gmail.com
+      name: Shane Starcher
+    name: uchiwa
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/sstarcher/docker-uchiwa
+    - https://github.com/sensu/uchiwa
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/uchiwa-0.2.0.tgz
+    version: 0.2.0
+  - apiVersion: v1
+    created: 2017-01-18T23:03:27.817024829Z
+    description: Dashboard for the Sensu monitoring framework
+    digest: 868d7e58adb2fead4ed9e4be17e2017c2d1c55d265b2a579625e787e6f15f4d5
+    engine: gotpl
+    home: https://uchiwa.io/
+    icon: https://uchiwa.io/img/favicon.png
+    keywords:
+    - uchiwa
+    - sensu
+    - monitoring
+    maintainers:
+    - email: shane.starcher@gmail.com
+      name: Shane Starcher
+    name: uchiwa
+    sources:
+    - https://github.com/kubernetes/charts
+    - https://github.com/sstarcher/docker-uchiwa
+    - https://github.com/sensu/uchiwa
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/uchiwa-0.1.0.tgz
+    version: 0.1.0
+  wordpress:
+  - created: 2017-04-28T00:18:30.114169329Z
+    description: Web publishing platform for building blogs and websites.
+    digest: 8df4b37c471d43b5b3955ecadcc0da1dad31ba28a93ae0b74be5fc94debf2876
+    engine: gotpl
+    home: http://www.wordpress.com/
+    icon: https://bitnami.com/assets/stacks/wordpress/img/wordpress-stack-220x234.png
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.6.0.tgz
+    version: 0.6.0
+  - created: 2017-04-03T22:33:26.700088102Z
+    description: Web publishing platform for building blogs and websites.
+    digest: 4413a17258eaca753252174a219ba9081283a406375d8ae49e5c1f3313c6619a
+    engine: gotpl
+    home: http://www.wordpress.com/
+    icon: https://bitnami.com/assets/stacks/wordpress/img/wordpress-stack-220x234.png
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.5.2.tgz
+    version: 0.5.2
+  - created: 2017-03-23T21:18:31.877594706Z
+    description: Web publishing platform for building blogs and websites.
+    digest: 3e408baaa5110edfd730603bd5d49d7a8c222f49c7e9de1bd168b564463d57d9
+    engine: gotpl
+    home: http://www.wordpress.com/
+    icon: https://bitnami.com/assets/stacks/wordpress/img/wordpress-stack-220x234.png
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.5.1.tgz
+    version: 0.5.1
+  - created: 2017-03-16T13:33:30.866725941Z
+    description: Web publishing platform for building blogs and websites.
+    digest: 40c767b4b2b7d494ea6da7a20a9fe58e76896a0bdad7c6c569f9d8cdab71f2e3
+    engine: gotpl
+    home: http://www.wordpress.com/
+    icon: https://bitnami.com/assets/stacks/wordpress/img/wordpress-stack-220x234.png
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.5.0.tgz
+    version: 0.5.0
+  - created: 2017-03-14T23:48:31.917245657Z
+    description: Web publishing platform for building blogs and websites.
+    digest: 306220e3c19f1360644eade517a2a8ca422e8f9ec6ea9c65181ce8fc9797772f
+    engine: gotpl
+    home: http://www.wordpress.com/
+    icon: https://bitnami.com/assets/stacks/wordpress/img/wordpress-stack-220x234.png
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.4.3.tgz
+    version: 0.4.3
+  - created: 2017-03-08T19:03:31.755452536Z
+    description: Web publishing platform for building blogs and websites.
+    digest: 0689b452d3c9a9bee6e5c84b48172c68de6eedc253223b96ab6500ad88a5de40
+    engine: gotpl
+    home: http://www.wordpress.com/
+    icon: https://bitnami.com/assets/stacks/wordpress/img/wordpress-stack-220x234.png
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.4.2.tgz
+    version: 0.4.2
+  - created: 2017-02-13T04:33:52.323397093Z
+    description: Web publishing platform for building blogs and websites.
+    digest: 0fc412dea55069b368183afefb74342001a91a7f3a0e9126a921581d7740d61c
+    engine: gotpl
+    home: http://www.wordpress.com/
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.4.1.tgz
+    version: 0.4.1
+  - created: 2017-01-28T00:18:32.769124587Z
+    description: Web publishing platform for building blogs and websites.
+    digest: 2f4a5d65350b36a6481c4c3d619f713835f091821d3f56c38c718061628ff712
+    engine: gotpl
+    home: http://www.wordpress.com/
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.4.0.tgz
+    version: 0.4.0
+  - created: 2017-01-04T00:48:19.757447587Z
+    description: Web publishing platform for building blogs and websites.
+    digest: f62b6f1728a33c5d59dd24dc6fb984f13d2dffac2bc6eec01724501e66ffc6a0
+    engine: gotpl
+    home: http://www.wordpress.com/
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.3.4.tgz
+    version: 0.3.4
+  - created: 2016-12-15T00:48:24.021239603Z
+    description: Web publishing platform for building blogs and websites.
+    digest: 0c86b7cec5877a3c3c55d919b2f02ae52340c953afd9dc541ae0280bc23fe9aa
+    engine: gotpl
+    home: http://www.wordpress.com/
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.3.3.tgz
+    version: 0.3.3
+  - created: 2016-12-09T18:48:20.19465733Z
+    description: Web publishing platform for building blogs and websites.
+    digest: 589e49370cb09f6d9ddb3ceba3b21f52697570cd4b40aff891a660c5daaa9bec
+    engine: gotpl
+    home: http://www.wordpress.com/
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.3.2.tgz
+    version: 0.3.2
+  - created: 2016-10-21T19:18:18.622178432Z
+    description: Web publishing platform for building blogs and websites.
+    digest: e70a072dcbb7252becc8899f54de8cb5977ceaea47197919c3990a6896adc350
+    engine: gotpl
+    home: http://www.wordpress.com/
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.3.1.tgz
+    version: 0.3.1
+  - created: 2016-10-19T00:03:14.037631856Z
+    description: Web publishing platform for building blogs and websites.
+    digest: 1c44515f02fb34b722dce1d8cf5fed0dfbbd2f8c03d63b335211b7bcb12b6dea
+    engine: gotpl
+    home: http://www.wordpress.com/
+    keywords:
+    - wordpress
+    - cms
+    - blog
+    - http
+    - web
+    - application
+    - php
+    maintainers:
+    - email: containers@bitnami.com
+      name: Bitnami
+    name: wordpress
+    sources:
+    - https://github.com/bitnami/bitnami-docker-wordpress
+    urls:
+    - https://kubernetes-charts.storage.googleapis.com/wordpress-0.3.0.tgz
+    version: 0.3.0
+generated: 2017-04-28T00:18:30.070608132Z
diff --git a/pkg/getter/testdata/repository/local/index.yaml b/pkg/getter/testdata/repository/local/index.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..efcf30c211be859f1e1f3439b5459f3ba1450c72
--- /dev/null
+++ b/pkg/getter/testdata/repository/local/index.yaml
@@ -0,0 +1,3 @@
+apiVersion: v1
+entries: {}
+generated: 2017-04-28T12:34:38.900985501-06:00
diff --git a/pkg/getter/testdata/repository/repositories.yaml b/pkg/getter/testdata/repository/repositories.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1d884a0c75cd1d63097c324ecc08a86d65ada81a
--- /dev/null
+++ b/pkg/getter/testdata/repository/repositories.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+generated: 2017-04-28T12:34:38.551693035-06:00
+repositories:
+- caFile: ""
+  cache: repository/cache/stable-index.yaml
+  certFile: ""
+  keyFile: ""
+  name: stable
+  url: https://kubernetes-charts.storage.googleapis.com
+- caFile: ""
+  cache: repository/cache/local-index.yaml
+  certFile: ""
+  keyFile: ""
+  name: local
+  url: http://127.0.0.1:8879/charts
diff --git a/pkg/helm/client.go b/pkg/helm/client.go
index 5b12047c8b6659db1cc10dfd7c6882ad29569a8d..7e41b89bc30c69fe94e0cf98e25a1fc645a7c67e 100644
--- a/pkg/helm/client.go
+++ b/pkg/helm/client.go
@@ -98,7 +98,7 @@ func (h *Client) InstallReleaseFromChart(chart *chart.Chart, ns string, opts ...
 	if err != nil {
 		return nil, err
 	}
-	err = chartutil.ProcessRequirementsImportValues(req.Chart, req.Values)
+	err = chartutil.ProcessRequirementsImportValues(req.Chart)
 	if err != nil {
 		return nil, err
 	}
@@ -159,6 +159,7 @@ func (h *Client) UpdateReleaseFromChart(rlsName string, chart *chart.Chart, opts
 	req.Name = rlsName
 	req.DisableHooks = h.opts.disableHooks
 	req.Recreate = h.opts.recreate
+	req.Force = h.opts.force
 	req.ResetValues = h.opts.resetValues
 	req.ReuseValues = h.opts.reuseValues
 	ctx := NewContext()
@@ -172,7 +173,7 @@ func (h *Client) UpdateReleaseFromChart(rlsName string, chart *chart.Chart, opts
 	if err != nil {
 		return nil, err
 	}
-	err = chartutil.ProcessRequirementsImportValues(req.Chart, req.Values)
+	err = chartutil.ProcessRequirementsImportValues(req.Chart)
 	if err != nil {
 		return nil, err
 	}
@@ -202,6 +203,8 @@ func (h *Client) RollbackRelease(rlsName string, opts ...RollbackOption) (*rls.R
 		opt(&h.opts)
 	}
 	req := &h.opts.rollbackReq
+	req.Recreate = h.opts.recreate
+	req.Force = h.opts.force
 	req.DisableHooks = h.opts.disableHooks
 	req.DryRun = h.opts.dryRun
 	req.Name = rlsName
diff --git a/pkg/helm/environment/environment.go b/pkg/helm/environment/environment.go
index 22fb43ae73e14771f9dfbff62db16cac8b262190..2092450e1500988b8a7121f912266cd851da1b0d 100644
--- a/pkg/helm/environment/environment.go
+++ b/pkg/helm/environment/environment.go
@@ -30,27 +30,37 @@ import (
 )
 
 const (
-	HomeEnvVar          = "HELM_HOME"
-	PluginEnvVar        = "HELM_PLUGIN"
+	// HomeEnvVar is the HELM_HOME environment variable key.
+	HomeEnvVar = "HELM_HOME"
+	// PluginEnvVar is the HELM_PLUGIN environment variable key.
+	PluginEnvVar = "HELM_PLUGIN"
+	// PluginDisableEnvVar is the HELM_NO_PLUGINS environment variable key.
 	PluginDisableEnvVar = "HELM_NO_PLUGINS"
-	HostEnvVar          = "HELM_HOST"
+	// HostEnvVar is the HELM_HOST environment variable key.
+	HostEnvVar = "HELM_HOST"
+	// DebugEnvVar is the HELM_DEBUG environment variable key.
+	DebugEnvVar = "HELM_DEBUG"
 )
 
-func DefaultHelmHome() string {
-	if home := os.Getenv(HomeEnvVar); home != "" {
-		return home
-	}
-	return filepath.Join(os.Getenv("HOME"), ".helm")
-}
-
-func DefaultHelmHost() string {
-	return os.Getenv(HostEnvVar)
-}
+// DefaultHelmHome is the default HELM_HOME.
+var DefaultHelmHome = filepath.Join("$HOME", ".helm")
 
+// EnvSettings describes all of the environment settings.
 type EnvSettings struct {
-	TillerHost      string
+	// TillerHost is the host and port of Tiller.
+	TillerHost string
+	// TillerNamespace is the namespace in which Tiller runs.
 	TillerNamespace string
-	Home            helmpath.Home
-	PlugDirs        string
-	Debug           bool
+	// Home is the local path to the Helm home directory.
+	Home helmpath.Home
+	// Debug indicates whether or not Helm is running in Debug mode.
+	Debug bool
+}
+
+// PluginDirs is the path to the plugin directories.
+func (s EnvSettings) PluginDirs() string {
+	if d := os.Getenv(PluginEnvVar); d != "" {
+		return d
+	}
+	return s.Home.Plugins()
 }
diff --git a/pkg/helm/helmpath/helmhome.go b/pkg/helm/helmpath/helmhome.go
index d3023dcba0f07c525f8526cddad5783e585d5430..c9aad70c65aa3f438b974bcaa10fc5a4430dc9e7 100644
--- a/pkg/helm/helmpath/helmhome.go
+++ b/pkg/helm/helmpath/helmhome.go
@@ -17,6 +17,7 @@ package helmpath
 
 import (
 	"fmt"
+	"os"
 	"path/filepath"
 )
 
@@ -29,12 +30,12 @@ type Home string
 //
 // Implements fmt.Stringer.
 func (h Home) String() string {
-	return string(h)
+	return os.ExpandEnv(string(h))
 }
 
 // Path returns Home with elements appended.
 func (h Home) Path(elem ...string) string {
-	p := []string{string(h)}
+	p := []string{h.String()}
 	p = append(p, elem...)
 	return filepath.Join(p...)
 }
diff --git a/pkg/helm/helmpath/helmhome_unix_test.go b/pkg/helm/helmpath/helmhome_unix_test.go
index cca303d2926eb815462ac16196ce734f0c2dc20e..9c31a9c07493e53d848349b6518a314d25aac11a 100644
--- a/pkg/helm/helmpath/helmhome_unix_test.go
+++ b/pkg/helm/helmpath/helmhome_unix_test.go
@@ -38,3 +38,9 @@ func TestHelmHome(t *testing.T) {
 	isEq(t, hh.CacheIndex("t"), "/r/repository/cache/t-index.yaml")
 	isEq(t, hh.Starters(), "/r/starters")
 }
+
+func TestHelmHome_expand(t *testing.T) {
+	if Home("$HOME").String() == "$HOME" {
+		t.Error("expected variable expansion")
+	}
+}
diff --git a/pkg/helm/option.go b/pkg/helm/option.go
index b4f6631c4f720847bffbc498bde96d7aa9c2e5ee..2b30cd3c595662f647f1bf62f4881cf9c4821a29 100644
--- a/pkg/helm/option.go
+++ b/pkg/helm/option.go
@@ -46,6 +46,8 @@ type options struct {
 	reuseName bool
 	// if set, performs pod restart during upgrade/rollback
 	recreate bool
+	// if set, force resource update through delete/recreate if needed
+	force bool
 	// if set, skip running hooks
 	disableHooks bool
 	// name of release
@@ -311,6 +313,13 @@ func RollbackRecreate(recreate bool) RollbackOption {
 	}
 }
 
+// RollbackForce will (if true) force resource update through delete/recreate if needed
+func RollbackForce(force bool) RollbackOption {
+	return func(opts *options) {
+		opts.force = force
+	}
+}
+
 // RollbackVersion sets the version of the release to deploy.
 func RollbackVersion(ver int32) RollbackOption {
 	return func(opts *options) {
@@ -353,6 +362,13 @@ func UpgradeRecreate(recreate bool) UpdateOption {
 	}
 }
 
+// UpgradeForce will (if true) force resource update through delete/recreate if needed
+func UpgradeForce(force bool) UpdateOption {
+	return func(opts *options) {
+		opts.force = force
+	}
+}
+
 // ContentOption allows setting optional attributes when
 // performing a GetReleaseContent tiller rpc.
 type ContentOption func(*options)
@@ -408,7 +424,7 @@ func WithMaxHistory(max int32) HistoryOption {
 
 // NewContext creates a versioned context.
 func NewContext() context.Context {
-	md := metadata.Pairs("x-helm-api-client", version.Version)
+	md := metadata.Pairs("x-helm-api-client", version.GetVersion())
 	return metadata.NewContext(context.TODO(), md)
 }
 
diff --git a/pkg/kube/client.go b/pkg/kube/client.go
index 333e3ab374988347aaecaf23ab32111284f2bca6..04e28e81692ac458934729e5395b484d950ad99e 100644
--- a/pkg/kube/client.go
+++ b/pkg/kube/client.go
@@ -59,6 +59,8 @@ type Client struct {
 	cmdutil.Factory
 	// SchemaCacheDir is the path for loading cached schema.
 	SchemaCacheDir string
+
+	Log func(string, ...interface{})
 }
 
 // New create a new Client
@@ -66,6 +68,7 @@ func New(config clientcmd.ClientConfig) *Client {
 	return &Client{
 		Factory:        cmdutil.NewFactory(config),
 		SchemaCacheDir: clientcmd.RecommendedSchemaFile,
+		Log:            func(_ string, _ ...interface{}) {},
 	}
 }
 
@@ -83,10 +86,12 @@ func (c *Client) Create(namespace string, reader io.Reader, timeout int64, shoul
 	if err := ensureNamespace(client, namespace); err != nil {
 		return err
 	}
+	c.Log("building resources from manifest")
 	infos, buildErr := c.BuildUnstructured(namespace, reader)
 	if buildErr != nil {
 		return buildErr
 	}
+	c.Log("creating %d resource(s)", len(infos))
 	if err := perform(infos, createResource); err != nil {
 		return err
 	}
@@ -99,7 +104,7 @@ func (c *Client) Create(namespace string, reader io.Reader, timeout int64, shoul
 func (c *Client) newBuilder(namespace string, reader io.Reader) *resource.Result {
 	schema, err := c.Validator(true, c.SchemaCacheDir)
 	if err != nil {
-		log.Printf("warning: failed to load schema: %s", err)
+		c.Log("warning: failed to load schema: %s", err)
 	}
 	return c.NewBuilder().
 		ContinueOnError().
@@ -115,12 +120,12 @@ func (c *Client) newBuilder(namespace string, reader io.Reader) *resource.Result
 func (c *Client) BuildUnstructured(namespace string, reader io.Reader) (Result, error) {
 	schema, err := c.Validator(true, c.SchemaCacheDir)
 	if err != nil {
-		log.Printf("warning: failed to load schema: %s", err)
+		c.Log("warning: failed to load schema: %s", err)
 	}
 
 	mapper, typer, err := c.UnstructuredObject()
 	if err != nil {
-		log.Printf("failed to load mapper: %s", err)
+		c.Log("failed to load mapper: %s", err)
 		return nil, err
 	}
 	var result Result
@@ -155,9 +160,9 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) {
 	}
 	missing := []string{}
 	err = perform(infos, func(info *resource.Info) error {
-		log.Printf("Doing get for %s: %q", info.Mapping.GroupVersionKind.Kind, info.Name)
+		c.Log("Doing get for %s: %q", info.Mapping.GroupVersionKind.Kind, info.Name)
 		if err := info.Get(); err != nil {
-			log.Printf("WARNING: Failed Get for resource %q: %s", info.Name, err)
+			c.Log("WARNING: Failed Get for resource %q: %s", info.Name, err)
 			missing = append(missing, fmt.Sprintf("%v\t\t%s", info.Mapping.Resource, info.Name))
 			return nil
 		}
@@ -185,7 +190,7 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) {
 		}
 		for _, o := range ot {
 			if err := p.PrintObj(o, buf); err != nil {
-				log.Printf("failed to print object type %s, object: %q :\n %v", t, o, err)
+				c.Log("failed to print object type %s, object: %q :\n %v", t, o, err)
 				return "", err
 			}
 		}
@@ -208,12 +213,13 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) {
 //  not present in the target configuration
 //
 // Namespace will set the namespaces
-func (c *Client) Update(namespace string, originalReader, targetReader io.Reader, recreate bool, timeout int64, shouldWait bool) error {
+func (c *Client) Update(namespace string, originalReader, targetReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error {
 	original, err := c.BuildUnstructured(namespace, originalReader)
 	if err != nil {
 		return fmt.Errorf("failed decoding reader into objects: %s", err)
 	}
 
+	c.Log("building resources from updated manifest")
 	target, err := c.BuildUnstructured(namespace, targetReader)
 	if err != nil {
 		return fmt.Errorf("failed decoding reader into objects: %s", err)
@@ -221,6 +227,7 @@ func (c *Client) Update(namespace string, originalReader, targetReader io.Reader
 
 	updateErrors := []string{}
 
+	c.Log("checking %d resources for changes", len(target))
 	err = target.Visit(func(info *resource.Info, err error) error {
 		if err != nil {
 			return err
@@ -229,7 +236,7 @@ func (c *Client) Update(namespace string, originalReader, targetReader io.Reader
 		helper := resource.NewHelper(info.Client, info.Mapping)
 		if _, err := helper.Get(info.Namespace, info.Name, info.Export); err != nil {
 			if !errors.IsNotFound(err) {
-				return fmt.Errorf("Could not get information about the resource: err: %s", err)
+				return fmt.Errorf("Could not get information about the resource: %s", err)
 			}
 
 			// Since the resource does not exist, create it.
@@ -238,7 +245,7 @@ func (c *Client) Update(namespace string, originalReader, targetReader io.Reader
 			}
 
 			kind := info.Mapping.GroupVersionKind.Kind
-			log.Printf("Created a new %s called %q\n", kind, info.Name)
+			c.Log("Created a new %s called %q\n", kind, info.Name)
 			return nil
 		}
 
@@ -247,8 +254,8 @@ func (c *Client) Update(namespace string, originalReader, targetReader io.Reader
 			return fmt.Errorf("no resource with the name %q found", info.Name)
 		}
 
-		if err := updateResource(c, info, originalInfo.Object, recreate); err != nil {
-			log.Printf("error updating the resource %q:\n\t %v", info.Name, err)
+		if err := updateResource(c, info, originalInfo.Object, force, recreate); err != nil {
+			c.Log("error updating the resource %q:\n\t %v", info.Name, err)
 			updateErrors = append(updateErrors, err.Error())
 		}
 
@@ -263,9 +270,9 @@ func (c *Client) Update(namespace string, originalReader, targetReader io.Reader
 	}
 
 	for _, info := range original.Difference(target) {
-		log.Printf("Deleting %q in %s...", info.Name, info.Namespace)
+		c.Log("Deleting %q in %s...", info.Name, info.Namespace)
 		if err := deleteResource(c, info); err != nil {
-			log.Printf("Failed to delete %q, err: %s", info.Name, err)
+			c.Log("Failed to delete %q, err: %s", info.Name, err)
 		}
 	}
 	if shouldWait {
@@ -283,23 +290,23 @@ func (c *Client) Delete(namespace string, reader io.Reader) error {
 		return err
 	}
 	return perform(infos, func(info *resource.Info) error {
-		log.Printf("Starting delete for %q %s", info.Name, info.Mapping.GroupVersionKind.Kind)
+		c.Log("Starting delete for %q %s", info.Name, info.Mapping.GroupVersionKind.Kind)
 		err := deleteResource(c, info)
-		return skipIfNotFound(err)
+		return c.skipIfNotFound(err)
 	})
 }
 
-func skipIfNotFound(err error) error {
+func (c *Client) skipIfNotFound(err error) error {
 	if errors.IsNotFound(err) {
-		log.Printf("%v", err)
+		c.Log("%v", err)
 		return nil
 	}
 	return err
 }
 
-func watchTimeout(t time.Duration) ResourceActorFunc {
+func (c *Client) watchTimeout(t time.Duration) ResourceActorFunc {
 	return func(info *resource.Info) error {
-		return watchUntilReady(t, info)
+		return c.watchUntilReady(t, info)
 	}
 }
 
@@ -322,7 +329,7 @@ func (c *Client) WatchUntilReady(namespace string, reader io.Reader, timeout int
 	}
 	// For jobs, there's also the option to do poll c.Jobs(namespace).Get():
 	// https://github.com/adamreese/kubernetes/blob/master/test/e2e/job.go#L291-L300
-	return perform(infos, watchTimeout(time.Duration(timeout)*time.Second))
+	return perform(infos, c.watchTimeout(time.Duration(timeout)*time.Second))
 }
 
 func perform(infos Result, fn ResourceActorFunc) error {
@@ -355,7 +362,7 @@ func deleteResource(c *Client, info *resource.Info) error {
 		}
 		return err
 	}
-	log.Printf("Using reaper for deleting %q", info.Name)
+	c.Log("Using reaper for deleting %q", info.Name)
 	return reaper.Stop(info.Namespace, info.Name, 0, nil)
 }
 
@@ -383,19 +390,18 @@ func createPatch(mapping *meta.RESTMapping, target, current runtime.Object) ([]b
 	case err != nil:
 		return nil, types.StrategicMergePatchType, fmt.Errorf("failed to get versionedObject: %s", err)
 	default:
-		log.Printf("generating strategic merge patch for %T", target)
 		patch, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, versionedObject)
 		return patch, types.StrategicMergePatchType, err
 	}
 }
 
-func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, recreate bool) error {
+func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, force bool, recreate bool) error {
 	patch, patchType, err := createPatch(target.Mapping, target.Object, currentObj)
 	if err != nil {
 		return fmt.Errorf("failed to create patch: %s", err)
 	}
 	if patch == nil {
-		log.Printf("Looks like there are no changes for %s %q", target.Mapping.GroupVersionKind.Kind, target.Name)
+		c.Log("Looks like there are no changes for %s %q", target.Mapping.GroupVersionKind.Kind, target.Name)
 		// This needs to happen to make sure that tiller has the latest info from the API
 		// Otherwise there will be no labels and other functions that use labels will panic
 		if err := target.Get(); err != nil {
@@ -406,12 +412,36 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object,
 
 	// send patch to server
 	helper := resource.NewHelper(target.Client, target.Mapping)
+
 	obj, err := helper.Patch(target.Namespace, target.Name, patchType, patch)
 	if err != nil {
-		return err
-	}
+		kind := target.Mapping.GroupVersionKind.Kind
+		log.Printf("Cannot patch %s: %q (%v)", kind, target.Name, err)
+
+		if force {
+			// Attempt to delete...
+			if err := deleteResource(c, target); err != nil {
+				return err
+			}
+			log.Printf("Deleted %s: %q", kind, target.Name)
+
+			// ... and recreate
+			if err := createResource(target); err != nil {
+				return fmt.Errorf("Failed to recreate resource: %s", err)
+			}
+			log.Printf("Created a new %s called %q\n", kind, target.Name)
 
-	target.Refresh(obj, true)
+			// No need to refresh the target, as we recreated the resource based
+			// on it. In addition, it might not exist yet and a call to `Refresh`
+			// may fail.
+		} else {
+			log.Print("Use --force to force recreation of the resource")
+			return err
+		}
+	} else {
+		// When patch succeeds without needing to recreate, refresh target.
+		target.Refresh(obj, true)
+	}
 
 	if !recreate {
 		return nil
@@ -429,7 +459,11 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object,
 	if err != nil {
 		return nil
 	}
-	client, _ := c.ClientSet()
+
+	client, err := c.ClientSet()
+	if err != nil {
+		return err
+	}
 
 	pods, err := client.Core().Pods(target.Namespace).List(metav1.ListOptions{
 		FieldSelector: fields.Everything().String(),
@@ -441,7 +475,7 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object,
 
 	// Restart pods
 	for _, pod := range pods.Items {
-		log.Printf("Restarting pod: %v/%v", pod.Namespace, pod.Name)
+		c.Log("Restarting pod: %v/%v", pod.Namespace, pod.Name)
 
 		// Delete each pod for get them restarted with changed spec.
 		if err := client.Core().Pods(pod.Namespace).Delete(pod.Name, metav1.NewPreconditionDeleteOptions(string(pod.UID))); err != nil {
@@ -470,14 +504,14 @@ func getSelectorFromObject(obj runtime.Object) (map[string]string, error) {
 	}
 }
 
-func watchUntilReady(timeout time.Duration, info *resource.Info) error {
+func (c *Client) watchUntilReady(timeout time.Duration, info *resource.Info) error {
 	w, err := resource.NewHelper(info.Client, info.Mapping).WatchSingle(info.Namespace, info.Name, info.ResourceVersion)
 	if err != nil {
 		return err
 	}
 
 	kind := info.Mapping.GroupVersionKind.Kind
-	log.Printf("Watching for changes to %s %s with timeout of %v", kind, info.Name, timeout)
+	c.Log("Watching for changes to %s %s with timeout of %v", kind, info.Name, timeout)
 
 	// What we watch for depends on the Kind.
 	// - For a Job, we watch for completion.
@@ -492,17 +526,17 @@ func watchUntilReady(timeout time.Duration, info *resource.Info) error {
 			// we get. We care mostly about jobs, where what we want to see is
 			// the status go into a good state. For other types, like ReplicaSet
 			// we don't really do anything to support these as hooks.
-			log.Printf("Add/Modify event for %s: %v", info.Name, e.Type)
+			c.Log("Add/Modify event for %s: %v", info.Name, e.Type)
 			if kind == "Job" {
-				return waitForJob(e, info.Name)
+				return c.waitForJob(e, info.Name)
 			}
 			return true, nil
 		case watch.Deleted:
-			log.Printf("Deleted event for %s", info.Name)
+			c.Log("Deleted event for %s", info.Name)
 			return true, nil
 		case watch.Error:
 			// Handle error and return with an error.
-			log.Printf("Error event for %s", info.Name)
+			c.Log("Error event for %s", info.Name)
 			return true, fmt.Errorf("Failed to deploy %s", info.Name)
 		default:
 			return false, nil
@@ -525,7 +559,7 @@ func (c *Client) AsVersionedObject(obj runtime.Object) (runtime.Object, error) {
 // waitForJob is a helper that waits for a job to complete.
 //
 // This operates on an event returned from a watcher.
-func waitForJob(e watch.Event, name string) (bool, error) {
+func (c *Client) waitForJob(e watch.Event, name string) (bool, error) {
 	o, ok := e.Object.(*batchinternal.Job)
 	if !ok {
 		return true, fmt.Errorf("Expected %s to be a *batch.Job, got %T", name, e.Object)
@@ -539,7 +573,7 @@ func waitForJob(e watch.Event, name string) (bool, error) {
 		}
 	}
 
-	log.Printf("%s: Jobs active: %d, jobs failed: %d, jobs succeeded: %d", name, o.Status.Active, o.Status.Failed, o.Status.Succeeded)
+	c.Log("%s: Jobs active: %d, jobs failed: %d, jobs succeeded: %d", name, o.Status.Active, o.Status.Failed, o.Status.Succeeded)
 	return false, nil
 }
 
@@ -570,7 +604,7 @@ func (c *Client) WaitAndGetCompletedPodPhase(namespace string, reader io.Reader,
 		return api.PodUnknown, fmt.Errorf("%s is not a Pod", info.Name)
 	}
 
-	if err := watchPodUntilComplete(timeout, info); err != nil {
+	if err := c.watchPodUntilComplete(timeout, info); err != nil {
 		return api.PodUnknown, err
 	}
 
@@ -582,13 +616,13 @@ func (c *Client) WaitAndGetCompletedPodPhase(namespace string, reader io.Reader,
 	return status, nil
 }
 
-func watchPodUntilComplete(timeout time.Duration, info *resource.Info) error {
+func (c *Client) watchPodUntilComplete(timeout time.Duration, info *resource.Info) error {
 	w, err := resource.NewHelper(info.Client, info.Mapping).WatchSingle(info.Namespace, info.Name, info.ResourceVersion)
 	if err != nil {
 		return err
 	}
 
-	log.Printf("Watching pod %s for completion with timeout of %v", info.Name, timeout)
+	c.Log("Watching pod %s for completion with timeout of %v", info.Name, timeout)
 	_, err = watch.Until(timeout, w, func(e watch.Event) (bool, error) {
 		return conditions.PodCompleted(e)
 	})
diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go
index 1f2032bb2ca3ab8cb05ae4b1a865fd2c6d4c5ae8..647a506521909db4d25dbb3730eba1fcaca650c9 100644
--- a/pkg/kube/client_test.go
+++ b/pkg/kube/client_test.go
@@ -138,6 +138,12 @@ func encodeAndMarshalEvent(e *watch.Event) ([]byte, error) {
 	return json.Marshal(encodedEvent)
 }
 
+func newTestClient(f cmdutil.Factory) *Client {
+	c := New(nil)
+	c.Factory = f
+	return c
+}
+
 func TestUpdate(t *testing.T) {
 	listA := newPodList("starfish", "otter", "squid")
 	listB := newPodList("starfish", "otter", "dolphin")
@@ -186,8 +192,8 @@ func TestUpdate(t *testing.T) {
 
 	reaper := &fakeReaper{}
 	rf := &fakeReaperFactory{Factory: f, reaper: reaper}
-	c := &Client{Factory: rf}
-	if err := c.Update(api.NamespaceDefault, objBody(codec, &listA), objBody(codec, &listB), false, 0, false); err != nil {
+	c := newTestClient(rf)
+	if err := c.Update(api.NamespaceDefault, objBody(codec, &listA), objBody(codec, &listB), false, false, 0, false); err != nil {
 		t.Fatal(err)
 	}
 	// TODO: Find a way to test methods that use Client Set
@@ -251,7 +257,7 @@ func TestBuild(t *testing.T) {
 
 	for _, tt := range tests {
 		f, tf, _, _ := cmdtesting.NewAPIFactory()
-		c := &Client{Factory: f}
+		c := newTestClient(f)
 		if tt.swaggerFile != "" {
 			data, err := ioutil.ReadFile(tt.swaggerFile)
 			if err != nil {
@@ -320,7 +326,7 @@ func TestGet(t *testing.T) {
 			}
 		}),
 	}
-	c := &Client{Factory: f}
+	c := newTestClient(f)
 
 	// Test Success
 	data := strings.NewReader("kind: Pod\napiVersion: v1\nmetadata:\n  name: otter")
@@ -380,7 +386,7 @@ func TestPerform(t *testing.T) {
 		}
 
 		f, tf, _, _ := cmdtesting.NewAPIFactory()
-		c := &Client{Factory: f}
+		c := newTestClient(f)
 		if tt.swaggerFile != "" {
 			data, err := ioutil.ReadFile(tt.swaggerFile)
 			if err != nil {
@@ -464,7 +470,7 @@ func TestWaitAndGetCompletedPodPhase(t *testing.T) {
 			}),
 		}
 
-		c := &Client{Factory: f}
+		c := newTestClient(f)
 
 		phase, err := c.WaitAndGetCompletedPodPhase("test", objBody(codec, &testPodList), 1*time.Second)
 		if (err != nil) != tt.err {
diff --git a/pkg/kube/wait.go b/pkg/kube/wait.go
index bef366b4f17147829177288c14c51db8dafe93ec..d917d79ede0670c23bffabf498ecae42880d8d47 100644
--- a/pkg/kube/wait.go
+++ b/pkg/kube/wait.go
@@ -17,7 +17,6 @@ limitations under the License.
 package kube // import "k8s.io/helm/pkg/kube"
 
 import (
-	"log"
 	"time"
 
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -44,15 +43,17 @@ type deployment struct {
 // waitForResources polls to get the current status of all pods, PVCs, and Services
 // until all are ready or a timeout is reached
 func (c *Client) waitForResources(timeout time.Duration, created Result) error {
-	log.Printf("beginning wait for resources with timeout of %v", timeout)
+	c.Log("beginning wait for %d resources with timeout of %v", len(created), timeout)
 
-	cs, _ := c.ClientSet()
+	cs, err := c.ClientSet()
+	if err != nil {
+		return err
+	}
 	client := versionedClientsetForDeployment(cs)
 	return wait.Poll(2*time.Second, timeout, func() (bool, error) {
 		pods := []v1.Pod{}
 		services := []v1.Service{}
 		pvc := []v1.PersistentVolumeClaim{}
-		replicaSets := []*extensions.ReplicaSet{}
 		deployments := []deployment{}
 		for _, v := range created {
 			obj, err := c.AsVersionedObject(v.Object)
@@ -73,26 +74,13 @@ func (c *Client) waitForResources(timeout time.Duration, created Result) error {
 				}
 				pods = append(pods, *pod)
 			case (*extensions.Deployment):
-				// Get the RS children first
-				rs, err := client.Extensions().ReplicaSets(value.Namespace).List(metav1.ListOptions{
-					FieldSelector: fields.Everything().String(),
-					LabelSelector: labels.Set(value.Spec.Selector.MatchLabels).AsSelector().String(),
-				})
-				if err != nil {
-					return false, err
-				}
-
-				for _, i := range rs.Items {
-					replicaSets = append(replicaSets, &i)
-				}
-
 				currentDeployment, err := client.Extensions().Deployments(value.Namespace).Get(value.Name, metav1.GetOptions{})
 				if err != nil {
 					return false, err
 				}
 				// Find RS associated with deployment
-				newReplicaSet, err := deploymentutil.FindNewReplicaSet(currentDeployment, replicaSets)
-				if err != nil {
+				newReplicaSet, err := deploymentutil.GetNewReplicaSet(currentDeployment, client)
+				if err != nil || newReplicaSet == nil {
 					return false, err
 				}
 				newDeployment := deployment{
@@ -132,7 +120,9 @@ func (c *Client) waitForResources(timeout time.Duration, created Result) error {
 				services = append(services, *svc)
 			}
 		}
-		return podsReady(pods) && servicesReady(services) && volumesReady(pvc) && deploymentsReady(deployments), nil
+		isReady := podsReady(pods) && servicesReady(services) && volumesReady(pvc) && deploymentsReady(deployments)
+		c.Log("resources ready: %v", isReady)
+		return isReady, nil
 	})
 }
 
@@ -147,6 +137,11 @@ func podsReady(pods []v1.Pod) bool {
 
 func servicesReady(svc []v1.Service) bool {
 	for _, s := range svc {
+		// ExternalName Services are external to cluster so helm shouldn't be checking to see if they're 'ready' (i.e. have an IP Set)
+		if s.Spec.Type == v1.ServiceTypeExternalName {
+			continue
+		}
+
 		// Make sure the service is not explicitly set to "None" before checking the IP
 		if s.Spec.ClusterIP != v1.ClusterIPNone && !v1.IsServiceIPSet(&s) {
 			return false
diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go
index 5b98d4886976fd205ca9c7ff57758b13d4937937..73206b80c05f32ad6ca272f430d4e495eb673c22 100644
--- a/pkg/lint/rules/template.go
+++ b/pkg/lint/rules/template.go
@@ -21,12 +21,15 @@ import (
 	"fmt"
 	"os"
 	"path/filepath"
+	"runtime"
 
 	"github.com/ghodss/yaml"
+	"k8s.io/apimachinery/pkg/version"
 	"k8s.io/helm/pkg/chartutil"
 	"k8s.io/helm/pkg/engine"
 	"k8s.io/helm/pkg/lint/support"
 	"k8s.io/helm/pkg/timeconv"
+	tversion "k8s.io/helm/pkg/version"
 )
 
 // Templates lints the templates in the Linter.
@@ -51,7 +54,17 @@ func Templates(linter *support.Linter) {
 	}
 
 	options := chartutil.ReleaseOptions{Name: "testRelease", Time: timeconv.Now(), Namespace: "testNamespace"}
-	caps := &chartutil.Capabilities{APIVersions: chartutil.DefaultVersionSet}
+	caps := &chartutil.Capabilities{
+		APIVersions: chartutil.DefaultVersionSet,
+		KubeVersion: &version.Info{
+			Major:     "1",
+			Minor:     "6",
+			GoVersion: runtime.Version(),
+			Compiler:  runtime.Compiler,
+			Platform:  fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
+		},
+		TillerVersion: tversion.GetVersionProto(),
+	}
 	valuesToRender, err := chartutil.ToRenderValuesCaps(chart, chart.Values, options, caps)
 	if err != nil {
 		// FIXME: This seems to generate a duplicate, but I can't find where the first
diff --git a/pkg/lint/rules/testdata/albatross/templates/svc.yaml b/pkg/lint/rules/testdata/albatross/templates/svc.yaml
index 2c44ea2c607a1c7f55e97f44afbf8e43f49e68d5..1671481125c75aeff69689895e1789a5d280a8f3 100644
--- a/pkg/lint/rules/testdata/albatross/templates/svc.yaml
+++ b/pkg/lint/rules/testdata/albatross/templates/svc.yaml
@@ -8,6 +8,8 @@ metadata:
     heritage: {{ .Release.Service | quote }}
     release: {{ .Release.Name | quote }}
     chart: "{{.Chart.Name}}-{{.Chart.Version}}"
+    kubeVersion: {{ .Capabilities.KubeVersion.Major }}
+    tillerVersion: {{ .Capabilities.TillerVersion }}
 spec:
   ports:
   - port: {{default 80 .Values.httpPort | quote}}
diff --git a/pkg/plugin/hooks.go b/pkg/plugin/hooks.go
index 1f435f9f8587bc0cbd270d4f83834630ae06e6a8..b5ca032ac3d96fe3516a221b8ccf3a372b1c5bc2 100644
--- a/pkg/plugin/hooks.go
+++ b/pkg/plugin/hooks.go
@@ -21,6 +21,8 @@ const (
 	Install = "install"
 	// Delete is executed after the plugin is removed.
 	Delete = "delete"
+	// Update is executed after the plugin is updated.
+	Update = "update"
 )
 
 // Hooks is a map of events to commands.
diff --git a/pkg/plugin/installer/installer.go b/pkg/plugin/installer/installer.go
index 31ef9ae534066ac42308a74e54cb9cc57ecac955..6ecec980a0396c2718b5e494313ee4008d6a6b7f 100644
--- a/pkg/plugin/installer/installer.go
+++ b/pkg/plugin/installer/installer.go
@@ -19,6 +19,7 @@ import (
 	"errors"
 	"fmt"
 	"os"
+	"path"
 	"path/filepath"
 
 	"k8s.io/helm/pkg/helm/helmpath"
@@ -36,13 +37,32 @@ type Installer interface {
 	Install() error
 	// Path is the directory of the installed plugin.
 	Path() string
+	// Update updates a plugin to $HELM_HOME.
+	Update() error
 }
 
 // Install installs a plugin to $HELM_HOME.
 func Install(i Installer) error {
+	if _, pathErr := os.Stat(path.Dir(i.Path())); os.IsNotExist(pathErr) {
+		return errors.New(`plugin home "$HELM_HOME/plugins" does not exist`)
+	}
+
+	if _, pathErr := os.Stat(i.Path()); !os.IsNotExist(pathErr) {
+		return errors.New("plugin already exists")
+	}
+
 	return i.Install()
 }
 
+// Update updates a plugin in $HELM_HOME.
+func Update(i Installer) error {
+	if _, pathErr := os.Stat(i.Path()); os.IsNotExist(pathErr) {
+		return errors.New("plugin does not exist")
+	}
+
+	return i.Update()
+}
+
 // NewForSource determines the correct Installer for the given source.
 func NewForSource(source, version string, home helmpath.Home) (Installer, error) {
 	// Check if source is a local directory
@@ -52,6 +72,15 @@ func NewForSource(source, version string, home helmpath.Home) (Installer, error)
 	return NewVCSInstaller(source, version, home)
 }
 
+// FindSource determines the correct Installer for the given source.
+func FindSource(location string, home helmpath.Home) (Installer, error) {
+	installer, err := existingVCSRepo(location, home)
+	if err != nil && err.Error() == "Cannot detect VCS" {
+		return installer, errors.New("cannot get information about plugin source")
+	}
+	return installer, err
+}
+
 // isLocalReference checks if the source exists on the filesystem.
 func isLocalReference(source string) bool {
 	_, err := os.Stat(source)
diff --git a/pkg/plugin/installer/local_installer.go b/pkg/plugin/installer/local_installer.go
index 7ab588d60fa7b515cdf63df77c9a43fd51b86907..18011f8de5a7005879a1ef37d0823061a79cf791 100644
--- a/pkg/plugin/installer/local_installer.go
+++ b/pkg/plugin/installer/local_installer.go
@@ -47,3 +47,9 @@ func (i *LocalInstaller) Install() error {
 	}
 	return i.link(src)
 }
+
+// Update updates a local repository
+func (i *LocalInstaller) Update() error {
+	debug("local repository is auto-updated")
+	return nil
+}
diff --git a/pkg/plugin/installer/local_installer_test.go b/pkg/plugin/installer/local_installer_test.go
index a2a1b541c1f0129665c2d5223e63628a6198eeab..6a7c957d6870b8c26e44dbf1a8694161ebaee790 100644
--- a/pkg/plugin/installer/local_installer_test.go
+++ b/pkg/plugin/installer/local_installer_test.go
@@ -31,7 +31,7 @@ func TestLocalInstaller(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	defer os.Remove(hh)
+	defer os.RemoveAll(hh)
 
 	home := helmpath.Home(hh)
 	if err := os.MkdirAll(home.Plugins(), 0755); err != nil {
@@ -43,7 +43,7 @@ func TestLocalInstaller(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	defer os.Remove(tdir)
+	defer os.RemoveAll(tdir)
 	if err := ioutil.WriteFile(filepath.Join(tdir, "plugin.yaml"), []byte{}, 0644); err != nil {
 		t.Fatal(err)
 	}
diff --git a/pkg/plugin/installer/vcs_installer.go b/pkg/plugin/installer/vcs_installer.go
index ce7a93b83db6e84ffec19d6b45a15ce6d6640d34..d2ba3aa31173f36efcab66b42888a827eed70095 100644
--- a/pkg/plugin/installer/vcs_installer.go
+++ b/pkg/plugin/installer/vcs_installer.go
@@ -16,6 +16,8 @@ limitations under the License.
 package installer // import "k8s.io/helm/pkg/plugin/installer"
 
 import (
+	"errors"
+	"fmt"
 	"os"
 	"sort"
 
@@ -33,6 +35,18 @@ type VCSInstaller struct {
 	base
 }
 
+func existingVCSRepo(location string, home helmpath.Home) (Installer, error) {
+	repo, err := vcs.NewRepo("", location)
+	if err != nil {
+		return nil, err
+	}
+	i := &VCSInstaller{
+		Repo: repo,
+		base: newBase(repo.Remote(), home),
+	}
+	return i, err
+}
+
 // NewVCSInstaller creates a new VCSInstaller.
 func NewVCSInstaller(source, version string, home helmpath.Home) (*VCSInstaller, error) {
 	key, err := cache.Key(source)
@@ -76,6 +90,21 @@ func (i *VCSInstaller) Install() error {
 	return i.link(i.Repo.LocalPath())
 }
 
+// Update updates a remote repository
+func (i *VCSInstaller) Update() error {
+	debug("updating %s", i.Repo.Remote())
+	if i.Repo.IsDirty() {
+		return errors.New("plugin repo was modified")
+	}
+	if err := i.Repo.Update(); err != nil {
+		return err
+	}
+	if !isPlugin(i.Repo.LocalPath()) {
+		return ErrMissingMetadata
+	}
+	return nil
+}
+
 func (i *VCSInstaller) solveVersion(repo vcs.Repo) (string, error) {
 	if i.Version == "" {
 		return "", nil
@@ -112,7 +141,8 @@ func (i *VCSInstaller) solveVersion(repo vcs.Repo) (string, error) {
 			return ver, nil
 		}
 	}
-	return "", nil
+
+	return "", fmt.Errorf("requested version %q does not exist for plugin %q", i.Version, i.Repo.Remote())
 }
 
 // setVersion attempts to checkout the version
diff --git a/pkg/plugin/installer/vcs_installer_test.go b/pkg/plugin/installer/vcs_installer_test.go
index e340bbe5a99393f0b729ba50f1b8eeec132485f4..4abfc4c09f27a5e13af8fa114fd07a6f314b1b16 100644
--- a/pkg/plugin/installer/vcs_installer_test.go
+++ b/pkg/plugin/installer/vcs_installer_test.go
@@ -16,8 +16,10 @@ limitations under the License.
 package installer // import "k8s.io/helm/pkg/plugin/installer"
 
 import (
+	"fmt"
 	"io/ioutil"
 	"os"
+	"path/filepath"
 	"testing"
 
 	"k8s.io/helm/pkg/helm/helmpath"
@@ -51,7 +53,7 @@ func TestVCSInstaller(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	defer os.Remove(hh)
+	defer os.RemoveAll(hh)
 
 	home := helmpath.Home(hh)
 	if err := os.MkdirAll(home.Plugins(), 0755); err != nil {
@@ -59,8 +61,9 @@ func TestVCSInstaller(t *testing.T) {
 	}
 
 	source := "https://github.com/adamreese/helm-env"
+	testRepoPath, _ := filepath.Abs("../testdata/plugdir/echo")
 	repo := &testRepo{
-		local: "../testdata/plugdir/echo",
+		local: testRepoPath,
 		tags:  []string{"0.1.0", "0.1.1"},
 	}
 
@@ -87,4 +90,114 @@ func TestVCSInstaller(t *testing.T) {
 	if i.Path() != home.Path("plugins", "helm-env") {
 		t.Errorf("expected path '$HELM_HOME/plugins/helm-env', got %q", i.Path())
 	}
+
+	// Install again to test plugin exists error
+	if err := Install(i); err == nil {
+		t.Error("expected error for plugin exists, got none")
+	} else if err.Error() != "plugin already exists" {
+		t.Errorf("expected error for plugin exists, got (%v)", err)
+	}
+
+	//Testing FindSource method, expect error because plugin code is not a cloned repository
+	if _, err := FindSource(i.Path(), home); err == nil {
+		t.Error("expected error for inability to find plugin source, got none")
+	} else if err.Error() != "cannot get information about plugin source" {
+		t.Errorf("expected error for inability to find plugin source, got (%v)", err)
+	}
+}
+
+func TestVCSInstallerNonExistentVersion(t *testing.T) {
+	hh, err := ioutil.TempDir("", "helm-home-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(hh)
+
+	home := helmpath.Home(hh)
+	if err := os.MkdirAll(home.Plugins(), 0755); err != nil {
+		t.Fatalf("Could not create %s: %s", home.Plugins(), err)
+	}
+
+	source := "https://github.com/adamreese/helm-env"
+	version := "0.2.0"
+
+	i, err := NewForSource(source, version, home)
+	if err != nil {
+		t.Errorf("unexpected error: %s", err)
+	}
+
+	// ensure a VCSInstaller was returned
+	_, ok := i.(*VCSInstaller)
+	if !ok {
+		t.Error("expected a VCSInstaller")
+	}
+
+	if err := Install(i); err == nil {
+		t.Error("expected error for version does not exists, got none")
+	} else if err.Error() != fmt.Sprintf("requested version %q does not exist for plugin %q", version, source) {
+		t.Errorf("expected error for version does not exists, got (%v)", err)
+	}
+}
+func TestVCSInstallerUpdate(t *testing.T) {
+
+	hh, err := ioutil.TempDir("", "helm-home-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(hh)
+
+	home := helmpath.Home(hh)
+	if err := os.MkdirAll(home.Plugins(), 0755); err != nil {
+		t.Fatalf("Could not create %s: %s", home.Plugins(), err)
+	}
+
+	source := "https://github.com/adamreese/helm-env"
+
+	i, err := NewForSource(source, "", home)
+	if err != nil {
+		t.Errorf("unexpected error: %s", err)
+	}
+
+	// ensure a VCSInstaller was returned
+	_, ok := i.(*VCSInstaller)
+	if !ok {
+		t.Error("expected a VCSInstaller")
+	}
+
+	if err := Update(i); err == nil {
+		t.Error("expected error for plugin does not exist, got none")
+	} else if err.Error() != "plugin does not exist" {
+		t.Errorf("expected error for plugin does not exist, got (%v)", err)
+	}
+
+	// Install plugin before update
+	if err := Install(i); err != nil {
+		t.Error(err)
+	}
+
+	// Test FindSource method for positive result
+	pluginInfo, err := FindSource(i.Path(), home)
+	if err != nil {
+		t.Error(err)
+	}
+
+	repoRemote := pluginInfo.(*VCSInstaller).Repo.Remote()
+	if repoRemote != source {
+		t.Errorf("invalid source found, expected %q got %q", source, repoRemote)
+	}
+
+	// Update plugin
+	if err := Update(i); err != nil {
+		t.Error(err)
+	}
+
+	// Test update failure
+	os.Remove(filepath.Join(i.Path(), "plugin.yaml"))
+	// Testing update for error
+	if err := Update(i); err == nil {
+		t.Error("expected error for plugin modified, got none")
+	} else if err.Error() != "plugin repo was modified" {
+		t.Errorf("expected error for plugin modified, got (%v)", err)
+	}
+
 }
diff --git a/pkg/plugin/plugin.go b/pkg/plugin/plugin.go
index 8bde6ad24085d8d483b8c855cefe5eda30810c22..75d808701579d17a8e2a4ba9fc0eb61dc889dccd 100644
--- a/pkg/plugin/plugin.go
+++ b/pkg/plugin/plugin.go
@@ -179,7 +179,7 @@ func SetupPluginEnv(settings helm_env.EnvSettings,
 
 		// Set vars that may not have been set, and save client the
 		// trouble of re-parsing.
-		helm_env.PluginEnvVar: settings.PlugDirs,
+		helm_env.PluginEnvVar: settings.PluginDirs(),
 		helm_env.HomeEnvVar:   settings.Home.String(),
 
 		// Set vars that convey common information.
diff --git a/pkg/proto/hapi/release/test_run.pb.go b/pkg/proto/hapi/release/test_run.pb.go
index 79fce4ab43153f8a2ecd16c67ae7122ef323bf39..bd3c0ab2bc0df6356cf4f86a0642cef3108c858a 100644
--- a/pkg/proto/hapi/release/test_run.pb.go
+++ b/pkg/proto/hapi/release/test_run.pb.go
@@ -20,17 +20,20 @@ const (
 	TestRun_UNKNOWN TestRun_Status = 0
 	TestRun_SUCCESS TestRun_Status = 1
 	TestRun_FAILURE TestRun_Status = 2
+	TestRun_RUNNING TestRun_Status = 3
 )
 
 var TestRun_Status_name = map[int32]string{
 	0: "UNKNOWN",
 	1: "SUCCESS",
 	2: "FAILURE",
+	3: "RUNNING",
 }
 var TestRun_Status_value = map[string]int32{
 	"UNKNOWN": 0,
 	"SUCCESS": 1,
 	"FAILURE": 2,
+	"RUNNING": 3,
 }
 
 func (x TestRun_Status) String() string {
@@ -94,22 +97,23 @@ func init() {
 func init() { proto.RegisterFile("hapi/release/test_run.proto", fileDescriptor4) }
 
 var fileDescriptor4 = []byte{
-	// 265 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0x41, 0x4b, 0xfb, 0x40,
-	0x14, 0xc4, 0xff, 0xc9, 0xbf, 0x26, 0x64, 0x53, 0x24, 0xec, 0x29, 0x54, 0xc1, 0xd0, 0x53, 0x4e,
-	0xbb, 0x50, 0xbd, 0x78, 0xf0, 0x10, 0x4b, 0x05, 0x51, 0x22, 0x6c, 0x1a, 0x04, 0x2f, 0x65, 0xab,
-	0xaf, 0x35, 0x90, 0x64, 0x43, 0xf6, 0xe5, 0x8b, 0xf8, 0x89, 0x65, 0x93, 0xad, 0x78, 0xf3, 0xf6,
-	0x86, 0xf9, 0xcd, 0x30, 0x8f, 0x5c, 0x7c, 0xca, 0xae, 0xe2, 0x3d, 0xd4, 0x20, 0x35, 0x70, 0x04,
-	0x8d, 0xbb, 0x7e, 0x68, 0x59, 0xd7, 0x2b, 0x54, 0x74, 0x6e, 0x4c, 0x66, 0xcd, 0xc5, 0xd5, 0x51,
-	0xa9, 0x63, 0x0d, 0x7c, 0xf4, 0xf6, 0xc3, 0x81, 0x63, 0xd5, 0x80, 0x46, 0xd9, 0x74, 0x13, 0xbe,
-	0xfc, 0x72, 0x89, 0xbf, 0x05, 0x8d, 0x62, 0x68, 0x29, 0x25, 0xb3, 0x56, 0x36, 0x10, 0x3b, 0x89,
-	0x93, 0x06, 0x62, 0xbc, 0xe9, 0x0d, 0xf1, 0x34, 0x4a, 0x1c, 0x74, 0xec, 0x26, 0x4e, 0x7a, 0xbe,
-	0xba, 0x64, 0xbf, 0xfb, 0x99, 0x8d, 0xb2, 0x62, 0x64, 0x84, 0x65, 0x4d, 0x53, 0xd5, 0x1e, 0x54,
-	0xfc, 0x7f, 0x6a, 0x32, 0x37, 0xbd, 0x25, 0x44, 0xa3, 0xec, 0x11, 0x3e, 0x76, 0x12, 0xe3, 0x59,
-	0xe2, 0xa4, 0xe1, 0x6a, 0xc1, 0xa6, 0x7d, 0xec, 0xb4, 0x8f, 0x6d, 0x4f, 0xfb, 0x44, 0x60, 0xe9,
-	0x0c, 0xe9, 0x1d, 0x99, 0xbf, 0xab, 0xa6, 0xab, 0xc1, 0x86, 0xcf, 0xfe, 0x0c, 0x87, 0x3f, 0x7c,
-	0x86, 0x4b, 0x4e, 0xbc, 0x69, 0x1f, 0x0d, 0x89, 0x5f, 0xe6, 0x4f, 0xf9, 0xcb, 0x6b, 0x1e, 0xfd,
-	0x33, 0xa2, 0x28, 0xd7, 0xeb, 0x4d, 0x51, 0x44, 0x8e, 0x11, 0x0f, 0xd9, 0xe3, 0x73, 0x29, 0x36,
-	0x91, 0x7b, 0x1f, 0xbc, 0xf9, 0xf6, 0xc1, 0xbd, 0x37, 0x96, 0x5f, 0x7f, 0x07, 0x00, 0x00, 0xff,
-	0xff, 0x8d, 0xb9, 0xce, 0x57, 0x74, 0x01, 0x00, 0x00,
+	// 274 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0xc1, 0x4b, 0xfb, 0x30,
+	0x1c, 0xc5, 0x7f, 0xe9, 0xf6, 0x6b, 0x69, 0x3a, 0xa4, 0xe4, 0x54, 0xa6, 0x60, 0xd9, 0xa9, 0xa7,
+	0x14, 0xa6, 0x17, 0x41, 0x0f, 0x75, 0x4c, 0x19, 0x4a, 0x84, 0x74, 0x45, 0xf0, 0x32, 0x32, 0xcd,
+	0x66, 0xa1, 0x6d, 0x4a, 0xf3, 0xed, 0xdf, 0xe3, 0xbf, 0x2a, 0x69, 0x33, 0xf1, 0xe6, 0xed, 0xfb,
+	0x78, 0x9f, 0xf7, 0xf2, 0x82, 0xcf, 0x3f, 0x45, 0x5b, 0xa6, 0x9d, 0xac, 0xa4, 0xd0, 0x32, 0x05,
+	0xa9, 0x61, 0xd7, 0xf5, 0x0d, 0x6d, 0x3b, 0x05, 0x8a, 0xcc, 0x8c, 0x49, 0xad, 0x39, 0xbf, 0x3c,
+	0x2a, 0x75, 0xac, 0x64, 0x3a, 0x78, 0xfb, 0xfe, 0x90, 0x42, 0x59, 0x4b, 0x0d, 0xa2, 0x6e, 0x47,
+	0x7c, 0xf1, 0xe5, 0x60, 0x6f, 0x2b, 0x35, 0xf0, 0xbe, 0x21, 0x04, 0x4f, 0x1b, 0x51, 0xcb, 0x08,
+	0xc5, 0x28, 0xf1, 0xf9, 0x70, 0x93, 0x6b, 0xec, 0x6a, 0x10, 0xd0, 0xeb, 0xc8, 0x89, 0x51, 0x72,
+	0xb6, 0xbc, 0xa0, 0xbf, 0xfb, 0xa9, 0x8d, 0xd2, 0x7c, 0x60, 0xb8, 0x65, 0x4d, 0x53, 0xd9, 0x1c,
+	0x54, 0x34, 0x19, 0x9b, 0xcc, 0x4d, 0x6e, 0x30, 0xd6, 0x20, 0x3a, 0x90, 0x1f, 0x3b, 0x01, 0xd1,
+	0x34, 0x46, 0x49, 0xb0, 0x9c, 0xd3, 0x71, 0x1f, 0x3d, 0xed, 0xa3, 0xdb, 0xd3, 0x3e, 0xee, 0x5b,
+	0x3a, 0x03, 0x72, 0x87, 0x67, 0xef, 0xaa, 0x6e, 0x2b, 0x69, 0xc3, 0xff, 0xff, 0x0c, 0x07, 0x3f,
+	0x7c, 0x06, 0x8b, 0x5b, 0xec, 0x8e, 0xfb, 0x48, 0x80, 0xbd, 0x82, 0x3d, 0xb1, 0x97, 0x57, 0x16,
+	0xfe, 0x33, 0x22, 0x2f, 0x56, 0xab, 0x75, 0x9e, 0x87, 0xc8, 0x88, 0x87, 0x6c, 0xf3, 0x5c, 0xf0,
+	0x75, 0xe8, 0x18, 0xc1, 0x0b, 0xc6, 0x36, 0xec, 0x31, 0x9c, 0xdc, 0xfb, 0x6f, 0x9e, 0xfd, 0xed,
+	0xde, 0x1d, 0x5e, 0xba, 0xfa, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x31, 0x86, 0x46, 0xdb, 0x81, 0x01,
+	0x00, 0x00,
 }
diff --git a/pkg/proto/hapi/rudder/rudder.pb.go b/pkg/proto/hapi/rudder/rudder.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..3f64ba71355df000ada0a7c4a3fdf8b4df353ead
--- /dev/null
+++ b/pkg/proto/hapi/rudder/rudder.pb.go
@@ -0,0 +1,723 @@
+// Code generated by protoc-gen-go.
+// source: hapi/rudder/rudder.proto
+// DO NOT EDIT!
+
+/*
+Package rudder is a generated protocol buffer package.
+
+It is generated from these files:
+	hapi/rudder/rudder.proto
+
+It has these top-level messages:
+	Result
+	VersionReleaseRequest
+	VersionReleaseResponse
+	InstallReleaseRequest
+	InstallReleaseResponse
+	DeleteReleaseRequest
+	DeleteReleaseResponse
+	UpgradeReleaseRequest
+	UpgradeReleaseResponse
+	RollbackReleaseRequest
+	RollbackReleaseResponse
+	ReleaseStatusRequest
+	ReleaseStatusResponse
+*/
+package rudder
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import hapi_release3 "k8s.io/helm/pkg/proto/hapi/release"
+import hapi_release5 "k8s.io/helm/pkg/proto/hapi/release"
+
+import (
+	context "golang.org/x/net/context"
+	grpc "google.golang.org/grpc"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type Result_Status int32
+
+const (
+	// No status set
+	Result_UNKNOWN Result_Status = 0
+	// Operation was successful
+	Result_SUCCESS Result_Status = 1
+	// Operation had no results (e.g. upgrade identical, rollback to same, delete non-existent)
+	Result_UNCHANGED Result_Status = 2
+	// Operation failed
+	Result_ERROR Result_Status = 3
+)
+
+var Result_Status_name = map[int32]string{
+	0: "UNKNOWN",
+	1: "SUCCESS",
+	2: "UNCHANGED",
+	3: "ERROR",
+}
+var Result_Status_value = map[string]int32{
+	"UNKNOWN":   0,
+	"SUCCESS":   1,
+	"UNCHANGED": 2,
+	"ERROR":     3,
+}
+
+func (x Result_Status) String() string {
+	return proto.EnumName(Result_Status_name, int32(x))
+}
+func (Result_Status) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} }
+
+type Result struct {
+	Info string   `protobuf:"bytes,1,opt,name=info" json:"info,omitempty"`
+	Log  []string `protobuf:"bytes,2,rep,name=log" json:"log,omitempty"`
+}
+
+func (m *Result) Reset()                    { *m = Result{} }
+func (m *Result) String() string            { return proto.CompactTextString(m) }
+func (*Result) ProtoMessage()               {}
+func (*Result) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+func (m *Result) GetInfo() string {
+	if m != nil {
+		return m.Info
+	}
+	return ""
+}
+
+func (m *Result) GetLog() []string {
+	if m != nil {
+		return m.Log
+	}
+	return nil
+}
+
+type VersionReleaseRequest struct {
+}
+
+func (m *VersionReleaseRequest) Reset()                    { *m = VersionReleaseRequest{} }
+func (m *VersionReleaseRequest) String() string            { return proto.CompactTextString(m) }
+func (*VersionReleaseRequest) ProtoMessage()               {}
+func (*VersionReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
+
+type VersionReleaseResponse struct {
+	Name    string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	Version string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"`
+}
+
+func (m *VersionReleaseResponse) Reset()                    { *m = VersionReleaseResponse{} }
+func (m *VersionReleaseResponse) String() string            { return proto.CompactTextString(m) }
+func (*VersionReleaseResponse) ProtoMessage()               {}
+func (*VersionReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
+
+func (m *VersionReleaseResponse) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *VersionReleaseResponse) GetVersion() string {
+	if m != nil {
+		return m.Version
+	}
+	return ""
+}
+
+type InstallReleaseRequest struct {
+	Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
+}
+
+func (m *InstallReleaseRequest) Reset()                    { *m = InstallReleaseRequest{} }
+func (m *InstallReleaseRequest) String() string            { return proto.CompactTextString(m) }
+func (*InstallReleaseRequest) ProtoMessage()               {}
+func (*InstallReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
+
+func (m *InstallReleaseRequest) GetRelease() *hapi_release5.Release {
+	if m != nil {
+		return m.Release
+	}
+	return nil
+}
+
+type InstallReleaseResponse struct {
+	Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
+	Result  *Result                `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
+}
+
+func (m *InstallReleaseResponse) Reset()                    { *m = InstallReleaseResponse{} }
+func (m *InstallReleaseResponse) String() string            { return proto.CompactTextString(m) }
+func (*InstallReleaseResponse) ProtoMessage()               {}
+func (*InstallReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
+
+func (m *InstallReleaseResponse) GetRelease() *hapi_release5.Release {
+	if m != nil {
+		return m.Release
+	}
+	return nil
+}
+
+func (m *InstallReleaseResponse) GetResult() *Result {
+	if m != nil {
+		return m.Result
+	}
+	return nil
+}
+
+type DeleteReleaseRequest struct {
+	Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
+}
+
+func (m *DeleteReleaseRequest) Reset()                    { *m = DeleteReleaseRequest{} }
+func (m *DeleteReleaseRequest) String() string            { return proto.CompactTextString(m) }
+func (*DeleteReleaseRequest) ProtoMessage()               {}
+func (*DeleteReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
+
+func (m *DeleteReleaseRequest) GetRelease() *hapi_release5.Release {
+	if m != nil {
+		return m.Release
+	}
+	return nil
+}
+
+type DeleteReleaseResponse struct {
+	Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
+	Result  *Result                `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
+}
+
+func (m *DeleteReleaseResponse) Reset()                    { *m = DeleteReleaseResponse{} }
+func (m *DeleteReleaseResponse) String() string            { return proto.CompactTextString(m) }
+func (*DeleteReleaseResponse) ProtoMessage()               {}
+func (*DeleteReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
+
+func (m *DeleteReleaseResponse) GetRelease() *hapi_release5.Release {
+	if m != nil {
+		return m.Release
+	}
+	return nil
+}
+
+func (m *DeleteReleaseResponse) GetResult() *Result {
+	if m != nil {
+		return m.Result
+	}
+	return nil
+}
+
+type UpgradeReleaseRequest struct {
+	Current  *hapi_release5.Release `protobuf:"bytes,1,opt,name=current" json:"current,omitempty"`
+	Target   *hapi_release5.Release `protobuf:"bytes,2,opt,name=target" json:"target,omitempty"`
+	Timeout  int64                  `protobuf:"varint,3,opt,name=Timeout" json:"Timeout,omitempty"`
+	Wait     bool                   `protobuf:"varint,4,opt,name=Wait" json:"Wait,omitempty"`
+	Recreate bool                   `protobuf:"varint,5,opt,name=Recreate" json:"Recreate,omitempty"`
+	Force    bool                   `protobuf:"varint,6,opt,name=Force" json:"Force,omitempty"`
+}
+
+func (m *UpgradeReleaseRequest) Reset()                    { *m = UpgradeReleaseRequest{} }
+func (m *UpgradeReleaseRequest) String() string            { return proto.CompactTextString(m) }
+func (*UpgradeReleaseRequest) ProtoMessage()               {}
+func (*UpgradeReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
+
+func (m *UpgradeReleaseRequest) GetCurrent() *hapi_release5.Release {
+	if m != nil {
+		return m.Current
+	}
+	return nil
+}
+
+func (m *UpgradeReleaseRequest) GetTarget() *hapi_release5.Release {
+	if m != nil {
+		return m.Target
+	}
+	return nil
+}
+
+func (m *UpgradeReleaseRequest) GetTimeout() int64 {
+	if m != nil {
+		return m.Timeout
+	}
+	return 0
+}
+
+func (m *UpgradeReleaseRequest) GetWait() bool {
+	if m != nil {
+		return m.Wait
+	}
+	return false
+}
+
+func (m *UpgradeReleaseRequest) GetRecreate() bool {
+	if m != nil {
+		return m.Recreate
+	}
+	return false
+}
+
+func (m *UpgradeReleaseRequest) GetForce() bool {
+	if m != nil {
+		return m.Force
+	}
+	return false
+}
+
+type UpgradeReleaseResponse struct {
+	Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
+	Result  *Result                `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
+}
+
+func (m *UpgradeReleaseResponse) Reset()                    { *m = UpgradeReleaseResponse{} }
+func (m *UpgradeReleaseResponse) String() string            { return proto.CompactTextString(m) }
+func (*UpgradeReleaseResponse) ProtoMessage()               {}
+func (*UpgradeReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
+
+func (m *UpgradeReleaseResponse) GetRelease() *hapi_release5.Release {
+	if m != nil {
+		return m.Release
+	}
+	return nil
+}
+
+func (m *UpgradeReleaseResponse) GetResult() *Result {
+	if m != nil {
+		return m.Result
+	}
+	return nil
+}
+
+type RollbackReleaseRequest struct {
+	Current  *hapi_release5.Release `protobuf:"bytes,1,opt,name=current" json:"current,omitempty"`
+	Target   *hapi_release5.Release `protobuf:"bytes,2,opt,name=target" json:"target,omitempty"`
+	Timeout  int64                  `protobuf:"varint,3,opt,name=Timeout" json:"Timeout,omitempty"`
+	Wait     bool                   `protobuf:"varint,4,opt,name=Wait" json:"Wait,omitempty"`
+	Recreate bool                   `protobuf:"varint,5,opt,name=Recreate" json:"Recreate,omitempty"`
+	Force    bool                   `protobuf:"varint,6,opt,name=Force" json:"Force,omitempty"`
+}
+
+func (m *RollbackReleaseRequest) Reset()                    { *m = RollbackReleaseRequest{} }
+func (m *RollbackReleaseRequest) String() string            { return proto.CompactTextString(m) }
+func (*RollbackReleaseRequest) ProtoMessage()               {}
+func (*RollbackReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
+
+func (m *RollbackReleaseRequest) GetCurrent() *hapi_release5.Release {
+	if m != nil {
+		return m.Current
+	}
+	return nil
+}
+
+func (m *RollbackReleaseRequest) GetTarget() *hapi_release5.Release {
+	if m != nil {
+		return m.Target
+	}
+	return nil
+}
+
+func (m *RollbackReleaseRequest) GetTimeout() int64 {
+	if m != nil {
+		return m.Timeout
+	}
+	return 0
+}
+
+func (m *RollbackReleaseRequest) GetWait() bool {
+	if m != nil {
+		return m.Wait
+	}
+	return false
+}
+
+func (m *RollbackReleaseRequest) GetRecreate() bool {
+	if m != nil {
+		return m.Recreate
+	}
+	return false
+}
+
+func (m *RollbackReleaseRequest) GetForce() bool {
+	if m != nil {
+		return m.Force
+	}
+	return false
+}
+
+type RollbackReleaseResponse struct {
+	Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
+	Result  *Result                `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
+}
+
+func (m *RollbackReleaseResponse) Reset()                    { *m = RollbackReleaseResponse{} }
+func (m *RollbackReleaseResponse) String() string            { return proto.CompactTextString(m) }
+func (*RollbackReleaseResponse) ProtoMessage()               {}
+func (*RollbackReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
+
+func (m *RollbackReleaseResponse) GetRelease() *hapi_release5.Release {
+	if m != nil {
+		return m.Release
+	}
+	return nil
+}
+
+func (m *RollbackReleaseResponse) GetResult() *Result {
+	if m != nil {
+		return m.Result
+	}
+	return nil
+}
+
+type ReleaseStatusRequest struct {
+	Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
+}
+
+func (m *ReleaseStatusRequest) Reset()                    { *m = ReleaseStatusRequest{} }
+func (m *ReleaseStatusRequest) String() string            { return proto.CompactTextString(m) }
+func (*ReleaseStatusRequest) ProtoMessage()               {}
+func (*ReleaseStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
+
+func (m *ReleaseStatusRequest) GetRelease() *hapi_release5.Release {
+	if m != nil {
+		return m.Release
+	}
+	return nil
+}
+
+type ReleaseStatusResponse struct {
+	Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
+	Info    *hapi_release3.Info    `protobuf:"bytes,2,opt,name=info" json:"info,omitempty"`
+}
+
+func (m *ReleaseStatusResponse) Reset()                    { *m = ReleaseStatusResponse{} }
+func (m *ReleaseStatusResponse) String() string            { return proto.CompactTextString(m) }
+func (*ReleaseStatusResponse) ProtoMessage()               {}
+func (*ReleaseStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
+
+func (m *ReleaseStatusResponse) GetRelease() *hapi_release5.Release {
+	if m != nil {
+		return m.Release
+	}
+	return nil
+}
+
+func (m *ReleaseStatusResponse) GetInfo() *hapi_release3.Info {
+	if m != nil {
+		return m.Info
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*Result)(nil), "hapi.services.rudder.Result")
+	proto.RegisterType((*VersionReleaseRequest)(nil), "hapi.services.rudder.VersionReleaseRequest")
+	proto.RegisterType((*VersionReleaseResponse)(nil), "hapi.services.rudder.VersionReleaseResponse")
+	proto.RegisterType((*InstallReleaseRequest)(nil), "hapi.services.rudder.InstallReleaseRequest")
+	proto.RegisterType((*InstallReleaseResponse)(nil), "hapi.services.rudder.InstallReleaseResponse")
+	proto.RegisterType((*DeleteReleaseRequest)(nil), "hapi.services.rudder.DeleteReleaseRequest")
+	proto.RegisterType((*DeleteReleaseResponse)(nil), "hapi.services.rudder.DeleteReleaseResponse")
+	proto.RegisterType((*UpgradeReleaseRequest)(nil), "hapi.services.rudder.UpgradeReleaseRequest")
+	proto.RegisterType((*UpgradeReleaseResponse)(nil), "hapi.services.rudder.UpgradeReleaseResponse")
+	proto.RegisterType((*RollbackReleaseRequest)(nil), "hapi.services.rudder.RollbackReleaseRequest")
+	proto.RegisterType((*RollbackReleaseResponse)(nil), "hapi.services.rudder.RollbackReleaseResponse")
+	proto.RegisterType((*ReleaseStatusRequest)(nil), "hapi.services.rudder.ReleaseStatusRequest")
+	proto.RegisterType((*ReleaseStatusResponse)(nil), "hapi.services.rudder.ReleaseStatusResponse")
+	proto.RegisterEnum("hapi.services.rudder.Result_Status", Result_Status_name, Result_Status_value)
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// Client API for ReleaseModuleService service
+
+type ReleaseModuleServiceClient interface {
+	Version(ctx context.Context, in *VersionReleaseRequest, opts ...grpc.CallOption) (*VersionReleaseResponse, error)
+	// InstallRelease requests installation of a chart as a new release.
+	InstallRelease(ctx context.Context, in *InstallReleaseRequest, opts ...grpc.CallOption) (*InstallReleaseResponse, error)
+	// DeleteRelease requests deletion of a named release.
+	DeleteRelease(ctx context.Context, in *DeleteReleaseRequest, opts ...grpc.CallOption) (*DeleteReleaseResponse, error)
+	// RollbackRelease rolls back a release to a previous version.
+	RollbackRelease(ctx context.Context, in *RollbackReleaseRequest, opts ...grpc.CallOption) (*RollbackReleaseResponse, error)
+	// UpgradeRelease updates release content.
+	UpgradeRelease(ctx context.Context, in *UpgradeReleaseRequest, opts ...grpc.CallOption) (*UpgradeReleaseResponse, error)
+	// ReleaseStatus retrieves release status.
+	ReleaseStatus(ctx context.Context, in *ReleaseStatusRequest, opts ...grpc.CallOption) (*ReleaseStatusResponse, error)
+}
+
+type releaseModuleServiceClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewReleaseModuleServiceClient(cc *grpc.ClientConn) ReleaseModuleServiceClient {
+	return &releaseModuleServiceClient{cc}
+}
+
+func (c *releaseModuleServiceClient) Version(ctx context.Context, in *VersionReleaseRequest, opts ...grpc.CallOption) (*VersionReleaseResponse, error) {
+	out := new(VersionReleaseResponse)
+	err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/Version", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *releaseModuleServiceClient) InstallRelease(ctx context.Context, in *InstallReleaseRequest, opts ...grpc.CallOption) (*InstallReleaseResponse, error) {
+	out := new(InstallReleaseResponse)
+	err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/InstallRelease", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *releaseModuleServiceClient) DeleteRelease(ctx context.Context, in *DeleteReleaseRequest, opts ...grpc.CallOption) (*DeleteReleaseResponse, error) {
+	out := new(DeleteReleaseResponse)
+	err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/DeleteRelease", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *releaseModuleServiceClient) RollbackRelease(ctx context.Context, in *RollbackReleaseRequest, opts ...grpc.CallOption) (*RollbackReleaseResponse, error) {
+	out := new(RollbackReleaseResponse)
+	err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/RollbackRelease", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *releaseModuleServiceClient) UpgradeRelease(ctx context.Context, in *UpgradeReleaseRequest, opts ...grpc.CallOption) (*UpgradeReleaseResponse, error) {
+	out := new(UpgradeReleaseResponse)
+	err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/UpgradeRelease", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *releaseModuleServiceClient) ReleaseStatus(ctx context.Context, in *ReleaseStatusRequest, opts ...grpc.CallOption) (*ReleaseStatusResponse, error) {
+	out := new(ReleaseStatusResponse)
+	err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/ReleaseStatus", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Server API for ReleaseModuleService service
+
+type ReleaseModuleServiceServer interface {
+	Version(context.Context, *VersionReleaseRequest) (*VersionReleaseResponse, error)
+	// InstallRelease requests installation of a chart as a new release.
+	InstallRelease(context.Context, *InstallReleaseRequest) (*InstallReleaseResponse, error)
+	// DeleteRelease requests deletion of a named release.
+	DeleteRelease(context.Context, *DeleteReleaseRequest) (*DeleteReleaseResponse, error)
+	// RollbackRelease rolls back a release to a previous version.
+	RollbackRelease(context.Context, *RollbackReleaseRequest) (*RollbackReleaseResponse, error)
+	// UpgradeRelease updates release content.
+	UpgradeRelease(context.Context, *UpgradeReleaseRequest) (*UpgradeReleaseResponse, error)
+	// ReleaseStatus retrieves release status.
+	ReleaseStatus(context.Context, *ReleaseStatusRequest) (*ReleaseStatusResponse, error)
+}
+
+func RegisterReleaseModuleServiceServer(s *grpc.Server, srv ReleaseModuleServiceServer) {
+	s.RegisterService(&_ReleaseModuleService_serviceDesc, srv)
+}
+
+func _ReleaseModuleService_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(VersionReleaseRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(ReleaseModuleServiceServer).Version(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/hapi.services.rudder.ReleaseModuleService/Version",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(ReleaseModuleServiceServer).Version(ctx, req.(*VersionReleaseRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _ReleaseModuleService_InstallRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(InstallReleaseRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(ReleaseModuleServiceServer).InstallRelease(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/hapi.services.rudder.ReleaseModuleService/InstallRelease",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(ReleaseModuleServiceServer).InstallRelease(ctx, req.(*InstallReleaseRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _ReleaseModuleService_DeleteRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(DeleteReleaseRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(ReleaseModuleServiceServer).DeleteRelease(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/hapi.services.rudder.ReleaseModuleService/DeleteRelease",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(ReleaseModuleServiceServer).DeleteRelease(ctx, req.(*DeleteReleaseRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _ReleaseModuleService_RollbackRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(RollbackReleaseRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(ReleaseModuleServiceServer).RollbackRelease(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/hapi.services.rudder.ReleaseModuleService/RollbackRelease",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(ReleaseModuleServiceServer).RollbackRelease(ctx, req.(*RollbackReleaseRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _ReleaseModuleService_UpgradeRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(UpgradeReleaseRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(ReleaseModuleServiceServer).UpgradeRelease(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/hapi.services.rudder.ReleaseModuleService/UpgradeRelease",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(ReleaseModuleServiceServer).UpgradeRelease(ctx, req.(*UpgradeReleaseRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _ReleaseModuleService_ReleaseStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ReleaseStatusRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(ReleaseModuleServiceServer).ReleaseStatus(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/hapi.services.rudder.ReleaseModuleService/ReleaseStatus",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(ReleaseModuleServiceServer).ReleaseStatus(ctx, req.(*ReleaseStatusRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _ReleaseModuleService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "hapi.services.rudder.ReleaseModuleService",
+	HandlerType: (*ReleaseModuleServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "Version",
+			Handler:    _ReleaseModuleService_Version_Handler,
+		},
+		{
+			MethodName: "InstallRelease",
+			Handler:    _ReleaseModuleService_InstallRelease_Handler,
+		},
+		{
+			MethodName: "DeleteRelease",
+			Handler:    _ReleaseModuleService_DeleteRelease_Handler,
+		},
+		{
+			MethodName: "RollbackRelease",
+			Handler:    _ReleaseModuleService_RollbackRelease_Handler,
+		},
+		{
+			MethodName: "UpgradeRelease",
+			Handler:    _ReleaseModuleService_UpgradeRelease_Handler,
+		},
+		{
+			MethodName: "ReleaseStatus",
+			Handler:    _ReleaseModuleService_ReleaseStatus_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "hapi/rudder/rudder.proto",
+}
+
+func init() { proto.RegisterFile("hapi/rudder/rudder.proto", fileDescriptor0) }
+
+var fileDescriptor0 = []byte{
+	// 597 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x56, 0x5f, 0x8f, 0xd2, 0x4e,
+	0x14, 0xa5, 0xb0, 0x14, 0xb8, 0x64, 0x7f, 0x3f, 0x32, 0xa1, 0xd0, 0x34, 0x3e, 0x90, 0x3e, 0x18,
+	0xe2, 0xba, 0x25, 0x41, 0x1f, 0x7d, 0x51, 0x96, 0xfd, 0x13, 0x23, 0x9b, 0x0c, 0xe2, 0x26, 0xbe,
+	0x75, 0xe1, 0x82, 0xd5, 0xd2, 0xd6, 0xe9, 0x74, 0x1f, 0xd5, 0x4f, 0xe3, 0x57, 0xd2, 0x8f, 0x63,
+	0xda, 0x69, 0x89, 0xad, 0xd3, 0x88, 0x6b, 0xc2, 0x83, 0x4f, 0x9d, 0xe9, 0x3d, 0xdc, 0x39, 0xe7,
+	0xf4, 0xce, 0x09, 0xa0, 0xbf, 0xb3, 0x03, 0x67, 0xc4, 0xa2, 0xd5, 0x0a, 0x59, 0xfa, 0xb0, 0x02,
+	0xe6, 0x73, 0x9f, 0x74, 0xe3, 0x8a, 0x15, 0x22, 0xbb, 0x73, 0x96, 0x18, 0x5a, 0xa2, 0x66, 0xf4,
+	0x05, 0x1e, 0x5d, 0xb4, 0x43, 0x1c, 0x39, 0xde, 0xda, 0x17, 0x70, 0xc3, 0xc8, 0x15, 0xd2, 0xa7,
+	0xa8, 0x99, 0x2e, 0xa8, 0x14, 0xc3, 0xc8, 0xe5, 0x84, 0xc0, 0x51, 0xfc, 0x1b, 0x5d, 0x19, 0x28,
+	0xc3, 0x16, 0x4d, 0xd6, 0xa4, 0x03, 0x35, 0xd7, 0xdf, 0xe8, 0xd5, 0x41, 0x6d, 0xd8, 0xa2, 0xf1,
+	0xd2, 0x7c, 0x06, 0xea, 0x9c, 0xdb, 0x3c, 0x0a, 0x49, 0x1b, 0x1a, 0x8b, 0xd9, 0xcb, 0xd9, 0xf5,
+	0xcd, 0xac, 0x53, 0x89, 0x37, 0xf3, 0xc5, 0x64, 0x32, 0x9d, 0xcf, 0x3b, 0x0a, 0x39, 0x86, 0xd6,
+	0x62, 0x36, 0xb9, 0x7c, 0x3e, 0xbb, 0x98, 0x9e, 0x75, 0xaa, 0xa4, 0x05, 0xf5, 0x29, 0xa5, 0xd7,
+	0xb4, 0x53, 0x33, 0xfb, 0xa0, 0xbd, 0x41, 0x16, 0x3a, 0xbe, 0x47, 0x05, 0x0b, 0x8a, 0x1f, 0x23,
+	0x0c, 0xb9, 0x79, 0x0e, 0xbd, 0x62, 0x21, 0x0c, 0x7c, 0x2f, 0xc4, 0x98, 0x96, 0x67, 0x6f, 0x31,
+	0xa3, 0x15, 0xaf, 0x89, 0x0e, 0x8d, 0x3b, 0x81, 0xd6, 0xab, 0xc9, 0xeb, 0x6c, 0x6b, 0x5e, 0x82,
+	0x76, 0xe5, 0x85, 0xdc, 0x76, 0xdd, 0xfc, 0x01, 0x64, 0x04, 0x8d, 0x54, 0x78, 0xd2, 0xa9, 0x3d,
+	0xd6, 0xac, 0xc4, 0xc4, 0xcc, 0x8d, 0x0c, 0x9e, 0xa1, 0xcc, 0xcf, 0xd0, 0x2b, 0x76, 0x4a, 0x19,
+	0xfd, 0x69, 0x2b, 0xf2, 0x14, 0x54, 0x96, 0x78, 0x9c, 0xb0, 0x6d, 0x8f, 0x1f, 0x58, 0xb2, 0xef,
+	0x67, 0x89, 0xef, 0x40, 0x53, 0xac, 0x79, 0x01, 0xdd, 0x33, 0x74, 0x91, 0xe3, 0xdf, 0x2a, 0xf9,
+	0x04, 0x5a, 0xa1, 0xd1, 0x61, 0x85, 0x7c, 0x53, 0x40, 0x5b, 0x04, 0x1b, 0x66, 0xaf, 0x24, 0x52,
+	0x96, 0x11, 0x63, 0xe8, 0xf1, 0xdf, 0x10, 0x48, 0x51, 0xe4, 0x14, 0x54, 0x6e, 0xb3, 0x0d, 0x66,
+	0x04, 0x4a, 0xf0, 0x29, 0x28, 0x9e, 0x93, 0xd7, 0xce, 0x16, 0xfd, 0x88, 0xeb, 0xb5, 0x81, 0x32,
+	0xac, 0xd1, 0x6c, 0x1b, 0x4f, 0xd5, 0x8d, 0xed, 0x70, 0xfd, 0x68, 0xa0, 0x0c, 0x9b, 0x34, 0x59,
+	0x13, 0x03, 0x9a, 0x14, 0x97, 0x0c, 0x6d, 0x8e, 0x7a, 0x3d, 0x79, 0xbf, 0xdb, 0x93, 0x2e, 0xd4,
+	0xcf, 0x7d, 0xb6, 0x44, 0x5d, 0x4d, 0x0a, 0x62, 0x13, 0xcf, 0x48, 0x51, 0xd8, 0x61, 0xad, 0xfd,
+	0xae, 0x40, 0x8f, 0xfa, 0xae, 0x7b, 0x6b, 0x2f, 0x3f, 0xfc, 0x63, 0xde, 0x7e, 0x51, 0xa0, 0xff,
+	0x8b, 0xb4, 0x83, 0xdf, 0xc0, 0xb4, 0x93, 0x88, 0xbc, 0x7b, 0xdf, 0xc0, 0x00, 0xb4, 0x42, 0xa3,
+	0xfb, 0x0a, 0x79, 0x98, 0x86, 0xb4, 0x90, 0x41, 0xf2, 0xe8, 0x2b, 0x6f, 0xed, 0x8b, 0xe0, 0x1e,
+	0x7f, 0xad, 0xef, 0xb8, 0xbf, 0xf2, 0x57, 0x91, 0x8b, 0x73, 0x21, 0x95, 0xac, 0xa1, 0x91, 0x06,
+	0x2d, 0x39, 0x91, 0x9b, 0x20, 0x0d, 0x68, 0xe3, 0xf1, 0x7e, 0x60, 0xa1, 0xcb, 0xac, 0x90, 0x2d,
+	0xfc, 0x97, 0x8f, 0xcf, 0xb2, 0xe3, 0xa4, 0x71, 0x5d, 0x76, 0x9c, 0x3c, 0x91, 0xcd, 0x0a, 0x79,
+	0x0f, 0xc7, 0xb9, 0x8c, 0x23, 0x8f, 0xe4, 0x0d, 0x64, 0x89, 0x6a, 0x9c, 0xec, 0x85, 0xdd, 0x9d,
+	0x15, 0xc0, 0xff, 0x85, 0xc1, 0x24, 0x25, 0x74, 0xe5, 0x57, 0xd3, 0x38, 0xdd, 0x13, 0xfd, 0xb3,
+	0x99, 0xf9, 0x9c, 0x29, 0x33, 0x53, 0x1a, 0xb3, 0x65, 0x66, 0xca, 0xa3, 0x4b, 0x98, 0x99, 0x1b,
+	0xd7, 0x32, 0x33, 0x65, 0x97, 0xa3, 0xcc, 0x4c, 0xe9, 0xfc, 0x9b, 0x95, 0x17, 0xcd, 0xb7, 0xaa,
+	0x40, 0xdc, 0xaa, 0xc9, 0x1f, 0x92, 0x27, 0x3f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xb6, 0xa5, 0x37,
+	0x75, 0xf7, 0x08, 0x00, 0x00,
+}
diff --git a/pkg/proto/hapi/services/tiller.pb.go b/pkg/proto/hapi/services/tiller.pb.go
index d3f8676fc9717e369d1fd42131403c4264437ec2..d629320c5bfca0fc27d2ac6b6407c431e4c2bac5 100644
--- a/pkg/proto/hapi/services/tiller.pb.go
+++ b/pkg/proto/hapi/services/tiller.pb.go
@@ -40,6 +40,7 @@ import hapi_chart3 "k8s.io/helm/pkg/proto/hapi/chart"
 import hapi_chart "k8s.io/helm/pkg/proto/hapi/chart"
 import hapi_release5 "k8s.io/helm/pkg/proto/hapi/release"
 import hapi_release4 "k8s.io/helm/pkg/proto/hapi/release"
+import hapi_release1 "k8s.io/helm/pkg/proto/hapi/release"
 import hapi_release3 "k8s.io/helm/pkg/proto/hapi/release"
 import hapi_version "k8s.io/helm/pkg/proto/hapi/version"
 
@@ -374,6 +375,8 @@ type UpdateReleaseRequest struct {
 	// ReuseValues will cause Tiller to reuse the values from the last release.
 	// This is ignored if reset_values is set.
 	ReuseValues bool `protobuf:"varint,10,opt,name=reuse_values,json=reuseValues" json:"reuse_values,omitempty"`
+	// Force resource update through delete/recreate if needed.
+	Force bool `protobuf:"varint,11,opt,name=force" json:"force,omitempty"`
 }
 
 func (m *UpdateReleaseRequest) Reset()                    { *m = UpdateReleaseRequest{} }
@@ -451,6 +454,13 @@ func (m *UpdateReleaseRequest) GetReuseValues() bool {
 	return false
 }
 
+func (m *UpdateReleaseRequest) GetForce() bool {
+	if m != nil {
+		return m.Force
+	}
+	return false
+}
+
 // UpdateReleaseResponse is the response to an update request.
 type UpdateReleaseResponse struct {
 	Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
@@ -484,6 +494,8 @@ type RollbackReleaseRequest struct {
 	// wait, if true, will wait until all Pods, PVCs, and Services are in a ready state
 	// before marking the release as successful. It will wait for as long as timeout
 	Wait bool `protobuf:"varint,7,opt,name=wait" json:"wait,omitempty"`
+	// Force resource update through delete/recreate if needed.
+	Force bool `protobuf:"varint,8,opt,name=force" json:"force,omitempty"`
 }
 
 func (m *RollbackReleaseRequest) Reset()                    { *m = RollbackReleaseRequest{} }
@@ -540,6 +552,13 @@ func (m *RollbackReleaseRequest) GetWait() bool {
 	return false
 }
 
+func (m *RollbackReleaseRequest) GetForce() bool {
+	if m != nil {
+		return m.Force
+	}
+	return false
+}
+
 // RollbackReleaseResponse is the response to an update request.
 type RollbackReleaseResponse struct {
 	Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
@@ -848,7 +867,8 @@ func (m *TestReleaseRequest) GetCleanup() bool {
 
 // TestReleaseResponse represents a message from executing a test
 type TestReleaseResponse struct {
-	Msg string `protobuf:"bytes,1,opt,name=msg" json:"msg,omitempty"`
+	Msg    string                       `protobuf:"bytes,1,opt,name=msg" json:"msg,omitempty"`
+	Status hapi_release1.TestRun_Status `protobuf:"varint,2,opt,name=status,enum=hapi.release.TestRun_Status" json:"status,omitempty"`
 }
 
 func (m *TestReleaseResponse) Reset()                    { *m = TestReleaseResponse{} }
@@ -863,6 +883,13 @@ func (m *TestReleaseResponse) GetMsg() string {
 	return ""
 }
 
+func (m *TestReleaseResponse) GetStatus() hapi_release1.TestRun_Status {
+	if m != nil {
+		return m.Status
+	}
+	return hapi_release1.TestRun_UNKNOWN
+}
+
 func init() {
 	proto.RegisterType((*ListReleasesRequest)(nil), "hapi.services.tiller.ListReleasesRequest")
 	proto.RegisterType((*ListSort)(nil), "hapi.services.tiller.ListSort")
@@ -1342,79 +1369,82 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{
 func init() { proto.RegisterFile("hapi/services/tiller.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-	// 1170 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xdb, 0x6e, 0xe3, 0x44,
-	0x18, 0xae, 0xe3, 0x1c, 0xff, 0x1e, 0x48, 0xa7, 0x27, 0xd7, 0x02, 0x54, 0x8c, 0xa0, 0xd9, 0x85,
-	0x4d, 0x21, 0x5c, 0x21, 0x21, 0xa4, 0x6e, 0x37, 0x6a, 0x0b, 0xa5, 0x2b, 0x39, 0xdb, 0x45, 0x42,
-	0x88, 0xc8, 0x4d, 0x26, 0xad, 0x59, 0xc7, 0x13, 0x3c, 0xe3, 0xb2, 0xbd, 0xe5, 0x8e, 0x47, 0xe1,
-	0x2d, 0x78, 0x01, 0x78, 0x01, 0x5e, 0x06, 0x79, 0x0e, 0x6e, 0xc6, 0xb5, 0x5b, 0x6f, 0x6e, 0x62,
-	0xcf, 0xfc, 0xe7, 0xef, 0xff, 0xfd, 0xcd, 0x04, 0xec, 0x6b, 0x6f, 0xe6, 0x1f, 0x50, 0x1c, 0xdd,
-	0xf8, 0x23, 0x4c, 0x0f, 0x98, 0x1f, 0x04, 0x38, 0xea, 0xce, 0x22, 0xc2, 0x08, 0xda, 0x4c, 0x64,
-	0x5d, 0x25, 0xeb, 0x0a, 0x99, 0xbd, 0xcd, 0x2d, 0x46, 0xd7, 0x5e, 0xc4, 0xc4, 0xaf, 0xd0, 0xb6,
-	0x77, 0xe6, 0xf7, 0x49, 0x38, 0xf1, 0xaf, 0xa4, 0x40, 0x84, 0x88, 0x70, 0x80, 0x3d, 0x8a, 0xd5,
-	0x53, 0x33, 0x52, 0x32, 0x3f, 0x9c, 0x10, 0x29, 0xd8, 0xd5, 0x04, 0x94, 0x79, 0x2c, 0xa6, 0x9a,
-	0xbf, 0x1b, 0x1c, 0x51, 0x9f, 0x84, 0xea, 0x29, 0x64, 0xce, 0xdf, 0x15, 0xd8, 0x38, 0xf3, 0x29,
-	0x73, 0x85, 0x21, 0x75, 0xf1, 0x6f, 0x31, 0xa6, 0x0c, 0x6d, 0x42, 0x2d, 0xf0, 0xa7, 0x3e, 0xb3,
-	0x8c, 0x3d, 0xa3, 0x63, 0xba, 0x62, 0x81, 0xb6, 0xa1, 0x4e, 0x26, 0x13, 0x8a, 0x99, 0x55, 0xd9,
-	0x33, 0x3a, 0x2d, 0x57, 0xae, 0xd0, 0xb7, 0xd0, 0xa0, 0x24, 0x62, 0xc3, 0xcb, 0x5b, 0xcb, 0xdc,
-	0x33, 0x3a, 0x6b, 0xbd, 0x4f, 0xba, 0x79, 0x50, 0x74, 0x93, 0x48, 0x03, 0x12, 0xb1, 0x6e, 0xf2,
-	0xf3, 0xfc, 0xd6, 0xad, 0x53, 0xfe, 0x4c, 0xfc, 0x4e, 0xfc, 0x80, 0xe1, 0xc8, 0xaa, 0x0a, 0xbf,
-	0x62, 0x85, 0x8e, 0x01, 0xb8, 0x5f, 0x12, 0x8d, 0x71, 0x64, 0xd5, 0xb8, 0xeb, 0x4e, 0x09, 0xd7,
-	0x2f, 0x13, 0x7d, 0xb7, 0x45, 0xd5, 0x2b, 0xfa, 0x06, 0x56, 0x04, 0x24, 0xc3, 0x11, 0x19, 0x63,
-	0x6a, 0xd5, 0xf7, 0xcc, 0xce, 0x5a, 0x6f, 0x57, 0xb8, 0x52, 0x08, 0x0f, 0x04, 0x68, 0x47, 0x64,
-	0x8c, 0xdd, 0x65, 0xa1, 0x9e, 0xbc, 0x53, 0xf4, 0x3e, 0xb4, 0x42, 0x6f, 0x8a, 0xe9, 0xcc, 0x1b,
-	0x61, 0xab, 0xc1, 0x33, 0xbc, 0xdb, 0x70, 0x7e, 0x81, 0xa6, 0x0a, 0xee, 0xf4, 0xa0, 0x2e, 0x4a,
-	0x43, 0xcb, 0xd0, 0xb8, 0x38, 0xff, 0xfe, 0xfc, 0xe5, 0x8f, 0xe7, 0xed, 0x25, 0xd4, 0x84, 0xea,
-	0xf9, 0xe1, 0x0f, 0xfd, 0xb6, 0x81, 0xd6, 0x61, 0xf5, 0xec, 0x70, 0xf0, 0x6a, 0xe8, 0xf6, 0xcf,
-	0xfa, 0x87, 0x83, 0xfe, 0x8b, 0x76, 0xc5, 0xf9, 0x10, 0x5a, 0x69, 0xce, 0xa8, 0x01, 0xe6, 0xe1,
-	0xe0, 0x48, 0x98, 0xbc, 0xe8, 0x0f, 0x8e, 0xda, 0x86, 0xf3, 0xa7, 0x01, 0x9b, 0x7a, 0x8b, 0xe8,
-	0x8c, 0x84, 0x14, 0x27, 0x3d, 0x1a, 0x91, 0x38, 0x4c, 0x7b, 0xc4, 0x17, 0x08, 0x41, 0x35, 0xc4,
-	0x6f, 0x55, 0x87, 0xf8, 0x7b, 0xa2, 0xc9, 0x08, 0xf3, 0x02, 0xde, 0x1d, 0xd3, 0x15, 0x0b, 0xf4,
-	0x25, 0x34, 0x65, 0xe9, 0xd4, 0xaa, 0xee, 0x99, 0x9d, 0xe5, 0xde, 0x96, 0x0e, 0x88, 0x8c, 0xe8,
-	0xa6, 0x6a, 0xce, 0x31, 0xec, 0x1c, 0x63, 0x95, 0x89, 0xc0, 0x4b, 0x4d, 0x4c, 0x12, 0xd7, 0x9b,
-	0x62, 0x9e, 0x4c, 0x12, 0xd7, 0x9b, 0x62, 0x64, 0x41, 0x43, 0x8e, 0x1b, 0x4f, 0xa7, 0xe6, 0xaa,
-	0xa5, 0xc3, 0xc0, 0xba, 0xef, 0x48, 0xd6, 0x95, 0xe7, 0xe9, 0x53, 0xa8, 0x26, 0xc3, 0xce, 0xdd,
-	0x2c, 0xf7, 0x90, 0x9e, 0xe7, 0x69, 0x38, 0x21, 0x2e, 0x97, 0xeb, 0xad, 0x32, 0xb3, 0xad, 0x3a,
-	0x99, 0x8f, 0x7a, 0x44, 0x42, 0x86, 0x43, 0xb6, 0x58, 0xfe, 0x67, 0xb0, 0x9b, 0xe3, 0x49, 0x16,
-	0x70, 0x00, 0x0d, 0x99, 0x1a, 0xf7, 0x56, 0x88, 0xab, 0xd2, 0x72, 0xfe, 0xa9, 0xc0, 0xe6, 0xc5,
-	0x6c, 0xec, 0x31, 0xac, 0x44, 0x0f, 0x24, 0xb5, 0x0f, 0x35, 0x4e, 0x1a, 0x12, 0x8b, 0x75, 0xe1,
-	0x5b, 0x30, 0xcb, 0x51, 0xf2, 0xeb, 0x0a, 0x39, 0x7a, 0x0a, 0xf5, 0x1b, 0x2f, 0x88, 0x31, 0xe5,
-	0x40, 0xa4, 0xa8, 0x49, 0x4d, 0xce, 0x38, 0xae, 0xd4, 0x40, 0x3b, 0xd0, 0x18, 0x47, 0xb7, 0xc3,
-	0x28, 0x0e, 0xf9, 0x27, 0xd8, 0x74, 0xeb, 0xe3, 0xe8, 0xd6, 0x8d, 0x43, 0xf4, 0x31, 0xac, 0x8e,
-	0x7d, 0xea, 0x5d, 0x06, 0x78, 0x78, 0x4d, 0xc8, 0x1b, 0xca, 0xbf, 0xc2, 0xa6, 0xbb, 0x22, 0x37,
-	0x4f, 0x92, 0x3d, 0x64, 0x27, 0x93, 0x34, 0x8a, 0xb0, 0xc7, 0xb0, 0x55, 0xe7, 0xf2, 0x74, 0x9d,
-	0x60, 0xc8, 0xfc, 0x29, 0x26, 0x31, 0xe3, 0x9f, 0x8e, 0xe9, 0xaa, 0x25, 0xfa, 0x08, 0x56, 0x22,
-	0x4c, 0x31, 0x1b, 0xca, 0x2c, 0x9b, 0xdc, 0x72, 0x99, 0xef, 0xbd, 0x16, 0x69, 0x21, 0xa8, 0xfe,
-	0xee, 0xf9, 0xcc, 0x6a, 0x71, 0x11, 0x7f, 0x17, 0x66, 0x31, 0xc5, 0xca, 0x0c, 0x94, 0x59, 0x4c,
-	0xb1, 0x30, 0x73, 0x4e, 0x60, 0x2b, 0x03, 0xe7, 0xa2, 0x9d, 0xf9, 0xd7, 0x80, 0x6d, 0x97, 0x04,
-	0xc1, 0xa5, 0x37, 0x7a, 0x53, 0xa2, 0x37, 0x73, 0x30, 0x56, 0x1e, 0x86, 0xd1, 0xcc, 0x81, 0x71,
-	0x6e, 0xdc, 0xaa, 0xda, 0xb8, 0x69, 0x00, 0xd7, 0x8a, 0x01, 0xae, 0xeb, 0x00, 0x2b, 0xf4, 0x1a,
-	0x77, 0xe8, 0x39, 0xdf, 0xc1, 0xce, 0xbd, 0x7a, 0x16, 0x05, 0xe7, 0xaf, 0x0a, 0x6c, 0x9d, 0x86,
-	0x94, 0x79, 0x41, 0x90, 0xc1, 0x26, 0x9d, 0x51, 0xa3, 0xf4, 0x8c, 0x56, 0xde, 0x65, 0x46, 0x4d,
-	0x0d, 0x5c, 0xd5, 0x89, 0xea, 0x5c, 0x27, 0x4a, 0xcd, 0xad, 0xc6, 0x16, 0xf5, 0x0c, 0x5b, 0xa0,
-	0x0f, 0x00, 0xc4, 0xa0, 0x71, 0xe7, 0x02, 0xc4, 0x16, 0xdf, 0x39, 0x97, 0xe4, 0xa0, 0x70, 0x6f,
-	0xe6, 0xe3, 0x3e, 0x37, 0xb5, 0xce, 0x29, 0x6c, 0x67, 0xa1, 0x5a, 0x14, 0xf6, 0x3f, 0x0c, 0xd8,
-	0xb9, 0x08, 0xfd, 0x5c, 0xe0, 0xf3, 0x86, 0xf2, 0x1e, 0x14, 0x95, 0x1c, 0x28, 0x36, 0xa1, 0x36,
-	0x8b, 0xa3, 0x2b, 0x2c, 0xa1, 0x15, 0x8b, 0xf9, 0x1a, 0xab, 0x5a, 0x8d, 0xce, 0x10, 0xac, 0xfb,
-	0x39, 0x2c, 0x58, 0x51, 0x92, 0x75, 0xca, 0xee, 0x2d, 0xc1, 0xe4, 0xce, 0x06, 0xac, 0x1f, 0x63,
-	0xf6, 0x5a, 0x7c, 0x00, 0xb2, 0x3c, 0xa7, 0x0f, 0x68, 0x7e, 0xf3, 0x2e, 0x9e, 0xdc, 0xd2, 0xe3,
-	0xa9, 0xab, 0x8e, 0xd2, 0x57, 0x5a, 0xce, 0xd7, 0xdc, 0xf7, 0x89, 0x4f, 0x19, 0x89, 0x6e, 0x1f,
-	0x82, 0xae, 0x0d, 0xe6, 0xd4, 0x7b, 0x2b, 0xc9, 0x3f, 0x79, 0x75, 0x8e, 0x79, 0x06, 0xa9, 0xa9,
-	0xcc, 0x60, 0xfe, 0x28, 0x35, 0xca, 0x1d, 0xa5, 0x3f, 0x03, 0x7a, 0x85, 0xd3, 0x53, 0xfd, 0x91,
-	0x53, 0x48, 0x35, 0xa1, 0xa2, 0x0f, 0x9a, 0x05, 0x8d, 0x51, 0x80, 0xbd, 0x30, 0x9e, 0xc9, 0xb6,
-	0xa9, 0xa5, 0xb3, 0x0f, 0x1b, 0x9a, 0x77, 0x99, 0x67, 0x52, 0x0f, 0xbd, 0x92, 0xde, 0x93, 0xd7,
-	0xde, 0x7f, 0x4d, 0x58, 0x53, 0xc7, 0xb0, 0xb8, 0x52, 0x21, 0x1f, 0x56, 0xe6, 0xef, 0x1b, 0xe8,
-	0x49, 0xf1, 0x8d, 0x2b, 0x73, 0x6d, 0xb4, 0x9f, 0x96, 0x51, 0x15, 0xb9, 0x38, 0x4b, 0x5f, 0x18,
-	0x88, 0x42, 0x3b, 0x7b, 0x0d, 0x40, 0xcf, 0xf2, 0x7d, 0x14, 0xdc, 0x3b, 0xec, 0x6e, 0x59, 0x75,
-	0x15, 0x16, 0xdd, 0xf0, 0xee, 0xeb, 0x67, 0x37, 0x7a, 0xd4, 0x8d, 0x7e, 0x5d, 0xb0, 0x0f, 0x4a,
-	0xeb, 0xa7, 0x71, 0x7f, 0x85, 0x55, 0xed, 0x54, 0x42, 0x05, 0x68, 0xe5, 0xdd, 0x04, 0xec, 0xcf,
-	0x4a, 0xe9, 0xa6, 0xb1, 0xa6, 0xb0, 0xa6, 0xd3, 0x0d, 0x2a, 0x70, 0x90, 0xcb, 0xdf, 0xf6, 0xe7,
-	0xe5, 0x94, 0xd3, 0x70, 0x14, 0xda, 0x59, 0x36, 0x28, 0xea, 0x63, 0x01, 0x73, 0x15, 0xf5, 0xb1,
-	0x88, 0x64, 0x9c, 0x25, 0xe4, 0x01, 0xdc, 0x91, 0x01, 0xda, 0x2f, 0x6c, 0x88, 0xce, 0x21, 0x76,
-	0xe7, 0x71, 0xc5, 0x34, 0xc4, 0x0c, 0xde, 0xcb, 0x9c, 0x96, 0xa8, 0x00, 0x9a, 0xfc, 0x4b, 0x82,
-	0xfd, 0xac, 0xa4, 0x76, 0xa6, 0x28, 0xc9, 0x2f, 0x0f, 0x14, 0xa5, 0x93, 0xd7, 0x03, 0x45, 0x65,
-	0xa8, 0xca, 0x59, 0x42, 0x3e, 0xac, 0xb9, 0x71, 0x28, 0x43, 0x27, 0x2c, 0x81, 0x0a, 0xac, 0xef,
-	0xf3, 0x93, 0xfd, 0xa4, 0x84, 0xe6, 0xdd, 0xf7, 0xfd, 0x1c, 0x7e, 0x6a, 0x2a, 0xd5, 0xcb, 0x3a,
-	0xff, 0xc7, 0xf9, 0xd5, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x30, 0x80, 0xed, 0x18, 0x42, 0x0f,
-	0x00, 0x00,
+	// 1217 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xdd, 0x6e, 0xe3, 0xc4,
+	0x17, 0xaf, 0xf3, 0x9d, 0x93, 0x36, 0xff, 0x74, 0x9a, 0xb6, 0xae, 0xff, 0x0b, 0x2a, 0x46, 0xb0,
+	0xd9, 0x85, 0x4d, 0x21, 0x70, 0x83, 0x84, 0x90, 0xba, 0xdd, 0xa8, 0x2d, 0x94, 0xae, 0xe4, 0x6c,
+	0x17, 0x09, 0x01, 0x91, 0x9b, 0x4c, 0x5a, 0xb3, 0x8e, 0x27, 0x78, 0xc6, 0x65, 0x7b, 0xcb, 0x1d,
+	0x8f, 0xc2, 0x5b, 0xf0, 0x1e, 0x5c, 0xc2, 0x83, 0x20, 0xcf, 0x87, 0xeb, 0x49, 0xed, 0xd6, 0xf4,
+	0x26, 0x9e, 0x99, 0xf3, 0xfd, 0x3b, 0x67, 0xce, 0x9c, 0x80, 0x75, 0xe9, 0x2e, 0xbc, 0x3d, 0x8a,
+	0xc3, 0x2b, 0x6f, 0x82, 0xe9, 0x1e, 0xf3, 0x7c, 0x1f, 0x87, 0xfd, 0x45, 0x48, 0x18, 0x41, 0xdd,
+	0x98, 0xd6, 0x57, 0xb4, 0xbe, 0xa0, 0x59, 0x5b, 0x5c, 0x62, 0x72, 0xe9, 0x86, 0x4c, 0xfc, 0x0a,
+	0x6e, 0x6b, 0x3b, 0x7d, 0x4e, 0x82, 0x99, 0x77, 0x21, 0x09, 0xc2, 0x44, 0x88, 0x7d, 0xec, 0x52,
+	0xac, 0xbe, 0x9a, 0x90, 0xa2, 0x79, 0xc1, 0x8c, 0x48, 0xc2, 0xff, 0x35, 0x02, 0xc3, 0x94, 0x8d,
+	0xc3, 0x28, 0x90, 0xc4, 0x1d, 0x8d, 0x48, 0x99, 0xcb, 0x22, 0xaa, 0x19, 0xbb, 0xc2, 0x21, 0xf5,
+	0x48, 0xa0, 0xbe, 0x82, 0x66, 0xff, 0x59, 0x82, 0x8d, 0x13, 0x8f, 0x32, 0x47, 0x08, 0x52, 0x07,
+	0xff, 0x12, 0x61, 0xca, 0x50, 0x17, 0xaa, 0xbe, 0x37, 0xf7, 0x98, 0x69, 0xec, 0x1a, 0xbd, 0xb2,
+	0x23, 0x36, 0x68, 0x0b, 0x6a, 0x64, 0x36, 0xa3, 0x98, 0x99, 0xa5, 0x5d, 0xa3, 0xd7, 0x74, 0xe4,
+	0x0e, 0x7d, 0x05, 0x75, 0x4a, 0x42, 0x36, 0x3e, 0xbf, 0x36, 0xcb, 0xbb, 0x46, 0xaf, 0x3d, 0xf8,
+	0xa0, 0x9f, 0x85, 0x53, 0x3f, 0xb6, 0x34, 0x22, 0x21, 0xeb, 0xc7, 0x3f, 0xcf, 0xaf, 0x9d, 0x1a,
+	0xe5, 0xdf, 0x58, 0xef, 0xcc, 0xf3, 0x19, 0x0e, 0xcd, 0x8a, 0xd0, 0x2b, 0x76, 0xe8, 0x10, 0x80,
+	0xeb, 0x25, 0xe1, 0x14, 0x87, 0x66, 0x95, 0xab, 0xee, 0x15, 0x50, 0xfd, 0x32, 0xe6, 0x77, 0x9a,
+	0x54, 0x2d, 0xd1, 0x97, 0xb0, 0x2a, 0x20, 0x19, 0x4f, 0xc8, 0x14, 0x53, 0xb3, 0xb6, 0x5b, 0xee,
+	0xb5, 0x07, 0x3b, 0x42, 0x95, 0x82, 0x7f, 0x24, 0x40, 0x3b, 0x20, 0x53, 0xec, 0xb4, 0x04, 0x7b,
+	0xbc, 0xa6, 0xe8, 0x11, 0x34, 0x03, 0x77, 0x8e, 0xe9, 0xc2, 0x9d, 0x60, 0xb3, 0xce, 0x3d, 0xbc,
+	0x39, 0xb0, 0x7f, 0x82, 0x86, 0x32, 0x6e, 0x0f, 0xa0, 0x26, 0x42, 0x43, 0x2d, 0xa8, 0x9f, 0x9d,
+	0x7e, 0x73, 0xfa, 0xf2, 0xbb, 0xd3, 0xce, 0x0a, 0x6a, 0x40, 0xe5, 0x74, 0xff, 0xdb, 0x61, 0xc7,
+	0x40, 0xeb, 0xb0, 0x76, 0xb2, 0x3f, 0x7a, 0x35, 0x76, 0x86, 0x27, 0xc3, 0xfd, 0xd1, 0xf0, 0x45,
+	0xa7, 0x64, 0xbf, 0x0b, 0xcd, 0xc4, 0x67, 0x54, 0x87, 0xf2, 0xfe, 0xe8, 0x40, 0x88, 0xbc, 0x18,
+	0x8e, 0x0e, 0x3a, 0x86, 0xfd, 0xbb, 0x01, 0x5d, 0x3d, 0x45, 0x74, 0x41, 0x02, 0x8a, 0xe3, 0x1c,
+	0x4d, 0x48, 0x14, 0x24, 0x39, 0xe2, 0x1b, 0x84, 0xa0, 0x12, 0xe0, 0xb7, 0x2a, 0x43, 0x7c, 0x1d,
+	0x73, 0x32, 0xc2, 0x5c, 0x9f, 0x67, 0xa7, 0xec, 0x88, 0x0d, 0xfa, 0x14, 0x1a, 0x32, 0x74, 0x6a,
+	0x56, 0x76, 0xcb, 0xbd, 0xd6, 0x60, 0x53, 0x07, 0x44, 0x5a, 0x74, 0x12, 0x36, 0xfb, 0x10, 0xb6,
+	0x0f, 0xb1, 0xf2, 0x44, 0xe0, 0xa5, 0x2a, 0x26, 0xb6, 0xeb, 0xce, 0x31, 0x77, 0x26, 0xb6, 0xeb,
+	0xce, 0x31, 0x32, 0xa1, 0x2e, 0xcb, 0x8d, 0xbb, 0x53, 0x75, 0xd4, 0xd6, 0x66, 0x60, 0xde, 0x56,
+	0x24, 0xe3, 0xca, 0xd2, 0xf4, 0x21, 0x54, 0xe2, 0x9b, 0xc0, 0xd5, 0xb4, 0x06, 0x48, 0xf7, 0xf3,
+	0x38, 0x98, 0x11, 0x87, 0xd3, 0xf5, 0x54, 0x95, 0x97, 0x53, 0x75, 0x94, 0xb6, 0x7a, 0x40, 0x02,
+	0x86, 0x03, 0xf6, 0x30, 0xff, 0x4f, 0x60, 0x27, 0x43, 0x93, 0x0c, 0x60, 0x0f, 0xea, 0xd2, 0x35,
+	0xae, 0x2d, 0x17, 0x57, 0xc5, 0x65, 0xff, 0x5d, 0x82, 0xee, 0xd9, 0x62, 0xea, 0x32, 0xac, 0x48,
+	0x77, 0x38, 0xf5, 0x18, 0xaa, 0xbc, 0xa3, 0x48, 0x2c, 0xd6, 0x85, 0x6e, 0xd1, 0x76, 0x0e, 0xe2,
+	0x5f, 0x47, 0xd0, 0xd1, 0x53, 0xa8, 0x5d, 0xb9, 0x7e, 0x84, 0x29, 0x07, 0x22, 0x41, 0x4d, 0x72,
+	0xf2, 0x76, 0xe4, 0x48, 0x0e, 0xb4, 0x0d, 0xf5, 0x69, 0x78, 0x1d, 0xf7, 0x13, 0x7e, 0x05, 0x1b,
+	0x4e, 0x6d, 0x1a, 0x5e, 0x3b, 0x51, 0x80, 0xde, 0x87, 0xb5, 0xa9, 0x47, 0xdd, 0x73, 0x1f, 0x8f,
+	0x2f, 0x09, 0x79, 0x43, 0xf9, 0x2d, 0x6c, 0x38, 0xab, 0xf2, 0xf0, 0x28, 0x3e, 0x43, 0x56, 0x5c,
+	0x49, 0x93, 0x10, 0xbb, 0x0c, 0x9b, 0x35, 0x4e, 0x4f, 0xf6, 0x31, 0x86, 0xcc, 0x9b, 0x63, 0x12,
+	0x31, 0x7e, 0x75, 0xca, 0x8e, 0xda, 0xa2, 0xf7, 0x60, 0x35, 0xc4, 0x14, 0xb3, 0xb1, 0xf4, 0xb2,
+	0xc1, 0x25, 0x5b, 0xfc, 0xec, 0xb5, 0x70, 0x0b, 0x41, 0xe5, 0x57, 0xd7, 0x63, 0x66, 0x93, 0x93,
+	0xf8, 0x5a, 0x88, 0x45, 0x14, 0x2b, 0x31, 0x50, 0x62, 0x11, 0xc5, 0x52, 0xac, 0x0b, 0xd5, 0x19,
+	0x09, 0x27, 0xd8, 0x6c, 0x71, 0x9a, 0xd8, 0xd8, 0x47, 0xb0, 0xb9, 0x04, 0xf2, 0x43, 0xf3, 0xf5,
+	0x8f, 0x01, 0x5b, 0x0e, 0xf1, 0xfd, 0x73, 0x77, 0xf2, 0xa6, 0x40, 0xc6, 0x52, 0xe0, 0x96, 0xee,
+	0x06, 0xb7, 0x9c, 0x01, 0x6e, 0xaa, 0x08, 0x2b, 0x5a, 0x11, 0x6a, 0xb0, 0x57, 0xf3, 0x61, 0xaf,
+	0xe9, 0xb0, 0x2b, 0x4c, 0xeb, 0x29, 0x4c, 0x13, 0xc0, 0x1a, 0x69, 0xc0, 0xbe, 0x86, 0xed, 0x5b,
+	0x51, 0x3e, 0x14, 0xb2, 0x3f, 0x4a, 0xb0, 0x79, 0x1c, 0x50, 0xe6, 0xfa, 0xfe, 0x12, 0x62, 0x49,
+	0x3d, 0x1b, 0x85, 0xeb, 0xb9, 0xf4, 0x5f, 0xea, 0xb9, 0xac, 0x41, 0xae, 0xf2, 0x53, 0x49, 0xe5,
+	0xa7, 0x50, 0x8d, 0x6b, 0x9d, 0xa5, 0xb6, 0xd4, 0x59, 0xd0, 0x3b, 0x00, 0xa2, 0x28, 0xb9, 0x72,
+	0x01, 0x6d, 0x93, 0x9f, 0x9c, 0xca, 0x46, 0xa2, 0xb2, 0xd1, 0xc8, 0xce, 0x46, 0xaa, 0xc2, 0xed,
+	0x63, 0xd8, 0x5a, 0x86, 0xea, 0xa1, 0xb0, 0xff, 0x66, 0xc0, 0xf6, 0x59, 0xe0, 0x65, 0x02, 0x9f,
+	0x55, 0xaa, 0xb7, 0xa0, 0x28, 0x65, 0x40, 0xd1, 0x85, 0xea, 0x22, 0x0a, 0x2f, 0xb0, 0x84, 0x56,
+	0x6c, 0xd2, 0x31, 0x56, 0xb4, 0x18, 0xed, 0x31, 0x98, 0xb7, 0x7d, 0x78, 0x60, 0x44, 0xb1, 0xd7,
+	0xc9, 0x4b, 0xd0, 0x14, 0x5d, 0xdf, 0xde, 0x80, 0xf5, 0x43, 0xcc, 0x5e, 0x8b, 0x6b, 0x21, 0xc3,
+	0xb3, 0x87, 0x80, 0xd2, 0x87, 0x37, 0xf6, 0xe4, 0x91, 0x6e, 0x4f, 0x8d, 0x45, 0x8a, 0x5f, 0x71,
+	0xd9, 0x5f, 0x70, 0xdd, 0x47, 0x1e, 0x65, 0x24, 0xbc, 0xbe, 0x0b, 0xba, 0x0e, 0x94, 0xe7, 0xee,
+	0x5b, 0xf9, 0x50, 0xc4, 0x4b, 0xfb, 0x90, 0x7b, 0x90, 0x88, 0x4a, 0x0f, 0xd2, 0xcf, 0xae, 0x51,
+	0xec, 0xd9, 0xfd, 0x01, 0xd0, 0x2b, 0x9c, 0x4c, 0x00, 0xf7, 0xbc, 0x58, 0x2a, 0x09, 0x25, 0xbd,
+	0xd0, 0x4c, 0xa8, 0x4f, 0x7c, 0xec, 0x06, 0xd1, 0x42, 0xa6, 0x4d, 0x6d, 0xed, 0x1f, 0x61, 0x43,
+	0xd3, 0x2e, 0xfd, 0x8c, 0xe3, 0xa1, 0x17, 0x52, 0x7b, 0xbc, 0x44, 0x9f, 0x43, 0x4d, 0x8c, 0x45,
+	0x5c, 0x77, 0x7b, 0xf0, 0x48, 0xf7, 0x9b, 0x2b, 0x89, 0x02, 0x39, 0x47, 0x39, 0x92, 0x77, 0xf0,
+	0x57, 0x03, 0xda, 0xea, 0xa1, 0x17, 0x43, 0x1b, 0xf2, 0x60, 0x35, 0x3d, 0xd1, 0xa0, 0x27, 0xf9,
+	0x33, 0xdd, 0xd2, 0x60, 0x6a, 0x3d, 0x2d, 0xc2, 0x2a, 0x22, 0xb0, 0x57, 0x3e, 0x31, 0x10, 0x85,
+	0xce, 0xf2, 0xa0, 0x81, 0x9e, 0x65, 0xeb, 0xc8, 0x99, 0x6c, 0xac, 0x7e, 0x51, 0x76, 0x65, 0x16,
+	0x5d, 0xf1, 0x9a, 0xd1, 0xa7, 0x03, 0x74, 0xaf, 0x1a, 0x7d, 0x20, 0xb1, 0xf6, 0x0a, 0xf3, 0x27,
+	0x76, 0x7f, 0x86, 0x35, 0xed, 0x85, 0x43, 0x39, 0x68, 0x65, 0xcd, 0x1a, 0xd6, 0x47, 0x85, 0x78,
+	0x13, 0x5b, 0x73, 0x68, 0xeb, 0x4d, 0x0a, 0xe5, 0x28, 0xc8, 0xec, 0xfa, 0xd6, 0xc7, 0xc5, 0x98,
+	0x13, 0x73, 0x14, 0x3a, 0xcb, 0x3d, 0x24, 0x2f, 0x8f, 0x39, 0xfd, 0x2e, 0x2f, 0x8f, 0x79, 0xad,
+	0xc9, 0x5e, 0x41, 0x2e, 0xc0, 0x4d, 0x0b, 0x41, 0x8f, 0x73, 0x13, 0xa2, 0x77, 0x1e, 0xab, 0x77,
+	0x3f, 0x63, 0x62, 0x62, 0x01, 0xff, 0x5b, 0x7a, 0x63, 0x51, 0x0e, 0x34, 0xd9, 0x03, 0x87, 0xf5,
+	0xac, 0x20, 0xf7, 0x52, 0x50, 0xb2, 0x2b, 0xdd, 0x11, 0x94, 0xde, 0xf2, 0xee, 0x08, 0x6a, 0xa9,
+	0xc1, 0xd9, 0x2b, 0xc8, 0x83, 0xb6, 0x13, 0x05, 0xd2, 0x74, 0xdc, 0x16, 0x50, 0x8e, 0xf4, 0xed,
+	0xae, 0x66, 0x3d, 0x29, 0xc0, 0x79, 0x73, 0xbf, 0x9f, 0xc3, 0xf7, 0x0d, 0xc5, 0x7a, 0x5e, 0xe3,
+	0xff, 0x69, 0x3f, 0xfb, 0x37, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x7c, 0x9c, 0x49, 0xc1, 0x0f, 0x00,
+	0x00,
 }
diff --git a/pkg/releasetesting/environment.go b/pkg/releasetesting/environment.go
index a567213331e97e2c40db2b2416646d9b188e9d4c..51c1aa95a10b84bf385a9a969f6b944013f1d0b8 100644
--- a/pkg/releasetesting/environment.go
+++ b/pkg/releasetesting/environment.go
@@ -83,31 +83,31 @@ func (env *Environment) streamResult(r *release.TestRun) error {
 
 func (env *Environment) streamRunning(name string) error {
 	msg := "RUNNING: " + name
-	return env.streamMessage(msg)
+	return env.streamMessage(msg, release.TestRun_RUNNING)
 }
 
 func (env *Environment) streamError(info string) error {
 	msg := "ERROR: " + info
-	return env.streamMessage(msg)
+	return env.streamMessage(msg, release.TestRun_FAILURE)
 }
 
 func (env *Environment) streamFailed(name string) error {
 	msg := fmt.Sprintf("FAILED: %s, run `kubectl logs %s --namespace %s` for more info", name, name, env.Namespace)
-	return env.streamMessage(msg)
+	return env.streamMessage(msg, release.TestRun_FAILURE)
 }
 
 func (env *Environment) streamSuccess(name string) error {
 	msg := fmt.Sprintf("PASSED: %s", name)
-	return env.streamMessage(msg)
+	return env.streamMessage(msg, release.TestRun_SUCCESS)
 }
 
 func (env *Environment) streamUnknown(name, info string) error {
 	msg := fmt.Sprintf("UNKNOWN: %s: %s", name, info)
-	return env.streamMessage(msg)
+	return env.streamMessage(msg, release.TestRun_UNKNOWN)
 }
 
-func (env *Environment) streamMessage(msg string) error {
-	resp := &services.TestReleaseResponse{Msg: msg}
+func (env *Environment) streamMessage(msg string, status release.TestRun_Status) error {
+	resp := &services.TestReleaseResponse{Msg: msg, Status: status}
 	return env.Stream.Send(resp)
 }
 
diff --git a/pkg/releasetesting/environment_test.go b/pkg/releasetesting/environment_test.go
index deb8617f620bc7c7f9643ba6ebe1c0cf02fcd0eb..29ca93d09a1b70c52bdb9bdb04a35c892f56c328 100644
--- a/pkg/releasetesting/environment_test.go
+++ b/pkg/releasetesting/environment_test.go
@@ -24,6 +24,7 @@ import (
 	"testing"
 
 	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
 	tillerEnv "k8s.io/helm/pkg/tiller/environment"
 )
 
@@ -88,6 +89,29 @@ func TestDeleteTestPodsFailingDelete(t *testing.T) {
 	}
 }
 
+func TestStreamMessage(t *testing.T) {
+	mockTestEnv := newMockTestingEnvironment()
+
+	expectedMessage := "testing streamMessage"
+	expectedStatus := release.TestRun_SUCCESS
+	err := mockTestEnv.streamMessage(expectedMessage, expectedStatus)
+	if err != nil {
+		t.Errorf("Expected no errors, got 1: %s", err)
+	}
+
+	stream := mockTestEnv.Stream.(*mockStream)
+	if len(stream.messages) != 1 {
+		t.Errorf("Expected 1 message, got: %v", len(stream.messages))
+	}
+
+	if stream.messages[0].Msg != expectedMessage {
+		t.Errorf("Expected message: %s, got: %s", expectedMessage, stream.messages[0])
+	}
+	if stream.messages[0].Status != expectedStatus {
+		t.Errorf("Expected status: %v, got: %v", expectedStatus, stream.messages[0].Status)
+	}
+}
+
 type MockTestingEnvironment struct {
 	*Environment
 }
@@ -110,7 +134,10 @@ func (mte MockTestingEnvironment) streamError(info string) error         { retur
 func (mte MockTestingEnvironment) streamFailed(name string) error        { return nil }
 func (mte MockTestingEnvironment) streamSuccess(name string) error       { return nil }
 func (mte MockTestingEnvironment) streamUnknown(name, info string) error { return nil }
-func (mte MockTestingEnvironment) streamMessage(msg string) error        { return nil }
+func (mte MockTestingEnvironment) streamMessage(msg string, status release.TestRun_Status) error {
+	mte.Stream.Send(&services.TestReleaseResponse{Msg: msg, Status: status})
+	return nil
+}
 
 type getFailingKubeClient struct {
 	tillerEnv.PrintingKubeClient
@@ -123,7 +150,7 @@ func newGetFailingKubeClient() *getFailingKubeClient {
 }
 
 func (p *getFailingKubeClient) Get(ns string, r io.Reader) (string, error) {
-	return "", errors.New("In the end, they did not find Nemo.")
+	return "", errors.New("in the end, they did not find Nemo")
 }
 
 type deleteFailingKubeClient struct {
diff --git a/pkg/releasetesting/test_suite.go b/pkg/releasetesting/test_suite.go
index f4362dc5b3b6f88e20ae84929f1b7bc258f4df10..e5e8db51e1f25bf4375363e87721e63cddfe523b 100644
--- a/pkg/releasetesting/test_suite.go
+++ b/pkg/releasetesting/test_suite.go
@@ -65,7 +65,8 @@ func (ts *TestSuite) Run(env *Environment) error {
 	ts.StartedAt = timeconv.Now()
 
 	if len(ts.TestManifests) == 0 {
-		env.streamMessage("No Tests Found")
+		// TODO: make this better, adding test run status on test suite is weird
+		env.streamMessage("No Tests Found", release.TestRun_UNKNOWN)
 	}
 
 	for _, testManifest := range ts.TestManifests {
@@ -78,6 +79,7 @@ func (ts *TestSuite) Run(env *Environment) error {
 		if err := env.streamRunning(test.result.Name); err != nil {
 			return err
 		}
+		test.result.Status = release.TestRun_RUNNING
 
 		resourceCreated := true
 		if err := env.createTestPod(test); err != nil {
@@ -93,7 +95,7 @@ func (ts *TestSuite) Run(env *Environment) error {
 			status, err = env.getTestPodStatus(test)
 			if err != nil {
 				resourceCleanExit = false
-				if streamErr := env.streamUnknown(test.result.Name, test.result.Info); streamErr != nil {
+				if streamErr := env.streamError(test.result.Info); streamErr != nil {
 					return streamErr
 				}
 			}
diff --git a/pkg/releaseutil/manifest.go b/pkg/releaseutil/manifest.go
index aad1641d715245a0f235f6da0241be0ec7fc5777..a0449cc551c9e95d20b3431061ab1463e732342b 100644
--- a/pkg/releaseutil/manifest.go
+++ b/pkg/releaseutil/manifest.go
@@ -19,6 +19,7 @@ package releaseutil
 import (
 	"fmt"
 	"regexp"
+	"strings"
 )
 
 // SimpleHead defines what the structure of the head of a manifest file
@@ -34,16 +35,25 @@ type SimpleHead struct {
 var sep = regexp.MustCompile("(?:^|\\s*\n)---\\s*")
 
 // SplitManifests takes a string of manifest and returns a map contains individual manifests
-func SplitManifests(bigfile string) map[string]string {
+func SplitManifests(bigFile string) map[string]string {
 	// Basically, we're quickly splitting a stream of YAML documents into an
 	// array of YAML docs. In the current implementation, the file name is just
 	// a place holder, and doesn't have any further meaning.
 	tpl := "manifest-%d"
 	res := map[string]string{}
 	// Making sure that any extra whitespace in YAML stream doesn't interfere in splitting documents correctly.
-	docs := sep.Split(bigfile, -1)
-	for i, d := range docs {
-		res[fmt.Sprintf(tpl, i)] = d
+	bigFileTmp := strings.TrimSpace(bigFile)
+	docs := sep.Split(bigFileTmp, -1)
+	var count int
+	for _, d := range docs {
+
+		if d == "" {
+			continue
+		}
+
+		d = strings.TrimSpace(d)
+		res[fmt.Sprintf(tpl, count)] = d
+		count = count + 1
 	}
 	return res
 }
diff --git a/pkg/releaseutil/manifest_test.go b/pkg/releaseutil/manifest_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..7906279adf76fbff698c33628e0833337a2eea0f
--- /dev/null
+++ b/pkg/releaseutil/manifest_test.go
@@ -0,0 +1,61 @@
+/*
+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 releaseutil // import "k8s.io/helm/pkg/releaseutil"
+
+import (
+	"reflect"
+	"testing"
+)
+
+const manifestFile = `
+
+---
+apiVersion: v1
+kind: Pod
+metadata:
+  name: finding-nemo,
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+  - name: nemo-test
+    image: fake-image
+    cmd: fake-command
+`
+
+const expectedManifest = `apiVersion: v1
+kind: Pod
+metadata:
+  name: finding-nemo,
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+  - name: nemo-test
+    image: fake-image
+    cmd: fake-command`
+
+func TestSplitManifest(t *testing.T) {
+	manifests := SplitManifests(manifestFile)
+	if len(manifests) != 1 {
+		t.Errorf("Expected 1 manifest, got %v", len(manifests))
+	}
+	expected := map[string]string{"manifest-0": expectedManifest}
+	if !reflect.DeepEqual(manifests, expected) {
+		t.Errorf("Expected %v, got %v", expected, manifests)
+	}
+}
diff --git a/pkg/repo/chartrepo.go b/pkg/repo/chartrepo.go
index d7a4267f8186959e79187fc2ec55e0eb4f98e802..9c833654ab0dbd9fbe41cda98b61d55600d1e1c9 100644
--- a/pkg/repo/chartrepo.go
+++ b/pkg/repo/chartrepo.go
@@ -50,13 +50,13 @@ type ChartRepository struct {
 }
 
 // NewChartRepository constructs ChartRepository
-func NewChartRepository(cfg *Entry, getters []getter.Prop) (*ChartRepository, error) {
+func NewChartRepository(cfg *Entry, getters getter.Providers) (*ChartRepository, error) {
 	u, err := url.Parse(cfg.URL)
 	if err != nil {
 		return nil, fmt.Errorf("invalid chart URL format: %s", cfg.URL)
 	}
 
-	getterConstructor, err := getter.ConstructorByScheme(getters, u.Scheme)
+	getterConstructor, err := getters.ByScheme(u.Scheme)
 	if err != nil {
 		return nil, fmt.Errorf("Could not find protocol handler for: %s", u.Scheme)
 	}
@@ -177,3 +177,50 @@ func (r *ChartRepository) generateIndex() error {
 	r.IndexFile.SortEntries()
 	return nil
 }
+
+// FindChartInRepoURL finds chart in chart repository pointed by repoURL
+// without adding repo to repostiories
+func FindChartInRepoURL(repoURL, chartName, chartVersion, certFile, keyFile, caFile string, getters getter.Providers) (string, error) {
+
+	// Download and write the index file to a temporary location
+	tempIndexFile, err := ioutil.TempFile("", "tmp-repo-file")
+	if err != nil {
+		return "", fmt.Errorf("cannot write index file for repository requested")
+	}
+	defer os.Remove(tempIndexFile.Name())
+
+	c := Entry{
+		URL:      repoURL,
+		CertFile: certFile,
+		KeyFile:  keyFile,
+		CAFile:   caFile,
+	}
+	r, err := NewChartRepository(&c, getters)
+	if err != nil {
+		return "", err
+	}
+	if err := r.DownloadIndexFile(tempIndexFile.Name()); err != nil {
+		return "", fmt.Errorf("Looks like %q is not a valid chart repository or cannot be reached: %s", repoURL, err)
+	}
+
+	// Read the index file for the repository to get chart information and return chart URL
+	repoIndex, err := LoadIndexFile(tempIndexFile.Name())
+	if err != nil {
+		return "", err
+	}
+
+	errMsg := fmt.Sprintf("chart %q", chartName)
+	if chartVersion != "" {
+		errMsg = fmt.Sprintf("%s version %q", errMsg, chartVersion)
+	}
+	cv, err := repoIndex.Get(chartName, chartVersion)
+	if err != nil {
+		return "", fmt.Errorf("%s not found in %s repository", errMsg, repoURL)
+	}
+
+	if len(cv.URLs) == 0 {
+		return "", fmt.Errorf("%s has no downloadable URLs", errMsg)
+	}
+
+	return cv.URLs[0], nil
+}
diff --git a/pkg/repo/chartrepo_test.go b/pkg/repo/chartrepo_test.go
index bab5019d88b47f38e3122d4757c3554c5fffa979..f6d6df74e9a43ed86eeef68d2adaf26cdbd66150 100644
--- a/pkg/repo/chartrepo_test.go
+++ b/pkg/repo/chartrepo_test.go
@@ -17,13 +17,17 @@ limitations under the License.
 package repo
 
 import (
+	"io/ioutil"
+	"net/http"
+	"net/http/httptest"
 	"os"
 	"path/filepath"
 	"reflect"
+	"strings"
 	"testing"
 	"time"
 
-	"k8s.io/helm/pkg/getter/defaultgetters"
+	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/helm/environment"
 	"k8s.io/helm/pkg/proto/hapi/chart"
 )
@@ -37,7 +41,7 @@ func TestLoadChartRepository(t *testing.T) {
 	r, err := NewChartRepository(&Entry{
 		Name: testRepository,
 		URL:  testURL,
-	}, defaultgetters.Get(environment.EnvSettings{}))
+	}, getter.All(environment.EnvSettings{}))
 	if err != nil {
 		t.Errorf("Problem creating chart repository from %s: %v", testRepository, err)
 	}
@@ -69,7 +73,7 @@ func TestIndex(t *testing.T) {
 	r, err := NewChartRepository(&Entry{
 		Name: testRepository,
 		URL:  testURL,
-	}, defaultgetters.Get(environment.EnvSettings{}))
+	}, getter.All(environment.EnvSettings{}))
 	if err != nil {
 		t.Errorf("Problem creating chart repository from %s: %v", testRepository, err)
 	}
@@ -185,3 +189,82 @@ func verifyIndex(t *testing.T, actual *IndexFile) {
 		}
 	}
 }
+
+// startLocalServerForTests Start the local helm server
+func startLocalServerForTests(handler http.Handler) (*httptest.Server, error) {
+	if handler == nil {
+		fileBytes, err := ioutil.ReadFile("testdata/local-index.yaml")
+		if err != nil {
+			return nil, err
+		}
+		handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+			w.Write(fileBytes)
+		})
+	}
+
+	return httptest.NewServer(handler), nil
+}
+
+func TestFindChartInRepoURL(t *testing.T) {
+	srv, err := startLocalServerForTests(nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer srv.Close()
+
+	chartURL, err := FindChartInRepoURL(srv.URL, "nginx", "", "", "", "", getter.All(environment.EnvSettings{}))
+	if err != nil {
+		t.Errorf("%s", err)
+	}
+	if chartURL != "https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz" {
+		t.Errorf("%s is not the valid URL", chartURL)
+	}
+
+	chartURL, err = FindChartInRepoURL(srv.URL, "nginx", "0.1.0", "", "", "", getter.All(environment.EnvSettings{}))
+	if err != nil {
+		t.Errorf("%s", err)
+	}
+	if chartURL != "https://kubernetes-charts.storage.googleapis.com/nginx-0.1.0.tgz" {
+		t.Errorf("%s is not the valid URL", chartURL)
+	}
+}
+
+func TestErrorFindChartInRepoURL(t *testing.T) {
+	_, err := FindChartInRepoURL("http://someserver/something", "nginx", "", "", "", "", getter.All(environment.EnvSettings{}))
+	if err == nil {
+		t.Errorf("Expected error for bad chart URL, but did not get any errors")
+	}
+	if err != nil && !strings.Contains(err.Error(), `Looks like "http://someserver/something" is not a valid chart repository or cannot be reached: Get http://someserver/something/index.yaml`) {
+		t.Errorf("Expected error for bad chart URL, but got a different error (%v)", err)
+	}
+
+	srv, err := startLocalServerForTests(nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer srv.Close()
+
+	_, err = FindChartInRepoURL(srv.URL, "nginx1", "", "", "", "", getter.All(environment.EnvSettings{}))
+	if err == nil {
+		t.Errorf("Expected error for chart not found, but did not get any errors")
+	}
+	if err != nil && err.Error() != `chart "nginx1" not found in `+srv.URL+` repository` {
+		t.Errorf("Expected error for chart not found, but got a different error (%v)", err)
+	}
+
+	_, err = FindChartInRepoURL(srv.URL, "nginx1", "0.1.0", "", "", "", getter.All(environment.EnvSettings{}))
+	if err == nil {
+		t.Errorf("Expected error for chart not found, but did not get any errors")
+	}
+	if err != nil && err.Error() != `chart "nginx1" version "0.1.0" not found in `+srv.URL+` repository` {
+		t.Errorf("Expected error for chart not found, but got a different error (%v)", err)
+	}
+
+	_, err = FindChartInRepoURL(srv.URL, "chartWithNoURL", "", "", "", "", getter.All(environment.EnvSettings{}))
+	if err == nil {
+		t.Errorf("Expected error for no chart URLs available, but did not get any errors")
+	}
+	if err != nil && err.Error() != `chart "chartWithNoURL" has no downloadable URLs` {
+		t.Errorf("Expected error for chart not found, but got a different error (%v)", err)
+	}
+}
diff --git a/pkg/repo/index_test.go b/pkg/repo/index_test.go
index c82e0e72787a94090a1bc2ab5bbc62e8b9f51d26..17a1cc209308f7650ed3cdcb2019a4ad0eb3d3f4 100644
--- a/pkg/repo/index_test.go
+++ b/pkg/repo/index_test.go
@@ -18,13 +18,11 @@ package repo
 
 import (
 	"io/ioutil"
-	"net/http"
-	"net/http/httptest"
 	"os"
 	"path/filepath"
 	"testing"
 
-	"k8s.io/helm/pkg/getter/defaultgetters"
+	"k8s.io/helm/pkg/getter"
 	"k8s.io/helm/pkg/helm/environment"
 	"k8s.io/helm/pkg/proto/hapi/chart"
 )
@@ -131,14 +129,10 @@ func TestMerge(t *testing.T) {
 }
 
 func TestDownloadIndexFile(t *testing.T) {
-	fileBytes, err := ioutil.ReadFile("testdata/local-index.yaml")
+	srv, err := startLocalServerForTests(nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-
-	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		w.Write(fileBytes)
-	}))
 	defer srv.Close()
 
 	dirName, err := ioutil.TempDir("", "tmp")
@@ -152,7 +146,7 @@ func TestDownloadIndexFile(t *testing.T) {
 		Name:  testRepo,
 		URL:   srv.URL,
 		Cache: indexFilePath,
-	}, defaultgetters.Get(environment.EnvSettings{}))
+	}, getter.All(environment.EnvSettings{}))
 	if err != nil {
 		t.Errorf("Problem creating chart repository from %s: %v", testRepo, err)
 	}
@@ -181,8 +175,8 @@ func TestDownloadIndexFile(t *testing.T) {
 
 func verifyLocalIndex(t *testing.T, i *IndexFile) {
 	numEntries := len(i.Entries)
-	if numEntries != 2 {
-		t.Errorf("Expected 2 entries in index file but got %d", numEntries)
+	if numEntries != 3 {
+		t.Errorf("Expected 3 entries in index file but got %d", numEntries)
 	}
 
 	alpine, ok := i.Entries["alpine"]
diff --git a/pkg/repo/local_test.go b/pkg/repo/local_test.go
index 3e2ecbbcffc14ab28df840e3e53eabd8d27d9bbd..1e5359dee6e38d7aca174326e23e0ea4336d4227 100644
--- a/pkg/repo/local_test.go
+++ b/pkg/repo/local_test.go
@@ -19,7 +19,6 @@ package repo
 import (
 	"io/ioutil"
 	"net/http"
-	"net/http/httptest"
 	"strings"
 	"testing"
 )
@@ -43,7 +42,10 @@ func TestRepositoryServer(t *testing.T) {
 	}
 
 	s := &RepositoryServer{RepoPath: "testdata/server"}
-	srv := httptest.NewServer(s)
+	srv, err := startLocalServerForTests(s)
+	if err != nil {
+		t.Fatal(err)
+	}
 	defer srv.Close()
 
 	for _, tt := range tests {
diff --git a/pkg/repo/repo.go b/pkg/repo/repo.go
index cbf54c572d1155e0d78a0e329255090de3f4d44d..5e1b5c6cd92fafe7c8a2a4abcf200a809eb9af1f 100644
--- a/pkg/repo/repo.go
+++ b/pkg/repo/repo.go
@@ -23,6 +23,7 @@ import (
 	"os"
 	"time"
 
+	"github.com/facebookgo/atomicfile"
 	"github.com/ghodss/yaml"
 )
 
@@ -134,9 +135,20 @@ func (r *RepoFile) Remove(name string) bool {
 
 // WriteFile writes a repositories file to the given path.
 func (r *RepoFile) WriteFile(path string, perm os.FileMode) error {
+	f, err := atomicfile.New(path, perm)
+	if err != nil {
+		return err
+	}
+
 	data, err := yaml.Marshal(r)
 	if err != nil {
 		return err
 	}
-	return ioutil.WriteFile(path, data, perm)
+
+	_, err = f.File.Write(data)
+	if err != nil {
+		return err
+	}
+
+	return f.Close()
 }
diff --git a/pkg/repo/repo_test.go b/pkg/repo/repo_test.go
index 6aee41faf4db4c54e053fd6e7bfce2c305e3526b..d4500c9e215fda2312a5d77a1376edb3832dc204 100644
--- a/pkg/repo/repo_test.go
+++ b/pkg/repo/repo_test.go
@@ -201,10 +201,18 @@ func TestWriteFile(t *testing.T) {
 		t.Errorf("failed to create test-file (%v)", err)
 	}
 	defer os.Remove(repoFile.Name())
-	if err := sampleRepository.WriteFile(repoFile.Name(), 744); err != nil {
+
+	fileMode := os.FileMode(0744)
+	if err := sampleRepository.WriteFile(repoFile.Name(), fileMode); err != nil {
 		t.Errorf("failed to write file (%v)", err)
 	}
 
+	info, _ := os.Stat(repoFile.Name())
+	mode := info.Mode()
+	if mode != fileMode {
+		t.Errorf("incorrect file mode: %s (expected %s)", mode, fileMode)
+	}
+
 	repos, err := LoadRepositoriesFile(repoFile.Name())
 	if err != nil {
 		t.Errorf("failed to load file (%v)", err)
diff --git a/pkg/repo/testdata/local-index-unordered.yaml b/pkg/repo/testdata/local-index-unordered.yaml
index ec529f1107550e004b43906fc52f6d9769cb2176..7482baaae85e8b11ace392205eb123acaa83253e 100644
--- a/pkg/repo/testdata/local-index-unordered.yaml
+++ b/pkg/repo/testdata/local-index-unordered.yaml
@@ -37,3 +37,12 @@ entries:
         - small
         - sumtin
       digest: "sha256:1234567890abcdef"
+  chartWithNoURL:
+    - name: chartWithNoURL
+      description: string
+      version: 1.0.0
+      home: https://github.com/something
+      keywords:
+        - small
+        - sumtin
+      digest: "sha256:1234567890abcdef"
diff --git a/pkg/repo/testdata/local-index.yaml b/pkg/repo/testdata/local-index.yaml
index f64c54c1b9e93d13221b97b08d3a1dae4b53417e..e680d2a3e7b46864a318f807456fb68c27da6cd7 100644
--- a/pkg/repo/testdata/local-index.yaml
+++ b/pkg/repo/testdata/local-index.yaml
@@ -37,3 +37,12 @@ entries:
         - small
         - sumtin
       digest: "sha256:1234567890abcdef"
+  chartWithNoURL:
+    - name: chartWithNoURL
+      description: string
+      version: 1.0.0
+      home: https://github.com/something
+      keywords:
+        - small
+        - sumtin
+      digest: "sha256:1234567890abcdef"
diff --git a/pkg/resolver/resolver_test.go b/pkg/resolver/resolver_test.go
index ef5a3bee0ff2ee877ea495e6bc6da043a2fbe922..b87022b932fa60ee494c4930cce51dd837d08e1b 100644
--- a/pkg/resolver/resolver_test.go
+++ b/pkg/resolver/resolver_test.go
@@ -146,7 +146,7 @@ func TestResolve(t *testing.T) {
 }
 
 func TestHashReq(t *testing.T) {
-	expect := "sha256:1feffe2016ca113f64159d91c1f77d6a83bcd23510b171d9264741bf9d63f741"
+	expect := "sha256:45b06fcc4496c705bf3d634f8a2ff84e6a6f0bdcaf010614b8886572d1e52b99"
 	req := &chartutil.Requirements{
 		Dependencies: []*chartutil.Dependency{
 			{Name: "alpine", Version: "0.1.0", Repository: "http://localhost:8879/charts"},
diff --git a/pkg/rudder/client.go b/pkg/rudder/client.go
new file mode 100644
index 0000000000000000000000000000000000000000..219bb010ac65cb88e4b8714f5c951b0699a0c7d7
--- /dev/null
+++ b/pkg/rudder/client.go
@@ -0,0 +1,91 @@
+/*
+Copyright 2017 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 rudder // import "k8s.io/helm/pkg/rudder"
+
+import (
+	"fmt"
+
+	"golang.org/x/net/context"
+	"google.golang.org/grpc"
+
+	rudderAPI "k8s.io/helm/pkg/proto/hapi/rudder"
+)
+
+// GrpcPort specifies port on which rudder will spawn a server
+const (
+	GrpcPort = 10001
+)
+
+var grpcAddr = fmt.Sprintf("127.0.0.1:%d", GrpcPort)
+
+// InstallRelease calls Rudder InstallRelease method which should create provided release
+func InstallRelease(rel *rudderAPI.InstallReleaseRequest) (*rudderAPI.InstallReleaseResponse, error) {
+	//TODO(mkwiek): parametrize this
+	conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure())
+	if err != nil {
+		return nil, err
+	}
+
+	defer conn.Close()
+	client := rudderAPI.NewReleaseModuleServiceClient(conn)
+	return client.InstallRelease(context.Background(), rel)
+}
+
+// UpgradeRelease calls Rudder UpgradeRelease method which should perform update
+func UpgradeRelease(req *rudderAPI.UpgradeReleaseRequest) (*rudderAPI.UpgradeReleaseResponse, error) {
+	conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure())
+	if err != nil {
+		return nil, err
+	}
+	defer conn.Close()
+	client := rudderAPI.NewReleaseModuleServiceClient(conn)
+	return client.UpgradeRelease(context.Background(), req)
+}
+
+// RollbackRelease calls Rudder RollbackRelease method which should perform update
+func RollbackRelease(req *rudderAPI.RollbackReleaseRequest) (*rudderAPI.RollbackReleaseResponse, error) {
+	conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure())
+	if err != nil {
+		return nil, err
+	}
+	defer conn.Close()
+	client := rudderAPI.NewReleaseModuleServiceClient(conn)
+	return client.RollbackRelease(context.Background(), req)
+}
+
+// ReleaseStatus calls Rudder ReleaseStatus method which should perform update
+func ReleaseStatus(req *rudderAPI.ReleaseStatusRequest) (*rudderAPI.ReleaseStatusResponse, error) {
+	conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure())
+	if err != nil {
+		return nil, err
+	}
+	defer conn.Close()
+	client := rudderAPI.NewReleaseModuleServiceClient(conn)
+	return client.ReleaseStatus(context.Background(), req)
+}
+
+// DeleteRelease calls Rudder DeleteRelease method which should uninstall provided release
+func DeleteRelease(rel *rudderAPI.DeleteReleaseRequest) (*rudderAPI.DeleteReleaseResponse, error) {
+	conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure())
+	if err != nil {
+		return nil, err
+	}
+
+	defer conn.Close()
+	client := rudderAPI.NewReleaseModuleServiceClient(conn)
+	return client.DeleteRelease(context.Background(), rel)
+}
diff --git a/pkg/storage/driver/cfgmaps.go b/pkg/storage/driver/cfgmaps.go
index d7d48a03279d5cf5a61df990dc254448c20b7bde..1c30951f3074f92074f183897168e7df9816e255 100644
--- a/pkg/storage/driver/cfgmaps.go
+++ b/pkg/storage/driver/cfgmaps.go
@@ -22,7 +22,6 @@ import (
 	"encoding/base64"
 	"fmt"
 	"io/ioutil"
-	"log"
 	"strconv"
 	"strings"
 	"time"
@@ -51,12 +50,16 @@ var magicGzip = []byte{0x1f, 0x8b, 0x08}
 // ConfigMapsInterface.
 type ConfigMaps struct {
 	impl internalversion.ConfigMapInterface
+	Log  func(string, ...interface{})
 }
 
 // NewConfigMaps initializes a new ConfigMaps wrapping an implmenetation of
 // the kubernetes ConfigMapsInterface.
 func NewConfigMaps(impl internalversion.ConfigMapInterface) *ConfigMaps {
-	return &ConfigMaps{impl: impl}
+	return &ConfigMaps{
+		impl: impl,
+		Log:  func(_ string, _ ...interface{}) {},
+	}
 }
 
 // Name returns the name of the driver.
@@ -74,13 +77,13 @@ func (cfgmaps *ConfigMaps) Get(key string) (*rspb.Release, error) {
 			return nil, ErrReleaseNotFound(key)
 		}
 
-		logerrf(err, "get: failed to get %q", key)
+		cfgmaps.Log("get: failed to get %q: %s", key, err)
 		return nil, err
 	}
 	// found the configmap, decode the base64 data string
 	r, err := decodeRelease(obj.Data["release"])
 	if err != nil {
-		logerrf(err, "get: failed to decode data %q", key)
+		cfgmaps.Log("get: failed to decode data %q: %s", key, err)
 		return nil, err
 	}
 	// return the release object
@@ -96,7 +99,7 @@ func (cfgmaps *ConfigMaps) List(filter func(*rspb.Release) bool) ([]*rspb.Releas
 
 	list, err := cfgmaps.impl.List(opts)
 	if err != nil {
-		logerrf(err, "list: failed to list")
+		cfgmaps.Log("list: failed to list: %s", err)
 		return nil, err
 	}
 
@@ -107,7 +110,7 @@ func (cfgmaps *ConfigMaps) List(filter func(*rspb.Release) bool) ([]*rspb.Releas
 	for _, item := range list.Items {
 		rls, err := decodeRelease(item.Data["release"])
 		if err != nil {
-			logerrf(err, "list: failed to decode release: %v", item)
+			cfgmaps.Log("list: failed to decode release: %v: %s", item, err)
 			continue
 		}
 		if filter(rls) {
@@ -132,7 +135,7 @@ func (cfgmaps *ConfigMaps) Query(labels map[string]string) ([]*rspb.Release, err
 
 	list, err := cfgmaps.impl.List(opts)
 	if err != nil {
-		logerrf(err, "query: failed to query with labels")
+		cfgmaps.Log("query: failed to query with labels: %s", err)
 		return nil, err
 	}
 
@@ -144,7 +147,7 @@ func (cfgmaps *ConfigMaps) Query(labels map[string]string) ([]*rspb.Release, err
 	for _, item := range list.Items {
 		rls, err := decodeRelease(item.Data["release"])
 		if err != nil {
-			logerrf(err, "query: failed to decode release: %s", err)
+			cfgmaps.Log("query: failed to decode release: %s", err)
 			continue
 		}
 		results = append(results, rls)
@@ -164,7 +167,7 @@ func (cfgmaps *ConfigMaps) Create(key string, rls *rspb.Release) error {
 	// create a new configmap to hold the release
 	obj, err := newConfigMapsObject(key, rls, lbs)
 	if err != nil {
-		logerrf(err, "create: failed to encode release %q", rls.Name)
+		cfgmaps.Log("create: failed to encode release %q: %s", rls.Name, err)
 		return err
 	}
 	// push the configmap object out into the kubiverse
@@ -173,7 +176,7 @@ func (cfgmaps *ConfigMaps) Create(key string, rls *rspb.Release) error {
 			return ErrReleaseExists(rls.Name)
 		}
 
-		logerrf(err, "create: failed to create")
+		cfgmaps.Log("create: failed to create: %s", err)
 		return err
 	}
 	return nil
@@ -191,13 +194,13 @@ func (cfgmaps *ConfigMaps) Update(key string, rls *rspb.Release) error {
 	// create a new configmap object to hold the release
 	obj, err := newConfigMapsObject(key, rls, lbs)
 	if err != nil {
-		logerrf(err, "update: failed to encode release %q", rls.Name)
+		cfgmaps.Log("update: failed to encode release %q: %s", rls.Name, err)
 		return err
 	}
 	// push the configmap object out into the kubiverse
 	_, err = cfgmaps.impl.Update(obj)
 	if err != nil {
-		logerrf(err, "update: failed to update")
+		cfgmaps.Log("update: failed to update: %s", err)
 		return err
 	}
 	return nil
@@ -211,7 +214,7 @@ func (cfgmaps *ConfigMaps) Delete(key string) (rls *rspb.Release, err error) {
 			return nil, ErrReleaseExists(rls.Name)
 		}
 
-		logerrf(err, "delete: failed to get release %q", key)
+		cfgmaps.Log("delete: failed to get release %q: %s", key, err)
 		return nil, err
 	}
 	// delete the release
@@ -316,8 +319,3 @@ func decodeRelease(data string) (*rspb.Release, error) {
 	}
 	return &rls, nil
 }
-
-// logerrf wraps an error with a formatted string (used for debugging)
-func logerrf(err error, format string, args ...interface{}) {
-	log.Printf("configmaps: %s: %s\n", fmt.Sprintf(format, args...), err)
-}
diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go
index a10f377da7e62030b4e571389406272d5b65528e..b5aa16ccb83a1918ce452386421feb13385d581c 100644
--- a/pkg/storage/storage.go
+++ b/pkg/storage/storage.go
@@ -18,7 +18,7 @@ package storage // import "k8s.io/helm/pkg/storage"
 
 import (
 	"fmt"
-	"log"
+	"sync"
 
 	rspb "k8s.io/helm/pkg/proto/hapi/release"
 	relutil "k8s.io/helm/pkg/releaseutil"
@@ -28,13 +28,20 @@ import (
 // Storage represents a storage engine for a Release.
 type Storage struct {
 	driver.Driver
+
+	// releaseLocks are for locking releases to make sure that only one operation at a time is executed on each release
+	releaseLocks map[string]*sync.Mutex
+	// releaseLocksLock is a mutex for accessing releaseLocks
+	releaseLocksLock *sync.Mutex
+
+	Log func(string, ...interface{})
 }
 
 // Get retrieves the release from storage. An error is returned
 // if the storage driver failed to fetch the release, or the
 // release identified by the key, version pair does not exist.
 func (s *Storage) Get(name string, version int32) (*rspb.Release, error) {
-	log.Printf("Getting release %q (v%d) from storage\n", name, version)
+	s.Log("getting release %q", makeKey(name, version))
 	return s.Driver.Get(makeKey(name, version))
 }
 
@@ -42,7 +49,7 @@ func (s *Storage) Get(name string, version int32) (*rspb.Release, error) {
 // error is returned if the storage driver failed to store the
 // release, or a release with identical an key already exists.
 func (s *Storage) Create(rls *rspb.Release) error {
-	log.Printf("Create release %q (v%d) in storage\n", rls.Name, rls.Version)
+	s.Log("creating release %q", makeKey(rls.Name, rls.Version))
 	return s.Driver.Create(makeKey(rls.Name, rls.Version), rls)
 }
 
@@ -50,7 +57,7 @@ func (s *Storage) Create(rls *rspb.Release) error {
 // storage backend fails to update the release or if the release
 // does not exist.
 func (s *Storage) Update(rls *rspb.Release) error {
-	log.Printf("Updating %q (v%d) in storage\n", rls.Name, rls.Version)
+	s.Log("updating release %q", makeKey(rls.Name, rls.Version))
 	return s.Driver.Update(makeKey(rls.Name, rls.Version), rls)
 }
 
@@ -58,21 +65,21 @@ func (s *Storage) Update(rls *rspb.Release) error {
 // the storage backend fails to delete the release or if the release
 // does not exist.
 func (s *Storage) Delete(name string, version int32) (*rspb.Release, error) {
-	log.Printf("Deleting release %q (v%d) from storage\n", name, version)
+	s.Log("deleting release %q", makeKey(name, version))
 	return s.Driver.Delete(makeKey(name, version))
 }
 
 // ListReleases returns all releases from storage. An error is returned if the
 // storage backend fails to retrieve the releases.
 func (s *Storage) ListReleases() ([]*rspb.Release, error) {
-	log.Println("Listing all releases in storage")
+	s.Log("listing all releases in storage")
 	return s.Driver.List(func(_ *rspb.Release) bool { return true })
 }
 
 // ListDeleted returns all releases with Status == DELETED. An error is returned
 // if the storage backend fails to retrieve the releases.
 func (s *Storage) ListDeleted() ([]*rspb.Release, error) {
-	log.Println("List deleted releases in storage")
+	s.Log("listing deleted releases in storage")
 	return s.Driver.List(func(rls *rspb.Release) bool {
 		return relutil.StatusFilter(rspb.Status_DELETED).Check(rls)
 	})
@@ -81,7 +88,7 @@ func (s *Storage) ListDeleted() ([]*rspb.Release, error) {
 // ListDeployed returns all releases with Status == DEPLOYED. An error is returned
 // if the storage backend fails to retrieve the releases.
 func (s *Storage) ListDeployed() ([]*rspb.Release, error) {
-	log.Println("Listing all deployed releases in storage")
+	s.Log("listing all deployed releases in storage")
 	return s.Driver.List(func(rls *rspb.Release) bool {
 		return relutil.StatusFilter(rspb.Status_DEPLOYED).Check(rls)
 	})
@@ -91,7 +98,7 @@ func (s *Storage) ListDeployed() ([]*rspb.Release, error) {
 // (filter0 && filter1 && ... && filterN), i.e. a Release is included in the results
 // if and only if all filters return true.
 func (s *Storage) ListFilterAll(fns ...relutil.FilterFunc) ([]*rspb.Release, error) {
-	log.Println("Listing all releases with filter")
+	s.Log("listing all releases with filter")
 	return s.Driver.List(func(rls *rspb.Release) bool {
 		return relutil.All(fns...).Check(rls)
 	})
@@ -101,7 +108,7 @@ func (s *Storage) ListFilterAll(fns ...relutil.FilterFunc) ([]*rspb.Release, err
 // (filter0 || filter1 || ... || filterN), i.e. a Release is included in the results
 // if at least one of the filters returns true.
 func (s *Storage) ListFilterAny(fns ...relutil.FilterFunc) ([]*rspb.Release, error) {
-	log.Println("Listing any releases with filter")
+	s.Log("listing any releases with filter")
 	return s.Driver.List(func(rls *rspb.Release) bool {
 		return relutil.Any(fns...).Check(rls)
 	})
@@ -110,7 +117,7 @@ func (s *Storage) ListFilterAny(fns ...relutil.FilterFunc) ([]*rspb.Release, err
 // Deployed returns the deployed release with the provided release name, or
 // returns ErrReleaseNotFound if not found.
 func (s *Storage) Deployed(name string) (*rspb.Release, error) {
-	log.Printf("Getting deployed release from '%s' history\n", name)
+	s.Log("getting deployed release from %q history", name)
 
 	ls, err := s.Driver.Query(map[string]string{
 		"NAME":   name,
@@ -121,7 +128,7 @@ func (s *Storage) Deployed(name string) (*rspb.Release, error) {
 	case err != nil:
 		return nil, err
 	case len(ls) == 0:
-		return nil, fmt.Errorf("'%s' has no deployed releases", name)
+		return nil, fmt.Errorf("%q has no deployed releases", name)
 	default:
 		return ls[0], nil
 	}
@@ -130,17 +137,14 @@ func (s *Storage) Deployed(name string) (*rspb.Release, error) {
 // History returns the revision history for the release with the provided name, or
 // returns ErrReleaseNotFound if no such release name exists.
 func (s *Storage) History(name string) ([]*rspb.Release, error) {
-	log.Printf("Getting release history for '%s'\n", name)
+	s.Log("getting release history for %q", name)
 
-	l, err := s.Driver.Query(map[string]string{"NAME": name, "OWNER": "TILLER"})
-	if err != nil {
-		return nil, err
-	}
-	return l, nil
+	return s.Driver.Query(map[string]string{"NAME": name, "OWNER": "TILLER"})
 }
 
 // Last fetches the last revision of the named release.
 func (s *Storage) Last(name string) (*rspb.Release, error) {
+	s.Log("getting last revision of %q", name)
 	h, err := s.History(name)
 	if err != nil {
 		return nil, err
@@ -153,6 +157,53 @@ func (s *Storage) Last(name string) (*rspb.Release, error) {
 	return h[0], nil
 }
 
+// LockRelease gains a mutually exclusive access to a release via a mutex.
+func (s *Storage) LockRelease(name string) error {
+	s.Log("locking release %s", name)
+	s.releaseLocksLock.Lock()
+	defer s.releaseLocksLock.Unlock()
+
+	var lock *sync.Mutex
+	lock, exists := s.releaseLocks[name]
+
+	if !exists {
+		releases, err := s.ListReleases()
+		if err != nil {
+			return err
+		}
+
+		found := false
+		for _, release := range releases {
+			if release.Name == name {
+				found = true
+			}
+		}
+		if !found {
+			return fmt.Errorf("Unable to lock release %q: release not found", name)
+		}
+
+		lock = &sync.Mutex{}
+		s.releaseLocks[name] = lock
+	}
+	lock.Lock()
+	return nil
+}
+
+// UnlockRelease releases a mutually exclusive access to a release.
+// If release doesn't exist or wasn't previously locked - the unlock will pass
+func (s *Storage) UnlockRelease(name string) {
+	s.Log("unlocking release %s", name)
+	s.releaseLocksLock.Lock()
+	defer s.releaseLocksLock.Unlock()
+
+	var lock *sync.Mutex
+	lock, exists := s.releaseLocks[name]
+	if !exists {
+		return
+	}
+	lock.Unlock()
+}
+
 // makeKey concatenates a release name and version into
 // a string with format ```<release_name>#v<version>```.
 // This key is used to uniquely identify storage objects.
@@ -167,5 +218,10 @@ func Init(d driver.Driver) *Storage {
 	if d == nil {
 		d = driver.NewMemory()
 	}
-	return &Storage{Driver: d}
+	return &Storage{
+		Driver:           d,
+		releaseLocks:     make(map[string]*sync.Mutex),
+		releaseLocksLock: &sync.Mutex{},
+		Log:              func(_ string, _ ...interface{}) {},
+	}
 }
diff --git a/pkg/storage/storage_test.go b/pkg/storage/storage_test.go
index 141a019fa2897fbc354e84b7cd6bd6336b87e809..d2dc8cdb27210fa29dec166f3101f29de984dfcd 100644
--- a/pkg/storage/storage_test.go
+++ b/pkg/storage/storage_test.go
@@ -272,3 +272,31 @@ func assertErrNil(eh func(args ...interface{}), err error, message string) {
 		eh(fmt.Sprintf("%s: %q", message, err))
 	}
 }
+
+func TestReleaseLocksNotExist(t *testing.T) {
+	s := Init(driver.NewMemory())
+
+	err := s.LockRelease("no-such-release")
+
+	if err == nil {
+		t.Errorf("Exptected error when trying to lock non-existing release, got nil")
+	}
+}
+
+func TestReleaseLocks(t *testing.T) {
+	s := Init(driver.NewMemory())
+
+	releaseName := "angry-beaver"
+	rls := ReleaseTestData{
+		Name:    releaseName,
+		Version: 1,
+	}.ToRelease()
+
+	s.Create(rls)
+
+	err := s.LockRelease(releaseName)
+	if err != nil {
+		t.Errorf("Exptected nil err when locking existing release")
+	}
+	s.UnlockRelease(releaseName)
+}
diff --git a/pkg/tiller/environment/environment.go b/pkg/tiller/environment/environment.go
index 26516474b3e66bc95ab9d15e5452f0e2184904a7..de0dbe33df3d913f5ec601650c9e8c451ee0c2b8 100644
--- a/pkg/tiller/environment/environment.go
+++ b/pkg/tiller/environment/environment.go
@@ -24,7 +24,6 @@ package environment
 
 import (
 	"io"
-	"os"
 	"time"
 
 	"k8s.io/helm/pkg/chartutil"
@@ -44,14 +43,6 @@ const TillerNamespaceEnvVar = "TILLER_NAMESPACE"
 // DefaultTillerNamespace is the default namespace for tiller.
 const DefaultTillerNamespace = "kube-system"
 
-// GetTillerNamespace returns the right tiller namespace.
-func GetTillerNamespace() string {
-	if ns := os.Getenv(TillerNamespaceEnvVar); ns != "" {
-		return ns
-	}
-	return DefaultTillerNamespace
-}
-
 // GoTplEngine is the name of the Go template engine, as registered in the EngineYard.
 const GoTplEngine = "gotpl"
 
@@ -147,7 +138,7 @@ type KubeClient interface {
 	//
 	// reader must contain a YAML stream (one or more YAML documents separated
 	// by "\n---\n").
-	Update(namespace string, originalReader, modifiedReader io.Reader, recreate bool, timeout int64, shouldWait bool) error
+	Update(namespace string, originalReader, modifiedReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error
 
 	Build(namespace string, reader io.Reader) (kube.Result, error)
 	BuildUnstructured(namespace string, reader io.Reader) (kube.Result, error)
@@ -190,7 +181,7 @@ func (p *PrintingKubeClient) WatchUntilReady(ns string, r io.Reader, timeout int
 }
 
 // Update implements KubeClient Update.
-func (p *PrintingKubeClient) Update(ns string, currentReader, modifiedReader io.Reader, recreate bool, timeout int64, shouldWait bool) error {
+func (p *PrintingKubeClient) Update(ns string, currentReader, modifiedReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error {
 	_, err := io.Copy(p.Out, modifiedReader)
 	return err
 }
@@ -235,6 +226,5 @@ func New() *Environment {
 	return &Environment{
 		EngineYard: ey,
 		Releases:   storage.Init(driver.NewMemory()),
-		KubeClient: kube.New(nil),
 	}
 }
diff --git a/pkg/tiller/environment/environment_test.go b/pkg/tiller/environment/environment_test.go
index 716836438710ae4862b9464c390485757e94a4df..916ff602f27fa3d93806316e13a6a4bd86d02870 100644
--- a/pkg/tiller/environment/environment_test.go
+++ b/pkg/tiller/environment/environment_test.go
@@ -48,7 +48,7 @@ func (k *mockKubeClient) Get(ns string, r io.Reader) (string, error) {
 func (k *mockKubeClient) Delete(ns string, r io.Reader) error {
 	return nil
 }
-func (k *mockKubeClient) Update(ns string, currentReader, modifiedReader io.Reader, recreate bool, timeout int64, shouldWait bool) error {
+func (k *mockKubeClient) Update(ns string, currentReader, modifiedReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error {
 	return nil
 }
 func (k *mockKubeClient) WatchUntilReady(ns string, r io.Reader, timeout int64, shouldWait bool) error {
diff --git a/pkg/tiller/hooks.go b/pkg/tiller/hooks.go
index b2624347999220e68e814a7f791d651052c49e71..9962533846574e6a46248ebf3df2d1d7ce2cfd5a 100644
--- a/pkg/tiller/hooks.go
+++ b/pkg/tiller/hooks.go
@@ -51,96 +51,149 @@ type manifest struct {
 	head    *util.SimpleHead
 }
 
-// sortManifests takes a map of filename/YAML contents and sorts them into hook types.
+type result struct {
+	hooks   []*release.Hook
+	generic []manifest
+}
+
+type manifestFile struct {
+	entries map[string]string
+	path    string
+	apis    chartutil.VersionSet
+}
+
+// sortManifests takes a map of filename/YAML contents, splits the file
+// by manifest entries, and sorts the entries into hook types.
 //
 // The resulting hooks struct will be populated with all of the generated hooks.
 // Any file that does not declare one of the hook types will be placed in the
 // 'generic' bucket.
 //
-// To determine hook type, this looks for a YAML structure like this:
-//
-//  kind: SomeKind
-//  apiVersion: v1
-// 	metadata:
-//		annotations:
-//			helm.sh/hook: pre-install
-//
-// Where HOOK_NAME is one of the known hooks.
-//
-// If a file declares more than one hook, it will be copied into all of the applicable
-// hook buckets. (Note: label keys are not unique within the labels section).
-//
 // Files that do not parse into the expected format are simply placed into a map and
 // returned.
 func sortManifests(files map[string]string, apis chartutil.VersionSet, sort SortOrder) ([]*release.Hook, []manifest, error) {
-	hs := []*release.Hook{}
-	generic := []manifest{}
+	result := &result{}
+
+	for filePath, c := range files {
 
-	for n, c := range files {
 		// Skip partials. We could return these as a separate map, but there doesn't
 		// seem to be any need for that at this time.
-		if strings.HasPrefix(path.Base(n), "_") {
+		if strings.HasPrefix(path.Base(filePath), "_") {
 			continue
 		}
-		// Skip empty files, and log this.
+		// Skip empty files and log this.
 		if len(strings.TrimSpace(c)) == 0 {
-			log.Printf("info: manifest %q is empty. Skipping.", n)
+			log.Printf("info: manifest %q is empty. Skipping.", filePath)
 			continue
 		}
 
-		var sh util.SimpleHead
-		err := yaml.Unmarshal([]byte(c), &sh)
+		manifestFile := &manifestFile{
+			entries: util.SplitManifests(c),
+			path:    filePath,
+			apis:    apis,
+		}
+
+		if err := manifestFile.sort(result); err != nil {
+			return result.hooks, result.generic, err
+		}
+	}
+
+	return result.hooks, sortByKind(result.generic, sort), nil
+}
+
+// sort takes a manifestFile object which may contain multiple resource definition
+// entries and sorts each entry by hook types, and saves the resulting hooks and
+// generic manifests (or non-hooks) to the result struct.
+//
+// To determine hook type, it looks for a YAML structure like this:
+//
+//  kind: SomeKind
+//  apiVersion: v1
+// 	metadata:
+//		annotations:
+//			helm.sh/hook: pre-install
+//
+func (file *manifestFile) sort(result *result) error {
+	for _, m := range file.entries {
+		var entry util.SimpleHead
+		err := yaml.Unmarshal([]byte(m), &entry)
 
 		if err != nil {
-			e := fmt.Errorf("YAML parse error on %s: %s", n, err)
-			return hs, generic, e
+			e := fmt.Errorf("YAML parse error on %s: %s", file.path, err)
+			return e
 		}
 
-		if sh.Version != "" && !apis.Has(sh.Version) {
-			return hs, generic, fmt.Errorf("apiVersion %q in %s is not available", sh.Version, n)
+		if entry.Version != "" && !file.apis.Has(entry.Version) {
+			return fmt.Errorf("apiVersion %q in %s is not available", entry.Version, file.path)
 		}
 
-		if sh.Metadata == nil || sh.Metadata.Annotations == nil || len(sh.Metadata.Annotations) == 0 {
-			generic = append(generic, manifest{name: n, content: c, head: &sh})
+		if !hasAnyAnnotation(entry) {
+			result.generic = append(result.generic, manifest{
+				name:    file.path,
+				content: m,
+				head:    &entry,
+			})
 			continue
 		}
 
-		hookTypes, ok := sh.Metadata.Annotations[hooks.HookAnno]
+		hookTypes, ok := entry.Metadata.Annotations[hooks.HookAnno]
 		if !ok {
-			generic = append(generic, manifest{name: n, content: c, head: &sh})
+			result.generic = append(result.generic, manifest{
+				name:    file.path,
+				content: m,
+				head:    &entry,
+			})
 			continue
 		}
 
-		hws, _ := sh.Metadata.Annotations[hooks.HookWeightAnno]
-		hw, err := strconv.Atoi(hws)
-		if err != nil {
-			hw = 0
-		}
+		hw := calculateHookWeight(entry)
 
 		h := &release.Hook{
-			Name:     sh.Metadata.Name,
-			Kind:     sh.Kind,
-			Path:     n,
-			Manifest: c,
+			Name:     entry.Metadata.Name,
+			Kind:     entry.Kind,
+			Path:     file.path,
+			Manifest: m,
 			Events:   []release.Hook_Event{},
-			Weight:   int32(hw),
+			Weight:   hw,
 		}
 
-		isHook := false
+		isKnownHook := false
 		for _, hookType := range strings.Split(hookTypes, ",") {
 			hookType = strings.ToLower(strings.TrimSpace(hookType))
 			e, ok := events[hookType]
 			if ok {
-				isHook = true
+				isKnownHook = true
 				h.Events = append(h.Events, e)
 			}
 		}
 
-		if !isHook {
+		if !isKnownHook {
 			log.Printf("info: skipping unknown hook: %q", hookTypes)
 			continue
 		}
-		hs = append(hs, h)
+
+		result.hooks = append(result.hooks, h)
+	}
+
+	return nil
+}
+
+func hasAnyAnnotation(entry util.SimpleHead) bool {
+	if entry.Metadata == nil ||
+		entry.Metadata.Annotations == nil ||
+		len(entry.Metadata.Annotations) == 0 {
+		return false
 	}
-	return hs, sortByKind(generic, sort), nil
+
+	return true
+}
+
+func calculateHookWeight(entry util.SimpleHead) int32 {
+	hws, _ := entry.Metadata.Annotations[hooks.HookWeightAnno]
+	hw, err := strconv.Atoi(hws)
+	if err != nil {
+		hw = 0
+	}
+
+	return int32(hw)
 }
diff --git a/pkg/tiller/hooks_test.go b/pkg/tiller/hooks_test.go
index 823e7469c208b7afd54e9b4195cd6b737f1f4379..eabdc7eac2f0605c3ccdd3519c98a5b3dd68c52c 100644
--- a/pkg/tiller/hooks_test.go
+++ b/pkg/tiller/hooks_test.go
@@ -17,6 +17,7 @@ limitations under the License.
 package tiller
 
 import (
+	"reflect"
 	"testing"
 
 	"github.com/ghodss/yaml"
@@ -29,17 +30,17 @@ import (
 func TestSortManifests(t *testing.T) {
 
 	data := []struct {
-		name     string
+		name     []string
 		path     string
-		kind     string
-		hooks    []release.Hook_Event
+		kind     []string
+		hooks    map[string][]release.Hook_Event
 		manifest string
 	}{
 		{
-			name:  "first",
+			name:  []string{"first"},
 			path:  "one",
-			kind:  "Job",
-			hooks: []release.Hook_Event{release.Hook_PRE_INSTALL},
+			kind:  []string{"Job"},
+			hooks: map[string][]release.Hook_Event{"first": {release.Hook_PRE_INSTALL}},
 			manifest: `apiVersion: v1
 kind: Job
 metadata:
@@ -51,10 +52,10 @@ metadata:
 `,
 		},
 		{
-			name:  "second",
+			name:  []string{"second"},
 			path:  "two",
-			kind:  "ReplicaSet",
-			hooks: []release.Hook_Event{release.Hook_POST_INSTALL},
+			kind:  []string{"ReplicaSet"},
+			hooks: map[string][]release.Hook_Event{"second": {release.Hook_POST_INSTALL}},
 			manifest: `kind: ReplicaSet
 apiVersion: v1beta1
 metadata:
@@ -63,10 +64,10 @@ metadata:
     "helm.sh/hook": post-install
 `,
 		}, {
-			name:  "third",
+			name:  []string{"third"},
 			path:  "three",
-			kind:  "ReplicaSet",
-			hooks: []release.Hook_Event{},
+			kind:  []string{"ReplicaSet"},
+			hooks: map[string][]release.Hook_Event{"third": nil},
 			manifest: `kind: ReplicaSet
 apiVersion: v1beta1
 metadata:
@@ -75,22 +76,21 @@ metadata:
     "helm.sh/hook": no-such-hook
 `,
 		}, {
-			name:  "fourth",
+			name:  []string{"fourth"},
 			path:  "four",
-			kind:  "Pod",
-			hooks: []release.Hook_Event{},
+			kind:  []string{"Pod"},
+			hooks: map[string][]release.Hook_Event{"fourth": nil},
 			manifest: `kind: Pod
 apiVersion: v1
 metadata:
   name: fourth
   annotations:
-    nothing: here
-`,
+    nothing: here`,
 		}, {
-			name:  "fifth",
+			name:  []string{"fifth"},
 			path:  "five",
-			kind:  "ReplicaSet",
-			hooks: []release.Hook_Event{release.Hook_POST_DELETE, release.Hook_POST_INSTALL},
+			kind:  []string{"ReplicaSet"},
+			hooks: map[string][]release.Hook_Event{"fifth": {release.Hook_POST_DELETE, release.Hook_POST_INSTALL}},
 			manifest: `kind: ReplicaSet
 apiVersion: v1beta1
 metadata:
@@ -100,19 +100,39 @@ metadata:
 `,
 		}, {
 			// Regression test: files with an underscore in the base name should be skipped.
-			name:     "sixth",
+			name:     []string{"sixth"},
 			path:     "six/_six",
-			kind:     "ReplicaSet",
-			hooks:    []release.Hook_Event{},
+			kind:     []string{"ReplicaSet"},
+			hooks:    map[string][]release.Hook_Event{"sixth": nil},
 			manifest: `invalid manifest`, // This will fail if partial is not skipped.
 		}, {
 			// Regression test: files with no content should be skipped.
-			name:     "seventh",
+			name:     []string{"seventh"},
 			path:     "seven",
-			kind:     "ReplicaSet",
-			hooks:    []release.Hook_Event{},
+			kind:     []string{"ReplicaSet"},
+			hooks:    map[string][]release.Hook_Event{"seventh": nil},
 			manifest: "",
 		},
+		{
+			name:  []string{"eighth", "example-test"},
+			path:  "eight",
+			kind:  []string{"ConfigMap", "Pod"},
+			hooks: map[string][]release.Hook_Event{"eighth": nil, "example-test": {release.Hook_RELEASE_TEST_SUCCESS}},
+			manifest: `kind: ConfigMap
+apiVersion: v1
+metadata:
+  name: eighth
+data:
+  name: value
+---
+apiVersion: v1
+kind: Pod
+metadata:
+  name: example-test
+  annotations:
+    "helm.sh/hook": test-success
+`,
+		},
 	}
 
 	manifests := make(map[string]string, len(data))
@@ -126,12 +146,12 @@ metadata:
 	}
 
 	// This test will fail if 'six' or 'seven' was added.
-	if len(generic) != 1 {
-		t.Errorf("Expected 1 generic manifest, got %d", len(generic))
+	if len(generic) != 2 {
+		t.Errorf("Expected 2 generic manifests, got %d", len(generic))
 	}
 
-	if len(hs) != 3 {
-		t.Errorf("Expected 3 hooks, got %d", len(hs))
+	if len(hs) != 4 {
+		t.Errorf("Expected 4 hooks, got %d", len(hs))
 	}
 
 	for _, out := range hs {
@@ -142,17 +162,30 @@ metadata:
 				if out.Path != expect.path {
 					t.Errorf("Expected path %s, got %s", expect.path, out.Path)
 				}
-				if out.Name != expect.name {
-					t.Errorf("Expected name %s, got %s", expect.name, out.Name)
+				nameFound := false
+				for _, expectedName := range expect.name {
+					if out.Name == expectedName {
+						nameFound = true
+					}
 				}
-				if out.Kind != expect.kind {
-					t.Errorf("Expected kind %s, got %s", expect.kind, out.Kind)
+				if !nameFound {
+					t.Errorf("Got unexpected name %s", out.Name)
 				}
-				for i := 0; i < len(out.Events); i++ {
-					if out.Events[i] != expect.hooks[i] {
-						t.Errorf("Expected event %d, got %d", expect.hooks[i], out.Events[i])
+				kindFound := false
+				for _, expectedKind := range expect.kind {
+					if out.Kind == expectedKind {
+						kindFound = true
 					}
 				}
+				if !kindFound {
+					t.Errorf("Got unexpected kind %s", out.Kind)
+				}
+
+				expectedHooks := expect.hooks[out.Name]
+				if !reflect.DeepEqual(expectedHooks, out.Events) {
+					t.Errorf("expected events: %v but got: %v", expectedHooks, out.Events)
+				}
+
 			}
 		}
 		if !found {
@@ -161,27 +194,40 @@ metadata:
 	}
 
 	// Verify the sort order
-	sorted := make([]manifest, len(data))
-	for i, s := range data {
-		var sh util.SimpleHead
-		err := yaml.Unmarshal([]byte(s.manifest), &sh)
-		if err != nil {
-			// This is expected for manifests that are corrupt or empty.
-			t.Log(err)
-		}
-		sorted[i] = manifest{
-			content: s.manifest,
-			name:    s.name,
-			head:    &sh,
+	sorted := []manifest{}
+	for _, s := range data {
+		manifests := util.SplitManifests(s.manifest)
+		mCount := 0
+		for _, m := range manifests {
+			name := s.name[mCount]
+
+			var sh util.SimpleHead
+			err := yaml.Unmarshal([]byte(m), &sh)
+			if err != nil {
+				// This is expected for manifests that are corrupt or empty.
+				t.Log(err)
+			}
+
+			//only keep track of non-hook manifests
+			if err == nil && s.hooks[name] == nil {
+				another := manifest{
+					content: m,
+					name:    name,
+					head:    &sh,
+				}
+				sorted = append(sorted, another)
+			}
+
+			mCount++
 		}
 	}
+
 	sorted = sortByKind(sorted, InstallOrder)
 	for i, m := range generic {
 		if m.content != sorted[i].content {
 			t.Errorf("Expected %q, got %q", m.content, sorted[i].content)
 		}
 	}
-
 }
 
 func TestVersionSet(t *testing.T) {
diff --git a/pkg/tiller/release_content.go b/pkg/tiller/release_content.go
new file mode 100644
index 0000000000000000000000000000000000000000..7586eb2d8facf845aa305787b26bbe355adcb3bc
--- /dev/null
+++ b/pkg/tiller/release_content.go
@@ -0,0 +1,37 @@
+/*
+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 tiller
+
+import (
+	ctx "golang.org/x/net/context"
+	"k8s.io/helm/pkg/proto/hapi/services"
+)
+
+// GetReleaseContent gets all of the stored information for the given release.
+func (s *ReleaseServer) GetReleaseContent(c ctx.Context, req *services.GetReleaseContentRequest) (*services.GetReleaseContentResponse, error) {
+	if !ValidName.MatchString(req.Name) {
+		return nil, errMissingRelease
+	}
+
+	if req.Version <= 0 {
+		rel, err := s.env.Releases.Last(req.Name)
+		return &services.GetReleaseContentResponse{Release: rel}, err
+	}
+
+	rel, err := s.env.Releases.Get(req.Name, req.Version)
+	return &services.GetReleaseContentResponse{Release: rel}, err
+}
diff --git a/pkg/tiller/release_content_test.go b/pkg/tiller/release_content_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..9a81f1e3f05564e2d9e614fcb49e93ec02187122
--- /dev/null
+++ b/pkg/tiller/release_content_test.go
@@ -0,0 +1,41 @@
+/*
+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 tiller
+
+import (
+	"k8s.io/helm/pkg/helm"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	"testing"
+)
+
+func TestGetReleaseContent(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	if err := rs.env.Releases.Create(rel); err != nil {
+		t.Fatalf("Could not store mock release: %s", err)
+	}
+
+	res, err := rs.GetReleaseContent(c, &services.GetReleaseContentRequest{Name: rel.Name, Version: 1})
+	if err != nil {
+		t.Errorf("Error getting release content: %s", err)
+	}
+
+	if res.Release.Chart.Metadata.Name != rel.Chart.Metadata.Name {
+		t.Errorf("Expected %q, got %q", rel.Chart.Metadata.Name, res.Release.Chart.Metadata.Name)
+	}
+}
diff --git a/pkg/tiller/release_history.go b/pkg/tiller/release_history.go
index 63f4275e9659809c7598ce47aef3972dc10d7e43..09131fad8b30868c5829e2fc48600d7fec42206f 100644
--- a/pkg/tiller/release_history.go
+++ b/pkg/tiller/release_history.go
@@ -25,6 +25,7 @@ import (
 
 // GetHistory gets the history for a given release.
 func (s *ReleaseServer) GetHistory(ctx context.Context, req *tpb.GetHistoryRequest) (*tpb.GetHistoryResponse, error) {
+	s.Log("getting history for release %s", req.Name)
 	h, err := s.env.Releases.History(req.Name)
 	if err != nil {
 		return nil, err
diff --git a/pkg/tiller/release_install.go b/pkg/tiller/release_install.go
new file mode 100644
index 0000000000000000000000000000000000000000..79b7b635412160a53d607fcb875435952d14c4c2
--- /dev/null
+++ b/pkg/tiller/release_install.go
@@ -0,0 +1,222 @@
+/*
+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 tiller
+
+import (
+	"fmt"
+	"strings"
+
+	ctx "golang.org/x/net/context"
+	"k8s.io/helm/pkg/chartutil"
+	"k8s.io/helm/pkg/hooks"
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	relutil "k8s.io/helm/pkg/releaseutil"
+	"k8s.io/helm/pkg/timeconv"
+)
+
+// InstallRelease installs a release and stores the release record.
+func (s *ReleaseServer) InstallRelease(c ctx.Context, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
+	s.Log("preparing install for %s", req.Name)
+	rel, err := s.prepareRelease(req)
+	if err != nil {
+		s.Log("failed install prepare step: %s", err)
+		res := &services.InstallReleaseResponse{Release: rel}
+
+		// On dry run, append the manifest contents to a failed release. This is
+		// a stop-gap until we can revisit an error backchannel post-2.0.
+		if req.DryRun && strings.HasPrefix(err.Error(), "YAML parse error") {
+			err = fmt.Errorf("%s\n%s", err, rel.Manifest)
+		}
+		return res, err
+	}
+
+	s.Log("performing install for %s", req.Name)
+	res, err := s.performRelease(rel, req)
+	if err != nil {
+		s.Log("failed install perform step: %s", err)
+	}
+	return res, err
+}
+
+// prepareRelease builds a release for an install operation.
+func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*release.Release, error) {
+	if req.Chart == nil {
+		return nil, errMissingChart
+	}
+
+	name, err := s.uniqName(req.Name, req.ReuseName)
+	if err != nil {
+		return nil, err
+	}
+
+	caps, err := capabilities(s.clientset.Discovery())
+	if err != nil {
+		return nil, err
+	}
+
+	revision := 1
+	ts := timeconv.Now()
+	options := chartutil.ReleaseOptions{
+		Name:      name,
+		Time:      ts,
+		Namespace: req.Namespace,
+		Revision:  revision,
+		IsInstall: true,
+	}
+	valuesToRender, err := chartutil.ToRenderValuesCaps(req.Chart, req.Values, options, caps)
+	if err != nil {
+		return nil, err
+	}
+
+	hooks, manifestDoc, notesTxt, err := s.renderResources(req.Chart, valuesToRender, caps.APIVersions)
+	if err != nil {
+		// Return a release with partial data so that client can show debugging
+		// information.
+		rel := &release.Release{
+			Name:      name,
+			Namespace: req.Namespace,
+			Chart:     req.Chart,
+			Config:    req.Values,
+			Info: &release.Info{
+				FirstDeployed: ts,
+				LastDeployed:  ts,
+				Status:        &release.Status{Code: release.Status_UNKNOWN},
+				Description:   fmt.Sprintf("Install failed: %s", err),
+			},
+			Version: 0,
+		}
+		if manifestDoc != nil {
+			rel.Manifest = manifestDoc.String()
+		}
+		return rel, err
+	}
+
+	// Store a release.
+	rel := &release.Release{
+		Name:      name,
+		Namespace: req.Namespace,
+		Chart:     req.Chart,
+		Config:    req.Values,
+		Info: &release.Info{
+			FirstDeployed: ts,
+			LastDeployed:  ts,
+			Status:        &release.Status{Code: release.Status_UNKNOWN},
+			Description:   "Initial install underway", // Will be overwritten.
+		},
+		Manifest: manifestDoc.String(),
+		Hooks:    hooks,
+		Version:  int32(revision),
+	}
+	if len(notesTxt) > 0 {
+		rel.Info.Status.Notes = notesTxt
+	}
+
+	err = validateManifest(s.env.KubeClient, req.Namespace, manifestDoc.Bytes())
+	return rel, err
+}
+
+// performRelease runs a release.
+func (s *ReleaseServer) performRelease(r *release.Release, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
+	res := &services.InstallReleaseResponse{Release: r}
+
+	if req.DryRun {
+		s.Log("dry run for %s", r.Name)
+		res.Release.Info.Description = "Dry run complete"
+		return res, nil
+	}
+
+	// pre-install hooks
+	if !req.DisableHooks {
+		if err := s.execHook(r.Hooks, r.Name, r.Namespace, hooks.PreInstall, req.Timeout); err != nil {
+			return res, err
+		}
+	} else {
+		s.Log("install hooks disabled for %s", req.Name)
+	}
+
+	switch h, err := s.env.Releases.History(req.Name); {
+	// if this is a replace operation, append to the release history
+	case req.ReuseName && err == nil && len(h) >= 1:
+		s.Log("name reuse for %s requested, replacing release", req.Name)
+		// get latest release revision
+		relutil.Reverse(h, relutil.SortByRevision)
+
+		// old release
+		old := h[0]
+
+		// update old release status
+		old.Info.Status.Code = release.Status_SUPERSEDED
+		s.recordRelease(old, true)
+
+		// update new release with next revision number
+		// so as to append to the old release's history
+		r.Version = old.Version + 1
+		updateReq := &services.UpdateReleaseRequest{
+			Wait:     req.Wait,
+			Recreate: false,
+			Timeout:  req.Timeout,
+		}
+		if err := s.ReleaseModule.Update(old, r, updateReq, s.env); err != nil {
+			msg := fmt.Sprintf("Release replace %q failed: %s", r.Name, err)
+			s.Log("warning: %s", msg)
+			old.Info.Status.Code = release.Status_SUPERSEDED
+			r.Info.Status.Code = release.Status_FAILED
+			r.Info.Description = msg
+			s.recordRelease(old, true)
+			s.recordRelease(r, false)
+			return res, err
+		}
+
+	default:
+		// nothing to replace, create as normal
+		// regular manifests
+		if err := s.ReleaseModule.Create(r, req, s.env); err != nil {
+			msg := fmt.Sprintf("Release %q failed: %s", r.Name, err)
+			s.Log("warning: %s", msg)
+			r.Info.Status.Code = release.Status_FAILED
+			r.Info.Description = msg
+			s.recordRelease(r, false)
+			return res, fmt.Errorf("release %s failed: %s", r.Name, err)
+		}
+	}
+
+	// post-install hooks
+	if !req.DisableHooks {
+		if err := s.execHook(r.Hooks, r.Name, r.Namespace, hooks.PostInstall, req.Timeout); err != nil {
+			msg := fmt.Sprintf("Release %q failed post-install: %s", r.Name, err)
+			s.Log("warning: %s", msg)
+			r.Info.Status.Code = release.Status_FAILED
+			r.Info.Description = msg
+			s.recordRelease(r, false)
+			return res, err
+		}
+	}
+
+	r.Info.Status.Code = release.Status_DEPLOYED
+	r.Info.Description = "Install complete"
+	// 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.
+	s.recordRelease(r, false)
+
+	return res, nil
+}
diff --git a/pkg/tiller/release_install_test.go b/pkg/tiller/release_install_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..481dee01bb9669c71e71c5dddc2751192a4871a6
--- /dev/null
+++ b/pkg/tiller/release_install_test.go
@@ -0,0 +1,454 @@
+/*
+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 tiller
+
+import (
+	"fmt"
+	"strings"
+	"testing"
+
+	"k8s.io/helm/pkg/helm"
+	"k8s.io/helm/pkg/proto/hapi/chart"
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	"k8s.io/helm/pkg/version"
+)
+
+func TestInstallRelease(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+
+	// TODO: Refactor this into a mock.
+	req := &services.InstallReleaseRequest{
+		Namespace: "spaced",
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello"},
+			Templates: []*chart.Template{
+				{Name: "templates/hello", Data: []byte("hello: world")},
+				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
+			},
+		},
+	}
+	res, err := rs.InstallRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed install: %s", err)
+	}
+	if res.Release.Name == "" {
+		t.Errorf("Expected release name.")
+	}
+	if res.Release.Namespace != "spaced" {
+		t.Errorf("Expected release namespace 'spaced', got '%s'.", res.Release.Namespace)
+	}
+
+	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
+	if err != nil {
+		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
+	}
+
+	t.Logf("rel: %v", rel)
+
+	if len(rel.Hooks) != 1 {
+		t.Fatalf("Expected 1 hook, got %d", len(rel.Hooks))
+	}
+	if rel.Hooks[0].Manifest != manifestWithHook {
+		t.Errorf("Unexpected manifest: %v", rel.Hooks[0].Manifest)
+	}
+
+	if rel.Hooks[0].Events[0] != release.Hook_POST_INSTALL {
+		t.Errorf("Expected event 0 is post install")
+	}
+	if rel.Hooks[0].Events[1] != release.Hook_PRE_DELETE {
+		t.Errorf("Expected event 0 is pre-delete")
+	}
+
+	if len(res.Release.Manifest) == 0 {
+		t.Errorf("No manifest returned: %v", res.Release)
+	}
+
+	if len(rel.Manifest) == 0 {
+		t.Errorf("Expected manifest in %v", res)
+	}
+
+	if !strings.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
+		t.Errorf("unexpected output: %s", rel.Manifest)
+	}
+
+	if rel.Info.Description != "Install complete" {
+		t.Errorf("unexpected description: %s", rel.Info.Description)
+	}
+}
+
+func TestInstallRelease_WithNotes(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+
+	// TODO: Refactor this into a mock.
+	req := &services.InstallReleaseRequest{
+		Namespace: "spaced",
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello"},
+			Templates: []*chart.Template{
+				{Name: "templates/hello", Data: []byte("hello: world")},
+				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
+				{Name: "templates/NOTES.txt", Data: []byte(notesText)},
+			},
+		},
+	}
+	res, err := rs.InstallRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed install: %s", err)
+	}
+	if res.Release.Name == "" {
+		t.Errorf("Expected release name.")
+	}
+	if res.Release.Namespace != "spaced" {
+		t.Errorf("Expected release namespace 'spaced', got '%s'.", res.Release.Namespace)
+	}
+
+	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
+	if err != nil {
+		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
+	}
+
+	t.Logf("rel: %v", rel)
+
+	if len(rel.Hooks) != 1 {
+		t.Fatalf("Expected 1 hook, got %d", len(rel.Hooks))
+	}
+	if rel.Hooks[0].Manifest != manifestWithHook {
+		t.Errorf("Unexpected manifest: %v", rel.Hooks[0].Manifest)
+	}
+
+	if rel.Info.Status.Notes != notesText {
+		t.Fatalf("Expected '%s', got '%s'", notesText, rel.Info.Status.Notes)
+	}
+
+	if rel.Hooks[0].Events[0] != release.Hook_POST_INSTALL {
+		t.Errorf("Expected event 0 is post install")
+	}
+	if rel.Hooks[0].Events[1] != release.Hook_PRE_DELETE {
+		t.Errorf("Expected event 0 is pre-delete")
+	}
+
+	if len(res.Release.Manifest) == 0 {
+		t.Errorf("No manifest returned: %v", res.Release)
+	}
+
+	if len(rel.Manifest) == 0 {
+		t.Errorf("Expected manifest in %v", res)
+	}
+
+	if !strings.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
+		t.Errorf("unexpected output: %s", rel.Manifest)
+	}
+
+	if rel.Info.Description != "Install complete" {
+		t.Errorf("unexpected description: %s", rel.Info.Description)
+	}
+}
+
+func TestInstallRelease_WithNotesRendered(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+
+	// TODO: Refactor this into a mock.
+	req := &services.InstallReleaseRequest{
+		Namespace: "spaced",
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello"},
+			Templates: []*chart.Template{
+				{Name: "templates/hello", Data: []byte("hello: world")},
+				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
+				{Name: "templates/NOTES.txt", Data: []byte(notesText + " {{.Release.Name}}")},
+			},
+		},
+	}
+	res, err := rs.InstallRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed install: %s", err)
+	}
+	if res.Release.Name == "" {
+		t.Errorf("Expected release name.")
+	}
+	if res.Release.Namespace != "spaced" {
+		t.Errorf("Expected release namespace 'spaced', got '%s'.", res.Release.Namespace)
+	}
+
+	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
+	if err != nil {
+		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
+	}
+
+	t.Logf("rel: %v", rel)
+
+	if len(rel.Hooks) != 1 {
+		t.Fatalf("Expected 1 hook, got %d", len(rel.Hooks))
+	}
+	if rel.Hooks[0].Manifest != manifestWithHook {
+		t.Errorf("Unexpected manifest: %v", rel.Hooks[0].Manifest)
+	}
+
+	expectedNotes := fmt.Sprintf("%s %s", notesText, res.Release.Name)
+	if rel.Info.Status.Notes != expectedNotes {
+		t.Fatalf("Expected '%s', got '%s'", expectedNotes, rel.Info.Status.Notes)
+	}
+
+	if rel.Hooks[0].Events[0] != release.Hook_POST_INSTALL {
+		t.Errorf("Expected event 0 is post install")
+	}
+	if rel.Hooks[0].Events[1] != release.Hook_PRE_DELETE {
+		t.Errorf("Expected event 0 is pre-delete")
+	}
+
+	if len(res.Release.Manifest) == 0 {
+		t.Errorf("No manifest returned: %v", res.Release)
+	}
+
+	if len(rel.Manifest) == 0 {
+		t.Errorf("Expected manifest in %v", res)
+	}
+
+	if !strings.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
+		t.Errorf("unexpected output: %s", rel.Manifest)
+	}
+
+	if rel.Info.Description != "Install complete" {
+		t.Errorf("unexpected description: %s", rel.Info.Description)
+	}
+}
+
+func TestInstallRelease_TillerVersion(t *testing.T) {
+	version.Version = "2.2.0"
+	c := helm.NewContext()
+	rs := rsFixture()
+
+	// TODO: Refactor this into a mock.
+	req := &services.InstallReleaseRequest{
+		Namespace: "spaced",
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello", TillerVersion: ">=2.2.0"},
+			Templates: []*chart.Template{
+				{Name: "templates/hello", Data: []byte("hello: world")},
+				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
+			},
+		},
+	}
+	_, err := rs.InstallRelease(c, req)
+	if err != nil {
+		t.Fatalf("Expected valid range. Got %q", err)
+	}
+}
+
+func TestInstallRelease_WrongTillerVersion(t *testing.T) {
+	version.Version = "2.2.0"
+	c := helm.NewContext()
+	rs := rsFixture()
+
+	// TODO: Refactor this into a mock.
+	req := &services.InstallReleaseRequest{
+		Namespace: "spaced",
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello", TillerVersion: "<2.0.0"},
+			Templates: []*chart.Template{
+				{Name: "templates/hello", Data: []byte("hello: world")},
+				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
+			},
+		},
+	}
+	_, err := rs.InstallRelease(c, req)
+	if err == nil {
+		t.Fatalf("Expected to fail because of wrong version")
+	}
+
+	expect := "Chart incompatible with Tiller"
+	if !strings.Contains(err.Error(), expect) {
+		t.Errorf("Expected %q to contain %q", err.Error(), expect)
+	}
+}
+
+func TestInstallRelease_WithChartAndDependencyNotes(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+
+	// TODO: Refactor this into a mock.
+	req := &services.InstallReleaseRequest{
+		Namespace: "spaced",
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello"},
+			Templates: []*chart.Template{
+				{Name: "templates/hello", Data: []byte("hello: world")},
+				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
+				{Name: "templates/NOTES.txt", Data: []byte(notesText)},
+			},
+			Dependencies: []*chart.Chart{
+				{
+					Metadata: &chart.Metadata{Name: "hello"},
+					Templates: []*chart.Template{
+						{Name: "templates/hello", Data: []byte("hello: world")},
+						{Name: "templates/hooks", Data: []byte(manifestWithHook)},
+						{Name: "templates/NOTES.txt", Data: []byte(notesText + " child")},
+					},
+				},
+			},
+		},
+	}
+
+	res, err := rs.InstallRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed install: %s", err)
+	}
+	if res.Release.Name == "" {
+		t.Errorf("Expected release name.")
+	}
+
+	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
+	if err != nil {
+		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
+	}
+
+	t.Logf("rel: %v", rel)
+
+	if rel.Info.Status.Notes != notesText {
+		t.Fatalf("Expected '%s', got '%s'", notesText, rel.Info.Status.Notes)
+	}
+
+	if rel.Info.Description != "Install complete" {
+		t.Errorf("unexpected description: %s", rel.Info.Description)
+	}
+}
+
+func TestInstallRelease_DryRun(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+
+	req := &services.InstallReleaseRequest{
+		Chart:  chartStub(),
+		DryRun: true,
+	}
+	res, err := rs.InstallRelease(c, req)
+	if err != nil {
+		t.Errorf("Failed install: %s", err)
+	}
+	if res.Release.Name == "" {
+		t.Errorf("Expected release name.")
+	}
+
+	if !strings.Contains(res.Release.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
+		t.Errorf("unexpected output: %s", res.Release.Manifest)
+	}
+
+	if !strings.Contains(res.Release.Manifest, "---\n# Source: hello/templates/goodbye\ngoodbye: world") {
+		t.Errorf("unexpected output: %s", res.Release.Manifest)
+	}
+
+	if !strings.Contains(res.Release.Manifest, "hello: Earth") {
+		t.Errorf("Should contain partial content. %s", res.Release.Manifest)
+	}
+
+	if strings.Contains(res.Release.Manifest, "hello: {{ template \"_planet\" . }}") {
+		t.Errorf("Should not contain partial templates itself. %s", res.Release.Manifest)
+	}
+
+	if strings.Contains(res.Release.Manifest, "empty") {
+		t.Errorf("Should not contain template data for an empty file. %s", res.Release.Manifest)
+	}
+
+	if _, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version); err == nil {
+		t.Errorf("Expected no stored release.")
+	}
+
+	if l := len(res.Release.Hooks); l != 1 {
+		t.Fatalf("Expected 1 hook, got %d", l)
+	}
+
+	if res.Release.Hooks[0].LastRun != nil {
+		t.Error("Expected hook to not be marked as run.")
+	}
+
+	if res.Release.Info.Description != "Dry run complete" {
+		t.Errorf("unexpected description: %s", res.Release.Info.Description)
+	}
+}
+
+func TestInstallRelease_NoHooks(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rs.env.Releases.Create(releaseStub())
+
+	req := &services.InstallReleaseRequest{
+		Chart:        chartStub(),
+		DisableHooks: true,
+	}
+	res, err := rs.InstallRelease(c, req)
+	if err != nil {
+		t.Errorf("Failed install: %s", err)
+	}
+
+	if hl := res.Release.Hooks[0].LastRun; hl != nil {
+		t.Errorf("Expected that no hooks were run. Got %d", hl)
+	}
+}
+
+func TestInstallRelease_FailedHooks(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rs.env.Releases.Create(releaseStub())
+	rs.env.KubeClient = newHookFailingKubeClient()
+
+	req := &services.InstallReleaseRequest{
+		Chart: chartStub(),
+	}
+	res, err := rs.InstallRelease(c, req)
+	if err == nil {
+		t.Error("Expected failed install")
+	}
+
+	if hl := res.Release.Info.Status.Code; hl != release.Status_FAILED {
+		t.Errorf("Expected FAILED release. Got %d", hl)
+	}
+}
+
+func TestInstallRelease_ReuseName(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rel.Info.Status.Code = release.Status_DELETED
+	rs.env.Releases.Create(rel)
+
+	req := &services.InstallReleaseRequest{
+		Chart:     chartStub(),
+		ReuseName: true,
+		Name:      rel.Name,
+	}
+	res, err := rs.InstallRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed install: %s", err)
+	}
+
+	if res.Release.Name != rel.Name {
+		t.Errorf("expected %q, got %q", rel.Name, res.Release.Name)
+	}
+
+	getreq := &services.GetReleaseStatusRequest{Name: rel.Name, Version: 0}
+	getres, err := rs.GetReleaseStatus(c, getreq)
+	if err != nil {
+		t.Errorf("Failed to retrieve release: %s", err)
+	}
+	if getres.Info.Status.Code != release.Status_DEPLOYED {
+		t.Errorf("Release status is %q", getres.Info.Status.Code)
+	}
+}
diff --git a/pkg/tiller/release_list.go b/pkg/tiller/release_list.go
new file mode 100644
index 0000000000000000000000000000000000000000..14d5c0d38360cd227ffceb3cf2f9898246eaaba2
--- /dev/null
+++ b/pkg/tiller/release_list.go
@@ -0,0 +1,141 @@
+/*
+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 tiller
+
+import (
+	"fmt"
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	relutil "k8s.io/helm/pkg/releaseutil"
+	"regexp"
+)
+
+// ListReleases lists the releases found by the server.
+func (s *ReleaseServer) ListReleases(req *services.ListReleasesRequest, stream services.ReleaseService_ListReleasesServer) error {
+	if len(req.StatusCodes) == 0 {
+		req.StatusCodes = []release.Status_Code{release.Status_DEPLOYED}
+	}
+
+	//rels, err := s.env.Releases.ListDeployed()
+	rels, err := s.env.Releases.ListFilterAll(func(r *release.Release) bool {
+		for _, sc := range req.StatusCodes {
+			if sc == r.Info.Status.Code {
+				return true
+			}
+		}
+		return false
+	})
+	if err != nil {
+		return err
+	}
+
+	if req.Namespace != "" {
+		rels, err = filterByNamespace(req.Namespace, rels)
+		if err != nil {
+			return err
+		}
+	}
+
+	if len(req.Filter) != 0 {
+		rels, err = filterReleases(req.Filter, rels)
+		if err != nil {
+			return err
+		}
+	}
+
+	total := int64(len(rels))
+
+	switch req.SortBy {
+	case services.ListSort_NAME:
+		relutil.SortByName(rels)
+	case services.ListSort_LAST_RELEASED:
+		relutil.SortByDate(rels)
+	}
+
+	if req.SortOrder == services.ListSort_DESC {
+		ll := len(rels)
+		rr := make([]*release.Release, ll)
+		for i, item := range rels {
+			rr[ll-i-1] = item
+		}
+		rels = rr
+	}
+
+	l := int64(len(rels))
+	if req.Offset != "" {
+
+		i := -1
+		for ii, cur := range rels {
+			if cur.Name == req.Offset {
+				i = ii
+			}
+		}
+		if i == -1 {
+			return fmt.Errorf("offset %q not found", req.Offset)
+		}
+
+		if len(rels) < i {
+			return fmt.Errorf("no items after %q", req.Offset)
+		}
+
+		rels = rels[i:]
+		l = int64(len(rels))
+	}
+
+	if req.Limit == 0 {
+		req.Limit = ListDefaultLimit
+	}
+
+	next := ""
+	if l > req.Limit {
+		next = rels[req.Limit].Name
+		rels = rels[0:req.Limit]
+		l = int64(len(rels))
+	}
+
+	res := &services.ListReleasesResponse{
+		Next:     next,
+		Count:    l,
+		Total:    total,
+		Releases: rels,
+	}
+	return stream.Send(res)
+}
+
+func filterByNamespace(namespace string, rels []*release.Release) ([]*release.Release, error) {
+	matches := []*release.Release{}
+	for _, r := range rels {
+		if namespace == r.Namespace {
+			matches = append(matches, r)
+		}
+	}
+	return matches, nil
+}
+
+func filterReleases(filter string, rels []*release.Release) ([]*release.Release, error) {
+	preg, err := regexp.Compile(filter)
+	if err != nil {
+		return rels, err
+	}
+	matches := []*release.Release{}
+	for _, r := range rels {
+		if preg.MatchString(r.Name) {
+			matches = append(matches, r)
+		}
+	}
+	return matches, nil
+}
diff --git a/pkg/tiller/release_list_test.go b/pkg/tiller/release_list_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..64877422a94a482e1a99df21914b2e3e71b06fb2
--- /dev/null
+++ b/pkg/tiller/release_list_test.go
@@ -0,0 +1,233 @@
+/*
+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 tiller
+
+import (
+	"fmt"
+	"testing"
+
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+)
+
+func TestListReleases(t *testing.T) {
+	rs := rsFixture()
+	num := 7
+	for i := 0; i < num; i++ {
+		rel := releaseStub()
+		rel.Name = fmt.Sprintf("rel-%d", i)
+		if err := rs.env.Releases.Create(rel); err != nil {
+			t.Fatalf("Could not store mock release: %s", err)
+		}
+	}
+
+	mrs := &mockListServer{}
+	if err := rs.ListReleases(&services.ListReleasesRequest{Offset: "", Limit: 64}, mrs); err != nil {
+		t.Fatalf("Failed listing: %s", err)
+	}
+
+	if len(mrs.val.Releases) != num {
+		t.Errorf("Expected %d releases, got %d", num, len(mrs.val.Releases))
+	}
+}
+
+func TestListReleasesByStatus(t *testing.T) {
+	rs := rsFixture()
+	stubs := []*release.Release{
+		namedReleaseStub("kamal", release.Status_DEPLOYED),
+		namedReleaseStub("astrolabe", release.Status_DELETED),
+		namedReleaseStub("octant", release.Status_FAILED),
+		namedReleaseStub("sextant", release.Status_UNKNOWN),
+	}
+	for _, stub := range stubs {
+		if err := rs.env.Releases.Create(stub); err != nil {
+			t.Fatalf("Could not create stub: %s", err)
+		}
+	}
+
+	tests := []struct {
+		statusCodes []release.Status_Code
+		names       []string
+	}{
+		{
+			names:       []string{"kamal"},
+			statusCodes: []release.Status_Code{release.Status_DEPLOYED},
+		},
+		{
+			names:       []string{"astrolabe"},
+			statusCodes: []release.Status_Code{release.Status_DELETED},
+		},
+		{
+			names:       []string{"kamal", "octant"},
+			statusCodes: []release.Status_Code{release.Status_DEPLOYED, release.Status_FAILED},
+		},
+		{
+			names: []string{"kamal", "astrolabe", "octant", "sextant"},
+			statusCodes: []release.Status_Code{
+				release.Status_DEPLOYED,
+				release.Status_DELETED,
+				release.Status_FAILED,
+				release.Status_UNKNOWN,
+			},
+		},
+	}
+
+	for i, tt := range tests {
+		mrs := &mockListServer{}
+		if err := rs.ListReleases(&services.ListReleasesRequest{StatusCodes: tt.statusCodes, Offset: "", Limit: 64}, mrs); err != nil {
+			t.Fatalf("Failed listing %d: %s", i, err)
+		}
+
+		if len(tt.names) != len(mrs.val.Releases) {
+			t.Fatalf("Expected %d releases, got %d", len(tt.names), len(mrs.val.Releases))
+		}
+
+		for _, name := range tt.names {
+			found := false
+			for _, rel := range mrs.val.Releases {
+				if rel.Name == name {
+					found = true
+				}
+			}
+			if !found {
+				t.Errorf("%d: Did not find name %q", i, name)
+			}
+		}
+	}
+}
+
+func TestListReleasesSort(t *testing.T) {
+	rs := rsFixture()
+
+	// Put them in by reverse order so that the mock doesn't "accidentally"
+	// sort.
+	num := 7
+	for i := num; i > 0; i-- {
+		rel := releaseStub()
+		rel.Name = fmt.Sprintf("rel-%d", i)
+		if err := rs.env.Releases.Create(rel); err != nil {
+			t.Fatalf("Could not store mock release: %s", err)
+		}
+	}
+
+	limit := 6
+	mrs := &mockListServer{}
+	req := &services.ListReleasesRequest{
+		Offset: "",
+		Limit:  int64(limit),
+		SortBy: services.ListSort_NAME,
+	}
+	if err := rs.ListReleases(req, mrs); err != nil {
+		t.Fatalf("Failed listing: %s", err)
+	}
+
+	if len(mrs.val.Releases) != limit {
+		t.Errorf("Expected %d releases, got %d", limit, len(mrs.val.Releases))
+	}
+
+	for i := 0; i < limit; i++ {
+		n := fmt.Sprintf("rel-%d", i+1)
+		if mrs.val.Releases[i].Name != n {
+			t.Errorf("Expected %q, got %q", n, mrs.val.Releases[i].Name)
+		}
+	}
+}
+
+func TestListReleasesFilter(t *testing.T) {
+	rs := rsFixture()
+	names := []string{
+		"axon",
+		"dendrite",
+		"neuron",
+		"neuroglia",
+		"synapse",
+		"nucleus",
+		"organelles",
+	}
+	num := 7
+	for i := 0; i < num; i++ {
+		rel := releaseStub()
+		rel.Name = names[i]
+		if err := rs.env.Releases.Create(rel); err != nil {
+			t.Fatalf("Could not store mock release: %s", err)
+		}
+	}
+
+	mrs := &mockListServer{}
+	req := &services.ListReleasesRequest{
+		Offset: "",
+		Limit:  64,
+		Filter: "neuro[a-z]+",
+		SortBy: services.ListSort_NAME,
+	}
+	if err := rs.ListReleases(req, mrs); err != nil {
+		t.Fatalf("Failed listing: %s", err)
+	}
+
+	if len(mrs.val.Releases) != 2 {
+		t.Errorf("Expected 2 releases, got %d", len(mrs.val.Releases))
+	}
+
+	if mrs.val.Releases[0].Name != "neuroglia" {
+		t.Errorf("Unexpected sort order: %v.", mrs.val.Releases)
+	}
+	if mrs.val.Releases[1].Name != "neuron" {
+		t.Errorf("Unexpected sort order: %v.", mrs.val.Releases)
+	}
+}
+
+func TestReleasesNamespace(t *testing.T) {
+	rs := rsFixture()
+
+	names := []string{
+		"axon",
+		"dendrite",
+		"neuron",
+		"ribosome",
+	}
+
+	namespaces := []string{
+		"default",
+		"test123",
+		"test123",
+		"cerebellum",
+	}
+	num := 4
+	for i := 0; i < num; i++ {
+		rel := releaseStub()
+		rel.Name = names[i]
+		rel.Namespace = namespaces[i]
+		if err := rs.env.Releases.Create(rel); err != nil {
+			t.Fatalf("Could not store mock release: %s", err)
+		}
+	}
+
+	mrs := &mockListServer{}
+	req := &services.ListReleasesRequest{
+		Offset:    "",
+		Limit:     64,
+		Namespace: "test123",
+	}
+
+	if err := rs.ListReleases(req, mrs); err != nil {
+		t.Fatalf("Failed listing: %s", err)
+	}
+
+	if len(mrs.val.Releases) != 2 {
+		t.Errorf("Expected 2 releases, got %d", len(mrs.val.Releases))
+	}
+}
diff --git a/pkg/tiller/release_modules.go b/pkg/tiller/release_modules.go
new file mode 100644
index 0000000000000000000000000000000000000000..2f2a3c6ff6ba241c3fb7781c7f684c7d63a129c4
--- /dev/null
+++ b/pkg/tiller/release_modules.go
@@ -0,0 +1,173 @@
+/*
+Copyright 2017 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 tiller
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"log"
+	"strings"
+
+	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
+
+	"k8s.io/helm/pkg/chartutil"
+	"k8s.io/helm/pkg/kube"
+	"k8s.io/helm/pkg/proto/hapi/release"
+	rudderAPI "k8s.io/helm/pkg/proto/hapi/rudder"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	relutil "k8s.io/helm/pkg/releaseutil"
+	"k8s.io/helm/pkg/rudder"
+	"k8s.io/helm/pkg/tiller/environment"
+)
+
+// ReleaseModule is an interface that allows ReleaseServer to run operations on release via either local implementation or Rudder service
+type ReleaseModule interface {
+	Create(r *release.Release, req *services.InstallReleaseRequest, env *environment.Environment) error
+	Update(current, target *release.Release, req *services.UpdateReleaseRequest, env *environment.Environment) error
+	Rollback(current, target *release.Release, req *services.RollbackReleaseRequest, env *environment.Environment) error
+	Status(r *release.Release, req *services.GetReleaseStatusRequest, env *environment.Environment) (string, error)
+	Delete(r *release.Release, req *services.UninstallReleaseRequest, env *environment.Environment) (string, []error)
+}
+
+// LocalReleaseModule is a local implementation of ReleaseModule
+type LocalReleaseModule struct {
+	clientset internalclientset.Interface
+}
+
+// Create creates a release via kubeclient from provided environment
+func (m *LocalReleaseModule) Create(r *release.Release, req *services.InstallReleaseRequest, env *environment.Environment) error {
+	b := bytes.NewBufferString(r.Manifest)
+	return env.KubeClient.Create(r.Namespace, b, req.Timeout, req.Wait)
+}
+
+// Update performs an update from current to target release
+func (m *LocalReleaseModule) Update(current, target *release.Release, req *services.UpdateReleaseRequest, env *environment.Environment) error {
+	c := bytes.NewBufferString(current.Manifest)
+	t := bytes.NewBufferString(target.Manifest)
+	return env.KubeClient.Update(target.Namespace, c, t, req.Force, req.Recreate, req.Timeout, req.Wait)
+}
+
+// Rollback performs a rollback from current to target release
+func (m *LocalReleaseModule) Rollback(current, target *release.Release, req *services.RollbackReleaseRequest, env *environment.Environment) error {
+	c := bytes.NewBufferString(current.Manifest)
+	t := bytes.NewBufferString(target.Manifest)
+	return env.KubeClient.Update(target.Namespace, c, t, req.Force, req.Recreate, req.Timeout, req.Wait)
+}
+
+// Status returns kubectl-like formatted status of release objects
+func (m *LocalReleaseModule) Status(r *release.Release, req *services.GetReleaseStatusRequest, env *environment.Environment) (string, error) {
+	return env.KubeClient.Get(r.Namespace, bytes.NewBufferString(r.Manifest))
+}
+
+// Delete deletes the release and returns manifests that were kept in the deletion process
+func (m *LocalReleaseModule) Delete(rel *release.Release, req *services.UninstallReleaseRequest, env *environment.Environment) (kept string, errs []error) {
+	vs, err := GetVersionSet(m.clientset.Discovery())
+	if err != nil {
+		return rel.Manifest, []error{fmt.Errorf("Could not get apiVersions from Kubernetes: %v", err)}
+	}
+	return DeleteRelease(rel, vs, env.KubeClient)
+}
+
+// RemoteReleaseModule is a ReleaseModule which calls Rudder service to operate on a release
+type RemoteReleaseModule struct{}
+
+// Create calls rudder.InstallRelease
+func (m *RemoteReleaseModule) Create(r *release.Release, req *services.InstallReleaseRequest, env *environment.Environment) error {
+	request := &rudderAPI.InstallReleaseRequest{Release: r}
+	_, err := rudder.InstallRelease(request)
+	return err
+}
+
+// Update calls rudder.UpgradeRelease
+func (m *RemoteReleaseModule) Update(current, target *release.Release, req *services.UpdateReleaseRequest, env *environment.Environment) error {
+	upgrade := &rudderAPI.UpgradeReleaseRequest{
+		Current:  current,
+		Target:   target,
+		Recreate: req.Recreate,
+		Timeout:  req.Timeout,
+		Wait:     req.Wait,
+		Force:    req.Force,
+	}
+	_, err := rudder.UpgradeRelease(upgrade)
+	return err
+}
+
+// Rollback calls rudder.Rollback
+func (m *RemoteReleaseModule) Rollback(current, target *release.Release, req *services.RollbackReleaseRequest, env *environment.Environment) error {
+	rollback := &rudderAPI.RollbackReleaseRequest{
+		Current:  current,
+		Target:   target,
+		Recreate: req.Recreate,
+		Timeout:  req.Timeout,
+		Wait:     req.Wait,
+	}
+	_, err := rudder.RollbackRelease(rollback)
+	return err
+}
+
+// Status returns status retrieved from rudder.ReleaseStatus
+func (m *RemoteReleaseModule) Status(r *release.Release, req *services.GetReleaseStatusRequest, env *environment.Environment) (string, error) {
+	statusRequest := &rudderAPI.ReleaseStatusRequest{Release: r}
+	resp, err := rudder.ReleaseStatus(statusRequest)
+	return resp.Info.Status.Resources, err
+}
+
+// Delete calls rudder.DeleteRelease
+func (m *RemoteReleaseModule) Delete(r *release.Release, req *services.UninstallReleaseRequest, env *environment.Environment) (string, []error) {
+	deleteRequest := &rudderAPI.DeleteReleaseRequest{Release: r}
+	resp, err := rudder.DeleteRelease(deleteRequest)
+	if err != nil {
+		return resp.Release.Manifest, []error{err}
+	}
+	return resp.Release.Manifest, []error{}
+}
+
+// DeleteRelease is a helper that allows Rudder to delete a release without exposing most of Tiller inner functions
+func DeleteRelease(rel *release.Release, vs chartutil.VersionSet, kubeClient environment.KubeClient) (kept string, errs []error) {
+	manifests := relutil.SplitManifests(rel.Manifest)
+	_, files, err := sortManifests(manifests, vs, UninstallOrder)
+	if err != nil {
+		// We could instead just delete everything in no particular order.
+		// FIXME: One way to delete at this point would be to try a label-based
+		// deletion. The problem with this is that we could get a false positive
+		// and delete something that was not legitimately part of this release.
+		return rel.Manifest, []error{fmt.Errorf("corrupted release record. You must manually delete the resources: %s", err)}
+	}
+
+	filesToKeep, filesToDelete := filterManifestsToKeep(files)
+	if len(filesToKeep) > 0 {
+		kept = summarizeKeptManifests(filesToKeep)
+	}
+
+	errs = []error{}
+	for _, file := range filesToDelete {
+		b := bytes.NewBufferString(strings.TrimSpace(file.content))
+		if b.Len() == 0 {
+			continue
+		}
+		if err := kubeClient.Delete(rel.Namespace, b); err != nil {
+			log.Printf("uninstall: Failed deletion of %q: %s", rel.Name, err)
+			if err == kube.ErrNoObjectsVisited {
+				// Rewrite the message from "no objects visited"
+				err = errors.New("object not found, skipping delete")
+			}
+			errs = append(errs, err)
+		}
+	}
+	return kept, errs
+}
diff --git a/pkg/tiller/release_rollback.go b/pkg/tiller/release_rollback.go
new file mode 100644
index 0000000000000000000000000000000000000000..43e06a6b68eb39eaa209aa10debd1db6cf2bcb41
--- /dev/null
+++ b/pkg/tiller/release_rollback.go
@@ -0,0 +1,152 @@
+/*
+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 tiller
+
+import (
+	"fmt"
+
+	ctx "golang.org/x/net/context"
+	"k8s.io/helm/pkg/hooks"
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	"k8s.io/helm/pkg/timeconv"
+)
+
+// RollbackRelease rolls back to a previous version of the given release.
+func (s *ReleaseServer) RollbackRelease(c ctx.Context, req *services.RollbackReleaseRequest) (*services.RollbackReleaseResponse, error) {
+	err := s.env.Releases.LockRelease(req.Name)
+	if err != nil {
+		return nil, err
+	}
+	defer s.env.Releases.UnlockRelease(req.Name)
+
+	s.Log("preparing rollback of %s", req.Name)
+	currentRelease, targetRelease, err := s.prepareRollback(req)
+	if err != nil {
+		return nil, err
+	}
+
+	s.Log("performing rollback of %s", req.Name)
+	res, err := s.performRollback(currentRelease, targetRelease, req)
+	if err != nil {
+		return res, err
+	}
+
+	if !req.DryRun {
+		s.Log("creating rolled back release %s", req.Name)
+		if err := s.env.Releases.Create(targetRelease); err != nil {
+			return res, err
+		}
+	}
+
+	return res, nil
+}
+
+// prepareRollback finds the previous release and prepares a new release object with
+// the previous release's configuration
+func (s *ReleaseServer) prepareRollback(req *services.RollbackReleaseRequest) (*release.Release, *release.Release, error) {
+	switch {
+	case !ValidName.MatchString(req.Name):
+		return nil, nil, errMissingRelease
+	case req.Version < 0:
+		return nil, nil, errInvalidRevision
+	}
+
+	crls, err := s.env.Releases.Last(req.Name)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	rbv := req.Version
+	if req.Version == 0 {
+		rbv = crls.Version - 1
+	}
+
+	s.Log("rolling back %s (current: v%d, target: v%d)", req.Name, crls.Version, rbv)
+
+	prls, err := s.env.Releases.Get(req.Name, rbv)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// Store a new release object with previous release's configuration
+	target := &release.Release{
+		Name:      req.Name,
+		Namespace: crls.Namespace,
+		Chart:     prls.Chart,
+		Config:    prls.Config,
+		Info: &release.Info{
+			FirstDeployed: crls.Info.FirstDeployed,
+			LastDeployed:  timeconv.Now(),
+			Status: &release.Status{
+				Code:  release.Status_UNKNOWN,
+				Notes: prls.Info.Status.Notes,
+			},
+			// Because we lose the reference to rbv elsewhere, we set the
+			// message here, and only override it later if we experience failure.
+			Description: fmt.Sprintf("Rollback to %d", rbv),
+		},
+		Version:  crls.Version + 1,
+		Manifest: prls.Manifest,
+		Hooks:    prls.Hooks,
+	}
+
+	return crls, target, nil
+}
+
+func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.Release, req *services.RollbackReleaseRequest) (*services.RollbackReleaseResponse, error) {
+	res := &services.RollbackReleaseResponse{Release: targetRelease}
+
+	if req.DryRun {
+		s.Log("dry run for %s", targetRelease.Name)
+		return res, nil
+	}
+
+	// pre-rollback hooks
+	if !req.DisableHooks {
+		if err := s.execHook(targetRelease.Hooks, targetRelease.Name, targetRelease.Namespace, hooks.PreRollback, req.Timeout); err != nil {
+			return res, err
+		}
+	} else {
+		s.Log("rollback hooks disabled for %s", req.Name)
+	}
+
+	if err := s.ReleaseModule.Rollback(currentRelease, targetRelease, req, s.env); err != nil {
+		msg := fmt.Sprintf("Rollback %q failed: %s", targetRelease.Name, err)
+		s.Log("warning: %s", msg)
+		currentRelease.Info.Status.Code = release.Status_SUPERSEDED
+		targetRelease.Info.Status.Code = release.Status_FAILED
+		targetRelease.Info.Description = msg
+		s.recordRelease(currentRelease, true)
+		s.recordRelease(targetRelease, false)
+		return res, err
+	}
+
+	// post-rollback hooks
+	if !req.DisableHooks {
+		if err := s.execHook(targetRelease.Hooks, targetRelease.Name, targetRelease.Namespace, hooks.PostRollback, req.Timeout); err != nil {
+			return res, err
+		}
+	}
+
+	currentRelease.Info.Status.Code = release.Status_SUPERSEDED
+	s.recordRelease(currentRelease, true)
+
+	targetRelease.Info.Status.Code = release.Status_DEPLOYED
+
+	return res, nil
+}
diff --git a/pkg/tiller/release_rollback_test.go b/pkg/tiller/release_rollback_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..11ba9d7e2342cf406c5cbe866bb19a44ec63dfbe
--- /dev/null
+++ b/pkg/tiller/release_rollback_test.go
@@ -0,0 +1,226 @@
+/*
+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 tiller
+
+import (
+	"k8s.io/helm/pkg/helm"
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	"strings"
+	"testing"
+)
+
+func TestRollbackRelease(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+	upgradedRel := upgradeReleaseVersion(rel)
+	upgradedRel.Hooks = []*release.Hook{
+		{
+			Name:     "test-cm",
+			Kind:     "ConfigMap",
+			Path:     "test-cm",
+			Manifest: manifestWithRollbackHooks,
+			Events: []release.Hook_Event{
+				release.Hook_PRE_ROLLBACK,
+				release.Hook_POST_ROLLBACK,
+			},
+		},
+	}
+
+	upgradedRel.Manifest = "hello world"
+	rs.env.Releases.Update(rel)
+	rs.env.Releases.Create(upgradedRel)
+
+	req := &services.RollbackReleaseRequest{
+		Name: rel.Name,
+	}
+	res, err := rs.RollbackRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed rollback: %s", err)
+	}
+
+	if res.Release.Name == "" {
+		t.Errorf("Expected release name.")
+	}
+
+	if res.Release.Name != rel.Name {
+		t.Errorf("Updated release name does not match previous release name. Expected %s, got %s", rel.Name, res.Release.Name)
+	}
+
+	if res.Release.Namespace != rel.Namespace {
+		t.Errorf("Expected release namespace '%s', got '%s'.", rel.Namespace, res.Release.Namespace)
+	}
+
+	if res.Release.Version != 3 {
+		t.Errorf("Expected release version to be %v, got %v", 3, res.Release.Version)
+	}
+
+	updated, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
+	if err != nil {
+		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
+	}
+
+	if len(updated.Hooks) != 2 {
+		t.Fatalf("Expected 2 hooks, got %d", len(updated.Hooks))
+	}
+
+	if updated.Hooks[0].Manifest != manifestWithHook {
+		t.Errorf("Unexpected manifest: %v", updated.Hooks[0].Manifest)
+	}
+
+	anotherUpgradedRelease := upgradeReleaseVersion(upgradedRel)
+	rs.env.Releases.Update(upgradedRel)
+	rs.env.Releases.Create(anotherUpgradedRelease)
+
+	res, err = rs.RollbackRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed rollback: %s", err)
+	}
+
+	updated, err = rs.env.Releases.Get(res.Release.Name, res.Release.Version)
+	if err != nil {
+		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
+	}
+
+	if len(updated.Hooks) != 1 {
+		t.Fatalf("Expected 1 hook, got %d", len(updated.Hooks))
+	}
+
+	if updated.Hooks[0].Manifest != manifestWithRollbackHooks {
+		t.Errorf("Unexpected manifest: %v", updated.Hooks[0].Manifest)
+	}
+
+	if res.Release.Version != 4 {
+		t.Errorf("Expected release version to be %v, got %v", 3, res.Release.Version)
+	}
+
+	if updated.Hooks[0].Events[0] != release.Hook_PRE_ROLLBACK {
+		t.Errorf("Expected event 0 to be pre rollback")
+	}
+
+	if updated.Hooks[0].Events[1] != release.Hook_POST_ROLLBACK {
+		t.Errorf("Expected event 1 to be post rollback")
+	}
+
+	if len(res.Release.Manifest) == 0 {
+		t.Errorf("No manifest returned: %v", res.Release)
+	}
+
+	if len(updated.Manifest) == 0 {
+		t.Errorf("Expected manifest in %v", res)
+	}
+
+	if !strings.Contains(updated.Manifest, "hello world") {
+		t.Errorf("unexpected output: %s", rel.Manifest)
+	}
+
+	if res.Release.Info.Description != "Rollback to 2" {
+		t.Errorf("Expected rollback to 2, got %q", res.Release.Info.Description)
+	}
+}
+
+func TestRollbackWithReleaseVersion(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+	upgradedRel := upgradeReleaseVersion(rel)
+	rs.env.Releases.Update(rel)
+	rs.env.Releases.Create(upgradedRel)
+
+	req := &services.RollbackReleaseRequest{
+		Name:         rel.Name,
+		DisableHooks: true,
+		Version:      1,
+	}
+
+	_, err := rs.RollbackRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed rollback: %s", err)
+	}
+}
+
+func TestRollbackReleaseNoHooks(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rel.Hooks = []*release.Hook{
+		{
+			Name:     "test-cm",
+			Kind:     "ConfigMap",
+			Path:     "test-cm",
+			Manifest: manifestWithRollbackHooks,
+			Events: []release.Hook_Event{
+				release.Hook_PRE_ROLLBACK,
+				release.Hook_POST_ROLLBACK,
+			},
+		},
+	}
+	rs.env.Releases.Create(rel)
+	upgradedRel := upgradeReleaseVersion(rel)
+	rs.env.Releases.Update(rel)
+	rs.env.Releases.Create(upgradedRel)
+
+	req := &services.RollbackReleaseRequest{
+		Name:         rel.Name,
+		DisableHooks: true,
+	}
+
+	res, err := rs.RollbackRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed rollback: %s", err)
+	}
+
+	if hl := res.Release.Hooks[0].LastRun; hl != nil {
+		t.Errorf("Expected that no hooks were run. Got %d", hl)
+	}
+}
+
+func TestRollbackReleaseFailure(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+	upgradedRel := upgradeReleaseVersion(rel)
+	rs.env.Releases.Update(rel)
+	rs.env.Releases.Create(upgradedRel)
+
+	req := &services.RollbackReleaseRequest{
+		Name:         rel.Name,
+		DisableHooks: true,
+	}
+
+	rs.env.KubeClient = newUpdateFailingKubeClient()
+	res, err := rs.RollbackRelease(c, req)
+	if err == nil {
+		t.Error("Expected failed rollback")
+	}
+
+	if targetStatus := res.Release.Info.Status.Code; targetStatus != release.Status_FAILED {
+		t.Errorf("Expected FAILED release. Got %v", targetStatus)
+	}
+
+	oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version)
+	if err != nil {
+		t.Errorf("Expected to be able to get previous release")
+	}
+	if oldStatus := oldRelease.Info.Status.Code; oldStatus != release.Status_SUPERSEDED {
+		t.Errorf("Expected SUPERSEDED status on previous Release version. Got %v", oldStatus)
+	}
+}
diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go
index 5bd0a48de74f4adce46be49b228741f1d9af3dd5..07ea872df91f3b66060ceb5d8a463144e78b4f93 100644
--- a/pkg/tiller/release_server.go
+++ b/pkg/tiller/release_server.go
@@ -20,24 +20,19 @@ import (
 	"bytes"
 	"errors"
 	"fmt"
-	"log"
 	"path"
 	"regexp"
 	"strings"
 
 	"github.com/technosophos/moniker"
-	ctx "golang.org/x/net/context"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/discovery"
 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
 
 	"k8s.io/helm/pkg/chartutil"
-	"k8s.io/helm/pkg/hooks"
-	"k8s.io/helm/pkg/kube"
 	"k8s.io/helm/pkg/proto/hapi/chart"
 	"k8s.io/helm/pkg/proto/hapi/release"
 	"k8s.io/helm/pkg/proto/hapi/services"
-	reltesting "k8s.io/helm/pkg/releasetesting"
 	relutil "k8s.io/helm/pkg/releaseutil"
 	"k8s.io/helm/pkg/tiller/environment"
 	"k8s.io/helm/pkg/timeconv"
@@ -82,267 +77,29 @@ var ValidName = regexp.MustCompile("^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])+
 
 // ReleaseServer implements the server-side gRPC endpoint for the HAPI services.
 type ReleaseServer struct {
+	ReleaseModule
 	env       *environment.Environment
 	clientset internalclientset.Interface
+	Log       func(string, ...interface{})
 }
 
 // NewReleaseServer creates a new release server.
-func NewReleaseServer(env *environment.Environment, clientset internalclientset.Interface) *ReleaseServer {
-	return &ReleaseServer{
-		env:       env,
-		clientset: clientset,
-	}
-}
-
-// ListReleases lists the releases found by the server.
-func (s *ReleaseServer) ListReleases(req *services.ListReleasesRequest, stream services.ReleaseService_ListReleasesServer) error {
-	if len(req.StatusCodes) == 0 {
-		req.StatusCodes = []release.Status_Code{release.Status_DEPLOYED}
-	}
-
-	//rels, err := s.env.Releases.ListDeployed()
-	rels, err := s.env.Releases.ListFilterAll(func(r *release.Release) bool {
-		for _, sc := range req.StatusCodes {
-			if sc == r.Info.Status.Code {
-				return true
-			}
-		}
-		return false
-	})
-	if err != nil {
-		return err
-	}
-
-	if req.Namespace != "" {
-		rels, err = filterByNamespace(req.Namespace, rels)
-		if err != nil {
-			return err
-		}
-	}
-
-	if len(req.Filter) != 0 {
-		rels, err = filterReleases(req.Filter, rels)
-		if err != nil {
-			return err
-		}
-	}
-
-	total := int64(len(rels))
-
-	switch req.SortBy {
-	case services.ListSort_NAME:
-		relutil.SortByName(rels)
-	case services.ListSort_LAST_RELEASED:
-		relutil.SortByDate(rels)
-	}
-
-	if req.SortOrder == services.ListSort_DESC {
-		ll := len(rels)
-		rr := make([]*release.Release, ll)
-		for i, item := range rels {
-			rr[ll-i-1] = item
-		}
-		rels = rr
-	}
-
-	l := int64(len(rels))
-	if req.Offset != "" {
-
-		i := -1
-		for ii, cur := range rels {
-			if cur.Name == req.Offset {
-				i = ii
-			}
-		}
-		if i == -1 {
-			return fmt.Errorf("offset %q not found", req.Offset)
-		}
-
-		if len(rels) < i {
-			return fmt.Errorf("no items after %q", req.Offset)
-		}
-
-		rels = rels[i:]
-		l = int64(len(rels))
-	}
-
-	if req.Limit == 0 {
-		req.Limit = ListDefaultLimit
-	}
-
-	next := ""
-	if l > req.Limit {
-		next = rels[req.Limit].Name
-		rels = rels[0:req.Limit]
-		l = int64(len(rels))
-	}
-
-	res := &services.ListReleasesResponse{
-		Next:     next,
-		Count:    l,
-		Total:    total,
-		Releases: rels,
-	}
-	return stream.Send(res)
-}
-
-func filterByNamespace(namespace string, rels []*release.Release) ([]*release.Release, error) {
-	matches := []*release.Release{}
-	for _, r := range rels {
-		if namespace == r.Namespace {
-			matches = append(matches, r)
-		}
-	}
-	return matches, nil
-}
-
-func filterReleases(filter string, rels []*release.Release) ([]*release.Release, error) {
-	preg, err := regexp.Compile(filter)
-	if err != nil {
-		return rels, err
-	}
-	matches := []*release.Release{}
-	for _, r := range rels {
-		if preg.MatchString(r.Name) {
-			matches = append(matches, r)
-		}
-	}
-	return matches, nil
-}
-
-// GetVersion sends the server version.
-func (s *ReleaseServer) GetVersion(c ctx.Context, req *services.GetVersionRequest) (*services.GetVersionResponse, error) {
-	v := version.GetVersionProto()
-	return &services.GetVersionResponse{Version: v}, nil
-}
-
-// GetReleaseStatus gets the status information for a named release.
-func (s *ReleaseServer) GetReleaseStatus(c ctx.Context, req *services.GetReleaseStatusRequest) (*services.GetReleaseStatusResponse, error) {
-	if !ValidName.MatchString(req.Name) {
-		return nil, errMissingRelease
-	}
-
-	var rel *release.Release
-
-	if req.Version <= 0 {
-		var err error
-		rel, err = s.env.Releases.Last(req.Name)
-		if err != nil {
-			return nil, fmt.Errorf("getting deployed release %q: %s", req.Name, err)
-		}
+func NewReleaseServer(env *environment.Environment, clientset internalclientset.Interface, useRemote bool) *ReleaseServer {
+	var releaseModule ReleaseModule
+	if useRemote {
+		releaseModule = &RemoteReleaseModule{}
 	} else {
-		var err error
-		if rel, err = s.env.Releases.Get(req.Name, req.Version); err != nil {
-			return nil, fmt.Errorf("getting release '%s' (v%d): %s", req.Name, req.Version, err)
-		}
-	}
-
-	if rel.Info == nil {
-		return nil, errors.New("release info is missing")
-	}
-	if rel.Chart == nil {
-		return nil, errors.New("release chart is missing")
-	}
-
-	sc := rel.Info.Status.Code
-	statusResp := &services.GetReleaseStatusResponse{
-		Name:      rel.Name,
-		Namespace: rel.Namespace,
-		Info:      rel.Info,
-	}
-
-	// Ok, we got the status of the release as we had jotted down, now we need to match the
-	// manifest we stashed away with reality from the cluster.
-	kubeCli := s.env.KubeClient
-	resp, err := kubeCli.Get(rel.Namespace, bytes.NewBufferString(rel.Manifest))
-	if sc == release.Status_DELETED || sc == release.Status_FAILED {
-		// Skip errors if this is already deleted or failed.
-		return statusResp, nil
-	} else if err != nil {
-		log.Printf("warning: Get for %s failed: %v", rel.Name, err)
-		return nil, err
-	}
-	rel.Info.Status.Resources = resp
-	return statusResp, nil
-}
-
-// GetReleaseContent gets all of the stored information for the given release.
-func (s *ReleaseServer) GetReleaseContent(c ctx.Context, req *services.GetReleaseContentRequest) (*services.GetReleaseContentResponse, error) {
-	if !ValidName.MatchString(req.Name) {
-		return nil, errMissingRelease
-	}
-
-	if req.Version <= 0 {
-		rel, err := s.env.Releases.Deployed(req.Name)
-		return &services.GetReleaseContentResponse{Release: rel}, err
-	}
-
-	rel, err := s.env.Releases.Get(req.Name, req.Version)
-	return &services.GetReleaseContentResponse{Release: rel}, err
-}
-
-// UpdateRelease takes an existing release and new information, and upgrades the release.
-func (s *ReleaseServer) UpdateRelease(c ctx.Context, req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) {
-	currentRelease, updatedRelease, err := s.prepareUpdate(req)
-	if err != nil {
-		return nil, err
-	}
-
-	res, err := s.performUpdate(currentRelease, updatedRelease, req)
-	if err != nil {
-		return res, err
-	}
-
-	if !req.DryRun {
-		if err := s.env.Releases.Create(updatedRelease); err != nil {
-			return res, err
-		}
-	}
-
-	return res, nil
-}
-
-func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.Release, req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) {
-	res := &services.UpdateReleaseResponse{Release: updatedRelease}
-
-	if req.DryRun {
-		log.Printf("Dry run for %s", updatedRelease.Name)
-		res.Release.Info.Description = "Dry run complete"
-		return res, nil
-	}
-
-	// pre-upgrade hooks
-	if !req.DisableHooks {
-		if err := s.execHook(updatedRelease.Hooks, updatedRelease.Name, updatedRelease.Namespace, hooks.PreUpgrade, req.Timeout); err != nil {
-			return res, err
+		releaseModule = &LocalReleaseModule{
+			clientset: clientset,
 		}
 	}
 
-	if err := s.performKubeUpdate(originalRelease, updatedRelease, req.Recreate, req.Timeout, req.Wait); err != nil {
-		msg := fmt.Sprintf("Upgrade %q failed: %s", updatedRelease.Name, err)
-		log.Printf("warning: %s", msg)
-		originalRelease.Info.Status.Code = release.Status_SUPERSEDED
-		updatedRelease.Info.Status.Code = release.Status_FAILED
-		updatedRelease.Info.Description = msg
-		s.recordRelease(originalRelease, true)
-		s.recordRelease(updatedRelease, false)
-		return res, err
-	}
-
-	// post-upgrade hooks
-	if !req.DisableHooks {
-		if err := s.execHook(updatedRelease.Hooks, updatedRelease.Name, updatedRelease.Namespace, hooks.PostUpgrade, req.Timeout); err != nil {
-			return res, err
-		}
+	return &ReleaseServer{
+		env:           env,
+		clientset:     clientset,
+		ReleaseModule: releaseModule,
+		Log:           func(_ string, _ ...interface{}) {},
 	}
-
-	originalRelease.Info.Status.Code = release.Status_SUPERSEDED
-	s.recordRelease(originalRelease, true)
-
-	updatedRelease.Info.Status.Code = release.Status_DEPLOYED
-	updatedRelease.Info.Description = "Upgrade complete"
-
-	return res, nil
 }
 
 // reuseValues copies values from the current release to a new release if the
@@ -356,19 +113,19 @@ func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.R
 func (s *ReleaseServer) reuseValues(req *services.UpdateReleaseRequest, current *release.Release) error {
 	if req.ResetValues {
 		// If ResetValues is set, we comletely ignore current.Config.
-		log.Print("Reset values to the chart's original version.")
+		s.Log("resetting values to the chart's original version")
 		return nil
 	}
 
 	// If the ReuseValues flag is set, we always copy the old values over the new config's values.
 	if req.ReuseValues {
-		log.Print("Reusing the old release's values")
+		s.Log("reusing the old release's values")
 
 		// We have to regenerate the old coalesced values:
 		oldVals, err := chartutil.CoalesceValues(current.Chart, current.Config)
 		if err != nil {
 			err := fmt.Errorf("failed to rebuild old values: %s", err)
-			log.Print(err)
+			s.Log("%s", err)
 			return err
 		}
 		nv, err := oldVals.YAML()
@@ -385,205 +142,12 @@ func (s *ReleaseServer) reuseValues(req *services.UpdateReleaseRequest, current
 		current.Config != nil &&
 		current.Config.Raw != "" &&
 		current.Config.Raw != "{}\n" {
-		log.Printf("Copying values from %s (v%d) to new release.", current.Name, current.Version)
+		s.Log("copying values from %s (v%d) to new release.", current.Name, current.Version)
 		req.Values = current.Config
 	}
 	return nil
 }
 
-// prepareUpdate builds an updated release for an update operation.
-func (s *ReleaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*release.Release, *release.Release, error) {
-	if !ValidName.MatchString(req.Name) {
-		return nil, nil, errMissingRelease
-	}
-
-	if req.Chart == nil {
-		return nil, nil, errMissingChart
-	}
-
-	// finds the non-deleted release with the given name
-	currentRelease, err := s.env.Releases.Last(req.Name)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// If new values were not supplied in the upgrade, re-use the existing values.
-	if err := s.reuseValues(req, currentRelease); err != nil {
-		return nil, nil, err
-	}
-
-	// Increment revision count. This is passed to templates, and also stored on
-	// the release object.
-	revision := currentRelease.Version + 1
-
-	ts := timeconv.Now()
-	options := chartutil.ReleaseOptions{
-		Name:      req.Name,
-		Time:      ts,
-		Namespace: currentRelease.Namespace,
-		IsUpgrade: true,
-		Revision:  int(revision),
-	}
-
-	caps, err := capabilities(s.clientset.Discovery())
-	if err != nil {
-		return nil, nil, err
-	}
-	valuesToRender, err := chartutil.ToRenderValuesCaps(req.Chart, req.Values, options, caps)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	hooks, manifestDoc, notesTxt, err := s.renderResources(req.Chart, valuesToRender, caps.APIVersions)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// Store an updated release.
-	updatedRelease := &release.Release{
-		Name:      req.Name,
-		Namespace: currentRelease.Namespace,
-		Chart:     req.Chart,
-		Config:    req.Values,
-		Info: &release.Info{
-			FirstDeployed: currentRelease.Info.FirstDeployed,
-			LastDeployed:  ts,
-			Status:        &release.Status{Code: release.Status_UNKNOWN},
-			Description:   "Preparing upgrade", // This should be overwritten later.
-		},
-		Version:  revision,
-		Manifest: manifestDoc.String(),
-		Hooks:    hooks,
-	}
-
-	if len(notesTxt) > 0 {
-		updatedRelease.Info.Status.Notes = notesTxt
-	}
-	err = validateManifest(s.env.KubeClient, currentRelease.Namespace, manifestDoc.Bytes())
-	return currentRelease, updatedRelease, err
-}
-
-// RollbackRelease rolls back to a previous version of the given release.
-func (s *ReleaseServer) RollbackRelease(c ctx.Context, req *services.RollbackReleaseRequest) (*services.RollbackReleaseResponse, error) {
-	currentRelease, targetRelease, err := s.prepareRollback(req)
-	if err != nil {
-		return nil, err
-	}
-
-	res, err := s.performRollback(currentRelease, targetRelease, req)
-	if err != nil {
-		return res, err
-	}
-
-	if !req.DryRun {
-		if err := s.env.Releases.Create(targetRelease); err != nil {
-			return res, err
-		}
-	}
-
-	return res, nil
-}
-
-func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.Release, req *services.RollbackReleaseRequest) (*services.RollbackReleaseResponse, error) {
-	res := &services.RollbackReleaseResponse{Release: targetRelease}
-
-	if req.DryRun {
-		log.Printf("Dry run for %s", targetRelease.Name)
-		return res, nil
-	}
-
-	// pre-rollback hooks
-	if !req.DisableHooks {
-		if err := s.execHook(targetRelease.Hooks, targetRelease.Name, targetRelease.Namespace, hooks.PreRollback, req.Timeout); err != nil {
-			return res, err
-		}
-	}
-
-	if err := s.performKubeUpdate(currentRelease, targetRelease, req.Recreate, req.Timeout, req.Wait); err != nil {
-		msg := fmt.Sprintf("Rollback %q failed: %s", targetRelease.Name, err)
-		log.Printf("warning: %s", msg)
-		currentRelease.Info.Status.Code = release.Status_SUPERSEDED
-		targetRelease.Info.Status.Code = release.Status_FAILED
-		targetRelease.Info.Description = msg
-		s.recordRelease(currentRelease, true)
-		s.recordRelease(targetRelease, false)
-		return res, err
-	}
-
-	// post-rollback hooks
-	if !req.DisableHooks {
-		if err := s.execHook(targetRelease.Hooks, targetRelease.Name, targetRelease.Namespace, hooks.PostRollback, req.Timeout); err != nil {
-			return res, err
-		}
-	}
-
-	currentRelease.Info.Status.Code = release.Status_SUPERSEDED
-	s.recordRelease(currentRelease, true)
-
-	targetRelease.Info.Status.Code = release.Status_DEPLOYED
-
-	return res, nil
-}
-
-func (s *ReleaseServer) performKubeUpdate(currentRelease, targetRelease *release.Release, recreate bool, timeout int64, shouldWait bool) error {
-	kubeCli := s.env.KubeClient
-	current := bytes.NewBufferString(currentRelease.Manifest)
-	target := bytes.NewBufferString(targetRelease.Manifest)
-	return kubeCli.Update(targetRelease.Namespace, current, target, recreate, timeout, shouldWait)
-}
-
-// prepareRollback finds the previous release and prepares a new release object with
-//  the previous release's configuration
-func (s *ReleaseServer) prepareRollback(req *services.RollbackReleaseRequest) (*release.Release, *release.Release, error) {
-	switch {
-	case !ValidName.MatchString(req.Name):
-		return nil, nil, errMissingRelease
-	case req.Version < 0:
-		return nil, nil, errInvalidRevision
-	}
-
-	crls, err := s.env.Releases.Last(req.Name)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	rbv := req.Version
-	if req.Version == 0 {
-		rbv = crls.Version - 1
-	}
-
-	log.Printf("rolling back %s (current: v%d, target: v%d)", req.Name, crls.Version, rbv)
-
-	prls, err := s.env.Releases.Get(req.Name, rbv)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// Store a new release object with previous release's configuration
-	target := &release.Release{
-		Name:      req.Name,
-		Namespace: crls.Namespace,
-		Chart:     prls.Chart,
-		Config:    prls.Config,
-		Info: &release.Info{
-			FirstDeployed: crls.Info.FirstDeployed,
-			LastDeployed:  timeconv.Now(),
-			Status: &release.Status{
-				Code:  release.Status_UNKNOWN,
-				Notes: prls.Info.Status.Notes,
-			},
-			// Because we lose the reference to rbv elsewhere, we set the
-			// message here, and only override it later if we experience failure.
-			Description: fmt.Sprintf("Rollback to %d", rbv),
-		},
-		Version:  crls.Version + 1,
-		Manifest: prls.Manifest,
-		Hooks:    prls.Hooks,
-	}
-
-	return crls, target, nil
-}
-
 func (s *ReleaseServer) uniqName(start string, reuse bool) (string, error) {
 
 	// If a name is supplied, we check to see if that name is taken. If not, it
@@ -604,13 +168,13 @@ func (s *ReleaseServer) uniqName(start string, reuse bool) (string, error) {
 
 		if st := rel.Info.Status.Code; reuse && (st == release.Status_DELETED || st == release.Status_FAILED) {
 			// Allowe re-use of names if the previous release is marked deleted.
-			log.Printf("reusing name %q", start)
+			s.Log("name %s exists but is not in use, reusing name", start)
 			return start, nil
 		} else if reuse {
 			return "", errors.New("cannot re-use a name that is still in use")
 		}
 
-		return "", fmt.Errorf("a release named %q already exists.\nPlease run: helm ls --all %q; helm del --help", start, start)
+		return "", fmt.Errorf("a release named %s already exists.\nRun: helm ls --all %s; to check the status of the release\nOr run: helm del --purge %s; to delete it", start, start, start)
 	}
 
 	maxTries := 5
@@ -623,9 +187,9 @@ func (s *ReleaseServer) uniqName(start string, reuse bool) (string, error) {
 		if _, err := s.env.Releases.Get(name, 1); strings.Contains(err.Error(), "not found") {
 			return name, nil
 		}
-		log.Printf("info: Name %q is taken. Searching again.", name)
+		s.Log("info: generated name %s is taken. Searching again.", name)
 	}
-	log.Printf("warning: No available release names found after %d tries", maxTries)
+	s.Log("warning: No available release names found after %d tries", maxTries)
 	return "ERROR", errors.New("no available release name found")
 }
 
@@ -635,41 +199,19 @@ func (s *ReleaseServer) engine(ch *chart.Chart) environment.Engine {
 		if r, ok := s.env.EngineYard.Get(ch.Metadata.Engine); ok {
 			renderer = r
 		} else {
-			log.Printf("warning: %s requested non-existent template engine %s", ch.Metadata.Name, ch.Metadata.Engine)
+			s.Log("warning: %s requested non-existent template engine %s", ch.Metadata.Name, ch.Metadata.Engine)
 		}
 	}
 	return renderer
 }
 
-// InstallRelease installs a release and stores the release record.
-func (s *ReleaseServer) InstallRelease(c ctx.Context, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
-	rel, err := s.prepareRelease(req)
-	if err != nil {
-		log.Printf("Failed install prepare step: %s", err)
-		res := &services.InstallReleaseResponse{Release: rel}
-
-		// On dry run, append the manifest contents to a failed release. This is
-		// a stop-gap until we can revisit an error backchannel post-2.0.
-		if req.DryRun && strings.HasPrefix(err.Error(), "YAML parse error") {
-			err = fmt.Errorf("%s\n%s", err, rel.Manifest)
-		}
-		return res, err
-	}
-
-	res, err := s.performRelease(rel, req)
-	if err != nil {
-		log.Printf("Failed install perform step: %s", err)
-	}
-	return res, err
-}
-
 // capabilities builds a Capabilities from discovery information.
 func capabilities(disc discovery.DiscoveryInterface) (*chartutil.Capabilities, error) {
 	sv, err := disc.ServerVersion()
 	if err != nil {
 		return nil, err
 	}
-	vs, err := getVersionSet(disc)
+	vs, err := GetVersionSet(disc)
 	if err != nil {
 		return nil, fmt.Errorf("Could not get apiVersions from Kubernetes: %s", err)
 	}
@@ -680,84 +222,8 @@ func capabilities(disc discovery.DiscoveryInterface) (*chartutil.Capabilities, e
 	}, nil
 }
 
-// prepareRelease builds a release for an install operation.
-func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*release.Release, error) {
-	if req.Chart == nil {
-		return nil, errMissingChart
-	}
-
-	name, err := s.uniqName(req.Name, req.ReuseName)
-	if err != nil {
-		return nil, err
-	}
-
-	caps, err := capabilities(s.clientset.Discovery())
-	if err != nil {
-		return nil, err
-	}
-
-	revision := 1
-	ts := timeconv.Now()
-	options := chartutil.ReleaseOptions{
-		Name:      name,
-		Time:      ts,
-		Namespace: req.Namespace,
-		Revision:  revision,
-		IsInstall: true,
-	}
-	valuesToRender, err := chartutil.ToRenderValuesCaps(req.Chart, req.Values, options, caps)
-	if err != nil {
-		return nil, err
-	}
-
-	hooks, manifestDoc, notesTxt, err := s.renderResources(req.Chart, valuesToRender, caps.APIVersions)
-	if err != nil {
-		// Return a release with partial data so that client can show debugging
-		// information.
-		rel := &release.Release{
-			Name:      name,
-			Namespace: req.Namespace,
-			Chart:     req.Chart,
-			Config:    req.Values,
-			Info: &release.Info{
-				FirstDeployed: ts,
-				LastDeployed:  ts,
-				Status:        &release.Status{Code: release.Status_UNKNOWN},
-				Description:   fmt.Sprintf("Install failed: %s", err),
-			},
-			Version: 0,
-		}
-		if manifestDoc != nil {
-			rel.Manifest = manifestDoc.String()
-		}
-		return rel, err
-	}
-
-	// Store a release.
-	rel := &release.Release{
-		Name:      name,
-		Namespace: req.Namespace,
-		Chart:     req.Chart,
-		Config:    req.Values,
-		Info: &release.Info{
-			FirstDeployed: ts,
-			LastDeployed:  ts,
-			Status:        &release.Status{Code: release.Status_UNKNOWN},
-			Description:   "Initial install underway", // Will be overwritten.
-		},
-		Manifest: manifestDoc.String(),
-		Hooks:    hooks,
-		Version:  int32(revision),
-	}
-	if len(notesTxt) > 0 {
-		rel.Info.Status.Notes = notesTxt
-	}
-
-	err = validateManifest(s.env.KubeClient, req.Namespace, manifestDoc.Bytes())
-	return rel, err
-}
-
-func getVersionSet(client discovery.ServerGroupsInterface) (chartutil.VersionSet, error) {
+// GetVersionSet retrieves a set of available k8s API versions
+func GetVersionSet(client discovery.ServerGroupsInterface) (chartutil.VersionSet, error) {
 	groups, err := client.ServerGroups()
 	if err != nil {
 		return chartutil.DefaultVersionSet, err
@@ -783,6 +249,7 @@ func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values
 		return nil, nil, "", fmt.Errorf("Chart incompatible with Tiller %s", sver)
 	}
 
+	s.Log("rendering %s chart using values", ch.GetMetadata().Name)
 	renderer := s.engine(ch)
 	files, err := renderer.Render(ch, values)
 	if err != nil {
@@ -840,106 +307,21 @@ func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values
 func (s *ReleaseServer) recordRelease(r *release.Release, reuse bool) {
 	if reuse {
 		if err := s.env.Releases.Update(r); err != nil {
-			log.Printf("warning: Failed to update release %q: %s", r.Name, err)
+			s.Log("warning: Failed to update release %s: %s", r.Name, err)
 		}
 	} else if err := s.env.Releases.Create(r); err != nil {
-		log.Printf("warning: Failed to record release %q: %s", r.Name, err)
+		s.Log("warning: Failed to record release %s: %s", r.Name, err)
 	}
 }
 
-// performRelease runs a release.
-func (s *ReleaseServer) performRelease(r *release.Release, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
-	res := &services.InstallReleaseResponse{Release: r}
-
-	if req.DryRun {
-		log.Printf("Dry run for %s", r.Name)
-		res.Release.Info.Description = "Dry run complete"
-		return res, nil
-	}
-
-	// pre-install hooks
-	if !req.DisableHooks {
-		if err := s.execHook(r.Hooks, r.Name, r.Namespace, hooks.PreInstall, req.Timeout); err != nil {
-			return res, err
-		}
-	}
-
-	switch h, err := s.env.Releases.History(req.Name); {
-	// if this is a replace operation, append to the release history
-	case req.ReuseName && err == nil && len(h) >= 1:
-		// get latest release revision
-		relutil.Reverse(h, relutil.SortByRevision)
-
-		// old release
-		old := h[0]
-
-		// update old release status
-		old.Info.Status.Code = release.Status_SUPERSEDED
-		s.recordRelease(old, true)
-
-		// update new release with next revision number
-		// so as to append to the old release's history
-		r.Version = old.Version + 1
-
-		if err := s.performKubeUpdate(old, r, false, req.Timeout, req.Wait); err != nil {
-			msg := fmt.Sprintf("Release replace %q failed: %s", r.Name, err)
-			log.Printf("warning: %s", msg)
-			old.Info.Status.Code = release.Status_SUPERSEDED
-			r.Info.Status.Code = release.Status_FAILED
-			r.Info.Description = msg
-			s.recordRelease(old, true)
-			s.recordRelease(r, false)
-			return res, err
-		}
-
-	default:
-		// nothing to replace, create as normal
-		// regular manifests
-		b := bytes.NewBufferString(r.Manifest)
-		if err := s.env.KubeClient.Create(r.Namespace, b, req.Timeout, req.Wait); err != nil {
-			msg := fmt.Sprintf("Release %q failed: %s", r.Name, err)
-			log.Printf("warning: %s", msg)
-			r.Info.Status.Code = release.Status_FAILED
-			r.Info.Description = msg
-			s.recordRelease(r, false)
-			return res, fmt.Errorf("release %s failed: %s", r.Name, err)
-		}
-	}
-
-	// post-install hooks
-	if !req.DisableHooks {
-		if err := s.execHook(r.Hooks, r.Name, r.Namespace, hooks.PostInstall, req.Timeout); err != nil {
-			msg := fmt.Sprintf("Release %q failed post-install: %s", r.Name, err)
-			log.Printf("warning: %s", msg)
-			r.Info.Status.Code = release.Status_FAILED
-			r.Info.Description = msg
-			s.recordRelease(r, false)
-			return res, err
-		}
-	}
-
-	r.Info.Status.Code = release.Status_DEPLOYED
-	r.Info.Description = "Install complete"
-	// 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.
-	s.recordRelease(r, false)
-
-	return res, nil
-}
-
 func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook string, timeout int64) error {
 	kubeCli := s.env.KubeClient
 	code, ok := events[hook]
 	if !ok {
-		return fmt.Errorf("unknown hook %q", hook)
+		return fmt.Errorf("unknown hook %s", hook)
 	}
 
-	log.Printf("Executing %s hooks for %s", hook, name)
+	s.Log("executing %d %s hooks for %s", len(hs), hook, name)
 	executingHooks := []*release.Hook{}
 	for _, h := range hs {
 		for _, e := range h.Events {
@@ -955,196 +337,25 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin
 
 		b := bytes.NewBufferString(h.Manifest)
 		if err := kubeCli.Create(namespace, b, timeout, false); err != nil {
-			log.Printf("warning: Release %q %s %s failed: %s", name, hook, h.Path, err)
+			s.Log("warning: Release %s %s %s failed: %s", name, hook, h.Path, err)
 			return err
 		}
 		// No way to rewind a bytes.Buffer()?
 		b.Reset()
 		b.WriteString(h.Manifest)
 		if err := kubeCli.WatchUntilReady(namespace, b, timeout, false); err != nil {
-			log.Printf("warning: Release %q %s %s could not complete: %s", name, hook, h.Path, err)
+			s.Log("warning: Release %s %s %s could not complete: %s", name, hook, h.Path, err)
 			return err
 		}
 		h.LastRun = timeconv.Now()
 	}
 
-	log.Printf("Hooks complete for %s %s", hook, name)
-	return nil
-}
-
-func (s *ReleaseServer) purgeReleases(rels ...*release.Release) error {
-	for _, rel := range rels {
-		if _, err := s.env.Releases.Delete(rel.Name, rel.Version); err != nil {
-			return err
-		}
-	}
+	s.Log("hooks complete for %s %s", hook, name)
 	return nil
 }
 
-// UninstallRelease deletes all of the resources associated with this release, and marks the release DELETED.
-func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallReleaseRequest) (*services.UninstallReleaseResponse, error) {
-	if !ValidName.MatchString(req.Name) {
-		log.Printf("uninstall: Release not found: %s", req.Name)
-		return nil, errMissingRelease
-	}
-
-	if len(req.Name) > releaseNameMaxLen {
-		return nil, fmt.Errorf("release name %q exceeds max length of %d", req.Name, releaseNameMaxLen)
-	}
-
-	rels, err := s.env.Releases.History(req.Name)
-	if err != nil {
-		log.Printf("uninstall: Release not loaded: %s", req.Name)
-		return nil, err
-	}
-	if len(rels) < 1 {
-		return nil, errMissingRelease
-	}
-
-	relutil.SortByRevision(rels)
-	rel := rels[len(rels)-1]
-
-	// TODO: Are there any cases where we want to force a delete even if it's
-	// already marked deleted?
-	if rel.Info.Status.Code == release.Status_DELETED {
-		if req.Purge {
-			if err := s.purgeReleases(rels...); err != nil {
-				log.Printf("uninstall: Failed to purge the release: %s", err)
-				return nil, err
-			}
-			return &services.UninstallReleaseResponse{Release: rel}, nil
-		}
-		return nil, fmt.Errorf("the release named %q is already deleted", req.Name)
-	}
-
-	log.Printf("uninstall: Deleting %s", req.Name)
-	rel.Info.Status.Code = release.Status_DELETING
-	rel.Info.Deleted = timeconv.Now()
-	rel.Info.Description = "Deletion in progress (or silently failed)"
-	res := &services.UninstallReleaseResponse{Release: rel}
-
-	if !req.DisableHooks {
-		if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, hooks.PreDelete, req.Timeout); err != nil {
-			return res, err
-		}
-	}
-
-	vs, err := getVersionSet(s.clientset.Discovery())
-	if err != nil {
-		return nil, fmt.Errorf("Could not get apiVersions from Kubernetes: %s", err)
-	}
-
-	// From here on out, the release is currently considered to be in Status_DELETING
-	// state.
-	if err := s.env.Releases.Update(rel); err != nil {
-		log.Printf("uninstall: Failed to store updated release: %s", err)
-	}
-
-	manifests := relutil.SplitManifests(rel.Manifest)
-	_, files, err := sortManifests(manifests, vs, UninstallOrder)
-	if err != nil {
-		// We could instead just delete everything in no particular order.
-		// FIXME: One way to delete at this point would be to try a label-based
-		// deletion. The problem with this is that we could get a false positive
-		// and delete something that was not legitimately part of this release.
-		return nil, fmt.Errorf("corrupted release record. You must manually delete the resources: %s", err)
-	}
-
-	filesToKeep, filesToDelete := filterManifestsToKeep(files)
-	if len(filesToKeep) > 0 {
-		res.Info = summarizeKeptManifests(filesToKeep)
-	}
-
-	// Collect the errors, and return them later.
-	es := []string{}
-	for _, file := range filesToDelete {
-		b := bytes.NewBufferString(strings.TrimSpace(file.content))
-		if b.Len() == 0 {
-			continue
-		}
-		if err := s.env.KubeClient.Delete(rel.Namespace, b); err != nil {
-			log.Printf("uninstall: Failed deletion of %q: %s", req.Name, err)
-			if err == kube.ErrNoObjectsVisited {
-				// Rewrite the message from "no objects visited"
-				err = errors.New("object not found, skipping delete")
-			}
-			es = append(es, err.Error())
-		}
-	}
-
-	if !req.DisableHooks {
-		if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, hooks.PostDelete, req.Timeout); err != nil {
-			es = append(es, err.Error())
-		}
-	}
-
-	rel.Info.Status.Code = release.Status_DELETED
-	rel.Info.Description = "Deletion complete"
-
-	if req.Purge {
-		err := s.purgeReleases(rels...)
-		if err != nil {
-			log.Printf("uninstall: Failed to purge the release: %s", err)
-		}
-		return res, err
-	}
-
-	if err := s.env.Releases.Update(rel); err != nil {
-		log.Printf("uninstall: Failed to store updated release: %s", err)
-	}
-
-	if len(es) > 0 {
-		return res, fmt.Errorf("deletion completed with %d error(s): %s", len(es), strings.Join(es, "; "))
-	}
-	return res, nil
-}
-
 func validateManifest(c environment.KubeClient, ns string, manifest []byte) error {
 	r := bytes.NewReader(manifest)
 	_, err := c.BuildUnstructured(ns, r)
 	return err
 }
-
-// RunReleaseTest runs pre-defined tests stored as hooks on a given release
-func (s *ReleaseServer) RunReleaseTest(req *services.TestReleaseRequest, stream services.ReleaseService_RunReleaseTestServer) error {
-
-	if !ValidName.MatchString(req.Name) {
-		return errMissingRelease
-	}
-
-	// finds the non-deleted release with the given name
-	rel, err := s.env.Releases.Last(req.Name)
-	if err != nil {
-		return err
-	}
-
-	testEnv := &reltesting.Environment{
-		Namespace:  rel.Namespace,
-		KubeClient: s.env.KubeClient,
-		Timeout:    req.Timeout,
-		Stream:     stream,
-	}
-
-	tSuite, err := reltesting.NewTestSuite(rel)
-	if err != nil {
-		log.Printf("Error creating test suite for %s", rel.Name)
-		return err
-	}
-
-	if err := tSuite.Run(testEnv); err != nil {
-		log.Printf("Error running test suite for %s", rel.Name)
-		return err
-	}
-
-	rel.Info.Status.LastTestSuiteRun = &release.TestSuite{
-		StartedAt:   tSuite.StartedAt,
-		CompletedAt: tSuite.CompletedAt,
-		Results:     tSuite.Results,
-	}
-
-	if req.Cleanup {
-		testEnv.DeleteTestPods(tSuite.TestManifests)
-	}
-
-	return s.env.Releases.Update(rel)
-}
diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go
index 636874b2000c0992aae710c938efa3c36b610c3b..8425a58f514e39ed437b05f0a9491979f901bcf2 100644
--- a/pkg/tiller/release_server_test.go
+++ b/pkg/tiller/release_server_test.go
@@ -18,11 +18,9 @@ package tiller
 
 import (
 	"errors"
-	"fmt"
 	"io"
 	"os"
 	"regexp"
-	"strings"
 	"testing"
 
 	"github.com/golang/protobuf/ptypes/timestamp"
@@ -49,8 +47,7 @@ metadata:
   annotations:
     "helm.sh/hook": post-install,pre-delete
 data:
-  name: value
-`
+  name: value`
 
 var manifestWithTestHook = `
 apiVersion: v1
@@ -83,8 +80,7 @@ metadata:
   annotations:
     "helm.sh/hook": post-upgrade,pre-upgrade
 data:
-  name: value
-`
+  name: value`
 
 var manifestWithRollbackHooks = `apiVersion: v1
 kind: ConfigMap
@@ -97,9 +93,14 @@ data:
 `
 
 func rsFixture() *ReleaseServer {
+	clientset := fake.NewSimpleClientset()
 	return &ReleaseServer{
+		ReleaseModule: &LocalReleaseModule{
+			clientset: clientset,
+		},
 		env:       MockEnvironment(),
-		clientset: fake.NewSimpleClientset(),
+		clientset: clientset,
+		Log:       func(_ string, _ ...interface{}) {},
 	}
 }
 
@@ -205,7 +206,7 @@ func TestValidName(t *testing.T) {
 
 func TestGetVersionSet(t *testing.T) {
 	rs := rsFixture()
-	vs, err := getVersionSet(rs.clientset.Discovery())
+	vs, err := GetVersionSet(rs.clientset.Discovery())
 	if err != nil {
 		t.Error(err)
 	}
@@ -261,1039 +262,23 @@ func TestUniqName(t *testing.T) {
 	}
 }
 
-func TestInstallRelease(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-
-	// TODO: Refactor this into a mock.
-	req := &services.InstallReleaseRequest{
-		Namespace: "spaced",
-		Chart: &chart.Chart{
-			Metadata: &chart.Metadata{Name: "hello"},
-			Templates: []*chart.Template{
-				{Name: "templates/hello", Data: []byte("hello: world")},
-				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
-			},
-		},
-	}
-	res, err := rs.InstallRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed install: %s", err)
-	}
-	if res.Release.Name == "" {
-		t.Errorf("Expected release name.")
-	}
-	if res.Release.Namespace != "spaced" {
-		t.Errorf("Expected release namespace 'spaced', got '%s'.", res.Release.Namespace)
-	}
-
-	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
-	if err != nil {
-		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
-	}
-
-	t.Logf("rel: %v", rel)
-
-	if len(rel.Hooks) != 1 {
-		t.Fatalf("Expected 1 hook, got %d", len(rel.Hooks))
-	}
-	if rel.Hooks[0].Manifest != manifestWithHook {
-		t.Errorf("Unexpected manifest: %v", rel.Hooks[0].Manifest)
-	}
-
-	if rel.Hooks[0].Events[0] != release.Hook_POST_INSTALL {
-		t.Errorf("Expected event 0 is post install")
-	}
-	if rel.Hooks[0].Events[1] != release.Hook_PRE_DELETE {
-		t.Errorf("Expected event 0 is pre-delete")
-	}
-
-	if len(res.Release.Manifest) == 0 {
-		t.Errorf("No manifest returned: %v", res.Release)
-	}
-
-	if len(rel.Manifest) == 0 {
-		t.Errorf("Expected manifest in %v", res)
-	}
-
-	if !strings.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
-		t.Errorf("unexpected output: %s", rel.Manifest)
-	}
-
-	if rel.Info.Description != "Install complete" {
-		t.Errorf("unexpected description: %s", rel.Info.Description)
-	}
-}
-
-func TestInstallRelease_WithNotes(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-
-	// TODO: Refactor this into a mock.
-	req := &services.InstallReleaseRequest{
-		Namespace: "spaced",
-		Chart: &chart.Chart{
-			Metadata: &chart.Metadata{Name: "hello"},
-			Templates: []*chart.Template{
-				{Name: "templates/hello", Data: []byte("hello: world")},
-				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
-				{Name: "templates/NOTES.txt", Data: []byte(notesText)},
-			},
-		},
-	}
-	res, err := rs.InstallRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed install: %s", err)
-	}
-	if res.Release.Name == "" {
-		t.Errorf("Expected release name.")
-	}
-	if res.Release.Namespace != "spaced" {
-		t.Errorf("Expected release namespace 'spaced', got '%s'.", res.Release.Namespace)
-	}
-
-	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
-	if err != nil {
-		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
-	}
-
-	t.Logf("rel: %v", rel)
-
-	if len(rel.Hooks) != 1 {
-		t.Fatalf("Expected 1 hook, got %d", len(rel.Hooks))
-	}
-	if rel.Hooks[0].Manifest != manifestWithHook {
-		t.Errorf("Unexpected manifest: %v", rel.Hooks[0].Manifest)
-	}
-
-	if rel.Info.Status.Notes != notesText {
-		t.Fatalf("Expected '%s', got '%s'", notesText, rel.Info.Status.Notes)
-	}
-
-	if rel.Hooks[0].Events[0] != release.Hook_POST_INSTALL {
-		t.Errorf("Expected event 0 is post install")
-	}
-	if rel.Hooks[0].Events[1] != release.Hook_PRE_DELETE {
-		t.Errorf("Expected event 0 is pre-delete")
-	}
-
-	if len(res.Release.Manifest) == 0 {
-		t.Errorf("No manifest returned: %v", res.Release)
-	}
-
-	if len(rel.Manifest) == 0 {
-		t.Errorf("Expected manifest in %v", res)
-	}
-
-	if !strings.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
-		t.Errorf("unexpected output: %s", rel.Manifest)
-	}
-
-	if rel.Info.Description != "Install complete" {
-		t.Errorf("unexpected description: %s", rel.Info.Description)
-	}
-}
-
-func TestInstallRelease_WithNotesRendered(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-
-	// TODO: Refactor this into a mock.
-	req := &services.InstallReleaseRequest{
-		Namespace: "spaced",
-		Chart: &chart.Chart{
-			Metadata: &chart.Metadata{Name: "hello"},
-			Templates: []*chart.Template{
-				{Name: "templates/hello", Data: []byte("hello: world")},
-				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
-				{Name: "templates/NOTES.txt", Data: []byte(notesText + " {{.Release.Name}}")},
-			},
-		},
-	}
-	res, err := rs.InstallRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed install: %s", err)
-	}
-	if res.Release.Name == "" {
-		t.Errorf("Expected release name.")
-	}
-	if res.Release.Namespace != "spaced" {
-		t.Errorf("Expected release namespace 'spaced', got '%s'.", res.Release.Namespace)
-	}
-
-	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
-	if err != nil {
-		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
-	}
-
-	t.Logf("rel: %v", rel)
-
-	if len(rel.Hooks) != 1 {
-		t.Fatalf("Expected 1 hook, got %d", len(rel.Hooks))
-	}
-	if rel.Hooks[0].Manifest != manifestWithHook {
-		t.Errorf("Unexpected manifest: %v", rel.Hooks[0].Manifest)
-	}
-
-	expectedNotes := fmt.Sprintf("%s %s", notesText, res.Release.Name)
-	if rel.Info.Status.Notes != expectedNotes {
-		t.Fatalf("Expected '%s', got '%s'", expectedNotes, rel.Info.Status.Notes)
-	}
-
-	if rel.Hooks[0].Events[0] != release.Hook_POST_INSTALL {
-		t.Errorf("Expected event 0 is post install")
-	}
-	if rel.Hooks[0].Events[1] != release.Hook_PRE_DELETE {
-		t.Errorf("Expected event 0 is pre-delete")
-	}
-
-	if len(res.Release.Manifest) == 0 {
-		t.Errorf("No manifest returned: %v", res.Release)
-	}
-
-	if len(rel.Manifest) == 0 {
-		t.Errorf("Expected manifest in %v", res)
-	}
-
-	if !strings.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
-		t.Errorf("unexpected output: %s", rel.Manifest)
-	}
-
-	if rel.Info.Description != "Install complete" {
-		t.Errorf("unexpected description: %s", rel.Info.Description)
-	}
-}
-
-func TestInstallRelease_TillerVersion(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-
-	// TODO: Refactor this into a mock.
-	req := &services.InstallReleaseRequest{
-		Namespace: "spaced",
-		Chart: &chart.Chart{
-			Metadata: &chart.Metadata{Name: "hello", TillerVersion: ">=2.2.0"},
-			Templates: []*chart.Template{
-				{Name: "templates/hello", Data: []byte("hello: world")},
-				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
-			},
-		},
-	}
-	_, err := rs.InstallRelease(c, req)
-	if err != nil {
-		t.Fatalf("Expected valid range. Got %q", err)
-	}
-}
-
-func TestInstallRelease_WrongTillerVersion(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-
-	// TODO: Refactor this into a mock.
-	req := &services.InstallReleaseRequest{
-		Namespace: "spaced",
-		Chart: &chart.Chart{
-			Metadata: &chart.Metadata{Name: "hello", TillerVersion: "<2.0.0"},
-			Templates: []*chart.Template{
-				{Name: "templates/hello", Data: []byte("hello: world")},
-				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
-			},
-		},
-	}
-	_, err := rs.InstallRelease(c, req)
-	if err == nil {
-		t.Fatalf("Expected to fail because of wrong version")
-	}
-
-	expect := "Chart incompatible with Tiller"
-	if !strings.Contains(err.Error(), expect) {
-		t.Errorf("Expected %q to contain %q", err.Error(), expect)
-	}
-}
-
-func TestInstallRelease_WithChartAndDependencyNotes(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-
-	// TODO: Refactor this into a mock.
-	req := &services.InstallReleaseRequest{
-		Namespace: "spaced",
-		Chart: &chart.Chart{
-			Metadata: &chart.Metadata{Name: "hello"},
-			Templates: []*chart.Template{
-				{Name: "templates/hello", Data: []byte("hello: world")},
-				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
-				{Name: "templates/NOTES.txt", Data: []byte(notesText)},
-			},
-			Dependencies: []*chart.Chart{
-				{
-					Metadata: &chart.Metadata{Name: "hello"},
-					Templates: []*chart.Template{
-						{Name: "templates/hello", Data: []byte("hello: world")},
-						{Name: "templates/hooks", Data: []byte(manifestWithHook)},
-						{Name: "templates/NOTES.txt", Data: []byte(notesText + " child")},
-					},
-				},
-			},
-		},
-	}
-
-	res, err := rs.InstallRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed install: %s", err)
-	}
-	if res.Release.Name == "" {
-		t.Errorf("Expected release name.")
-	}
-
-	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
-	if err != nil {
-		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
-	}
-
-	t.Logf("rel: %v", rel)
-
-	if rel.Info.Status.Notes != notesText {
-		t.Fatalf("Expected '%s', got '%s'", notesText, rel.Info.Status.Notes)
-	}
-
-	if rel.Info.Description != "Install complete" {
-		t.Errorf("unexpected description: %s", rel.Info.Description)
-	}
-}
-
-func TestInstallRelease_DryRun(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-
-	req := &services.InstallReleaseRequest{
-		Chart:  chartStub(),
-		DryRun: true,
-	}
-	res, err := rs.InstallRelease(c, req)
-	if err != nil {
-		t.Errorf("Failed install: %s", err)
-	}
-	if res.Release.Name == "" {
-		t.Errorf("Expected release name.")
-	}
-
-	if !strings.Contains(res.Release.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
-		t.Errorf("unexpected output: %s", res.Release.Manifest)
-	}
-
-	if !strings.Contains(res.Release.Manifest, "---\n# Source: hello/templates/goodbye\ngoodbye: world") {
-		t.Errorf("unexpected output: %s", res.Release.Manifest)
-	}
-
-	if !strings.Contains(res.Release.Manifest, "hello: Earth") {
-		t.Errorf("Should contain partial content. %s", res.Release.Manifest)
-	}
-
-	if strings.Contains(res.Release.Manifest, "hello: {{ template \"_planet\" . }}") {
-		t.Errorf("Should not contain partial templates itself. %s", res.Release.Manifest)
-	}
-
-	if strings.Contains(res.Release.Manifest, "empty") {
-		t.Errorf("Should not contain template data for an empty file. %s", res.Release.Manifest)
-	}
-
-	if _, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version); err == nil {
-		t.Errorf("Expected no stored release.")
-	}
-
-	if l := len(res.Release.Hooks); l != 1 {
-		t.Fatalf("Expected 1 hook, got %d", l)
-	}
-
-	if res.Release.Hooks[0].LastRun != nil {
-		t.Error("Expected hook to not be marked as run.")
-	}
-
-	if res.Release.Info.Description != "Dry run complete" {
-		t.Errorf("unexpected description: %s", res.Release.Info.Description)
-	}
-}
-
-func TestInstallRelease_NoHooks(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rs.env.Releases.Create(releaseStub())
-
-	req := &services.InstallReleaseRequest{
-		Chart:        chartStub(),
-		DisableHooks: true,
-	}
-	res, err := rs.InstallRelease(c, req)
-	if err != nil {
-		t.Errorf("Failed install: %s", err)
-	}
-
-	if hl := res.Release.Hooks[0].LastRun; hl != nil {
-		t.Errorf("Expected that no hooks were run. Got %d", hl)
-	}
-}
-
-func TestInstallRelease_FailedHooks(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rs.env.Releases.Create(releaseStub())
-	rs.env.KubeClient = newHookFailingKubeClient()
-
-	req := &services.InstallReleaseRequest{
-		Chart: chartStub(),
-	}
-	res, err := rs.InstallRelease(c, req)
-	if err == nil {
-		t.Error("Expected failed install")
-	}
-
-	if hl := res.Release.Info.Status.Code; hl != release.Status_FAILED {
-		t.Errorf("Expected FAILED release. Got %d", hl)
-	}
-}
-
-func TestInstallRelease_ReuseName(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rel.Info.Status.Code = release.Status_DELETED
-	rs.env.Releases.Create(rel)
-
-	req := &services.InstallReleaseRequest{
-		Chart:     chartStub(),
-		ReuseName: true,
-		Name:      rel.Name,
-	}
-	res, err := rs.InstallRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed install: %s", err)
-	}
-
-	if res.Release.Name != rel.Name {
-		t.Errorf("expected %q, got %q", rel.Name, res.Release.Name)
-	}
-
-	getreq := &services.GetReleaseStatusRequest{Name: rel.Name, Version: 0}
-	getres, err := rs.GetReleaseStatus(c, getreq)
-	if err != nil {
-		t.Errorf("Failed to retrieve release: %s", err)
-	}
-	if getres.Info.Status.Code != release.Status_DEPLOYED {
-		t.Errorf("Release status is %q", getres.Info.Status.Code)
-	}
-}
-
-func TestUpdateRelease(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rs.env.Releases.Create(rel)
-
-	req := &services.UpdateReleaseRequest{
-		Name: rel.Name,
-		Chart: &chart.Chart{
-			Metadata: &chart.Metadata{Name: "hello"},
-			Templates: []*chart.Template{
-				{Name: "templates/hello", Data: []byte("hello: world")},
-				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
-			},
+func releaseWithKeepStub(rlsName string) *release.Release {
+	ch := &chart.Chart{
+		Metadata: &chart.Metadata{
+			Name: "bunnychart",
 		},
-	}
-	res, err := rs.UpdateRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed updated: %s", err)
-	}
-
-	if res.Release.Name == "" {
-		t.Errorf("Expected release name.")
-	}
-
-	if res.Release.Name != rel.Name {
-		t.Errorf("Updated release name does not match previous release name. Expected %s, got %s", rel.Name, res.Release.Name)
-	}
-
-	if res.Release.Namespace != rel.Namespace {
-		t.Errorf("Expected release namespace '%s', got '%s'.", rel.Namespace, res.Release.Namespace)
-	}
-
-	updated, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
-	if err != nil {
-		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
-	}
-
-	if len(updated.Hooks) != 1 {
-		t.Fatalf("Expected 1 hook, got %d", len(updated.Hooks))
-	}
-	if updated.Hooks[0].Manifest != manifestWithUpgradeHooks {
-		t.Errorf("Unexpected manifest: %v", updated.Hooks[0].Manifest)
-	}
-
-	if updated.Hooks[0].Events[0] != release.Hook_POST_UPGRADE {
-		t.Errorf("Expected event 0 to be post upgrade")
-	}
-
-	if updated.Hooks[0].Events[1] != release.Hook_PRE_UPGRADE {
-		t.Errorf("Expected event 0 to be pre upgrade")
-	}
-
-	if len(res.Release.Manifest) == 0 {
-		t.Errorf("No manifest returned: %v", res.Release)
-	}
-
-	if res.Release.Config == nil {
-		t.Errorf("Got release without config: %#v", res.Release)
-	} else if res.Release.Config.Raw != rel.Config.Raw {
-		t.Errorf("Expected release values %q, got %q", rel.Config.Raw, res.Release.Config.Raw)
-	}
-
-	if len(updated.Manifest) == 0 {
-		t.Errorf("Expected manifest in %v", res)
-	}
-
-	if !strings.Contains(updated.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
-		t.Errorf("unexpected output: %s", rel.Manifest)
-	}
-
-	if res.Release.Version != 2 {
-		t.Errorf("Expected release version to be %v, got %v", 2, res.Release.Version)
-	}
-
-	edesc := "Upgrade complete"
-	if got := res.Release.Info.Description; got != edesc {
-		t.Errorf("Expected description %q, got %q", edesc, got)
-	}
-}
-func TestUpdateRelease_ResetValues(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rs.env.Releases.Create(rel)
-
-	req := &services.UpdateReleaseRequest{
-		Name: rel.Name,
-		Chart: &chart.Chart{
-			Metadata: &chart.Metadata{Name: "hello"},
-			Templates: []*chart.Template{
-				{Name: "templates/hello", Data: []byte("hello: world")},
-				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
-			},
+		Templates: []*chart.Template{
+			{Name: "templates/configmap", Data: []byte(manifestWithKeep)},
 		},
-		ResetValues: true,
-	}
-	res, err := rs.UpdateRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed updated: %s", err)
 	}
-	// This should have been unset. Config:  &chart.Config{Raw: `name: value`},
-	if res.Release.Config != nil && res.Release.Config.Raw != "" {
-		t.Errorf("Expected chart config to be empty, got %q", res.Release.Config.Raw)
-	}
-}
-
-func TestUpdateRelease_ReuseValues(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rs.env.Releases.Create(rel)
 
-	req := &services.UpdateReleaseRequest{
-		Name: rel.Name,
-		Chart: &chart.Chart{
-			Metadata: &chart.Metadata{Name: "hello"},
-			Templates: []*chart.Template{
-				{Name: "templates/hello", Data: []byte("hello: world")},
-				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
-			},
-			// Since reuseValues is set, this should get ignored.
-			Values: &chart.Config{Raw: "foo: bar\n"},
-		},
-		Values:      &chart.Config{Raw: "name2: val2"},
-		ReuseValues: true,
-	}
-	res, err := rs.UpdateRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed updated: %s", err)
-	}
-	// This should have been overwritten with the old value.
-	expect := "name: value\n"
-	if res.Release.Chart.Values != nil && res.Release.Chart.Values.Raw != expect {
-		t.Errorf("Expected chart values to be %q, got %q", expect, res.Release.Chart.Values.Raw)
-	}
-	// This should have the newly-passed overrides.
-	expect = "name2: val2"
-	if res.Release.Config != nil && res.Release.Config.Raw != expect {
-		t.Errorf("Expected request config to be %q, got %q", expect, res.Release.Config.Raw)
-	}
-}
-
-func TestUpdateRelease_ResetReuseValues(t *testing.T) {
-	// This verifies that when both reset and reuse are set, reset wins.
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rs.env.Releases.Create(rel)
-
-	req := &services.UpdateReleaseRequest{
-		Name: rel.Name,
-		Chart: &chart.Chart{
-			Metadata: &chart.Metadata{Name: "hello"},
-			Templates: []*chart.Template{
-				{Name: "templates/hello", Data: []byte("hello: world")},
-				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
-			},
-		},
-		ResetValues: true,
-		ReuseValues: true,
-	}
-	res, err := rs.UpdateRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed updated: %s", err)
-	}
-	// This should have been unset. Config:  &chart.Config{Raw: `name: value`},
-	if res.Release.Config != nil && res.Release.Config.Raw != "" {
-		t.Errorf("Expected chart config to be empty, got %q", res.Release.Config.Raw)
-	}
-}
-
-func TestUpdateReleaseFailure(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rs.env.Releases.Create(rel)
-	rs.env.KubeClient = newUpdateFailingKubeClient()
-
-	req := &services.UpdateReleaseRequest{
-		Name:         rel.Name,
-		DisableHooks: true,
-		Chart: &chart.Chart{
-			Metadata: &chart.Metadata{Name: "hello"},
-			Templates: []*chart.Template{
-				{Name: "templates/something", Data: []byte("hello: world")},
-			},
-		},
-	}
-
-	res, err := rs.UpdateRelease(c, req)
-	if err == nil {
-		t.Error("Expected failed update")
-	}
-
-	if updatedStatus := res.Release.Info.Status.Code; updatedStatus != release.Status_FAILED {
-		t.Errorf("Expected FAILED release. Got %d", updatedStatus)
-	}
-
-	edesc := "Upgrade \"angry-panda\" failed: Failed update in kube client"
-	if got := res.Release.Info.Description; got != edesc {
-		t.Errorf("Expected description %q, got %q", edesc, got)
-	}
-
-	oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version)
-	if err != nil {
-		t.Errorf("Expected to be able to get previous release")
-	}
-	if oldStatus := oldRelease.Info.Status.Code; oldStatus != release.Status_SUPERSEDED {
-		t.Errorf("Expected SUPERSEDED status on previous Release version. Got %v", oldStatus)
-	}
-}
-
-func TestRollbackReleaseFailure(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rs.env.Releases.Create(rel)
-	upgradedRel := upgradeReleaseVersion(rel)
-	rs.env.Releases.Update(rel)
-	rs.env.Releases.Create(upgradedRel)
-
-	req := &services.RollbackReleaseRequest{
-		Name:         rel.Name,
-		DisableHooks: true,
-	}
-
-	rs.env.KubeClient = newUpdateFailingKubeClient()
-	res, err := rs.RollbackRelease(c, req)
-	if err == nil {
-		t.Error("Expected failed rollback")
-	}
-
-	if targetStatus := res.Release.Info.Status.Code; targetStatus != release.Status_FAILED {
-		t.Errorf("Expected FAILED release. Got %v", targetStatus)
-	}
-
-	oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version)
-	if err != nil {
-		t.Errorf("Expected to be able to get previous release")
-	}
-	if oldStatus := oldRelease.Info.Status.Code; oldStatus != release.Status_SUPERSEDED {
-		t.Errorf("Expected SUPERSEDED status on previous Release version. Got %v", oldStatus)
-	}
-}
-
-func TestUpdateReleaseNoHooks(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rs.env.Releases.Create(rel)
-
-	req := &services.UpdateReleaseRequest{
-		Name:         rel.Name,
-		DisableHooks: true,
-		Chart: &chart.Chart{
-			Metadata: &chart.Metadata{Name: "hello"},
-			Templates: []*chart.Template{
-				{Name: "templates/hello", Data: []byte("hello: world")},
-				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
-			},
-		},
-	}
-
-	res, err := rs.UpdateRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed updated: %s", err)
-	}
-
-	if hl := res.Release.Hooks[0].LastRun; hl != nil {
-		t.Errorf("Expected that no hooks were run. Got %d", hl)
-	}
-
-}
-
-func TestUpdateReleaseNoChanges(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rs.env.Releases.Create(rel)
-
-	req := &services.UpdateReleaseRequest{
-		Name:         rel.Name,
-		DisableHooks: true,
-		Chart:        rel.GetChart(),
-	}
-
-	_, err := rs.UpdateRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed updated: %s", err)
-	}
-}
-
-func TestRollbackReleaseNoHooks(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rel.Hooks = []*release.Hook{
-		{
-			Name:     "test-cm",
-			Kind:     "ConfigMap",
-			Path:     "test-cm",
-			Manifest: manifestWithRollbackHooks,
-			Events: []release.Hook_Event{
-				release.Hook_PRE_ROLLBACK,
-				release.Hook_POST_ROLLBACK,
-			},
-		},
-	}
-	rs.env.Releases.Create(rel)
-	upgradedRel := upgradeReleaseVersion(rel)
-	rs.env.Releases.Update(rel)
-	rs.env.Releases.Create(upgradedRel)
-
-	req := &services.RollbackReleaseRequest{
-		Name:         rel.Name,
-		DisableHooks: true,
-	}
-
-	res, err := rs.RollbackRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed rollback: %s", err)
-	}
-
-	if hl := res.Release.Hooks[0].LastRun; hl != nil {
-		t.Errorf("Expected that no hooks were run. Got %d", hl)
-	}
-}
-
-func TestRollbackWithReleaseVersion(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rs.env.Releases.Create(rel)
-	upgradedRel := upgradeReleaseVersion(rel)
-	rs.env.Releases.Update(rel)
-	rs.env.Releases.Create(upgradedRel)
-
-	req := &services.RollbackReleaseRequest{
-		Name:         rel.Name,
-		DisableHooks: true,
-		Version:      1,
-	}
-
-	_, err := rs.RollbackRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed rollback: %s", err)
-	}
-}
-
-func TestRollbackRelease(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rs.env.Releases.Create(rel)
-	upgradedRel := upgradeReleaseVersion(rel)
-	upgradedRel.Hooks = []*release.Hook{
-		{
-			Name:     "test-cm",
-			Kind:     "ConfigMap",
-			Path:     "test-cm",
-			Manifest: manifestWithRollbackHooks,
-			Events: []release.Hook_Event{
-				release.Hook_PRE_ROLLBACK,
-				release.Hook_POST_ROLLBACK,
-			},
-		},
-	}
-
-	upgradedRel.Manifest = "hello world"
-	rs.env.Releases.Update(rel)
-	rs.env.Releases.Create(upgradedRel)
-
-	req := &services.RollbackReleaseRequest{
-		Name: rel.Name,
-	}
-	res, err := rs.RollbackRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed rollback: %s", err)
-	}
-
-	if res.Release.Name == "" {
-		t.Errorf("Expected release name.")
-	}
-
-	if res.Release.Name != rel.Name {
-		t.Errorf("Updated release name does not match previous release name. Expected %s, got %s", rel.Name, res.Release.Name)
-	}
-
-	if res.Release.Namespace != rel.Namespace {
-		t.Errorf("Expected release namespace '%s', got '%s'.", rel.Namespace, res.Release.Namespace)
-	}
-
-	if res.Release.Version != 3 {
-		t.Errorf("Expected release version to be %v, got %v", 3, res.Release.Version)
-	}
-
-	updated, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
-	if err != nil {
-		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
-	}
-
-	if len(updated.Hooks) != 2 {
-		t.Fatalf("Expected 2 hooks, got %d", len(updated.Hooks))
-	}
-
-	if updated.Hooks[0].Manifest != manifestWithHook {
-		t.Errorf("Unexpected manifest: %v", updated.Hooks[0].Manifest)
-	}
-
-	anotherUpgradedRelease := upgradeReleaseVersion(upgradedRel)
-	rs.env.Releases.Update(upgradedRel)
-	rs.env.Releases.Create(anotherUpgradedRelease)
-
-	res, err = rs.RollbackRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed rollback: %s", err)
-	}
-
-	updated, err = rs.env.Releases.Get(res.Release.Name, res.Release.Version)
-	if err != nil {
-		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
-	}
-
-	if len(updated.Hooks) != 1 {
-		t.Fatalf("Expected 1 hook, got %d", len(updated.Hooks))
-	}
-
-	if updated.Hooks[0].Manifest != manifestWithRollbackHooks {
-		t.Errorf("Unexpected manifest: %v", updated.Hooks[0].Manifest)
-	}
-
-	if res.Release.Version != 4 {
-		t.Errorf("Expected release version to be %v, got %v", 3, res.Release.Version)
-	}
-
-	if updated.Hooks[0].Events[0] != release.Hook_PRE_ROLLBACK {
-		t.Errorf("Expected event 0 to be pre rollback")
-	}
-
-	if updated.Hooks[0].Events[1] != release.Hook_POST_ROLLBACK {
-		t.Errorf("Expected event 1 to be post rollback")
-	}
-
-	if len(res.Release.Manifest) == 0 {
-		t.Errorf("No manifest returned: %v", res.Release)
-	}
-
-	if len(updated.Manifest) == 0 {
-		t.Errorf("Expected manifest in %v", res)
-	}
-
-	if !strings.Contains(updated.Manifest, "hello world") {
-		t.Errorf("unexpected output: %s", rel.Manifest)
-	}
-
-	if res.Release.Info.Description != "Rollback to 2" {
-		t.Errorf("Expected rollback to 2, got %q", res.Release.Info.Description)
-	}
-
-}
-
-func TestUninstallRelease(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rs.env.Releases.Create(releaseStub())
-
-	req := &services.UninstallReleaseRequest{
-		Name: "angry-panda",
-	}
-
-	res, err := rs.UninstallRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed uninstall: %s", err)
-	}
-
-	if res.Release.Name != "angry-panda" {
-		t.Errorf("Expected angry-panda, got %q", res.Release.Name)
-	}
-
-	if res.Release.Info.Status.Code != release.Status_DELETED {
-		t.Errorf("Expected status code to be DELETED, got %d", res.Release.Info.Status.Code)
-	}
-
-	if res.Release.Hooks[0].LastRun.Seconds == 0 {
-		t.Error("Expected LastRun to be greater than zero.")
-	}
-
-	if res.Release.Info.Deleted.Seconds <= 0 {
-		t.Errorf("Expected valid UNIX date, got %d", res.Release.Info.Deleted.Seconds)
-	}
-
-	if res.Release.Info.Description != "Deletion complete" {
-		t.Errorf("Expected Deletion complete, got %q", res.Release.Info.Description)
-	}
-}
-
-func TestUninstallPurgeRelease(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rs.env.Releases.Create(rel)
-	upgradedRel := upgradeReleaseVersion(rel)
-	rs.env.Releases.Update(rel)
-	rs.env.Releases.Create(upgradedRel)
-
-	req := &services.UninstallReleaseRequest{
-		Name:  "angry-panda",
-		Purge: true,
-	}
-
-	res, err := rs.UninstallRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed uninstall: %s", err)
-	}
-
-	if res.Release.Name != "angry-panda" {
-		t.Errorf("Expected angry-panda, got %q", res.Release.Name)
-	}
-
-	if res.Release.Info.Status.Code != release.Status_DELETED {
-		t.Errorf("Expected status code to be DELETED, got %d", res.Release.Info.Status.Code)
-	}
-
-	if res.Release.Info.Deleted.Seconds <= 0 {
-		t.Errorf("Expected valid UNIX date, got %d", res.Release.Info.Deleted.Seconds)
-	}
-	rels, err := rs.GetHistory(helm.NewContext(), &services.GetHistoryRequest{Name: "angry-panda"})
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(rels.Releases) != 0 {
-		t.Errorf("Expected no releases in storage, got %d", len(rels.Releases))
-	}
-}
-
-func TestUninstallPurgeDeleteRelease(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rs.env.Releases.Create(releaseStub())
-
-	req := &services.UninstallReleaseRequest{
-		Name: "angry-panda",
-	}
-
-	_, err := rs.UninstallRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed uninstall: %s", err)
-	}
-
-	req2 := &services.UninstallReleaseRequest{
-		Name:  "angry-panda",
-		Purge: true,
-	}
-
-	_, err2 := rs.UninstallRelease(c, req2)
-	if err2 != nil && err2.Error() != "'angry-panda' has no deployed releases" {
-		t.Errorf("Failed uninstall: %s", err2)
-	}
-}
-
-func TestUninstallReleaseWithKeepPolicy(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	name := "angry-bunny"
-	rs.env.Releases.Create(releaseWithKeepStub(name))
-
-	req := &services.UninstallReleaseRequest{
-		Name: name,
-	}
-
-	res, err := rs.UninstallRelease(c, req)
-	if err != nil {
-		t.Fatalf("Failed uninstall: %s", err)
-	}
-
-	if res.Release.Name != name {
-		t.Errorf("Expected angry-bunny, got %q", res.Release.Name)
-	}
-
-	if res.Release.Info.Status.Code != release.Status_DELETED {
-		t.Errorf("Expected status code to be DELETED, got %d", res.Release.Info.Status.Code)
-	}
-
-	if res.Info == "" {
-		t.Errorf("Expected response info to not be empty")
-	} else {
-		if !strings.Contains(res.Info, "[ConfigMap] test-cm-keep") {
-			t.Errorf("unexpected output: %s", res.Info)
-		}
-	}
-}
-
-func releaseWithKeepStub(rlsName string) *release.Release {
-	ch := &chart.Chart{
-		Metadata: &chart.Metadata{
-			Name: "bunnychart",
-		},
-		Templates: []*chart.Template{
-			{Name: "templates/configmap", Data: []byte(manifestWithKeep)},
-		},
-	}
-
-	date := timestamp.Timestamp{Seconds: 242085845, Nanos: 0}
-	return &release.Release{
-		Name: rlsName,
-		Info: &release.Info{
-			FirstDeployed: &date,
-			LastDeployed:  &date,
-			Status:        &release.Status{Code: release.Status_DEPLOYED},
+	date := timestamp.Timestamp{Seconds: 242085845, Nanos: 0}
+	return &release.Release{
+		Name: rlsName,
+		Info: &release.Info{
+			FirstDeployed: &date,
+			LastDeployed:  &date,
+			Status:        &release.Status{Code: release.Status_DEPLOYED},
 		},
 		Chart:    ch,
 		Config:   &chart.Config{Raw: `name: value`},
@@ -1302,305 +287,6 @@ func releaseWithKeepStub(rlsName string) *release.Release {
 	}
 }
 
-func TestUninstallReleaseNoHooks(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rs.env.Releases.Create(releaseStub())
-
-	req := &services.UninstallReleaseRequest{
-		Name:         "angry-panda",
-		DisableHooks: true,
-	}
-
-	res, err := rs.UninstallRelease(c, req)
-	if err != nil {
-		t.Errorf("Failed uninstall: %s", err)
-	}
-
-	// The default value for a protobuf timestamp is nil.
-	if res.Release.Hooks[0].LastRun != nil {
-		t.Errorf("Expected LastRun to be zero, got %d.", res.Release.Hooks[0].LastRun.Seconds)
-	}
-}
-
-func TestGetReleaseContent(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	if err := rs.env.Releases.Create(rel); err != nil {
-		t.Fatalf("Could not store mock release: %s", err)
-	}
-
-	res, err := rs.GetReleaseContent(c, &services.GetReleaseContentRequest{Name: rel.Name, Version: 1})
-	if err != nil {
-		t.Errorf("Error getting release content: %s", err)
-	}
-
-	if res.Release.Chart.Metadata.Name != rel.Chart.Metadata.Name {
-		t.Errorf("Expected %q, got %q", rel.Chart.Metadata.Name, res.Release.Chart.Metadata.Name)
-	}
-}
-
-func TestGetReleaseStatus(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	if err := rs.env.Releases.Create(rel); err != nil {
-		t.Fatalf("Could not store mock release: %s", err)
-	}
-
-	res, err := rs.GetReleaseStatus(c, &services.GetReleaseStatusRequest{Name: rel.Name, Version: 1})
-	if err != nil {
-		t.Errorf("Error getting release content: %s", err)
-	}
-
-	if res.Name != rel.Name {
-		t.Errorf("Expected name %q, got %q", rel.Name, res.Name)
-	}
-	if res.Info.Status.Code != release.Status_DEPLOYED {
-		t.Errorf("Expected %d, got %d", release.Status_DEPLOYED, res.Info.Status.Code)
-	}
-}
-
-func TestGetReleaseStatusDeleted(t *testing.T) {
-	c := helm.NewContext()
-	rs := rsFixture()
-	rel := releaseStub()
-	rel.Info.Status.Code = release.Status_DELETED
-	if err := rs.env.Releases.Create(rel); err != nil {
-		t.Fatalf("Could not store mock release: %s", err)
-	}
-
-	res, err := rs.GetReleaseStatus(c, &services.GetReleaseStatusRequest{Name: rel.Name, Version: 1})
-	if err != nil {
-		t.Fatalf("Error getting release content: %s", err)
-	}
-
-	if res.Info.Status.Code != release.Status_DELETED {
-		t.Errorf("Expected %d, got %d", release.Status_DELETED, res.Info.Status.Code)
-	}
-}
-
-func TestListReleases(t *testing.T) {
-	rs := rsFixture()
-	num := 7
-	for i := 0; i < num; i++ {
-		rel := releaseStub()
-		rel.Name = fmt.Sprintf("rel-%d", i)
-		if err := rs.env.Releases.Create(rel); err != nil {
-			t.Fatalf("Could not store mock release: %s", err)
-		}
-	}
-
-	mrs := &mockListServer{}
-	if err := rs.ListReleases(&services.ListReleasesRequest{Offset: "", Limit: 64}, mrs); err != nil {
-		t.Fatalf("Failed listing: %s", err)
-	}
-
-	if len(mrs.val.Releases) != num {
-		t.Errorf("Expected %d releases, got %d", num, len(mrs.val.Releases))
-	}
-}
-
-func TestListReleasesByStatus(t *testing.T) {
-	rs := rsFixture()
-	stubs := []*release.Release{
-		namedReleaseStub("kamal", release.Status_DEPLOYED),
-		namedReleaseStub("astrolabe", release.Status_DELETED),
-		namedReleaseStub("octant", release.Status_FAILED),
-		namedReleaseStub("sextant", release.Status_UNKNOWN),
-	}
-	for _, stub := range stubs {
-		if err := rs.env.Releases.Create(stub); err != nil {
-			t.Fatalf("Could not create stub: %s", err)
-		}
-	}
-
-	tests := []struct {
-		statusCodes []release.Status_Code
-		names       []string
-	}{
-		{
-			names:       []string{"kamal"},
-			statusCodes: []release.Status_Code{release.Status_DEPLOYED},
-		},
-		{
-			names:       []string{"astrolabe"},
-			statusCodes: []release.Status_Code{release.Status_DELETED},
-		},
-		{
-			names:       []string{"kamal", "octant"},
-			statusCodes: []release.Status_Code{release.Status_DEPLOYED, release.Status_FAILED},
-		},
-		{
-			names: []string{"kamal", "astrolabe", "octant", "sextant"},
-			statusCodes: []release.Status_Code{
-				release.Status_DEPLOYED,
-				release.Status_DELETED,
-				release.Status_FAILED,
-				release.Status_UNKNOWN,
-			},
-		},
-	}
-
-	for i, tt := range tests {
-		mrs := &mockListServer{}
-		if err := rs.ListReleases(&services.ListReleasesRequest{StatusCodes: tt.statusCodes, Offset: "", Limit: 64}, mrs); err != nil {
-			t.Fatalf("Failed listing %d: %s", i, err)
-		}
-
-		if len(tt.names) != len(mrs.val.Releases) {
-			t.Fatalf("Expected %d releases, got %d", len(tt.names), len(mrs.val.Releases))
-		}
-
-		for _, name := range tt.names {
-			found := false
-			for _, rel := range mrs.val.Releases {
-				if rel.Name == name {
-					found = true
-				}
-			}
-			if !found {
-				t.Errorf("%d: Did not find name %q", i, name)
-			}
-		}
-	}
-}
-
-func TestListReleasesSort(t *testing.T) {
-	rs := rsFixture()
-
-	// Put them in by reverse order so that the mock doesn't "accidentally"
-	// sort.
-	num := 7
-	for i := num; i > 0; i-- {
-		rel := releaseStub()
-		rel.Name = fmt.Sprintf("rel-%d", i)
-		if err := rs.env.Releases.Create(rel); err != nil {
-			t.Fatalf("Could not store mock release: %s", err)
-		}
-	}
-
-	limit := 6
-	mrs := &mockListServer{}
-	req := &services.ListReleasesRequest{
-		Offset: "",
-		Limit:  int64(limit),
-		SortBy: services.ListSort_NAME,
-	}
-	if err := rs.ListReleases(req, mrs); err != nil {
-		t.Fatalf("Failed listing: %s", err)
-	}
-
-	if len(mrs.val.Releases) != limit {
-		t.Errorf("Expected %d releases, got %d", limit, len(mrs.val.Releases))
-	}
-
-	for i := 0; i < limit; i++ {
-		n := fmt.Sprintf("rel-%d", i+1)
-		if mrs.val.Releases[i].Name != n {
-			t.Errorf("Expected %q, got %q", n, mrs.val.Releases[i].Name)
-		}
-	}
-}
-
-func TestListReleasesFilter(t *testing.T) {
-	rs := rsFixture()
-	names := []string{
-		"axon",
-		"dendrite",
-		"neuron",
-		"neuroglia",
-		"synapse",
-		"nucleus",
-		"organelles",
-	}
-	num := 7
-	for i := 0; i < num; i++ {
-		rel := releaseStub()
-		rel.Name = names[i]
-		if err := rs.env.Releases.Create(rel); err != nil {
-			t.Fatalf("Could not store mock release: %s", err)
-		}
-	}
-
-	mrs := &mockListServer{}
-	req := &services.ListReleasesRequest{
-		Offset: "",
-		Limit:  64,
-		Filter: "neuro[a-z]+",
-		SortBy: services.ListSort_NAME,
-	}
-	if err := rs.ListReleases(req, mrs); err != nil {
-		t.Fatalf("Failed listing: %s", err)
-	}
-
-	if len(mrs.val.Releases) != 2 {
-		t.Errorf("Expected 2 releases, got %d", len(mrs.val.Releases))
-	}
-
-	if mrs.val.Releases[0].Name != "neuroglia" {
-		t.Errorf("Unexpected sort order: %v.", mrs.val.Releases)
-	}
-	if mrs.val.Releases[1].Name != "neuron" {
-		t.Errorf("Unexpected sort order: %v.", mrs.val.Releases)
-	}
-}
-
-func TestReleasesNamespace(t *testing.T) {
-	rs := rsFixture()
-
-	names := []string{
-		"axon",
-		"dendrite",
-		"neuron",
-		"ribosome",
-	}
-
-	namespaces := []string{
-		"default",
-		"test123",
-		"test123",
-		"cerebellum",
-	}
-	num := 4
-	for i := 0; i < num; i++ {
-		rel := releaseStub()
-		rel.Name = names[i]
-		rel.Namespace = namespaces[i]
-		if err := rs.env.Releases.Create(rel); err != nil {
-			t.Fatalf("Could not store mock release: %s", err)
-		}
-	}
-
-	mrs := &mockListServer{}
-	req := &services.ListReleasesRequest{
-		Offset:    "",
-		Limit:     64,
-		Namespace: "test123",
-	}
-
-	if err := rs.ListReleases(req, mrs); err != nil {
-		t.Fatalf("Failed listing: %s", err)
-	}
-
-	if len(mrs.val.Releases) != 2 {
-		t.Errorf("Expected 2 releases, got %d", len(mrs.val.Releases))
-	}
-}
-
-func TestRunReleaseTest(t *testing.T) {
-	rs := rsFixture()
-	rel := namedReleaseStub("nemo", release.Status_DEPLOYED)
-	rs.env.Releases.Create(rel)
-
-	req := &services.TestReleaseRequest{Name: "nemo", Timeout: 2}
-	err := rs.RunReleaseTest(req, mockRunReleaseTestServer{})
-	if err != nil {
-		t.Fatalf("failed to run release tests on %s: %s", rel.Name, err)
-	}
-}
-
 func MockEnvironment() *environment.Environment {
 	e := environment.New()
 	e.Releases = storage.Init(driver.NewMemory())
@@ -1619,7 +305,7 @@ type updateFailingKubeClient struct {
 	environment.PrintingKubeClient
 }
 
-func (u *updateFailingKubeClient) Update(namespace string, originalReader, modifiedReader io.Reader, recreate bool, timeout int64, shouldWait bool) error {
+func (u *updateFailingKubeClient) Update(namespace string, originalReader, modifiedReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error {
 	return errors.New("Failed update in kube client")
 }
 
diff --git a/pkg/tiller/release_status.go b/pkg/tiller/release_status.go
new file mode 100644
index 0000000000000000000000000000000000000000..41eba117493dfed7c98aea55f1fcffc136945c85
--- /dev/null
+++ b/pkg/tiller/release_status.go
@@ -0,0 +1,74 @@
+/*
+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 tiller
+
+import (
+	"errors"
+	"fmt"
+	ctx "golang.org/x/net/context"
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+)
+
+// GetReleaseStatus gets the status information for a named release.
+func (s *ReleaseServer) GetReleaseStatus(c ctx.Context, req *services.GetReleaseStatusRequest) (*services.GetReleaseStatusResponse, error) {
+	if !ValidName.MatchString(req.Name) {
+		return nil, errMissingRelease
+	}
+
+	var rel *release.Release
+
+	if req.Version <= 0 {
+		var err error
+		rel, err = s.env.Releases.Last(req.Name)
+		if err != nil {
+			return nil, fmt.Errorf("getting deployed release %q: %s", req.Name, err)
+		}
+	} else {
+		var err error
+		if rel, err = s.env.Releases.Get(req.Name, req.Version); err != nil {
+			return nil, fmt.Errorf("getting release '%s' (v%d): %s", req.Name, req.Version, err)
+		}
+	}
+
+	if rel.Info == nil {
+		return nil, errors.New("release info is missing")
+	}
+	if rel.Chart == nil {
+		return nil, errors.New("release chart is missing")
+	}
+
+	sc := rel.Info.Status.Code
+	statusResp := &services.GetReleaseStatusResponse{
+		Name:      rel.Name,
+		Namespace: rel.Namespace,
+		Info:      rel.Info,
+	}
+
+	// Ok, we got the status of the release as we had jotted down, now we need to match the
+	// manifest we stashed away with reality from the cluster.
+	resp, err := s.ReleaseModule.Status(rel, req, s.env)
+	if sc == release.Status_DELETED || sc == release.Status_FAILED {
+		// Skip errors if this is already deleted or failed.
+		return statusResp, nil
+	} else if err != nil {
+		s.Log("warning: Get for %s failed: %v", rel.Name, err)
+		return nil, err
+	}
+	rel.Info.Status.Resources = resp
+	return statusResp, nil
+}
diff --git a/pkg/tiller/release_status_test.go b/pkg/tiller/release_status_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..9128b43a1388462e4954fdea9879f52dc6b1878c
--- /dev/null
+++ b/pkg/tiller/release_status_test.go
@@ -0,0 +1,64 @@
+/*
+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 tiller
+
+import (
+	"k8s.io/helm/pkg/helm"
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	"testing"
+)
+
+func TestGetReleaseStatus(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	if err := rs.env.Releases.Create(rel); err != nil {
+		t.Fatalf("Could not store mock release: %s", err)
+	}
+
+	res, err := rs.GetReleaseStatus(c, &services.GetReleaseStatusRequest{Name: rel.Name, Version: 1})
+	if err != nil {
+		t.Errorf("Error getting release content: %s", err)
+	}
+
+	if res.Name != rel.Name {
+		t.Errorf("Expected name %q, got %q", rel.Name, res.Name)
+	}
+	if res.Info.Status.Code != release.Status_DEPLOYED {
+		t.Errorf("Expected %d, got %d", release.Status_DEPLOYED, res.Info.Status.Code)
+	}
+}
+
+func TestGetReleaseStatusDeleted(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rel.Info.Status.Code = release.Status_DELETED
+	if err := rs.env.Releases.Create(rel); err != nil {
+		t.Fatalf("Could not store mock release: %s", err)
+	}
+
+	res, err := rs.GetReleaseStatus(c, &services.GetReleaseStatusRequest{Name: rel.Name, Version: 1})
+	if err != nil {
+		t.Fatalf("Error getting release content: %s", err)
+	}
+
+	if res.Info.Status.Code != release.Status_DELETED {
+		t.Errorf("Expected %d, got %d", release.Status_DELETED, res.Info.Status.Code)
+	}
+}
diff --git a/pkg/tiller/release_testing.go b/pkg/tiller/release_testing.go
new file mode 100644
index 0000000000000000000000000000000000000000..4f9a38a9697b75d638cb733874e3b04bf7f1926d
--- /dev/null
+++ b/pkg/tiller/release_testing.go
@@ -0,0 +1,71 @@
+/*
+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 tiller
+
+import (
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	reltesting "k8s.io/helm/pkg/releasetesting"
+)
+
+// RunReleaseTest runs pre-defined tests stored as hooks on a given release
+func (s *ReleaseServer) RunReleaseTest(req *services.TestReleaseRequest, stream services.ReleaseService_RunReleaseTestServer) error {
+
+	if !ValidName.MatchString(req.Name) {
+		return errMissingRelease
+	}
+
+	// finds the non-deleted release with the given name
+	rel, err := s.env.Releases.Last(req.Name)
+	if err != nil {
+		return err
+	}
+
+	testEnv := &reltesting.Environment{
+		Namespace:  rel.Namespace,
+		KubeClient: s.env.KubeClient,
+		Timeout:    req.Timeout,
+		Stream:     stream,
+	}
+	s.Log("running tests for release %s", rel.Name)
+	tSuite, err := reltesting.NewTestSuite(rel)
+	if err != nil {
+		s.Log("error creating test suite for %s: %s", rel.Name, err)
+		return err
+	}
+
+	if err := tSuite.Run(testEnv); err != nil {
+		s.Log("error running test suite for %s: %s", rel.Name, err)
+		return err
+	}
+
+	rel.Info.Status.LastTestSuiteRun = &release.TestSuite{
+		StartedAt:   tSuite.StartedAt,
+		CompletedAt: tSuite.CompletedAt,
+		Results:     tSuite.Results,
+	}
+
+	if req.Cleanup {
+		testEnv.DeleteTestPods(tSuite.TestManifests)
+	}
+
+	if err := s.env.Releases.Update(rel); err != nil {
+		s.Log("test: Failed to store updated release: %s", err)
+	}
+
+	return nil
+}
diff --git a/pkg/tiller/release_testing_test.go b/pkg/tiller/release_testing_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..0b3b7768ea844fc2e17e2b542e5351b7008460dc
--- /dev/null
+++ b/pkg/tiller/release_testing_test.go
@@ -0,0 +1,35 @@
+/*
+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 tiller
+
+import (
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	"testing"
+)
+
+func TestRunReleaseTest(t *testing.T) {
+	rs := rsFixture()
+	rel := namedReleaseStub("nemo", release.Status_DEPLOYED)
+	rs.env.Releases.Create(rel)
+
+	req := &services.TestReleaseRequest{Name: "nemo", Timeout: 2}
+	err := rs.RunReleaseTest(req, mockRunReleaseTestServer{})
+	if err != nil {
+		t.Fatalf("failed to run release tests on %s: %s", rel.Name, err)
+	}
+}
diff --git a/pkg/tiller/release_uninstall.go b/pkg/tiller/release_uninstall.go
new file mode 100644
index 0000000000000000000000000000000000000000..54971ee6e3dca8927074f142fb78f1de13f391a9
--- /dev/null
+++ b/pkg/tiller/release_uninstall.go
@@ -0,0 +1,137 @@
+/*
+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 tiller
+
+import (
+	"fmt"
+	"strings"
+
+	ctx "golang.org/x/net/context"
+	"k8s.io/helm/pkg/hooks"
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	relutil "k8s.io/helm/pkg/releaseutil"
+	"k8s.io/helm/pkg/timeconv"
+)
+
+// UninstallRelease deletes all of the resources associated with this release, and marks the release DELETED.
+func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallReleaseRequest) (*services.UninstallReleaseResponse, error) {
+	if !ValidName.MatchString(req.Name) {
+		s.Log("uninstall: Release not found: %s", req.Name)
+		return nil, errMissingRelease
+	}
+
+	if len(req.Name) > releaseNameMaxLen {
+		return nil, fmt.Errorf("release name %q exceeds max length of %d", req.Name, releaseNameMaxLen)
+	}
+
+	err := s.env.Releases.LockRelease(req.Name)
+	if err != nil {
+		return nil, err
+	}
+	defer s.env.Releases.UnlockRelease(req.Name)
+
+	rels, err := s.env.Releases.History(req.Name)
+	if err != nil {
+		s.Log("uninstall: Release not loaded: %s", req.Name)
+		return nil, err
+	}
+	if len(rels) < 1 {
+		return nil, errMissingRelease
+	}
+
+	relutil.SortByRevision(rels)
+	rel := rels[len(rels)-1]
+
+	// TODO: Are there any cases where we want to force a delete even if it's
+	// already marked deleted?
+	if rel.Info.Status.Code == release.Status_DELETED {
+		if req.Purge {
+			if err := s.purgeReleases(rels...); err != nil {
+				s.Log("uninstall: Failed to purge the release: %s", err)
+				return nil, err
+			}
+			return &services.UninstallReleaseResponse{Release: rel}, nil
+		}
+		return nil, fmt.Errorf("the release named %q is already deleted", req.Name)
+	}
+
+	s.Log("uninstall: Deleting %s", req.Name)
+	rel.Info.Status.Code = release.Status_DELETING
+	rel.Info.Deleted = timeconv.Now()
+	rel.Info.Description = "Deletion in progress (or silently failed)"
+	res := &services.UninstallReleaseResponse{Release: rel}
+
+	if !req.DisableHooks {
+		if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, hooks.PreDelete, req.Timeout); err != nil {
+			return res, err
+		}
+	} else {
+		s.Log("delete hooks disabled for %s", req.Name)
+	}
+
+	// From here on out, the release is currently considered to be in Status_DELETING
+	// state.
+	if err := s.env.Releases.Update(rel); err != nil {
+		s.Log("uninstall: Failed to store updated release: %s", err)
+	}
+
+	kept, errs := s.ReleaseModule.Delete(rel, req, s.env)
+	res.Info = kept
+
+	es := make([]string, 0, len(errs))
+	for _, e := range errs {
+		s.Log("error: %v", e)
+		es = append(es, e.Error())
+	}
+
+	if !req.DisableHooks {
+		if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, hooks.PostDelete, req.Timeout); err != nil {
+			es = append(es, err.Error())
+		}
+	}
+
+	rel.Info.Status.Code = release.Status_DELETED
+	rel.Info.Description = "Deletion complete"
+
+	if req.Purge {
+		s.Log("purge requested for %s", req.Name)
+		err := s.purgeReleases(rels...)
+		if err != nil {
+			s.Log("uninstall: Failed to purge the release: %s", err)
+		}
+		return res, err
+	}
+
+	if err := s.env.Releases.Update(rel); err != nil {
+		s.Log("uninstall: Failed to store updated release: %s", err)
+	}
+
+	if len(es) > 0 {
+		return res, fmt.Errorf("deletion completed with %d error(s): %s", len(es), strings.Join(es, "; "))
+	}
+	return res, nil
+}
+
+func (s *ReleaseServer) purgeReleases(rels ...*release.Release) error {
+	for _, rel := range rels {
+		if _, err := s.env.Releases.Delete(rel.Name, rel.Version); err != nil {
+			return err
+		}
+	}
+	return nil
+}
diff --git a/pkg/tiller/release_uninstall_test.go b/pkg/tiller/release_uninstall_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..ef3afb4445c09f315b49395fd5765a7c33d377bf
--- /dev/null
+++ b/pkg/tiller/release_uninstall_test.go
@@ -0,0 +1,177 @@
+/*
+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 tiller
+
+import (
+	"k8s.io/helm/pkg/helm"
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	"strings"
+	"testing"
+)
+
+func TestUninstallRelease(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rs.env.Releases.Create(releaseStub())
+
+	req := &services.UninstallReleaseRequest{
+		Name: "angry-panda",
+	}
+
+	res, err := rs.UninstallRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed uninstall: %s", err)
+	}
+
+	if res.Release.Name != "angry-panda" {
+		t.Errorf("Expected angry-panda, got %q", res.Release.Name)
+	}
+
+	if res.Release.Info.Status.Code != release.Status_DELETED {
+		t.Errorf("Expected status code to be DELETED, got %d", res.Release.Info.Status.Code)
+	}
+
+	if res.Release.Hooks[0].LastRun.Seconds == 0 {
+		t.Error("Expected LastRun to be greater than zero.")
+	}
+
+	if res.Release.Info.Deleted.Seconds <= 0 {
+		t.Errorf("Expected valid UNIX date, got %d", res.Release.Info.Deleted.Seconds)
+	}
+
+	if res.Release.Info.Description != "Deletion complete" {
+		t.Errorf("Expected Deletion complete, got %q", res.Release.Info.Description)
+	}
+}
+
+func TestUninstallPurgeRelease(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+	upgradedRel := upgradeReleaseVersion(rel)
+	rs.env.Releases.Update(rel)
+	rs.env.Releases.Create(upgradedRel)
+
+	req := &services.UninstallReleaseRequest{
+		Name:  "angry-panda",
+		Purge: true,
+	}
+
+	res, err := rs.UninstallRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed uninstall: %s", err)
+	}
+
+	if res.Release.Name != "angry-panda" {
+		t.Errorf("Expected angry-panda, got %q", res.Release.Name)
+	}
+
+	if res.Release.Info.Status.Code != release.Status_DELETED {
+		t.Errorf("Expected status code to be DELETED, got %d", res.Release.Info.Status.Code)
+	}
+
+	if res.Release.Info.Deleted.Seconds <= 0 {
+		t.Errorf("Expected valid UNIX date, got %d", res.Release.Info.Deleted.Seconds)
+	}
+	rels, err := rs.GetHistory(helm.NewContext(), &services.GetHistoryRequest{Name: "angry-panda"})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(rels.Releases) != 0 {
+		t.Errorf("Expected no releases in storage, got %d", len(rels.Releases))
+	}
+}
+
+func TestUninstallPurgeDeleteRelease(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rs.env.Releases.Create(releaseStub())
+
+	req := &services.UninstallReleaseRequest{
+		Name: "angry-panda",
+	}
+
+	_, err := rs.UninstallRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed uninstall: %s", err)
+	}
+
+	req2 := &services.UninstallReleaseRequest{
+		Name:  "angry-panda",
+		Purge: true,
+	}
+
+	_, err2 := rs.UninstallRelease(c, req2)
+	if err2 != nil && err2.Error() != "'angry-panda' has no deployed releases" {
+		t.Errorf("Failed uninstall: %s", err2)
+	}
+}
+
+func TestUninstallReleaseWithKeepPolicy(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	name := "angry-bunny"
+	rs.env.Releases.Create(releaseWithKeepStub(name))
+
+	req := &services.UninstallReleaseRequest{
+		Name: name,
+	}
+
+	res, err := rs.UninstallRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed uninstall: %s", err)
+	}
+
+	if res.Release.Name != name {
+		t.Errorf("Expected angry-bunny, got %q", res.Release.Name)
+	}
+
+	if res.Release.Info.Status.Code != release.Status_DELETED {
+		t.Errorf("Expected status code to be DELETED, got %d", res.Release.Info.Status.Code)
+	}
+
+	if res.Info == "" {
+		t.Errorf("Expected response info to not be empty")
+	} else {
+		if !strings.Contains(res.Info, "[ConfigMap] test-cm-keep") {
+			t.Errorf("unexpected output: %s", res.Info)
+		}
+	}
+}
+
+func TestUninstallReleaseNoHooks(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rs.env.Releases.Create(releaseStub())
+
+	req := &services.UninstallReleaseRequest{
+		Name:         "angry-panda",
+		DisableHooks: true,
+	}
+
+	res, err := rs.UninstallRelease(c, req)
+	if err != nil {
+		t.Errorf("Failed uninstall: %s", err)
+	}
+
+	// The default value for a protobuf timestamp is nil.
+	if res.Release.Hooks[0].LastRun != nil {
+		t.Errorf("Expected LastRun to be zero, got %d.", res.Release.Hooks[0].LastRun.Seconds)
+	}
+}
diff --git a/pkg/tiller/release_update.go b/pkg/tiller/release_update.go
new file mode 100644
index 0000000000000000000000000000000000000000..fb30d16617bde8fb5730fd1e68fd3bae83e807d0
--- /dev/null
+++ b/pkg/tiller/release_update.go
@@ -0,0 +1,174 @@
+/*
+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 tiller
+
+import (
+	"fmt"
+
+	ctx "golang.org/x/net/context"
+	"k8s.io/helm/pkg/chartutil"
+	"k8s.io/helm/pkg/hooks"
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	"k8s.io/helm/pkg/timeconv"
+)
+
+// UpdateRelease takes an existing release and new information, and upgrades the release.
+func (s *ReleaseServer) UpdateRelease(c ctx.Context, req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) {
+	err := s.env.Releases.LockRelease(req.Name)
+	if err != nil {
+		return nil, err
+	}
+	defer s.env.Releases.UnlockRelease(req.Name)
+
+	s.Log("preparing update for %s", req.Name)
+	currentRelease, updatedRelease, err := s.prepareUpdate(req)
+	if err != nil {
+		return nil, err
+	}
+
+	s.Log("performing update for %s", req.Name)
+	res, err := s.performUpdate(currentRelease, updatedRelease, req)
+	if err != nil {
+		return res, err
+	}
+
+	if !req.DryRun {
+		s.Log("creating updated release for %s", req.Name)
+		if err := s.env.Releases.Create(updatedRelease); err != nil {
+			return res, err
+		}
+	}
+
+	return res, nil
+}
+
+// prepareUpdate builds an updated release for an update operation.
+func (s *ReleaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*release.Release, *release.Release, error) {
+	if !ValidName.MatchString(req.Name) {
+		return nil, nil, errMissingRelease
+	}
+
+	if req.Chart == nil {
+		return nil, nil, errMissingChart
+	}
+
+	// finds the non-deleted release with the given name
+	currentRelease, err := s.env.Releases.Last(req.Name)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// If new values were not supplied in the upgrade, re-use the existing values.
+	if err := s.reuseValues(req, currentRelease); err != nil {
+		return nil, nil, err
+	}
+
+	// Increment revision count. This is passed to templates, and also stored on
+	// the release object.
+	revision := currentRelease.Version + 1
+
+	ts := timeconv.Now()
+	options := chartutil.ReleaseOptions{
+		Name:      req.Name,
+		Time:      ts,
+		Namespace: currentRelease.Namespace,
+		IsUpgrade: true,
+		Revision:  int(revision),
+	}
+
+	caps, err := capabilities(s.clientset.Discovery())
+	if err != nil {
+		return nil, nil, err
+	}
+	valuesToRender, err := chartutil.ToRenderValuesCaps(req.Chart, req.Values, options, caps)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	hooks, manifestDoc, notesTxt, err := s.renderResources(req.Chart, valuesToRender, caps.APIVersions)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// Store an updated release.
+	updatedRelease := &release.Release{
+		Name:      req.Name,
+		Namespace: currentRelease.Namespace,
+		Chart:     req.Chart,
+		Config:    req.Values,
+		Info: &release.Info{
+			FirstDeployed: currentRelease.Info.FirstDeployed,
+			LastDeployed:  ts,
+			Status:        &release.Status{Code: release.Status_UNKNOWN},
+			Description:   "Preparing upgrade", // This should be overwritten later.
+		},
+		Version:  revision,
+		Manifest: manifestDoc.String(),
+		Hooks:    hooks,
+	}
+
+	if len(notesTxt) > 0 {
+		updatedRelease.Info.Status.Notes = notesTxt
+	}
+	err = validateManifest(s.env.KubeClient, currentRelease.Namespace, manifestDoc.Bytes())
+	return currentRelease, updatedRelease, err
+}
+
+func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.Release, req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) {
+	res := &services.UpdateReleaseResponse{Release: updatedRelease}
+
+	if req.DryRun {
+		s.Log("dry run for %s", updatedRelease.Name)
+		res.Release.Info.Description = "Dry run complete"
+		return res, nil
+	}
+
+	// pre-upgrade hooks
+	if !req.DisableHooks {
+		if err := s.execHook(updatedRelease.Hooks, updatedRelease.Name, updatedRelease.Namespace, hooks.PreUpgrade, req.Timeout); err != nil {
+			return res, err
+		}
+	} else {
+		s.Log("update hooks disabled for %s", req.Name)
+	}
+	if err := s.ReleaseModule.Update(originalRelease, updatedRelease, req, s.env); err != nil {
+		msg := fmt.Sprintf("Upgrade %q failed: %s", updatedRelease.Name, err)
+		s.Log("warning: %s", msg)
+		originalRelease.Info.Status.Code = release.Status_SUPERSEDED
+		updatedRelease.Info.Status.Code = release.Status_FAILED
+		updatedRelease.Info.Description = msg
+		s.recordRelease(originalRelease, true)
+		s.recordRelease(updatedRelease, false)
+		return res, err
+	}
+
+	// post-upgrade hooks
+	if !req.DisableHooks {
+		if err := s.execHook(updatedRelease.Hooks, updatedRelease.Name, updatedRelease.Namespace, hooks.PostUpgrade, req.Timeout); err != nil {
+			return res, err
+		}
+	}
+
+	originalRelease.Info.Status.Code = release.Status_SUPERSEDED
+	s.recordRelease(originalRelease, true)
+
+	updatedRelease.Info.Status.Code = release.Status_DEPLOYED
+	updatedRelease.Info.Description = "Upgrade complete"
+
+	return res, nil
+}
diff --git a/pkg/tiller/release_update_test.go b/pkg/tiller/release_update_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..cba07e11e4be429d9f6b7e1dc17a88a8a9369b41
--- /dev/null
+++ b/pkg/tiller/release_update_test.go
@@ -0,0 +1,286 @@
+/*
+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 tiller
+
+import (
+	"k8s.io/helm/pkg/helm"
+	"k8s.io/helm/pkg/proto/hapi/chart"
+	"k8s.io/helm/pkg/proto/hapi/release"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	"strings"
+	"testing"
+)
+
+func TestUpdateRelease(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+
+	req := &services.UpdateReleaseRequest{
+		Name: rel.Name,
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello"},
+			Templates: []*chart.Template{
+				{Name: "templates/hello", Data: []byte("hello: world")},
+				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
+			},
+		},
+	}
+	res, err := rs.UpdateRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed updated: %s", err)
+	}
+
+	if res.Release.Name == "" {
+		t.Errorf("Expected release name.")
+	}
+
+	if res.Release.Name != rel.Name {
+		t.Errorf("Updated release name does not match previous release name. Expected %s, got %s", rel.Name, res.Release.Name)
+	}
+
+	if res.Release.Namespace != rel.Namespace {
+		t.Errorf("Expected release namespace '%s', got '%s'.", rel.Namespace, res.Release.Namespace)
+	}
+
+	updated, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
+	if err != nil {
+		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
+	}
+
+	if len(updated.Hooks) != 1 {
+		t.Fatalf("Expected 1 hook, got %d", len(updated.Hooks))
+	}
+	if updated.Hooks[0].Manifest != manifestWithUpgradeHooks {
+		t.Errorf("Unexpected manifest: %v", updated.Hooks[0].Manifest)
+	}
+
+	if updated.Hooks[0].Events[0] != release.Hook_POST_UPGRADE {
+		t.Errorf("Expected event 0 to be post upgrade")
+	}
+
+	if updated.Hooks[0].Events[1] != release.Hook_PRE_UPGRADE {
+		t.Errorf("Expected event 0 to be pre upgrade")
+	}
+
+	if len(res.Release.Manifest) == 0 {
+		t.Errorf("No manifest returned: %v", res.Release)
+	}
+
+	if res.Release.Config == nil {
+		t.Errorf("Got release without config: %#v", res.Release)
+	} else if res.Release.Config.Raw != rel.Config.Raw {
+		t.Errorf("Expected release values %q, got %q", rel.Config.Raw, res.Release.Config.Raw)
+	}
+
+	if len(updated.Manifest) == 0 {
+		t.Errorf("Expected manifest in %v", res)
+	}
+
+	if !strings.Contains(updated.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
+		t.Errorf("unexpected output: %s", rel.Manifest)
+	}
+
+	if res.Release.Version != 2 {
+		t.Errorf("Expected release version to be %v, got %v", 2, res.Release.Version)
+	}
+
+	edesc := "Upgrade complete"
+	if got := res.Release.Info.Description; got != edesc {
+		t.Errorf("Expected description %q, got %q", edesc, got)
+	}
+}
+func TestUpdateRelease_ResetValues(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+
+	req := &services.UpdateReleaseRequest{
+		Name: rel.Name,
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello"},
+			Templates: []*chart.Template{
+				{Name: "templates/hello", Data: []byte("hello: world")},
+				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
+			},
+		},
+		ResetValues: true,
+	}
+	res, err := rs.UpdateRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed updated: %s", err)
+	}
+	// This should have been unset. Config:  &chart.Config{Raw: `name: value`},
+	if res.Release.Config != nil && res.Release.Config.Raw != "" {
+		t.Errorf("Expected chart config to be empty, got %q", res.Release.Config.Raw)
+	}
+}
+
+func TestUpdateRelease_ReuseValues(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+
+	req := &services.UpdateReleaseRequest{
+		Name: rel.Name,
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello"},
+			Templates: []*chart.Template{
+				{Name: "templates/hello", Data: []byte("hello: world")},
+				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
+			},
+			// Since reuseValues is set, this should get ignored.
+			Values: &chart.Config{Raw: "foo: bar\n"},
+		},
+		Values:      &chart.Config{Raw: "name2: val2"},
+		ReuseValues: true,
+	}
+	res, err := rs.UpdateRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed updated: %s", err)
+	}
+	// This should have been overwritten with the old value.
+	expect := "name: value\n"
+	if res.Release.Chart.Values != nil && res.Release.Chart.Values.Raw != expect {
+		t.Errorf("Expected chart values to be %q, got %q", expect, res.Release.Chart.Values.Raw)
+	}
+	// This should have the newly-passed overrides.
+	expect = "name2: val2"
+	if res.Release.Config != nil && res.Release.Config.Raw != expect {
+		t.Errorf("Expected request config to be %q, got %q", expect, res.Release.Config.Raw)
+	}
+}
+
+func TestUpdateRelease_ResetReuseValues(t *testing.T) {
+	// This verifies that when both reset and reuse are set, reset wins.
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+
+	req := &services.UpdateReleaseRequest{
+		Name: rel.Name,
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello"},
+			Templates: []*chart.Template{
+				{Name: "templates/hello", Data: []byte("hello: world")},
+				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
+			},
+		},
+		ResetValues: true,
+		ReuseValues: true,
+	}
+	res, err := rs.UpdateRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed updated: %s", err)
+	}
+	// This should have been unset. Config:  &chart.Config{Raw: `name: value`},
+	if res.Release.Config != nil && res.Release.Config.Raw != "" {
+		t.Errorf("Expected chart config to be empty, got %q", res.Release.Config.Raw)
+	}
+}
+
+func TestUpdateReleaseFailure(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+	rs.env.KubeClient = newUpdateFailingKubeClient()
+
+	req := &services.UpdateReleaseRequest{
+		Name:         rel.Name,
+		DisableHooks: true,
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello"},
+			Templates: []*chart.Template{
+				{Name: "templates/something", Data: []byte("hello: world")},
+			},
+		},
+	}
+
+	res, err := rs.UpdateRelease(c, req)
+	if err == nil {
+		t.Error("Expected failed update")
+	}
+
+	if updatedStatus := res.Release.Info.Status.Code; updatedStatus != release.Status_FAILED {
+		t.Errorf("Expected FAILED release. Got %d", updatedStatus)
+	}
+
+	edesc := "Upgrade \"angry-panda\" failed: Failed update in kube client"
+	if got := res.Release.Info.Description; got != edesc {
+		t.Errorf("Expected description %q, got %q", edesc, got)
+	}
+
+	oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version)
+	if err != nil {
+		t.Errorf("Expected to be able to get previous release")
+	}
+	if oldStatus := oldRelease.Info.Status.Code; oldStatus != release.Status_SUPERSEDED {
+		t.Errorf("Expected SUPERSEDED status on previous Release version. Got %v", oldStatus)
+	}
+}
+
+func TestUpdateReleaseNoHooks(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+
+	req := &services.UpdateReleaseRequest{
+		Name:         rel.Name,
+		DisableHooks: true,
+		Chart: &chart.Chart{
+			Metadata: &chart.Metadata{Name: "hello"},
+			Templates: []*chart.Template{
+				{Name: "templates/hello", Data: []byte("hello: world")},
+				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
+			},
+		},
+	}
+
+	res, err := rs.UpdateRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed updated: %s", err)
+	}
+
+	if hl := res.Release.Hooks[0].LastRun; hl != nil {
+		t.Errorf("Expected that no hooks were run. Got %d", hl)
+	}
+
+}
+
+func TestUpdateReleaseNoChanges(t *testing.T) {
+	c := helm.NewContext()
+	rs := rsFixture()
+	rel := releaseStub()
+	rs.env.Releases.Create(rel)
+
+	req := &services.UpdateReleaseRequest{
+		Name:         rel.Name,
+		DisableHooks: true,
+		Chart:        rel.GetChart(),
+	}
+
+	_, err := rs.UpdateRelease(c, req)
+	if err != nil {
+		t.Fatalf("Failed updated: %s", err)
+	}
+}
diff --git a/pkg/tiller/release_version.go b/pkg/tiller/release_version.go
new file mode 100644
index 0000000000000000000000000000000000000000..5cf3ff828ce88d791d0e86090520723bbfe7b692
--- /dev/null
+++ b/pkg/tiller/release_version.go
@@ -0,0 +1,29 @@
+/*
+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 tiller
+
+import (
+	ctx "golang.org/x/net/context"
+	"k8s.io/helm/pkg/proto/hapi/services"
+	"k8s.io/helm/pkg/version"
+)
+
+// GetVersion sends the server version.
+func (s *ReleaseServer) GetVersion(c ctx.Context, req *services.GetVersionRequest) (*services.GetVersionResponse, error) {
+	v := version.GetVersionProto()
+	return &services.GetVersionResponse{Version: v}, nil
+}
diff --git a/pkg/tiller/server.go b/pkg/tiller/server.go
index 75db5e093f5c881fd61aeb35049f994c6e638ba7..8d6b6fa136d2a69721d53fc37ce33565b31a2d96 100644
--- a/pkg/tiller/server.go
+++ b/pkg/tiller/server.go
@@ -88,8 +88,8 @@ func versionFromContext(ctx context.Context) string {
 
 func checkClientVersion(ctx context.Context) error {
 	clientVersion := versionFromContext(ctx)
-	if !version.IsCompatible(clientVersion, version.Version) {
-		return fmt.Errorf("incompatible versions client: %s server: %s", clientVersion, version.Version)
+	if !version.IsCompatible(clientVersion, version.GetVersion()) {
+		return fmt.Errorf("incompatible versions client[%s] server[%s]", clientVersion, version.GetVersion())
 	}
 	return nil
 }
diff --git a/pkg/urlutil/urlutil.go b/pkg/urlutil/urlutil.go
index 3a6570470766b7c138b8624fa754479fada43a3b..fb67708ae175bd8d80a1093ef99dbd1319f31b81 100644
--- a/pkg/urlutil/urlutil.go
+++ b/pkg/urlutil/urlutil.go
@@ -17,10 +17,10 @@ limitations under the License.
 package urlutil
 
 import (
-	"net"
 	"net/url"
 	"path"
 	"path/filepath"
+	"strings"
 )
 
 // URLJoin joins a base URL to one or more path components.
@@ -70,10 +70,18 @@ func ExtractHostname(addr string) (string, error) {
 	if err != nil {
 		return "", err
 	}
+	return stripPort(u.Host), nil
+}
 
-	host, _, err := net.SplitHostPort(u.Host)
-	if err != nil {
-		return "", err
+// Backported from Go 1.8 because Circle is still on 1.7
+func stripPort(hostport string) string {
+	colon := strings.IndexByte(hostport, ':')
+	if colon == -1 {
+		return hostport
 	}
-	return host, nil
+	if i := strings.IndexByte(hostport, ']'); i != -1 {
+		return strings.TrimPrefix(hostport[:i], "[")
+	}
+	return hostport[:colon]
+
 }
diff --git a/pkg/urlutil/urlutil_test.go b/pkg/urlutil/urlutil_test.go
index 5944df1ae87170a45e5c105e318aabb289a41e89..f0c82c0a929d91e3e470da1d801d4ea0654c3e3a 100644
--- a/pkg/urlutil/urlutil_test.go
+++ b/pkg/urlutil/urlutil_test.go
@@ -62,3 +62,16 @@ func TestEqual(t *testing.T) {
 		}
 	}
 }
+
+func TestExtractHostname(t *testing.T) {
+	tests := map[string]string{
+		"http://example.com":                                      "example.com",
+		"https://example.com/foo":                                 "example.com",
+		"https://example.com:31337/not/with/a/bang/but/a/whimper": "example.com",
+	}
+	for start, expect := range tests {
+		if got, _ := ExtractHostname(start); got != expect {
+			t.Errorf("Got %q, expected %q", got, expect)
+		}
+	}
+}
diff --git a/pkg/version/compatible.go b/pkg/version/compatible.go
index c8f359971b0d51646ddfe95124f6dc1ed70f0769..735610778beb8ff3d851f2bc5e34d6032a7b2713 100644
--- a/pkg/version/compatible.go
+++ b/pkg/version/compatible.go
@@ -18,12 +18,16 @@ package version // import "k8s.io/helm/pkg/version"
 
 import (
 	"fmt"
+	"strings"
 
 	"github.com/Masterminds/semver"
 )
 
 // IsCompatible tests if a client and server version are compatible.
 func IsCompatible(client, server string) bool {
+	if isUnreleased(client) || isUnreleased(server) {
+		return true
+	}
 	cv, err := semver.NewVersion(client)
 	if err != nil {
 		return false
@@ -55,3 +59,7 @@ func IsCompatibleRange(constraint, ver string) bool {
 	}
 	return c.Check(sv)
 }
+
+func isUnreleased(v string) bool {
+	return strings.HasSuffix(v, "unreleased")
+}
diff --git a/pkg/version/version.go b/pkg/version/version.go
index ff68c4a913bce83e78e3fedc7fd546ebc56a7214..c0b54fef70876eab4485402b5120bc9227e962c3 100644
--- a/pkg/version/version.go
+++ b/pkg/version/version.go
@@ -26,10 +26,10 @@ var (
 	// Increment major number for new feature additions and behavioral changes.
 	// Increment minor number for bug fixes and performance enhancements.
 	// Increment patch number for critical fixes to existing releases.
-	Version = "v2.3.0"
+	Version = "v2.4"
 
 	// BuildMetadata is extra build time data
-	BuildMetadata = ""
+	BuildMetadata = "unreleased"
 	// GitCommit is the git sha1
 	GitCommit = ""
 	// GitTreeState is the state of the git tree
diff --git a/rootfs/Dockerfile b/rootfs/Dockerfile
index e30d981cbf0f4d5e97695ca1fd3103466303817b..53757cd8d5eb301c46b2697d611351333ad8beb1 100644
--- a/rootfs/Dockerfile
+++ b/rootfs/Dockerfile
@@ -14,9 +14,11 @@
 
 FROM alpine:3.3
 
+RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
+
 ENV HOME /tmp
 
-COPY . /
+COPY tiller /tiller
 
 EXPOSE 44134
 
diff --git a/rootfs/Dockerfile.experimental b/rootfs/Dockerfile.experimental
new file mode 100644
index 0000000000000000000000000000000000000000..990bcde516c73012e5d2f96a910bf2f4ad05cfb6
--- /dev/null
+++ b/rootfs/Dockerfile.experimental
@@ -0,0 +1,26 @@
+# Copyright 2017 The Kubernetes Authors.
+#
+# 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.
+
+FROM alpine:3.3
+
+RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
+
+ENV HOME /tmp
+
+COPY tiller /tiller
+
+EXPOSE 44134
+
+CMD ["/tiller", "--experimental-release"]
+
diff --git a/rootfs/Dockerfile.rudder b/rootfs/Dockerfile.rudder
new file mode 100644
index 0000000000000000000000000000000000000000..6bb3a2d9236c5362340791624c5f29560f4adc0a
--- /dev/null
+++ b/rootfs/Dockerfile.rudder
@@ -0,0 +1,25 @@
+# Copyright 2017 The Kubernetes Authors.
+#
+# 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.
+
+FROM alpine:3.3
+
+RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
+
+ENV HOME /tmp
+
+COPY rudder /rudder
+
+EXPOSE 10001
+
+CMD ["/rudder"]
diff --git a/scripts/cluster/skydns.yaml b/scripts/cluster/skydns.yaml
deleted file mode 100644
index 720877d5de98f4c24e4c4b10e47ae65224d827ac..0000000000000000000000000000000000000000
--- a/scripts/cluster/skydns.yaml
+++ /dev/null
@@ -1,137 +0,0 @@
-apiVersion: v1
-kind: ReplicationController
-metadata:
-  name: kube-dns-v10
-  namespace: kube-system
-  labels:
-    k8s-app: kube-dns
-    version: v10
-    kubernetes.io/cluster-service: "true"
-spec:
-  replicas: 1
-  selector:
-    k8s-app: kube-dns
-    version: v10
-  template:
-    metadata:
-      labels:
-        k8s-app: kube-dns
-        version: v10
-        kubernetes.io/cluster-service: "true"
-    spec:
-      containers:
-      - name: etcd
-        image: gcr.io/google_containers/etcd-amd64:2.2.1
-        resources:
-          # keep request = limit to keep this container in guaranteed class
-          limits:
-            cpu: 100m
-            memory: 50Mi
-          requests:
-            cpu: 100m
-            memory: 50Mi
-        command:
-        - /usr/local/bin/etcd
-        - -data-dir
-        - /var/etcd/data
-        - -listen-client-urls
-        - http://127.0.0.1:2379,http://127.0.0.1:4001
-        - -advertise-client-urls
-        - http://127.0.0.1:2379,http://127.0.0.1:4001
-        - -initial-cluster-token
-        - skydns-etcd
-        volumeMounts:
-        - name: etcd-storage
-          mountPath: /var/etcd/data
-      - name: kube2sky
-        image: gcr.io/google_containers/kube2sky:1.12
-        resources:
-          # keep request = limit to keep this container in guaranteed class
-          limits:
-            cpu: 100m
-            memory: 50Mi
-          requests:
-            cpu: 100m
-            memory: 50Mi
-        args:
-        # command = "/kube2sky"
-        - --domain=cluster.local
-      - name: skydns
-        image: gcr.io/google_containers/skydns:2015-10-13-8c72f8c
-        resources:
-          # keep request = limit to keep this container in guaranteed class
-          limits:
-            cpu: 100m
-            memory: 50Mi
-          requests:
-            cpu: 100m
-            memory: 50Mi
-        args:
-        # command = "/skydns"
-        - -machines=http://127.0.0.1:4001
-        - -addr=0.0.0.0:53
-        - -ns-rotate=false
-        - -domain=cluster.local.
-        ports:
-        - containerPort: 53
-          name: dns
-          protocol: UDP
-        - containerPort: 53
-          name: dns-tcp
-          protocol: TCP
-        livenessProbe:
-          httpGet:
-            path: /healthz
-            port: 8080
-            scheme: HTTP
-          initialDelaySeconds: 30
-          timeoutSeconds: 5
-        readinessProbe:
-          httpGet:
-            path: /healthz
-            port: 8080
-            scheme: HTTP
-          initialDelaySeconds: 1
-          timeoutSeconds: 5
-      - name: healthz
-        image: gcr.io/google_containers/exechealthz:1.0
-        resources:
-          # keep request = limit to keep this container in guaranteed class
-          limits:
-            cpu: 10m
-            memory: 20Mi
-          requests:
-            cpu: 10m
-            memory: 20Mi
-        args:
-        - -cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null
-        - -port=8080
-        ports:
-        - containerPort: 8080
-          protocol: TCP
-      volumes:
-      - name: etcd-storage
-        emptyDir: {}
-      dnsPolicy: Default  # Don't use cluster DNS.
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: kube-dns
-  namespace: kube-system
-  labels:
-    k8s-app: kube-dns
-    kubernetes.io/cluster-service: "true"
-    kubernetes.io/name: "KubeDNS"
-spec:
-  selector:
-    k8s-app: kube-dns
-  clusterIP: 10.0.0.10
-  ports:
-  - name: dns
-    port: 53
-    protocol: UDP
-  - name: dns-tcp
-    port: 53
-    protocol: TCP
-
diff --git a/scripts/completions.bash b/scripts/completions.bash
index f928ae5026bb032325da8b667d67d6dad65abbdf..b2524ea3804894358dd0e6c4593c20c99904cc08 100644
--- a/scripts/completions.bash
+++ b/scripts/completions.bash
@@ -242,6 +242,8 @@ _helm_completion()
 
     must_have_one_flag=()
     must_have_one_noun=()
+    must_have_one_noun+=("bash")
+    must_have_one_noun+=("zsh")
     noun_aliases=()
 }
 
@@ -422,13 +424,23 @@ _helm_fetch()
     flags_with_completion=()
     flags_completion=()
 
+    flags+=("--ca-file=")
+    local_nonpersistent_flags+=("--ca-file=")
+    flags+=("--cert-file=")
+    local_nonpersistent_flags+=("--cert-file=")
     flags+=("--destination=")
     two_word_flags+=("-d")
     local_nonpersistent_flags+=("--destination=")
+    flags+=("--devel")
+    local_nonpersistent_flags+=("--devel")
+    flags+=("--key-file=")
+    local_nonpersistent_flags+=("--key-file=")
     flags+=("--keyring=")
     local_nonpersistent_flags+=("--keyring=")
     flags+=("--prov")
     local_nonpersistent_flags+=("--prov")
+    flags+=("--repo=")
+    local_nonpersistent_flags+=("--repo=")
     flags+=("--untar")
     local_nonpersistent_flags+=("--untar")
     flags+=("--untardir=")
@@ -638,6 +650,8 @@ _helm_init()
     local_nonpersistent_flags+=("--local-repo-url=")
     flags+=("--net-host")
     local_nonpersistent_flags+=("--net-host")
+    flags+=("--service-account=")
+    local_nonpersistent_flags+=("--service-account=")
     flags+=("--skip-refresh")
     local_nonpersistent_flags+=("--skip-refresh")
     flags+=("--stable-repo-url=")
@@ -679,8 +693,16 @@ _helm_inspect_chart()
     flags_with_completion=()
     flags_completion=()
 
+    flags+=("--ca-file=")
+    local_nonpersistent_flags+=("--ca-file=")
+    flags+=("--cert-file=")
+    local_nonpersistent_flags+=("--cert-file=")
+    flags+=("--key-file=")
+    local_nonpersistent_flags+=("--key-file=")
     flags+=("--keyring=")
     local_nonpersistent_flags+=("--keyring=")
+    flags+=("--repo=")
+    local_nonpersistent_flags+=("--repo=")
     flags+=("--verify")
     local_nonpersistent_flags+=("--verify")
     flags+=("--version=")
@@ -707,8 +729,16 @@ _helm_inspect_values()
     flags_with_completion=()
     flags_completion=()
 
+    flags+=("--ca-file=")
+    local_nonpersistent_flags+=("--ca-file=")
+    flags+=("--cert-file=")
+    local_nonpersistent_flags+=("--cert-file=")
+    flags+=("--key-file=")
+    local_nonpersistent_flags+=("--key-file=")
     flags+=("--keyring=")
     local_nonpersistent_flags+=("--keyring=")
+    flags+=("--repo=")
+    local_nonpersistent_flags+=("--repo=")
     flags+=("--verify")
     local_nonpersistent_flags+=("--verify")
     flags+=("--version=")
@@ -737,8 +767,16 @@ _helm_inspect()
     flags_with_completion=()
     flags_completion=()
 
+    flags+=("--ca-file=")
+    local_nonpersistent_flags+=("--ca-file=")
+    flags+=("--cert-file=")
+    local_nonpersistent_flags+=("--cert-file=")
+    flags+=("--key-file=")
+    local_nonpersistent_flags+=("--key-file=")
     flags+=("--keyring=")
     local_nonpersistent_flags+=("--keyring=")
+    flags+=("--repo=")
+    local_nonpersistent_flags+=("--repo=")
     flags+=("--verify")
     local_nonpersistent_flags+=("--verify")
     flags+=("--version=")
@@ -765,8 +803,16 @@ _helm_install()
     flags_with_completion=()
     flags_completion=()
 
+    flags+=("--ca-file=")
+    local_nonpersistent_flags+=("--ca-file=")
+    flags+=("--cert-file=")
+    local_nonpersistent_flags+=("--cert-file=")
+    flags+=("--devel")
+    local_nonpersistent_flags+=("--devel")
     flags+=("--dry-run")
     local_nonpersistent_flags+=("--dry-run")
+    flags+=("--key-file=")
+    local_nonpersistent_flags+=("--key-file=")
     flags+=("--keyring=")
     local_nonpersistent_flags+=("--keyring=")
     flags+=("--name=")
@@ -780,6 +826,8 @@ _helm_install()
     local_nonpersistent_flags+=("--no-hooks")
     flags+=("--replace")
     local_nonpersistent_flags+=("--replace")
+    flags+=("--repo=")
+    local_nonpersistent_flags+=("--repo=")
     flags+=("--set=")
     local_nonpersistent_flags+=("--set=")
     flags+=("--timeout=")
@@ -1000,6 +1048,28 @@ _helm_plugin_remove()
     noun_aliases=()
 }
 
+_helm_plugin_update()
+{
+    last_command="helm_plugin_update"
+    commands=()
+
+    flags=()
+    two_word_flags=()
+    local_nonpersistent_flags=()
+    flags_with_completion=()
+    flags_completion=()
+
+    flags+=("--debug")
+    flags+=("--home=")
+    flags+=("--host=")
+    flags+=("--kube-context=")
+    flags+=("--tiller-namespace=")
+
+    must_have_one_flag=()
+    must_have_one_noun=()
+    noun_aliases=()
+}
+
 _helm_plugin()
 {
     last_command="helm_plugin"
@@ -1007,6 +1077,7 @@ _helm_plugin()
     commands+=("install")
     commands+=("list")
     commands+=("remove")
+    commands+=("update")
 
     flags=()
     two_word_flags=()
@@ -1224,6 +1295,8 @@ _helm_rollback()
 
     flags+=("--dry-run")
     local_nonpersistent_flags+=("--dry-run")
+    flags+=("--force")
+    local_nonpersistent_flags+=("--force")
     flags+=("--no-hooks")
     local_nonpersistent_flags+=("--no-hooks")
     flags+=("--recreate-pods")
@@ -1392,13 +1465,23 @@ _helm_upgrade()
     flags_with_completion=()
     flags_completion=()
 
+    flags+=("--ca-file=")
+    local_nonpersistent_flags+=("--ca-file=")
+    flags+=("--cert-file=")
+    local_nonpersistent_flags+=("--cert-file=")
+    flags+=("--devel")
+    local_nonpersistent_flags+=("--devel")
     flags+=("--disable-hooks")
     local_nonpersistent_flags+=("--disable-hooks")
     flags+=("--dry-run")
     local_nonpersistent_flags+=("--dry-run")
+    flags+=("--force")
+    local_nonpersistent_flags+=("--force")
     flags+=("--install")
     flags+=("-i")
     local_nonpersistent_flags+=("--install")
+    flags+=("--key-file=")
+    local_nonpersistent_flags+=("--key-file=")
     flags+=("--keyring=")
     local_nonpersistent_flags+=("--keyring=")
     flags+=("--namespace=")
@@ -1407,6 +1490,8 @@ _helm_upgrade()
     local_nonpersistent_flags+=("--no-hooks")
     flags+=("--recreate-pods")
     local_nonpersistent_flags+=("--recreate-pods")
+    flags+=("--repo=")
+    local_nonpersistent_flags+=("--repo=")
     flags+=("--reset-values")
     local_nonpersistent_flags+=("--reset-values")
     flags+=("--reuse-values")
diff --git a/scripts/get b/scripts/get
index a52a0a9a19a8b425a57f325d228f56bf180140e9..02884d7f9310f9bbbcc133fa0d8e6e69b4b166a1 100755
--- a/scripts/get
+++ b/scripts/get
@@ -62,31 +62,31 @@ verifySupported() {
   fi
 }
 
-# checkLatestVersion checks the latest available version.
-checkLatestVersion() {
-  # Use the GitHub releases webpage for the project to find the latest version for this project.
-  local latest_url="https://github.com/kubernetes/helm/releases/latest"
+# checkDesiredVersion checks if the desired version is available.
+checkDesiredVersion() {
+  # Use the GitHub releases webpage for the project to find the desired version for this project.
+  local release_url="https://github.com/kubernetes/helm/releases/${DESIRED_VERSION:-latest}"
   if type "curl" > /dev/null; then
-    TAG=$(curl -SsL $latest_url | awk '/\/tag\//' | head -n 1 | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}')
+    TAG=$(curl -SsL $release_url | awk '/\/tag\//' | head -n 1 | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}')
   elif type "wget" > /dev/null; then
-    TAG=$(wget -q -O - $latest_url | awk '/\/tag\//' | head -n 1 | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}')
+    TAG=$(wget -q -O - $release_url | awk '/\/tag\//' | head -n 1 | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}')
   fi
   if [ "x$TAG" == "x" ]; then
-    echo "Cannot determine latest tag."
+    echo "Cannot determine ${DESIRED_VERSION} tag."
     exit 1
   fi
 }
 
 # checkHelmInstalledVersion checks which version of helm is installed and
-# if it needs to be updated.
+# if it needs to be changed.
 checkHelmInstalledVersion() {
   if [[ -f "${HELM_INSTALL_DIR}/${PROJECT_NAME}" ]]; then
     local version=$(helm version | grep '^Client' | cut -d'"' -f2)
     if [[ "$version" == "$TAG" ]]; then
-      echo "Helm ${version} is up-to-date."
+      echo "Helm ${version} is already ${DESIRED_VERSION:-latest}"
       return 0
     else
-      echo "Helm ${TAG} is available. Upgrading from version ${version}."
+      echo "Helm ${TAG} is available. Changing from version ${version}."
       return 1
     fi
   else
@@ -137,7 +137,12 @@ installFile() {
 fail_trap() {
   result=$?
   if [ "$result" != "0" ]; then
-    echo "Failed to install $PROJECT_NAME"
+    if [[ -n "$INPUT_ARGUMENTS" ]]; then
+      echo "Failed to install $PROJECT_NAME with the arguments provided: $INPUT_ARGUMENTS"
+      help
+    else
+      echo "Failed to install $PROJECT_NAME"
+    fi
     echo -e "\tFor support, go to https://github.com/kubernetes/helm."
   fi
   exit $result
@@ -156,15 +161,44 @@ testVersion() {
   echo "Run '$PROJECT_NAME init' to configure $PROJECT_NAME."
 }
 
+# help provides possible cli installation arguments
+help () {
+  echo "Accepted cli arguments are:"
+  echo -e "\t[--help|-h ] ->> prints this help"
+  echo -e "\t[--version|-v <desired_version>] . When not defined it defaults to latest"
+  echo -e "\te.g. --version v2.4.0  or -v latest"
+}
+
 # Execution
 
 #Stop execution on any error
 trap "fail_trap" EXIT
 set -e
+
+# Parsing input arguments (if any)
+export INPUT_ARGUMENTS="${@}"
+set -u
+while [[ $# -gt 0 ]]; do
+  case $1 in
+    '--version'|-v) 
+       export DESIRED_VERSION="${2}" 
+       shift
+       ;;
+    '--help'|-h) 
+       help
+       exit 0
+       ;;
+    *) exit 1
+       ;;
+  esac
+  shift
+done
+set +u
+
 initArch
 initOS
 verifySupported
-checkLatestVersion
+checkDesiredVersion
 if ! checkHelmInstalledVersion; then
   downloadFile
   installFile
diff --git a/scripts/local-cluster.sh b/scripts/local-cluster.sh
deleted file mode 100755
index 83a57c3ce7e3b36860a8039562beaf0707185459..0000000000000000000000000000000000000000
--- a/scripts/local-cluster.sh
+++ /dev/null
@@ -1,358 +0,0 @@
-#!/usr/bin/env bash
-
-# 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.
-
-# Bash 'Strict Mode'
-# http://redsymbol.net/articles/unofficial-bash-strict-mode
-set -euo pipefail
-IFS=$'\n\t'
-
-HELM_ROOT="${BASH_SOURCE[0]%/*}/.."
-cd "$HELM_ROOT"
-
-# Globals ----------------------------------------------------------------------
-
-KUBE_VERSION=${KUBE_VERSION:-}
-KUBE_PORT=${KUBE_PORT:-8080}
-KUBE_CONTEXT=${KUBE_CONTEXT:-docker}
-KUBECTL=${KUBECTL:-kubectl}
-ENABLE_CLUSTER_DNS=${KUBE_ENABLE_CLUSTER_DNS:-true}
-LOG_LEVEL=${LOG_LEVEL:-2}
-
-# Helper Functions -------------------------------------------------------------
-
-# Display error message and exit
-error_exit() {
-  echo "error: ${1:-"unknown error"}" 1>&2
-  exit 1
-}
-
-# Checks if a command exists.  Returns 1 or 0
-command_exists() {
-  hash "${1}" 2>/dev/null
-}
-
-# fetch url using wget or curl and print to stdout
-fetch_url() {
-  local url="$1"
-  if command_exists wget; then
-    curl -sSL "$url"
-  elif command_exists curl; then
-    wget -qO- "$url"
-  else
-    error_exit "Couldn't find curl or wget.  Bailing out."
-  fi
-}
-
-# Program Functions ------------------------------------------------------------
-
-# Check host platform and docker host
-verify_prereqs() {
-  echo "Verifying Prerequisites...."
-
-  case "$(uname -s)" in
-    Darwin)
-      host_os=darwin
-      ;;
-    Linux)
-      host_os=linux
-      ;;
-    *)
-      error_exit "Unsupported host OS.  Must be Linux or Mac OS X."
-      ;;
-  esac
-
-  case "$(uname -m)" in
-    x86_64*)
-      host_arch=amd64
-      ;;
-    i?86_64*)
-      host_arch=amd64
-      ;;
-    amd64*)
-      host_arch=amd64
-      ;;
-    arm*)
-      host_arch=arm
-      ;;
-    i?86*)
-      host_arch=x86
-      ;;
-    s390x*)
-      host_arch=s390x
-      ;;
-    ppc64le*)
-      host_arch=ppc64le
-      ;;
-    *)
-      error_exit "Unsupported host arch. Must be x86_64, 386, arm, s390x or ppc64le."
-      ;;
-  esac
-
-
-  command_exists docker || error_exit "You need docker"
-
-  if ! docker info >/dev/null 2>&1 ; then
-    error_exit "Can't connect to 'docker' daemon."
-  fi
-
-  if docker inspect kubelet >/dev/null 2>&1 ; then
-    error_exit "Kubernetes is already running"
-  fi
-
-  $KUBECTL version --client >/dev/null || download_kubectl
-}
-
-# Get the latest stable release tag
-get_latest_version_number() {
-  local channel="stable"
-  if [[ -n "${ALPHA:-}" ]]; then
-    channel="latest"
-  fi
-  local latest_url="https://storage.googleapis.com/kubernetes-release/release/${channel}.txt"
-  fetch_url "$latest_url"
-}
-
-# Detect ip address od docker host
-detect_docker_host_ip() {
-  if [[ -n "${DOCKER_HOST:-}" ]]; then
-    awk -F'[/:]' '{print $4}' <<< "$DOCKER_HOST"
-  else
-    ifconfig docker0 \
-      | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' \
-      | grep -Eo '([0-9]*\.){3}[0-9]*' >/dev/null 2>&1 || :
-  fi
-}
-
-# Set KUBE_MASTER_IP from docker host ip.  Defaults to localhost
-set_master_ip() {
-  local docker_ip
-
-  if [[ -z "${KUBE_MASTER_IP:-}" ]]; then
-    docker_ip=$(detect_docker_host_ip)
-    if [[ -n "${docker_ip}" ]]; then
-      KUBE_MASTER_IP="${docker_ip}"
-    else
-      KUBE_MASTER_IP=localhost
-    fi
-  fi
-}
-
-# Start dockerized kubelet
-start_kubernetes() {
-  echo "Starting kubelet"
-
-  # Enable dns
-  if [[ "${ENABLE_CLUSTER_DNS}" = true ]]; then
-    dns_args="--cluster-dns=10.0.0.10 --cluster-domain=cluster.local"
-  else
-    # DNS server for real world hostnames.
-    dns_args="--cluster-dns=8.8.8.8"
-  fi
-
-  local start_time=$(date +%s)
-
-  docker run \
-    --name=kubelet \
-    --volume=/:/rootfs:ro \
-    --volume=/sys:/sys:ro \
-    --volume=/var/lib/docker/:/var/lib/docker:rw \
-    --volume=/var/lib/kubelet/:/var/lib/kubelet:rw,rslave \
-    --volume=/var/run:/var/run:rw \
-    --net=host \
-    --pid=host \
-    --privileged=true \
-    -d \
-    gcr.io/google_containers/hyperkube-amd64:${KUBE_VERSION} \
-      /hyperkube kubelet \
-        --containerized \
-        --hostname-override="127.0.0.1" \
-        --api-servers=http://localhost:${KUBE_PORT} \
-        --config=/etc/kubernetes/manifests \
-        --allow-privileged=true \
-        ${dns_args} \
-        --v=${LOG_LEVEL} >/dev/null
-
-  until $KUBECTL cluster-info &> /dev/null; do
-    sleep 1
-  done
-
-  if [[ $KUBE_VERSION == "1.2"* ]]; then
-    create_kube_system_namespace
-    create_kube_dns
-  fi
-
-  # We expect to have at least 3 running pods - etcd, master and kube-proxy.
-  local attempt=1
-  while (($(KUBECTL get pods --all-namespaces --no-headers 2>/dev/null | grep -c "Running") < 3)); do
-    echo -n "."
-    sleep $(( attempt++ ))
-  done
-  echo
-
-  echo "Started master components in $(($(date +%s) - start_time)) seconds."
-}
-
-# Open kubernetes master api port.
-setup_firewall() {
-  [[ -n "${DOCKER_MACHINE_NAME:-}" ]] || return
-
-  echo "Adding iptables hackery for docker-machine..."
-
-  local machine_ip
-  machine_ip=$(docker-machine ip "$DOCKER_MACHINE_NAME")
-  local iptables_rule="PREROUTING -p tcp -d ${machine_ip} --dport ${KUBE_PORT} -j DNAT --to-destination 127.0.0.1:${KUBE_PORT}"
-
-  if ! docker-machine ssh "${DOCKER_MACHINE_NAME}" "sudo /usr/local/sbin/iptables -t nat -C ${iptables_rule}" &> /dev/null; then
-    docker-machine ssh "${DOCKER_MACHINE_NAME}" "sudo /usr/local/sbin/iptables -t nat -I ${iptables_rule}"
-  fi
-}
-
-# Create kube-system namespace in kubernetes
-create_kube_system_namespace() {
-  $KUBECTL create namespace kube-system >/dev/null
-}
-
-# Activate skydns in kubernetes and wait for pods to be ready.
-create_kube_dns() {
-  [[ "${ENABLE_CLUSTER_DNS}" = true ]] || return
-
-  local start_time=$(date +%s)
-
-  echo "Setting up cluster dns..."
-
-  $KUBECTL create -f ./scripts/cluster/skydns.yaml >/dev/null
-
-  echo "Waiting for cluster DNS to become available..."
-
-  local attempt=1
-  until $KUBECTL get pods --no-headers --namespace kube-system --selector=k8s-app=kube-dns 2>/dev/null | grep "Running" &>/dev/null; do
-    echo -n "."
-    sleep $(( attempt++ ))
-  done
-  echo
-  echo "Started DNS in $(($(date +%s) - start_time)) seconds."
-}
-
-# Generate kubeconfig data for the created cluster.
-generate_kubeconfig() {
-  local cluster_args=(
-      "--server=http://${KUBE_MASTER_IP}:${KUBE_PORT}"
-      "--insecure-skip-tls-verify=true"
-  )
-
-  $KUBECTL config set-cluster "${KUBE_CONTEXT}" "${cluster_args[@]}" >/dev/null
-  $KUBECTL config set-context "${KUBE_CONTEXT}" --cluster="${KUBE_CONTEXT}" >/dev/null
-  $KUBECTL config use-context "${KUBE_CONTEXT}" >/dev/null
-
-  echo "Wrote config for kubeconfig using context: '${KUBE_CONTEXT}'"
-}
-
-# Download kubectl
-download_kubectl() {
-  echo "Downloading kubectl binary..."
-
-  local output="/usr/local/bin/kubectl"
-
-  kubectl_url="https://storage.googleapis.com/kubernetes-release/release/${KUBE_VERSION}/bin/${host_os}/${host_arch}/kubectl"
-  fetch_url "${kubectl_url}" > "${output}"
-  chmod a+x "${output}"
-
-  KUBECTL="${output}"
-}
-
-# Clean volumes that are left by kubelet
-#
-# https://github.com/kubernetes/kubernetes/issues/23197
-# code stolen from https://github.com/huggsboson/docker-compose-kubernetes/blob/SwitchToSharedMount/kube-up.sh
-clean_volumes() {
-  if [[ -n "${DOCKER_MACHINE_NAME:-}" ]]; then
-    docker-machine ssh "${DOCKER_MACHINE_NAME}" "mount | grep -o 'on /var/lib/kubelet.* type' | cut -c 4- | rev | cut -c 6- | rev | sort -r | xargs --no-run-if-empty sudo umount"
-    docker-machine ssh "${DOCKER_MACHINE_NAME}" "sudo rm -Rf /var/lib/kubelet"
-    docker-machine ssh "${DOCKER_MACHINE_NAME}" "sudo mkdir -p /var/lib/kubelet"
-    docker-machine ssh "${DOCKER_MACHINE_NAME}" "sudo mount --bind /var/lib/kubelet /var/lib/kubelet"
-    docker-machine ssh "${DOCKER_MACHINE_NAME}" "sudo mount --make-shared /var/lib/kubelet"
-  else
-    mount | grep -o 'on /var/lib/kubelet.* type' | cut -c 4- | rev | cut -c 6- | rev | sort -r | xargs --no-run-if-empty sudo umount
-    sudo rm -Rf /var/lib/kubelet
-    sudo mkdir -p /var/lib/kubelet
-    sudo mount --bind /var/lib/kubelet /var/lib/kubelet
-    sudo mount --make-shared /var/lib/kubelet
-  fi
-}
-
-# Helper function to properly remove containers
-delete_container() {
-  local container=("$@")
-  docker stop "${container[@]}" &>/dev/null || :
-  docker wait "${container[@]}" &>/dev/null || :
-  docker rm --force --volumes "${container[@]}" &>/dev/null || :
-}
-
-# Delete master components and resources in kubernetes.
-kube_down() {
-  echo "Deleting all resources in kubernetes..."
-  $KUBECTL delete replicationcontrollers,services,pods,secrets --all >/dev/null 2>&1 || :
-  $KUBECTL delete replicationcontrollers,services,pods,secrets --all --namespace=kube-system >/dev/null 2>&1 || :
-  $KUBECTL delete namespace kube-system >/dev/null 2>&1 || :
-
-  echo "Stopping kubelet..."
-  delete_container kubelet
-
-  echo "Stopping remaining kubernetes containers..."
-  local kube_containers=($(docker ps -aqf "name=k8s_"))
-  if [[ "${#kube_containers[@]}" -gt 0 ]]; then
-    delete_container "${kube_containers[@]}"
-  fi
-}
-
-# Start a kubernetes cluster in docker.
-kube_up() {
-  verify_prereqs
-
-  set_master_ip
-  clean_volumes
-  setup_firewall
-
-  generate_kubeconfig
-  start_kubernetes
-
-  $KUBECTL cluster-info
-}
-
-KUBE_VERSION=${KUBE_VERSION:-$(get_latest_version_number)}
-
-# Main -------------------------------------------------------------------------
-
-main() {
-  case "$1" in
-    up|start)
-      kube_up
-      ;;
-    down|stop)
-      kube_down
-      ;;
-    restart)
-      kube_down
-      kube_up
-      ;;
-    *)
-      echo "Usage: $0 {up|down|restart}"
-      ;;
-  esac
-}
-
-main "${@:-}"
-
diff --git a/scripts/update-docs.sh b/scripts/update-docs.sh
index 12a4ead4b3069b7d3f8af072c097ca5579048fa2..e014b537efd65149c5186557e55005704a53a72b 100755
--- a/scripts/update-docs.sh
+++ b/scripts/update-docs.sh
@@ -31,11 +31,13 @@ kube::util::ensure-temp-dir
 
 export HELM_NO_PLUGINS=1
 
-mkdir -p ${KUBE_TEMP}/docs/helm ${KUBE_TEMP}/docs/man/man1 ${KUBE_TEMP}/scripts
+# Reset Helm Home because it is used in the generation of docs.
+OLD_HELM_HOME=${HELM_HOME:-}
+HELM_HOME="$HOME/.helm"
+bin/helm init --client-only
+mkdir -p ${KUBE_TEMP}/docs/helm
 bin/helm docs --dir ${KUBE_TEMP}/docs/helm
-bin/helm docs --dir ${KUBE_TEMP}/docs/man/man1 --type man
-bin/helm docs --dir ${KUBE_TEMP}/scripts --type bash
-
+HELM_HOME=$OLD_HELM_HOME
 
 FILES=$(find ${KUBE_TEMP} -type f)
 
diff --git a/scripts/verify-docs.sh b/scripts/verify-docs.sh
index 72af9e743d05a9b06fc267e2f64a373d89c5060f..b0b799eacb075351701c705567e09f2388a8fc6c 100755
--- a/scripts/verify-docs.sh
+++ b/scripts/verify-docs.sh
@@ -31,10 +31,13 @@ kube::util::ensure-temp-dir
 
 export HELM_NO_PLUGINS=1
 
-mkdir -p ${KUBE_TEMP}/docs/helm ${KUBE_TEMP}/docs/man/man1 ${KUBE_TEMP}/scripts
+# Reset Helm Home because it is used in the generation of docs.
+OLD_HELM_HOME=${HELM_HOME:-}
+HELM_HOME="$HOME/.helm"
+bin/helm init --client-only
+mkdir -p ${KUBE_TEMP}/docs/helm
 bin/helm docs --dir ${KUBE_TEMP}/docs/helm
-bin/helm docs --dir ${KUBE_TEMP}/docs/man/man1 --type man
-bin/helm docs --dir ${KUBE_TEMP}/scripts --type bash
+HELM_HOME=$OLD_HELM_HOME
 
 
 FILES=$(find ${KUBE_TEMP} -type f)
diff --git a/versioning.mk b/versioning.mk
index b336a7999bad3c5b026cfc011492938c965d993a..2333530d93f8cea5a355edda08e9ab13a5593013 100644
--- a/versioning.mk
+++ b/versioning.mk
@@ -1,9 +1,9 @@
-MUTABLE_VERSION ?= canary
+MUTABLE_VERSION := canary
 
-GIT_COMMIT ?= $(shell git rev-parse HEAD)
-GIT_SHA ?= $(shell git rev-parse --short HEAD)
-GIT_TAG ?= $(shell git describe --tags --abbrev=0 2>/dev/null)
-GIT_DIRTY ?= $(shell test -n "`git status --porcelain`" && echo "dirty" || echo "clean")
+GIT_COMMIT = $(shell git rev-parse HEAD)
+GIT_SHA    = $(shell git rev-parse --short HEAD)
+GIT_TAG    = $(shell git describe --tags --abbrev=0 --exact-match 2>/dev/null)
+GIT_DIRTY  = $(shell test -n "`git status --porcelain`" && echo "dirty" || echo "clean")
 
 ifdef VERSION
 	DOCKER_VERSION = $(VERSION)
@@ -11,25 +11,39 @@ ifdef VERSION
 endif
 
 DOCKER_VERSION ?= git-${GIT_SHA}
-BINARY_VERSION ?= ${GIT_TAG}-${GIT_SHA}
+BINARY_VERSION ?= ${GIT_TAG}
 
-IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${DOCKER_VERSION}
-MUTABLE_IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${MUTABLE_VERSION}
+# Only set Version if building a tag or VERSION is set
+ifneq ($(BINARY_VERSION),)
+	LDFLAGS += -X k8s.io/helm/pkg/version.Version=${BINARY_VERSION}
+endif
 
-LDFLAGS += -X k8s.io/helm/pkg/version.Version=${GIT_TAG}
+# Clear the "unreleased" string in BuildMetadata
+ifneq ($(GIT_TAG),)
+	LDFLAGS += -X k8s.io/helm/pkg/version.BuildMetadata=
+endif
 LDFLAGS += -X k8s.io/helm/pkg/version.GitCommit=${GIT_COMMIT}
 LDFLAGS += -X k8s.io/helm/pkg/version.GitTreeState=${GIT_DIRTY}
 
+IMAGE                := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${DOCKER_VERSION}
+IMAGE_RUDDER         := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME_RUDDER}:${DOCKER_VERSION}
+MUTABLE_IMAGE        := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${MUTABLE_VERSION}
+MUTABLE_IMAGE_RUDDER := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME_RUDDER}:${DOCKER_VERSION}
+
 DOCKER_PUSH = docker push
 ifeq ($(DOCKER_REGISTRY),gcr.io)
 	DOCKER_PUSH = gcloud docker push
 endif
 
 info:
-	@echo "Build tag:       ${DOCKER_VERSION}"
-	@echo "Registry:        ${DOCKER_REGISTRY}"
-	@echo "Immutable tag:   ${IMAGE}"
-	@echo "Mutable tag:     ${MUTABLE_IMAGE}"
+	 @echo "Version:           ${VERSION}"
+	 @echo "Git Tag:           ${GIT_TAG}"
+	 @echo "Git Commit:        ${GIT_COMMIT}"
+	 @echo "Git Tree State:    ${GIT_DIRTY}"
+	 @echo "Docker Version:    ${DOCKER_VERSION}"
+	 @echo "Registry:          ${DOCKER_REGISTRY}"
+	 @echo "Immutable Image:   ${IMAGE}"
+	 @echo "Mutable Image:     ${MUTABLE_IMAGE}"
 
 .PHONY: docker-push
 docker-push: docker-mutable-push docker-immutable-push