Merge branch 'master' into feat/add-hpa-and-env

pull/5110/head
Naseem 6 years ago committed by GitHub
commit f9d6aadbb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,17 +0,0 @@
version: "{build}"
clone_folder: c:\go\src\k8s.io\helm
environment:
GOPATH: c:\go
PATH: c:\ProgramData\bin;$(PATH)
install:
- ps: iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/fishworks/gofish/master/scripts/install.ps1'))
- gofish init
- gofish install glide
- glide install --strip-vendor
cache:
- vendor -> glide.lock
build: "off"
deploy: "off"
test_script:
- go build .\cmd\...
- go test .\...

@ -4,13 +4,13 @@ jobs:
working_directory: /go/src/k8s.io/helm working_directory: /go/src/k8s.io/helm
parallelism: 3 parallelism: 3
docker: docker:
- image: golang:1.11 - image: golang:1.12.5
environment: environment:
PROJECT_NAME: "kubernetes-helm" PROJECT_NAME: "kubernetes-helm"
steps: steps:
- checkout - checkout
- setup_remote_docker: - setup_remote_docker:
version: 17.09.0-ce version: 18.06.0-ce
- restore_cache: - restore_cache:
keys: keys:
- glide-{{ checksum "glide.yaml" }}-{{ checksum "glide.lock" }} - glide-{{ checksum "glide.yaml" }}-{{ checksum "glide.lock" }}

7
.gitignore vendored

@ -11,4 +11,9 @@ rootfs/rudder
vendor/ vendor/
*.exe *.exe
.idea/ .idea/
*.iml *.iml
*.swp
*~
.classpath
.project
.settings/**

@ -1,6 +1,6 @@
# Contributing Guidelines # Contributing Guidelines
The Kubernetes Helm project accepts contributions via GitHub pull requests. This document outlines the process to help get your contribution accepted. The Helm project accepts contributions via GitHub pull requests. This document outlines the process to help get your contribution accepted.
## Reporting a Security Issue ## Reporting a Security Issue
@ -15,7 +15,7 @@ us a chance to try to fix the issue before it is exploited in the wild.
The sign-off is a simple line at the end of the explanation for a commit. All The sign-off is a simple line at the end of the explanation for a commit. All
commits needs to be signed. Your signature certifies that you wrote the patch or commits needs to be signed. Your signature certifies that you wrote the patch or
otherwise have the right to contribute the material. The rules are pretty simple, otherwise have the right to contribute the material. The rules are pretty simple,
if you can certify the below (from [developercertificate.org](http://developercertificate.org/)): if you can certify the below (from [developercertificate.org](https://developercertificate.org/)):
``` ```
Developer Certificate of Origin Developer Certificate of Origin
@ -172,10 +172,44 @@ contributing to Helm. All issue types follow the same general lifecycle. Differe
## How to Contribute a Patch ## How to Contribute a Patch
1. Fork the repo, develop and test your code changes. 1. **Fork** the repo [helm](https://github.com/helm/helm)
1. Use sign-off when making each of your commits (see [above](#sign-your-work)).
Go to https://github.com/helm/helm then hit the `Fork` button to fork your own copy of repository **helm** to your github account.
2. **Clone** the forked repo to your local working directory.
```sh
$ git clone https://github.com/$your_github_account/helm.git
```
3. Add an `upstream` remote to keep your fork in sync with the main repo.
```sh
$ cd helm
$ git remote add upstream https://github.com/helm/helm.git
$ git remote -v
origin https://github.com/$your_github_account/helm.git (fetch)
origin https://github.com/$your_github_account/helm.git (push)
upstream https://github.com/helm/helm.git (fetch)
upstream https://github.com/helm/helm.git (push)
```
4. Sync your local `master` branch.
```sh
$ git pull upstream master
```
5. Create a branch to add a new feature or fix issues.
```sh
$ git checkout -b new-feature
```
6. Make any change on the branch `new-feature` then build and test your codes.
7. Include in what will be committed.
```sh
$ git add <file>
```
8. Use sign-off when making each of your commits (see [above](#sign-your-work)).
If you forgot to sign some commits that are part of the contribution, you can ask [git to rewrite your commit history](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History). If you forgot to sign some commits that are part of the contribution, you can ask [git to rewrite your commit history](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History).
1. Submit a pull request. ```sh
$ git commit --signoff
```
9. Submit a pull request.
Coding conventions and standards are explained in the official developer docs: Coding conventions and standards are explained in the official developer docs:
[Developers Guide](docs/developers.md) [Developers Guide](docs/developers.md)
@ -242,7 +276,7 @@ Documentation PRs will follow the same lifecycle as other PRs. They will also be
## The Triager ## The Triager
Each week, one of the core maintainers will serve as the designated "triager" starting after the Each week, one of the core maintainers will serve as the designated "triager" starting after the
public standup meetings on Thursday. This person will be in charge triaging new PRs and issues public stand-up meetings on Thursday. This person will be in charge triaging new PRs and issues
throughout the work week. throughout the work week.
## Labels ## Labels

@ -1,9 +1,10 @@
DOCKER_REGISTRY ?= gcr.io DOCKER_REGISTRY ?= gcr.io
IMAGE_PREFIX ?= kubernetes-helm IMAGE_PREFIX ?= kubernetes-helm
DEV_IMAGE ?= golang:1.11 DEV_IMAGE ?= golang:1.12.5
SHORT_NAME ?= tiller SHORT_NAME ?= tiller
SHORT_NAME_RUDDER ?= rudder SHORT_NAME_RUDDER ?= rudder
TARGETS ?= darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le linux/s390x windows/amd64 TARGETS ?= darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le linux/s390x windows/amd64
TARGET_OBJS ?= darwin-amd64.tar.gz darwin-amd64.tar.gz.sha256 linux-amd64.tar.gz linux-amd64.tar.gz.sha256 linux-386.tar.gz linux-386.tar.gz.sha256 linux-arm.tar.gz linux-arm.tar.gz.sha256 linux-arm64.tar.gz linux-arm64.tar.gz.sha256 linux-ppc64le.tar.gz linux-ppc64le.tar.gz.sha256 linux-s390x.tar.gz linux-s390x.tar.gz.sha256 windows-amd64.zip windows-amd64.zip.sha256
DIST_DIRS = find * -type d -exec DIST_DIRS = find * -type d -exec
# go option # go option
@ -44,10 +45,25 @@ dist:
$(DIST_DIRS) zip -r helm-${VERSION}-{}.zip {} \; \ $(DIST_DIRS) zip -r helm-${VERSION}-{}.zip {} \; \
) )
.PHONY: fetch-dist
fetch-dist:
mkdir -p _dist
cd _dist && \
for obj in ${TARGET_OBJS} ; do \
curl -sSL -o helm-${VERSION}-$${obj} https://storage.googleapis.com/kubernetes-helm/helm-${VERSION}-$${obj} ; \
done
.PHONY: sign
sign:
for f in _dist/*.{gz,zip,sha256} ; do \
gpg --armor --detach-sign $${f} ; \
done
.PHONY: checksum .PHONY: checksum
checksum: checksum:
for f in _dist/*.{gz,zip} ; do \ for f in _dist/*.{gz,zip} ; do \
shasum -a 256 "$${f}" | awk '{print $$1}' > "$${f}.sha256" ; \ shasum -a 256 "$${f}" | awk '{print $$1}' > "$${f}.sha256" ; \
echo -n "Checksum: " && cat $${f}.sha256 ; \
done done
.PHONY: check-docker .PHONY: check-docker

@ -1,24 +1,11 @@
maintainers: maintainers:
- adamreese
- bacongobbler
- jascott1
- mattfarina
- michelleN
- nebril
- prydonius
- SlickNik
- technosophos
- thomastaylor312
- viglesiasce
reviewers:
- adamreese - adamreese
- bacongobbler - bacongobbler
- fibonacci1729 - fibonacci1729
- hickeyma
- jascott1 - jascott1
- mattfarina - mattfarina
- michelleN - michelleN
- migmartri
- nebril
- prydonius - prydonius
- SlickNik - SlickNik
- technosophos - technosophos
@ -26,6 +13,7 @@ reviewers:
- viglesiasce - viglesiasce
emeritus: emeritus:
- migmartri - migmartri
- nebril
- seh - seh
- vaikas-google - vaikas-google
- rimusz - rimusz

@ -3,8 +3,8 @@ Protobuf3 type declarations for the Helm API
Packages Packages
- `hapi.chart` Complete serialization of Heml charts - `hapi.chart` Complete serialization of Helm charts
- `hapi.release` Information about installed charts (Releases) such as metadata about when they were installed, their status, and how they were configured. - `hapi.release` Information about installed charts (Releases) such as metadata about when they were installed, their status, and how they were configured.
- `hapi.services.rudder` Definition for the ReleaseModuleService used by Tiller to manipulate releases on a given node - `hapi.services.rudder` Definition for the ReleaseModuleService used by Tiller to manipulate releases on a given node
- `hapi.services.tiller` Definition of the ReleaseService provided by Tiller and used by Helm clients to manipulate releases cluster wide. - `hapi.services.tiller` Definition of the ReleaseService provided by Tiller and used by Helm clients to manipulate releases cluster wide.
- `hapi.version` Version meta-data used by tiller to express it's version - `hapi.version` Version metadata used by Tiller to express its version

@ -29,7 +29,7 @@ message Status {
UNKNOWN = 0; UNKNOWN = 0;
// Status_DEPLOYED indicates that the release has been pushed to Kubernetes. // Status_DEPLOYED indicates that the release has been pushed to Kubernetes.
DEPLOYED = 1; DEPLOYED = 1;
// Status_DELETED indicates that a release has been deleted from Kubermetes. // Status_DELETED indicates that a release has been deleted from Kubernetes.
DELETED = 2; DELETED = 2;
// Status_SUPERSEDED indicates that this release object is outdated and a newer one exists. // Status_SUPERSEDED indicates that this release object is outdated and a newer one exists.
SUPERSEDED = 3; SUPERSEDED = 3;

@ -92,6 +92,7 @@ message UpgradeReleaseRequest{
bool Wait = 4; bool Wait = 4;
bool Recreate = 5; bool Recreate = 5;
bool Force = 6; bool Force = 6;
bool CleanupOnFail = 7;
} }
message UpgradeReleaseResponse{ message UpgradeReleaseResponse{
hapi.release.Release release = 1; hapi.release.Release release = 1;
@ -105,6 +106,7 @@ message RollbackReleaseRequest{
bool Wait = 4; bool Wait = 4;
bool Recreate = 5; bool Recreate = 5;
bool Force = 6; bool Force = 6;
bool CleanupOnFail = 7;
} }
message RollbackReleaseResponse{ message RollbackReleaseResponse{
hapi.release.Release release = 1; hapi.release.Release release = 1;

@ -212,8 +212,10 @@ message UpdateReleaseRequest {
bool force = 11; bool force = 11;
// Description, if set, will set the description for the updated release // Description, if set, will set the description for the updated release
string description = 12; string description = 12;
// Render subchart notes if enabled // Render subchart notes if enabled
bool subNotes = 13; bool subNotes = 13;
// Allow deletion of new resources created in this update when update failed
bool cleanup_on_fail = 14;
} }
// UpdateReleaseResponse is the response to an update request. // UpdateReleaseResponse is the response to an update request.
@ -241,6 +243,8 @@ message RollbackReleaseRequest {
bool force = 8; bool force = 8;
// Description, if set, will set the description for the rollback // Description, if set, will set the description for the rollback
string description = 9; string description = 9;
// Allow deletion of new resources created in this rollback when rollback failed
bool cleanup_on_fail = 10;
} }
// RollbackReleaseResponse is the response to an update request. // RollbackReleaseResponse is the response to an update request.
@ -283,8 +287,8 @@ message InstallReleaseRequest {
// Description, if set, will set the description for the installed release // Description, if set, will set the description for the installed release
string description = 11; string description = 11;
bool subNotes = 12; bool subNotes = 12;
} }

@ -212,7 +212,8 @@ __helm_convert_bash_to_zsh() {
-e "s/${LWORD}compopt${RWORD}/__helm_compopt/g" \ -e "s/${LWORD}compopt${RWORD}/__helm_compopt/g" \
-e "s/${LWORD}declare${RWORD}/__helm_declare/g" \ -e "s/${LWORD}declare${RWORD}/__helm_declare/g" \
-e "s/\\\$(type${RWORD}/\$(__helm_type/g" \ -e "s/\\\$(type${RWORD}/\$(__helm_type/g" \
-e 's/aliashash\["\(\w\+\)"\]/aliashash[\1]/g' \ -e 's/aliashash\["\(.\{1,\}\)"\]/aliashash[\1]/g' \
-e 's/FUNCNAME/funcstack/g' \
<<'BASH_COMPLETION_EOF' <<'BASH_COMPLETION_EOF'
` `
out.Write([]byte(zshInitialization)) out.Write([]byte(zshInitialization))

@ -73,7 +73,7 @@ the dependency charts stored locally. The path should start with a prefix of
repository: "file://../dependency_chart/nginx" repository: "file://../dependency_chart/nginx"
If the dependency chart is retrieved locally, it is not required to have the If the dependency chart is retrieved locally, it is not required to have the
repository added to helm by "helm add repo". Version matching is also supported repository added to helm by "helm repo add". Version matching is also supported
for this case. for this case.
` `

@ -29,11 +29,11 @@ const dependencyBuildDesc = `
Build out the charts/ directory from the requirements.lock file. Build out the charts/ directory from the requirements.lock file.
Build is used to reconstruct a chart's dependencies to the state specified in Build is used to reconstruct a chart's dependencies to the state specified in
the lock file. This will not re-negotiate dependencies, as 'helm dependency update' the lock file.
does.
If no lock file is found, 'helm dependency build' will mirror the behavior If no lock file is found, 'helm dependency build' will mirror the behavior of
of 'helm dependency update'. the 'helm dependency update' command. This means it will update the on-disk
dependencies to mirror the requirements.yaml file and generate a lock file.
` `
type dependencyBuildCmd struct { type dependencyBuildCmd struct {

@ -41,10 +41,11 @@ chart, the supplied values, and the generated manifest file.
var errReleaseRequired = errors.New("release name is required") var errReleaseRequired = errors.New("release name is required")
type getCmd struct { type getCmd struct {
release string release string
out io.Writer out io.Writer
client helm.Interface client helm.Interface
version int32 version int32
template string
} }
func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command { func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
@ -73,6 +74,7 @@ func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
f := cmd.Flags() f := cmd.Flags()
settings.AddFlagsTLS(f) settings.AddFlagsTLS(f)
f.Int32Var(&get.version, "revision", 0, "get the named release with revision") f.Int32Var(&get.version, "revision", 0, "get the named release with revision")
f.StringVar(&get.template, "template", "", "go template for formatting the output, eg: {{.Release.Name}}")
cmd.AddCommand(newGetValuesCmd(nil, out)) cmd.AddCommand(newGetValuesCmd(nil, out))
cmd.AddCommand(newGetManifestCmd(nil, out)) cmd.AddCommand(newGetManifestCmd(nil, out))
@ -91,5 +93,9 @@ func (g *getCmd) run() error {
if err != nil { if err != nil {
return prettyError(err) return prettyError(err)
} }
if g.template != "" {
return tpl(g.template, res, g.out)
}
return printRelease(g.out, res.Release) return printRelease(g.out, res.Release)
} }

@ -35,6 +35,13 @@ func TestGetCmd(t *testing.T) {
expected: "REVISION: 1\nRELEASED: (.*)\nCHART: foo-0.1.0-beta.1\nUSER-SUPPLIED VALUES:\nname: \"value\"\nCOMPUTED VALUES:\nname: value\n\nHOOKS:\n---\n# pre-install-hook\n" + helm.MockHookTemplate + "\nMANIFEST:", expected: "REVISION: 1\nRELEASED: (.*)\nCHART: foo-0.1.0-beta.1\nUSER-SUPPLIED VALUES:\nname: \"value\"\nCOMPUTED VALUES:\nname: value\n\nHOOKS:\n---\n# pre-install-hook\n" + helm.MockHookTemplate + "\nMANIFEST:",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"})},
}, },
{
name: "get with a formatted release",
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "elevated-turkey"}),
args: []string{"elevated-turkey", "--template", "{{.Release.Chart.Metadata.Version}}"},
expected: "0.1.0-beta.1",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "elevated-turkey"})},
},
{ {
name: "get requires release name arg", name: "get requires release name arg",
err: true, err: true,

@ -61,18 +61,19 @@ Common actions from this point include:
- helm list: list releases of charts - helm list: list releases of charts
Environment: Environment:
$HELM_HOME set an alternative location for Helm files. By default, these are stored in ~/.helm
$HELM_HOST set an alternative Tiller host. The format is host:port - $HELM_HOME: set an alternative location for Helm files. By default, these are stored in ~/.helm
$HELM_NO_PLUGINS disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. - $HELM_HOST: set an alternative Tiller host. The format is host:port
$TILLER_NAMESPACE set an alternative Tiller namespace (default "kube-system") - $HELM_NO_PLUGINS: disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.
$KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config") - $TILLER_NAMESPACE: set an alternative Tiller namespace (default "kube-system")
$HELM_TLS_CA_CERT path to TLS CA certificate used to verify the Helm client and Tiller server certificates (default "$HELM_HOME/ca.pem") - $KUBECONFIG: set an alternative Kubernetes configuration file (default "~/.kube/config")
$HELM_TLS_CERT path to TLS client certificate file for authenticating to Tiller (default "$HELM_HOME/cert.pem") - $HELM_TLS_CA_CERT: path to TLS CA certificate used to verify the Helm client and Tiller server certificates (default "$HELM_HOME/ca.pem")
$HELM_TLS_KEY path to TLS client key file for authenticating to Tiller (default "$HELM_HOME/key.pem") - $HELM_TLS_CERT: path to TLS client certificate file for authenticating to Tiller (default "$HELM_HOME/cert.pem")
$HELM_TLS_VERIFY enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false") - $HELM_TLS_KEY: path to TLS client key file for authenticating to Tiller (default "$HELM_HOME/key.pem")
$HELM_TLS_ENABLE enable TLS connection between Helm and Tiller (default "false") - $HELM_TLS_ENABLE: enable TLS connection between Helm and Tiller (default "false")
$HELM_KEY_PASSPHRASE set HELM_KEY_PASSPHRASE to the passphrase of your PGP private key. If set, you will not be prompted for - $HELM_TLS_VERIFY: enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false")
the passphrase while signing helm charts - $HELM_TLS_HOSTNAME: the hostname or IP address used to verify the Tiller server certificate (default "127.0.0.1")
- $HELM_KEY_PASSPHRASE: set HELM_KEY_PASSPHRASE to the passphrase of your PGP private key. If set, you will not be prompted for the passphrase while signing helm charts
` `

@ -30,6 +30,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/client-go/util/homedir" "k8s.io/client-go/util/homedir"
"k8s.io/helm/cmd/helm/installer"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/helm/environment" "k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/helm/helmpath" "k8s.io/helm/pkg/helm/helmpath"
@ -137,7 +138,7 @@ func ensureTestHome(home helmpath.Home, t *testing.T) error {
} }
} }
localRepoIndexFile := home.LocalRepository(localRepositoryIndexFile) localRepoIndexFile := home.LocalRepository(installer.LocalRepositoryIndexFile)
if fi, err := os.Stat(localRepoIndexFile); err != nil { if fi, err := os.Stat(localRepoIndexFile); err != nil {
i := repo.NewIndexFile() i := repo.NewIndexFile()
if err := i.WriteFile(localRepoIndexFile, 0644); err != nil { if err := i.WriteFile(localRepoIndexFile, 0644); err != nil {

@ -31,11 +31,9 @@ import (
"k8s.io/apimachinery/pkg/util/yaml" "k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/helm/cmd/helm/installer" "k8s.io/helm/cmd/helm/installer"
"k8s.io/helm/pkg/getter"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/helm/helmpath" "k8s.io/helm/pkg/helm/helmpath"
"k8s.io/helm/pkg/helm/portforwarder" "k8s.io/helm/pkg/helm/portforwarder"
"k8s.io/helm/pkg/repo"
"k8s.io/helm/pkg/version" "k8s.io/helm/pkg/version"
) )
@ -60,12 +58,6 @@ To dump a manifest containing the Tiller deployment YAML, combine the
'--dry-run' and '--debug' flags. '--dry-run' and '--debug' flags.
` `
const (
stableRepository = "stable"
localRepository = "local"
localRepositoryIndexFile = "index.yaml"
)
var ( var (
stableRepositoryURL = "https://kubernetes-charts.storage.googleapis.com" stableRepositoryURL = "https://kubernetes-charts.storage.googleapis.com"
// This is the IPv4 loopback, not localhost, because we have to force IPv4 // This is the IPv4 loopback, not localhost, because we have to force IPv4
@ -266,14 +258,8 @@ func (i *initCmd) run() error {
return nil return nil
} }
if err := ensureDirectories(i.home, i.out); err != nil { if err := installer.Initialize(i.home, i.out, i.skipRefresh, settings, stableRepositoryURL, localRepositoryURL); err != nil {
return err return fmt.Errorf("error initializing: %s", err)
}
if err := ensureDefaultRepos(i.home, i.out, i.skipRefresh); err != nil {
return err
}
if err := ensureRepoFileFormat(i.home.RepositoryFile(), i.out); err != nil {
return err
} }
fmt.Fprintf(i.out, "$HELM_HOME has been configured at %s.\n", settings.Home) fmt.Fprintf(i.out, "$HELM_HOME has been configured at %s.\n", settings.Home)
@ -324,7 +310,6 @@ func (i *initCmd) run() error {
"$ helm init --tiller-image gcr.io/kubernetes-helm/tiller:v2.8.2\n\n") "$ helm init --tiller-image gcr.io/kubernetes-helm/tiller:v2.8.2\n\n")
} }
fmt.Fprintln(i.out, "Happy Helming!")
return nil return nil
} }
@ -351,117 +336,6 @@ func (i *initCmd) ping(image string) error {
return nil return nil
} }
// ensureDirectories checks to see if $HELM_HOME exists.
//
// If $HELM_HOME does not exist, this function will create it.
func ensureDirectories(home helmpath.Home, out io.Writer) error {
configDirectories := []string{
home.String(),
home.Repository(),
home.Cache(),
home.LocalRepository(),
home.Plugins(),
home.Starters(),
home.Archive(),
}
for _, p := range configDirectories {
if fi, err := os.Stat(p); err != nil {
fmt.Fprintf(out, "Creating %s \n", p)
if err := os.MkdirAll(p, 0755); err != nil {
return fmt.Errorf("Could not create %s: %s", p, err)
}
} else if !fi.IsDir() {
return fmt.Errorf("%s must be a directory", p)
}
}
return nil
}
func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool) error {
repoFile := home.RepositoryFile()
if fi, err := os.Stat(repoFile); err != nil {
fmt.Fprintf(out, "Creating %s \n", repoFile)
f := repo.NewRepoFile()
sr, err := initStableRepo(home.CacheIndex(stableRepository), out, skipRefresh, home)
if err != nil {
return err
}
lr, err := initLocalRepo(home.LocalRepository(localRepositoryIndexFile), home.CacheIndex("local"), out, home)
if err != nil {
return err
}
f.Add(sr)
f.Add(lr)
if err := f.WriteFile(repoFile, 0644); err != nil {
return err
}
} else if fi.IsDir() {
return fmt.Errorf("%s must be a file, not a directory", repoFile)
}
return nil
}
func initStableRepo(cacheFile string, out io.Writer, skipRefresh bool, home helmpath.Home) (*repo.Entry, error) {
fmt.Fprintf(out, "Adding %s repo with URL: %s \n", stableRepository, stableRepositoryURL)
c := repo.Entry{
Name: stableRepository,
URL: stableRepositoryURL,
Cache: cacheFile,
}
r, err := repo.NewChartRepository(&c, getter.All(settings))
if err != nil {
return nil, err
}
if skipRefresh {
return &c, nil
}
// In this case, the cacheFile is always absolute. So passing empty string
// is safe.
if err := r.DownloadIndexFile(""); err != nil {
return nil, fmt.Errorf("Looks like %q is not a valid chart repository or cannot be reached: %s", stableRepositoryURL, err.Error())
}
return &c, nil
}
func initLocalRepo(indexFile, cacheFile string, out io.Writer, home helmpath.Home) (*repo.Entry, error) {
if fi, err := os.Stat(indexFile); err != nil {
fmt.Fprintf(out, "Adding %s repo with URL: %s \n", localRepository, localRepositoryURL)
i := repo.NewIndexFile()
if err := i.WriteFile(indexFile, 0644); err != nil {
return nil, err
}
//TODO: take this out and replace with helm update functionality
if err := createLink(indexFile, cacheFile, home); err != nil {
return nil, err
}
} else if fi.IsDir() {
return nil, fmt.Errorf("%s must be a file, not a directory", indexFile)
}
return &repo.Entry{
Name: localRepository,
URL: localRepositoryURL,
Cache: cacheFile,
}, nil
}
func ensureRepoFileFormat(file string, out io.Writer) error {
r, err := repo.LoadRepositoriesFile(file)
if err == repo.ErrRepoOutOfDate {
fmt.Fprintln(out, "Updating repository file format...")
if err := r.WriteFile(file, 0644); err != nil {
return err
}
}
return nil
}
// watchTillerUntilReady waits for the tiller pod to become available. This is useful in situations where we // watchTillerUntilReady waits for the tiller pod to become available. This is useful in situations where we
// want to wait before we call New(). // want to wait before we call New().
// //

@ -28,7 +28,7 @@ import (
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1" "k8s.io/api/extensions/v1beta1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -179,51 +179,6 @@ func TestInitCmd_dryRun(t *testing.T) {
} }
} }
func TestEnsureHome(t *testing.T) {
home, err := ioutil.TempDir("", "helm_home")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(home)
b := bytes.NewBuffer(nil)
hh := helmpath.Home(home)
settings.Home = hh
if err := ensureDirectories(hh, b); err != nil {
t.Error(err)
}
if err := ensureDefaultRepos(hh, b, false); err != nil {
t.Error(err)
}
if err := ensureDefaultRepos(hh, b, true); err != nil {
t.Error(err)
}
if err := ensureRepoFileFormat(hh.RepositoryFile(), b); err != nil {
t.Error(err)
}
expectedDirs := []string{hh.String(), hh.Repository(), hh.Cache(), hh.LocalRepository()}
for _, dir := range expectedDirs {
if fi, err := os.Stat(dir); err != nil {
t.Errorf("%s", err)
} else if !fi.IsDir() {
t.Errorf("%s is not a directory", fi)
}
}
if fi, err := os.Stat(hh.RepositoryFile()); err != nil {
t.Error(err)
} else if fi.IsDir() {
t.Errorf("%s should not be a directory", fi)
}
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)
}
}
func TestInitCmd_tlsOptions(t *testing.T) { func TestInitCmd_tlsOptions(t *testing.T) {
const testDir = "../../testdata" const testDir = "../../testdata"

@ -27,27 +27,26 @@ import (
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
) )
const inspectDesc = ` const (
inspectDesc = `
This command inspects a chart and displays information. It takes a chart reference This command inspects a chart and displays information. It takes a chart reference
('stable/drupal'), a full path to a directory or packaged chart, or a URL. ('stable/drupal'), a full path to a directory or packaged chart, or a URL.
Inspect prints the contents of the Chart.yaml file and the values.yaml file. Inspect prints the contents of the Chart.yaml file and the values.yaml file.
` `
inspectValuesDesc = `
const inspectValuesDesc = `
This command inspects a chart (directory, file, or URL) and displays the contents This command inspects a chart (directory, file, or URL) and displays the contents
of the values.yaml file of the values.yaml file
` `
inspectChartDesc = `
const inspectChartDesc = `
This command inspects a chart (directory, file, or URL) and displays the contents This command inspects a chart (directory, file, or URL) and displays the contents
of the Charts.yaml file of the Charts.yaml file
` `
readmeChartDesc = `
const readmeChartDesc = `
This command inspects a chart (directory, file, or URL) and displays the contents This command inspects a chart (directory, file, or URL) and displays the contents
of the README file of the README file
` `
)
type inspectCmd struct { type inspectCmd struct {
chartpath string chartpath string

@ -0,0 +1,163 @@
/*
Copyright The Helm 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.
*/
package installer // import "k8s.io/helm/cmd/helm/installer"
import (
"fmt"
"io"
"os"
"k8s.io/helm/pkg/getter"
helm_env "k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/helm/helmpath"
"k8s.io/helm/pkg/repo"
)
const (
stableRepository = "stable"
// LocalRepository is the standard name of the local repository
LocalRepository = "local"
// LocalRepositoryIndexFile is the standard name of the local repository index file
LocalRepositoryIndexFile = "index.yaml"
)
// Initialize initializes local config
//
// Returns an error if the command failed.
func Initialize(home helmpath.Home, out io.Writer, skipRefresh bool, settings helm_env.EnvSettings, stableRepositoryURL, localRepositoryURL string) error {
if err := ensureDirectories(home, out); err != nil {
return err
}
if err := ensureDefaultRepos(home, out, skipRefresh, settings, stableRepositoryURL, localRepositoryURL); err != nil {
return err
}
return ensureRepoFileFormat(home.RepositoryFile(), out)
}
// ensureDirectories checks to see if $HELM_HOME exists.
//
// If $HELM_HOME does not exist, this function will create it.
func ensureDirectories(home helmpath.Home, out io.Writer) error {
configDirectories := []string{
home.String(),
home.Repository(),
home.Cache(),
home.LocalRepository(),
home.Plugins(),
home.Starters(),
home.Archive(),
}
for _, p := range configDirectories {
if fi, err := os.Stat(p); err != nil {
fmt.Fprintf(out, "Creating %s \n", p)
if err := os.MkdirAll(p, 0755); err != nil {
return fmt.Errorf("Could not create %s: %s", p, err)
}
} else if !fi.IsDir() {
return fmt.Errorf("%s must be a directory", p)
}
}
return nil
}
func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool, settings helm_env.EnvSettings, stableRepositoryURL, localRepositoryURL string) error {
repoFile := home.RepositoryFile()
if fi, err := os.Stat(repoFile); err != nil {
fmt.Fprintf(out, "Creating %s \n", repoFile)
f := repo.NewRepoFile()
sr, err := initStableRepo(home.CacheIndex(stableRepository), home, out, skipRefresh, settings, stableRepositoryURL)
if err != nil {
return err
}
lr, err := initLocalRepo(home.LocalRepository(LocalRepositoryIndexFile), home.CacheIndex("local"), home, out, settings, localRepositoryURL)
if err != nil {
return err
}
f.Add(sr)
f.Add(lr)
if err := f.WriteFile(repoFile, 0644); err != nil {
return err
}
} else if fi.IsDir() {
return fmt.Errorf("%s must be a file, not a directory", repoFile)
}
return nil
}
func initStableRepo(cacheFile string, home helmpath.Home, out io.Writer, skipRefresh bool, settings helm_env.EnvSettings, stableRepositoryURL string) (*repo.Entry, error) {
fmt.Fprintf(out, "Adding %s repo with URL: %s \n", stableRepository, stableRepositoryURL)
c := repo.Entry{
Name: stableRepository,
URL: stableRepositoryURL,
Cache: cacheFile,
}
r, err := repo.NewChartRepository(&c, getter.All(settings))
if err != nil {
return nil, err
}
if skipRefresh {
return &c, nil
}
// In this case, the cacheFile is always absolute. So passing empty string
// is safe.
if err := r.DownloadIndexFile(""); err != nil {
return nil, fmt.Errorf("Looks like %q is not a valid chart repository or cannot be reached: %s", stableRepositoryURL, err.Error())
}
return &c, nil
}
func initLocalRepo(indexFile, cacheFile string, home helmpath.Home, out io.Writer, settings helm_env.EnvSettings, localRepositoryURL string) (*repo.Entry, error) {
if fi, err := os.Stat(indexFile); err != nil {
fmt.Fprintf(out, "Adding %s repo with URL: %s \n", LocalRepository, localRepositoryURL)
i := repo.NewIndexFile()
if err := i.WriteFile(indexFile, 0644); err != nil {
return nil, err
}
//TODO: take this out and replace with helm update functionality
if err := createLink(indexFile, cacheFile, home); err != nil {
return nil, err
}
} else if fi.IsDir() {
return nil, fmt.Errorf("%s must be a file, not a directory", indexFile)
}
return &repo.Entry{
Name: LocalRepository,
URL: localRepositoryURL,
Cache: cacheFile,
}, nil
}
func ensureRepoFileFormat(file string, out io.Writer) error {
r, err := repo.LoadRepositoriesFile(file)
if err == repo.ErrRepoOutOfDate {
fmt.Fprintln(out, "Updating repository file format...")
if err := r.WriteFile(file, 0644); err != nil {
return err
}
}
return nil
}

@ -0,0 +1,120 @@
/*
Copyright The Helm 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.
*/
package installer // import "k8s.io/helm/cmd/helm/installer"
import (
"bytes"
"io/ioutil"
"os"
"testing"
helm_env "k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/helm/helmpath"
)
func TestInitialize(t *testing.T) {
home, err := ioutil.TempDir("", "helm_home")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(home)
b := bytes.NewBuffer(nil)
hh := helmpath.Home(home)
settings := helm_env.EnvSettings{
Home: hh,
}
stableRepositoryURL := "https://kubernetes-charts.storage.googleapis.com"
localRepositoryURL := "http://127.0.0.1:8879/charts"
if err := Initialize(hh, b, false, settings, stableRepositoryURL, localRepositoryURL); err != nil {
t.Error(err)
}
expectedDirs := []string{hh.String(), hh.Repository(), hh.Cache(), hh.LocalRepository()}
for _, dir := range expectedDirs {
if fi, err := os.Stat(dir); err != nil {
t.Errorf("%s", err)
} else if !fi.IsDir() {
t.Errorf("%s is not a directory", fi)
}
}
if fi, err := os.Stat(hh.RepositoryFile()); err != nil {
t.Error(err)
} else if fi.IsDir() {
t.Errorf("%s should not be a directory", fi)
}
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)
}
}
func TestEnsureHome(t *testing.T) {
home, err := ioutil.TempDir("", "helm_home")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(home)
b := bytes.NewBuffer(nil)
hh := helmpath.Home(home)
settings := helm_env.EnvSettings{
Home: hh,
}
stableRepositoryURL := "https://kubernetes-charts.storage.googleapis.com"
localRepositoryURL := "http://127.0.0.1:8879/charts"
if err := ensureDirectories(hh, b); err != nil {
t.Error(err)
}
if err := ensureDefaultRepos(hh, b, false, settings, stableRepositoryURL, localRepositoryURL); err != nil {
t.Error(err)
}
if err := ensureDefaultRepos(hh, b, true, settings, stableRepositoryURL, localRepositoryURL); err != nil {
t.Error(err)
}
if err := ensureRepoFileFormat(hh.RepositoryFile(), b); err != nil {
t.Error(err)
}
expectedDirs := []string{hh.String(), hh.Repository(), hh.Cache(), hh.LocalRepository()}
for _, dir := range expectedDirs {
if fi, err := os.Stat(dir); err != nil {
t.Errorf("%s", err)
} else if !fi.IsDir() {
t.Errorf("%s is not a directory", fi)
}
}
if fi, err := os.Stat(hh.RepositoryFile()); err != nil {
t.Error(err)
} else if fi.IsDir() {
t.Errorf("%s should not be a directory", fi)
}
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)
}
}

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package main package installer // import "k8s.io/helm/cmd/helm/installer"
import ( import (
"os" "os"

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package main package installer // import "k8s.io/helm/cmd/helm/installer"
import ( import (
"os" "os"

@ -36,6 +36,7 @@ import (
"k8s.io/helm/pkg/version" "k8s.io/helm/pkg/version"
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/tiller/environment"
) )
// Install uses Kubernetes client to install Tiller. // Install uses Kubernetes client to install Tiller.
@ -226,8 +227,8 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) {
Image: opts.SelectImage(), Image: opts.SelectImage(),
ImagePullPolicy: opts.pullPolicy(), ImagePullPolicy: opts.pullPolicy(),
Ports: []v1.ContainerPort{ Ports: []v1.ContainerPort{
{ContainerPort: 44134, Name: "tiller"}, {ContainerPort: environment.DefaultTillerPort, Name: "tiller"},
{ContainerPort: 44135, Name: "http"}, {ContainerPort: environment.DefaultTillerProbePort, Name: "http"},
}, },
Env: []v1.EnvVar{ Env: []v1.EnvVar{
{Name: "TILLER_NAMESPACE", Value: opts.Namespace}, {Name: "TILLER_NAMESPACE", Value: opts.Namespace},
@ -237,7 +238,7 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) {
Handler: v1.Handler{ Handler: v1.Handler{
HTTPGet: &v1.HTTPGetAction{ HTTPGet: &v1.HTTPGetAction{
Path: "/liveness", Path: "/liveness",
Port: intstr.FromInt(44135), Port: intstr.FromInt(environment.DefaultTillerProbePort),
}, },
}, },
InitialDelaySeconds: 1, InitialDelaySeconds: 1,
@ -247,7 +248,7 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) {
Handler: v1.Handler{ Handler: v1.Handler{
HTTPGet: &v1.HTTPGetAction{ HTTPGet: &v1.HTTPGetAction{
Path: "/readiness", Path: "/readiness",
Port: intstr.FromInt(44135), Port: intstr.FromInt(environment.DefaultTillerProbePort),
}, },
}, },
InitialDelaySeconds: 1, InitialDelaySeconds: 1,
@ -341,7 +342,7 @@ func generateService(namespace string) *v1.Service {
Ports: []v1.ServicePort{ Ports: []v1.ServicePort{
{ {
Name: "tiller", Name: "tiller",
Port: 44134, Port: environment.DefaultTillerPort,
TargetPort: intstr.FromString("tiller"), TargetPort: intstr.FromString("tiller"),
}, },
}, },

@ -24,7 +24,12 @@ import (
"k8s.io/helm/pkg/version" "k8s.io/helm/pkg/version"
) )
const defaultImage = "gcr.io/kubernetes-helm/tiller" const (
defaultImage = "gcr.io/kubernetes-helm/tiller"
fmtJSON OutputFormat = "json"
fmtYAML OutputFormat = "yaml"
)
// Options control how to install Tiller into a cluster, upgrade, and uninstall Tiller from a cluster. // Options control how to install Tiller into a cluster, upgrade, and uninstall Tiller from a cluster.
type Options struct { type Options struct {
@ -154,11 +159,6 @@ func (f *OutputFormat) Type() string {
return "OutputFormat" return "OutputFormat"
} }
const (
fmtJSON OutputFormat = "json"
fmtYAML OutputFormat = "yaml"
)
// Set validates and sets the value of the OutputFormat // Set validates and sets the value of the OutputFormat
func (f *OutputFormat) Set(s string) error { func (f *OutputFormat) Set(s string) error {
for _, of := range []OutputFormat{fmtJSON, fmtYAML} { for _, of := range []OutputFormat{fmtJSON, fmtYAML} {

@ -31,13 +31,13 @@ const (
// Uninstall uses Kubernetes client to uninstall Tiller. // Uninstall uses Kubernetes client to uninstall Tiller.
func Uninstall(client kubernetes.Interface, opts *Options) error { func Uninstall(client kubernetes.Interface, opts *Options) error {
if err := deleteService(client.Core(), opts.Namespace); err != nil { if err := deleteService(client.CoreV1(), opts.Namespace); err != nil {
return err return err
} }
if err := deleteDeployment(client, opts.Namespace); err != nil { if err := deleteDeployment(client, opts.Namespace); err != nil {
return err return err
} }
return deleteSecret(client.Core(), opts.Namespace) return deleteSecret(client.CoreV1(), opts.Namespace)
} }
// deleteService deletes the Tiller Service resource // deleteService deletes the Tiller Service resource

@ -166,7 +166,7 @@ func lintChart(path string, vals []byte, namespace string, strict bool) (support
chartPath = path chartPath = path
} }
// Guard: Error out of this is not a chart. // Guard: Error out if this is not a chart.
if _, err := os.Stat(filepath.Join(chartPath, "Chart.yaml")); err != nil { if _, err := os.Stat(filepath.Join(chartPath, "Chart.yaml")); err != nil {
return linter, errLintNoChart return linter, errLintNoChart
} }
@ -177,7 +177,7 @@ func lintChart(path string, vals []byte, namespace string, strict bool) (support
// vals merges values from files specified via -f/--values and // vals merges values from files specified via -f/--values and
// directly via --set or --set-string or --set-file, marshaling them to YAML // directly via --set or --set-string or --set-file, marshaling them to YAML
// //
// This func is implemented intentionally and separately from the `vals` func for the `install` and `upgrade` comammdsn. // This func is implemented intentionally and separately from the `vals` func for the `install` and `upgrade` commands.
// Compared to the alternative func, this func lacks the parameters for tls opts - ca key, cert, and ca cert. // Compared to the alternative func, this func lacks the parameters for tls opts - ca key, cert, and ca cert.
// That's because this command, `lint`, is explicitly forbidden from making server connections. // That's because this command, `lint`, is explicitly forbidden from making server connections.
func (l *lintCmd) vals() ([]byte, error) { func (l *lintCmd) vals() ([]byte, error) {

@ -66,7 +66,7 @@ func printRelease(out io.Writer, rel *release.Release) error {
return tpl(printReleaseTemplate, data, out) return tpl(printReleaseTemplate, data, out)
} }
func tpl(t string, vals map[string]interface{}, out io.Writer) error { func tpl(t string, vals interface{}, out io.Writer) error {
tt, err := template.New("_").Parse(t) tt, err := template.New("_").Parse(t)
if err != nil { if err != nil {
return err return err

@ -24,6 +24,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/helm/cmd/helm/installer"
"k8s.io/helm/pkg/getter" "k8s.io/helm/pkg/getter"
"k8s.io/helm/pkg/helm/helmpath" "k8s.io/helm/pkg/helm/helmpath"
"k8s.io/helm/pkg/repo" "k8s.io/helm/pkg/repo"
@ -99,7 +100,7 @@ func updateCharts(repos []*repo.ChartRepository, out io.Writer, home helmpath.Ho
wg.Add(1) wg.Add(1)
go func(re *repo.ChartRepository) { go func(re *repo.ChartRepository) {
defer wg.Done() defer wg.Done()
if re.Config.Name == localRepository { if re.Config.Name == installer.LocalRepository {
mu.Lock() mu.Lock()
fmt.Fprintf(out, "...Skip %s chart repository\n", re.Config.Name) fmt.Fprintf(out, "...Skip %s chart repository\n", re.Config.Name)
mu.Unlock() mu.Unlock()
@ -124,6 +125,6 @@ func updateCharts(repos []*repo.ChartRepository, out io.Writer, home helmpath.Ho
return errors.New("Update Failed. Check log for details") return errors.New("Update Failed. Check log for details")
} }
fmt.Fprintln(out, "Update Complete. ⎈ Happy Helming!⎈ ") fmt.Fprintln(out, "Update Complete.")
return nil return nil
} }

@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -59,7 +60,11 @@ func newResetCmd(client helm.Interface, out io.Writer) *cobra.Command {
Short: "uninstalls Tiller from a cluster", Short: "uninstalls Tiller from a cluster",
Long: resetDesc, Long: resetDesc,
PreRunE: func(cmd *cobra.Command, args []string) error { PreRunE: func(cmd *cobra.Command, args []string) error {
if err := setupConnection(); !d.force && err != nil { err := setupConnection()
if !d.force && err != nil {
return err
}
if d.force && err != nil && strings.EqualFold(err.Error(), "could not find tiller") {
return err return err
} }
return nil return nil

@ -36,17 +36,18 @@ second is a revision (version) number. To see revision numbers, run
` `
type rollbackCmd struct { type rollbackCmd struct {
name string name string
revision int32 revision int32
dryRun bool dryRun bool
recreate bool recreate bool
force bool force bool
disableHooks bool disableHooks bool
out io.Writer out io.Writer
client helm.Interface client helm.Interface
timeout int64 timeout int64
wait bool wait bool
description string description string
cleanupOnFail bool
} }
func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command { func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
@ -87,6 +88,7 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
f.Int64Var(&rollback.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)") 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") 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")
f.StringVar(&rollback.description, "description", "", "specify a description for the release") f.StringVar(&rollback.description, "description", "", "specify a description for the release")
f.BoolVar(&rollback.cleanupOnFail, "cleanup-on-fail", false, "allow deletion of new resources created in this rollback when rollback failed")
// set defaults from environment // set defaults from environment
settings.InitTLS(f) settings.InitTLS(f)
@ -104,12 +106,13 @@ func (r *rollbackCmd) run() error {
helm.RollbackVersion(r.revision), helm.RollbackVersion(r.revision),
helm.RollbackTimeout(r.timeout), helm.RollbackTimeout(r.timeout),
helm.RollbackWait(r.wait), helm.RollbackWait(r.wait),
helm.RollbackDescription(r.description)) helm.RollbackDescription(r.description),
helm.RollbackCleanupOnFail(r.cleanupOnFail))
if err != nil { if err != nil {
return prettyError(err) return prettyError(err)
} }
fmt.Fprintf(r.out, "Rollback was a success! Happy Helming!\n") fmt.Fprintf(r.out, "Rollback was a success.\n")
return nil return nil
} }

@ -31,25 +31,25 @@ func TestRollbackCmd(t *testing.T) {
{ {
name: "rollback a release", name: "rollback a release",
args: []string{"funny-honey", "1"}, args: []string{"funny-honey", "1"},
expected: "Rollback was a success! Happy Helming!", expected: "Rollback was a success.",
}, },
{ {
name: "rollback a release with timeout", name: "rollback a release with timeout",
args: []string{"funny-honey", "1"}, args: []string{"funny-honey", "1"},
flags: []string{"--timeout", "120"}, flags: []string{"--timeout", "120"},
expected: "Rollback was a success! Happy Helming!", expected: "Rollback was a success.",
}, },
{ {
name: "rollback a release with wait", name: "rollback a release with wait",
args: []string{"funny-honey", "1"}, args: []string{"funny-honey", "1"},
flags: []string{"--wait"}, flags: []string{"--wait"},
expected: "Rollback was a success! Happy Helming!", expected: "Rollback was a success.",
}, },
{ {
name: "rollback a release with description", name: "rollback a release with description",
args: []string{"funny-honey", "1"}, args: []string{"funny-honey", "1"},
flags: []string{"--description", "foo"}, flags: []string{"--description", "foo"},
expected: "Rollback was a success! Happy Helming!", expected: "Rollback was a success.",
}, },
{ {
name: "rollback a release without revision", name: "rollback a release without revision",

@ -33,6 +33,12 @@ import (
"k8s.io/helm/pkg/repo" "k8s.io/helm/pkg/repo"
) )
const (
sep = "\v"
// verSep is a separator for version fields in map keys.
verSep = "$$"
)
// Result is a search result. // Result is a search result.
// //
// Score indicates how close it is to match. The higher the score, the longer // Score indicates how close it is to match. The higher the score, the longer
@ -49,16 +55,11 @@ type Index struct {
charts map[string]*repo.ChartVersion charts map[string]*repo.ChartVersion
} }
const sep = "\v"
// NewIndex creats a new Index. // NewIndex creats a new Index.
func NewIndex() *Index { func NewIndex() *Index {
return &Index{lines: map[string]string{}, charts: map[string]*repo.ChartVersion{}} return &Index{lines: map[string]string{}, charts: map[string]*repo.ChartVersion{}}
} }
// verSep is a separator for version fields in map keys.
const verSep = "$$"
// AddRepo adds a repository index to the search index. // AddRepo adds a repository index to the search index.
func (i *Index) AddRepo(rname string, ind *repo.IndexFile, all bool) { func (i *Index) AddRepo(rname string, ind *repo.IndexFile, all bool) {
ind.SortEntries() ind.SortEntries()

@ -1,3 +1,4 @@
appVersion: "3.3"
description: Deploy a basic Alpine Linux pod description: Deploy a basic Alpine Linux pod
home: https://k8s.io/helm home: https://k8s.io/helm
name: alpine name: alpine

@ -10,6 +10,7 @@ metadata:
# The "release" convention makes it easy to tie a release to all of the # The "release" convention makes it easy to tie a release to all of the
# Kubernetes resources that were created as part of that release. # Kubernetes resources that were created as part of that release.
app.kubernetes.io/instance: {{.Release.Name | quote }} app.kubernetes.io/instance: {{.Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
# This makes it easy to audit chart usage. # This makes it easy to audit chart usage.
helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}" helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}"
values: {{.Values.test.Name}} values: {{.Values.test.Name}}

@ -4,3 +4,4 @@ name: novals
sources: sources:
- https://github.com/helm/helm - https://github.com/helm/helm
version: 0.2.0 version: 0.2.0
appVersion: 3.3

@ -10,6 +10,7 @@ metadata:
# The "release" convention makes it easy to tie a release to all of the # The "release" convention makes it easy to tie a release to all of the
# Kubernetes resources that were created as part of that release. # Kubernetes resources that were created as part of that release.
app.kubernetes.io/instance: {{.Release.Name | quote }} app.kubernetes.io/instance: {{.Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
# This makes it easy to audit chart usage. # This makes it easy to audit chart usage.
helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}" helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}"
annotations: annotations:

@ -84,34 +84,35 @@ which results in "pwd: 3jk$o2z=f\30with'quote".
` `
type upgradeCmd struct { type upgradeCmd struct {
release string release string
chart string chart string
out io.Writer out io.Writer
client helm.Interface client helm.Interface
dryRun bool dryRun bool
recreate bool recreate bool
force bool force bool
disableHooks bool disableHooks bool
valueFiles valueFiles valueFiles valueFiles
values []string values []string
stringValues []string stringValues []string
fileValues []string fileValues []string
verify bool verify bool
keyring string keyring string
install bool install bool
namespace string namespace string
version string version string
timeout int64 timeout int64
resetValues bool resetValues bool
reuseValues bool reuseValues bool
wait bool wait bool
atomic bool atomic bool
repoURL string repoURL string
username string username string
password string password string
devel bool devel bool
subNotes bool subNotes bool
description string description string
cleanupOnFail bool
certFile string certFile string
keyFile string keyFile string
@ -179,6 +180,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&upgrade.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.") f.BoolVar(&upgrade.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
f.BoolVar(&upgrade.subNotes, "render-subchart-notes", false, "render subchart notes along with parent") f.BoolVar(&upgrade.subNotes, "render-subchart-notes", false, "render subchart notes along with parent")
f.StringVar(&upgrade.description, "description", "", "specify the description to use for the upgrade, rather than the default") f.StringVar(&upgrade.description, "description", "", "specify the description to use for the upgrade, rather than the default")
f.BoolVar(&upgrade.cleanupOnFail, "cleanup-on-fail", false, "allow deletion of new resources created in this upgrade when upgrade failed")
f.MarkDeprecated("disable-hooks", "use --no-hooks instead") f.MarkDeprecated("disable-hooks", "use --no-hooks instead")
@ -248,7 +250,8 @@ func (u *upgradeCmd) run() error {
} }
// Check chart requirements to make sure all dependencies are present in /charts // Check chart requirements to make sure all dependencies are present in /charts
if ch, err := chartutil.Load(chartPath); err == nil { ch, err := chartutil.Load(chartPath)
if err == nil {
if req, err := chartutil.LoadRequirements(ch); err == nil { if req, err := chartutil.LoadRequirements(ch); err == nil {
if err := renderutil.CheckDependencies(ch, req); err != nil { if err := renderutil.CheckDependencies(ch, req); err != nil {
return err return err
@ -260,9 +263,9 @@ func (u *upgradeCmd) run() error {
return prettyError(err) return prettyError(err)
} }
resp, err := u.client.UpdateRelease( resp, err := u.client.UpdateReleaseFromChart(
u.release, u.release,
chartPath, ch,
helm.UpdateValueOverrides(rawVals), helm.UpdateValueOverrides(rawVals),
helm.UpgradeDryRun(u.dryRun), helm.UpgradeDryRun(u.dryRun),
helm.UpgradeRecreate(u.recreate), helm.UpgradeRecreate(u.recreate),
@ -273,22 +276,25 @@ func (u *upgradeCmd) run() error {
helm.ReuseValues(u.reuseValues), helm.ReuseValues(u.reuseValues),
helm.UpgradeSubNotes(u.subNotes), helm.UpgradeSubNotes(u.subNotes),
helm.UpgradeWait(u.wait), helm.UpgradeWait(u.wait),
helm.UpgradeDescription(u.description)) helm.UpgradeDescription(u.description),
helm.UpgradeCleanupOnFail(u.cleanupOnFail))
if err != nil { if err != nil {
fmt.Fprintf(u.out, "UPGRADE FAILED\nROLLING BACK\nError: %v\n", prettyError(err)) fmt.Fprintf(u.out, "UPGRADE FAILED\nError: %v\n", prettyError(err))
if u.atomic { if u.atomic {
fmt.Fprint(u.out, "ROLLING BACK")
rollback := &rollbackCmd{ rollback := &rollbackCmd{
out: u.out, out: u.out,
client: u.client, client: u.client,
name: u.release, name: u.release,
dryRun: u.dryRun, dryRun: u.dryRun,
recreate: u.recreate, recreate: u.recreate,
force: u.force, force: u.force,
timeout: u.timeout, timeout: u.timeout,
wait: u.wait, wait: u.wait,
description: "", description: "",
revision: releaseHistory.Releases[0].Version, revision: releaseHistory.Releases[0].Version,
disableHooks: u.disableHooks, disableHooks: u.disableHooks,
cleanupOnFail: u.cleanupOnFail,
} }
if err := rollback.run(); err != nil { if err := rollback.run(); err != nil {
return err return err
@ -301,7 +307,7 @@ func (u *upgradeCmd) run() error {
printRelease(u.out, resp.Release) printRelease(u.out, resp.Release)
} }
fmt.Fprintf(u.out, "Release %q has been upgraded. Happy Helming!\n", u.release) fmt.Fprintf(u.out, "Release %q has been upgraded.\n", u.release)
// Print the status like status command does // Print the status like status command does
status, err := u.client.ReleaseStatus(u.release) status, err := u.client.ReleaseStatus(u.release)

@ -96,7 +96,7 @@ func TestUpgradeCmd(t *testing.T) {
name: "upgrade a release", name: "upgrade a release",
args: []string{"funny-bunny", chartPath}, args: []string{"funny-bunny", chartPath},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 2, Chart: ch}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 2, Chart: ch}),
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n", expected: "Release \"funny-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 2, Chart: ch})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 2, Chart: ch})},
}, },
{ {
@ -104,7 +104,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"funny-bunny", chartPath}, args: []string{"funny-bunny", chartPath},
flags: []string{"--timeout", "120"}, flags: []string{"--timeout", "120"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 3, Chart: ch2}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 3, Chart: ch2}),
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n", expected: "Release \"funny-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 3, Chart: ch2})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 3, Chart: ch2})},
}, },
{ {
@ -112,7 +112,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"funny-bunny", chartPath}, args: []string{"funny-bunny", chartPath},
flags: []string{"--reset-values", "true"}, flags: []string{"--reset-values", "true"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 4, Chart: ch2}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 4, Chart: ch2}),
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n", expected: "Release \"funny-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 4, Chart: ch2})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 4, Chart: ch2})},
}, },
{ {
@ -120,7 +120,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"funny-bunny", chartPath}, args: []string{"funny-bunny", chartPath},
flags: []string{"--reuse-values", "true"}, flags: []string{"--reuse-values", "true"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 5, Chart: ch2}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 5, Chart: ch2}),
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n", expected: "Release \"funny-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 5, Chart: ch2})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 5, Chart: ch2})},
}, },
{ {
@ -128,7 +128,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"funny-bunny", chartPath}, args: []string{"funny-bunny", chartPath},
flags: []string{"--atomic"}, flags: []string{"--atomic"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 6, Chart: ch}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 6, Chart: ch}),
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n", expected: "Release \"funny-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 6, Chart: ch})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 6, Chart: ch})},
}, },
{ {
@ -136,7 +136,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"zany-bunny", chartPath}, args: []string{"zany-bunny", chartPath},
flags: []string{"-i"}, flags: []string{"-i"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "zany-bunny", Version: 1, Chart: ch}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "zany-bunny", Version: 1, Chart: ch}),
expected: "Release \"zany-bunny\" has been upgraded. Happy Helming!\n", expected: "Release \"zany-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "zany-bunny", Version: 1, Chart: ch})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "zany-bunny", Version: 1, Chart: ch})},
}, },
{ {
@ -144,7 +144,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"crazy-bunny", chartPath}, args: []string{"crazy-bunny", chartPath},
flags: []string{"-i", "--timeout", "120"}, flags: []string{"-i", "--timeout", "120"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch}),
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n", expected: "Release \"crazy-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch})},
}, },
{ {
@ -152,7 +152,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"crazy-bunny", chartPath}, args: []string{"crazy-bunny", chartPath},
flags: []string{"-i", "--description", "foo"}, flags: []string{"-i", "--description", "foo"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch, Description: "foo"}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch, Description: "foo"}),
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n", expected: "Release \"crazy-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch, Description: "foo"})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch, Description: "foo"})},
}, },
{ {
@ -160,7 +160,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"crazy-bunny", chartPath}, args: []string{"crazy-bunny", chartPath},
flags: []string{"--wait"}, flags: []string{"--wait"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2}),
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n", expected: "Release \"crazy-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2})},
}, },
{ {
@ -168,7 +168,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"crazy-bunny", chartPath}, args: []string{"crazy-bunny", chartPath},
flags: []string{"--description", "foo"}, flags: []string{"--description", "foo"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2}),
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n", expected: "Release \"crazy-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2, Description: "foo"})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2, Description: "foo"})},
}, },
{ {

@ -27,7 +27,7 @@ import (
const verifyDesc = ` const verifyDesc = `
Verify that the given chart has a valid provenance file. Verify that the given chart has a valid provenance file.
Provenance files provide crytographic verification that a chart has not been Provenance files provide cryptographic verification that a chart has not been
tampered with, and was packaged by a trusted provider. tampered with, and was packaged by a trusted provider.
This command can be used to verify a local chart. Several other commands provide This command can be used to verify a local chart. Several other commands provide

@ -151,5 +151,5 @@ func formatVersion(v *pb.Version, short bool) string {
if short && v.GitCommit != "" { if short && v.GitCommit != "" {
return fmt.Sprintf("%s+g%s", v.SemVer, v.GitCommit[:7]) return fmt.Sprintf("%s+g%s", v.SemVer, v.GitCommit[:7])
} }
return fmt.Sprintf("%#v", v) return fmt.Sprintf("&version.Version{SemVer:\"%s\", GitCommit:\"%s\", GitTreeState:\"%s\"}", v.SemVer, v.GitCommit, v.GitTreeState)
} }

@ -131,7 +131,13 @@ func (r *ReleaseModuleServiceServer) RollbackRelease(ctx context.Context, in *ru
grpclog.Print("rollback") grpclog.Print("rollback")
c := bytes.NewBufferString(in.Current.Manifest) c := bytes.NewBufferString(in.Current.Manifest)
t := bytes.NewBufferString(in.Target.Manifest) t := bytes.NewBufferString(in.Target.Manifest)
err := kubeClient.Update(in.Target.Namespace, c, t, in.Force, in.Recreate, in.Timeout, in.Wait) err := kubeClient.UpdateWithOptions(in.Target.Namespace, c, t, kube.UpdateOptions{
Force: in.Force,
Recreate: in.Recreate,
Timeout: in.Timeout,
ShouldWait: in.Wait,
CleanupOnFail: in.CleanupOnFail,
})
return &rudderAPI.RollbackReleaseResponse{}, err return &rudderAPI.RollbackReleaseResponse{}, err
} }
@ -140,7 +146,13 @@ func (r *ReleaseModuleServiceServer) UpgradeRelease(ctx context.Context, in *rud
grpclog.Print("upgrade") grpclog.Print("upgrade")
c := bytes.NewBufferString(in.Current.Manifest) c := bytes.NewBufferString(in.Current.Manifest)
t := bytes.NewBufferString(in.Target.Manifest) t := bytes.NewBufferString(in.Target.Manifest)
err := kubeClient.Update(in.Target.Namespace, c, t, in.Force, in.Recreate, in.Timeout, in.Wait) err := kubeClient.UpdateWithOptions(in.Target.Namespace, c, t, kube.UpdateOptions{
Force: in.Force,
Recreate: in.Recreate,
Timeout: in.Timeout,
ShouldWait: in.Wait,
CleanupOnFail: in.CleanupOnFail,
})
// upgrade response object should be changed to include status // upgrade response object should be changed to include status
return &rudderAPI.UpgradeReleaseResponse{}, err return &rudderAPI.UpgradeReleaseResponse{}, err
} }

@ -36,6 +36,7 @@ import (
"google.golang.org/grpc/health" "google.golang.org/grpc/health"
healthpb "google.golang.org/grpc/health/grpc_health_v1" healthpb "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/keepalive" "google.golang.org/grpc/keepalive"
"k8s.io/klog"
// Import to initialize client auth plugins. // Import to initialize client auth plugins.
_ "k8s.io/client-go/plugin/pkg/client/auth" _ "k8s.io/client-go/plugin/pkg/client/auth"
@ -65,8 +66,8 @@ const (
storageMemory = "memory" storageMemory = "memory"
storageConfigMap = "configmap" storageConfigMap = "configmap"
storageSecret = "secret" storageSecret = "secret"
storageSQL = "sql"
probeAddr = ":44135"
traceAddr = ":44136" traceAddr = ":44136"
// defaultMaxHistory sets the maximum number of releases to 0: unlimited // defaultMaxHistory sets the maximum number of releases to 0: unlimited
@ -74,17 +75,23 @@ const (
) )
var ( var (
grpcAddr = flag.String("listen", ":44134", "address:port to listen on") grpcAddr = flag.String("listen", fmt.Sprintf(":%v", environment.DefaultTillerPort), "address:port to listen on")
enableTracing = flag.Bool("trace", false, "enable rpc tracing") probeAddr = flag.String("probe-listen", fmt.Sprintf(":%v", environment.DefaultTillerProbePort), "address:port to listen on for probes")
store = flag.String("storage", storageConfigMap, "storage driver to use. One of 'configmap', 'memory', or 'secret'") enableTracing = flag.Bool("trace", false, "enable rpc tracing")
store = flag.String("storage", storageConfigMap, "storage driver to use. One of 'configmap', 'memory', 'sql' or 'secret'")
sqlDialect = flag.String("sql-dialect", "postgres", "SQL dialect to use (only postgres is supported for now")
sqlConnectionString = flag.String("sql-connection-string", "", "SQL connection string to use")
remoteReleaseModules = flag.Bool("experimental-release", false, "enable experimental release modules") remoteReleaseModules = flag.Bool("experimental-release", false, "enable experimental release modules")
tlsEnable = flag.Bool("tls", tlsEnableEnvVarDefault(), "enable TLS")
tlsVerify = flag.Bool("tls-verify", tlsVerifyEnvVarDefault(), "enable TLS and verify remote certificate") tlsEnable = flag.Bool("tls", tlsEnableEnvVarDefault(), "enable TLS")
keyFile = flag.String("tls-key", tlsDefaultsFromEnv("tls-key"), "path to TLS private key file") tlsVerify = flag.Bool("tls-verify", tlsVerifyEnvVarDefault(), "enable TLS and verify remote certificate")
certFile = flag.String("tls-cert", tlsDefaultsFromEnv("tls-cert"), "path to TLS certificate file") keyFile = flag.String("tls-key", tlsDefaultsFromEnv("tls-key"), "path to TLS private key file")
caCertFile = flag.String("tls-ca-cert", tlsDefaultsFromEnv("tls-ca-cert"), "trust certificates signed by this CA") certFile = flag.String("tls-cert", tlsDefaultsFromEnv("tls-cert"), "path to TLS certificate file")
maxHistory = flag.Int("history-max", historyMaxFromEnv(), "maximum number of releases kept in release history, with 0 meaning no limit") caCertFile = flag.String("tls-ca-cert", tlsDefaultsFromEnv("tls-ca-cert"), "trust certificates signed by this CA")
printVersion = flag.Bool("version", false, "print the version number") maxHistory = flag.Int("history-max", historyMaxFromEnv(), "maximum number of releases kept in release history, with 0 meaning no limit")
printVersion = flag.Bool("version", false, "print the version number")
// rootServer is the root gRPC server. // rootServer is the root gRPC server.
// //
@ -100,6 +107,7 @@ var (
) )
func main() { func main() {
klog.InitFlags(nil)
// TODO: use spf13/cobra for tiller instead of flags // TODO: use spf13/cobra for tiller instead of flags
flag.Parse() flag.Parse()
@ -141,6 +149,18 @@ func start() {
env.Releases = storage.Init(secrets) env.Releases = storage.Init(secrets)
env.Releases.Log = newLogger("storage").Printf env.Releases.Log = newLogger("storage").Printf
case storageSQL:
sqlDriver, err := driver.NewSQL(
*sqlDialect,
*sqlConnectionString,
newLogger("storage/driver").Printf,
)
if err != nil {
logger.Fatalf("Cannot initialize SQL storage driver: %v", err)
}
env.Releases = storage.Init(sqlDriver)
env.Releases.Log = newLogger("storage").Printf
} }
if *maxHistory > 0 { if *maxHistory > 0 {
@ -185,7 +205,7 @@ func start() {
logger.Printf("Starting Tiller %s (tls=%t)", version.GetVersion(), *tlsEnable || *tlsVerify) logger.Printf("Starting Tiller %s (tls=%t)", version.GetVersion(), *tlsEnable || *tlsVerify)
logger.Printf("GRPC listening on %s", *grpcAddr) logger.Printf("GRPC listening on %s", *grpcAddr)
logger.Printf("Probes listening on %s", probeAddr) logger.Printf("Probes listening on %s", *probeAddr)
logger.Printf("Storage driver is %s", env.Releases.Name()) logger.Printf("Storage driver is %s", env.Releases.Name())
logger.Printf("Max history per release is %d", *maxHistory) logger.Printf("Max history per release is %d", *maxHistory)
@ -211,7 +231,7 @@ func start() {
goprom.Register(rootServer) goprom.Register(rootServer)
addPrometheusHandler(mux) addPrometheusHandler(mux)
if err := http.ListenAndServe(probeAddr, mux); err != nil { if err := http.ListenAndServe(*probeAddr, mux); err != nil {
probeErrCh <- err probeErrCh <- err
} }
}() }()

@ -22,7 +22,7 @@ The directory that contains a chart MUST have the same name as the chart. Thus,
## Version Numbers ## Version Numbers
Wherever possible, Helm uses [SemVer 2](http://semver.org) to represent version numbers. (Note that Docker image tags do not necessarily follow SemVer, and are thus considered an unfortunate exception to the rule.) Wherever possible, Helm uses [SemVer 2](https://semver.org) to represent version numbers. (Note that Docker image tags do not necessarily follow SemVer, and are thus considered an unfortunate exception to the rule.)
When SemVer versions are stored in Kubernetes labels, we conventionally alter the `+` character to an `_` character, as labels do not allow the `+` sign as a value. When SemVer versions are stored in Kubernetes labels, we conventionally alter the `+` character to an `_` character, as labels do not allow the `+` sign as a value.

@ -26,7 +26,7 @@ are recommended, and _should_ be placed onto a chart for global consistency. Tho
Name|Status|Description Name|Status|Description
-----|------|---------- -----|------|----------
`app.kubernetes.io/name` | REC | This should be the app name, reflecting the entire app. Usually `{{ template "name" . }}` is used for this. This is used by many Kubernetes manifests, and is not Helm-specific. `app.kubernetes.io/name` | REC | This should be the app name, reflecting the entire app. Usually `{{ template "name" . }}` is used for this. This is used by many Kubernetes manifests, and is not Helm-specific.
`helm.sh/chart` | REC | This should be the chart name and version: `{{ .Chart.Name }}-{{ .Chart.Version \| replace "+" "_" }}`. `helm.sh/chart` | REC | This should be the chart name and version: `{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}`.
`app.kubernetes.io/managed-by` | REC | This should always be set to `{{ .Release.Service }}`. It is for finding all things managed by Tiller. `app.kubernetes.io/managed-by` | REC | This should always be set to `{{ .Release.Service }}`. It is for finding all things managed by Tiller.
`app.kubernetes.io/instance` | REC | This should be the `{{ .Release.Name }}`. It aids in differentiating between different instances of the same application. `app.kubernetes.io/instance` | REC | This should be the `{{ .Release.Name }}`. It aids in differentiating between different instances of the same application.
`app.kubernetes.io/version` | OPT | The version of the app and can be set to `{{ .Chart.AppVersion }}`. `app.kubernetes.io/version` | OPT | The version of the app and can be set to `{{ .Chart.AppVersion }}`.

@ -88,7 +88,7 @@ data is lost after one parse.
## Consider How Users Will Use Your Values ## Consider How Users Will Use Your Values
There are three potential sources of values: There are four potential sources of values:
- A chart's `values.yaml` file - A chart's `values.yaml` file
- A values file supplied by `helm install -f` or `helm upgrade -f` - A values file supplied by `helm install -f` or `helm upgrade -f`

@ -123,6 +123,35 @@ startup.
This part shows several ways to serve a chart repository. This part shows several ways to serve a chart repository.
### ChartMuseum
The Helm project provides an open-source Helm repository server called [ChartMuseum](https://chartmuseum.com) that you can host yourself.
ChartMuseum supports multiple cloud storage backends. Configure it to point to the directory or bucket containing your chart packages, and the index.yaml file will be generated dynamically.
It can be deployed easily as a [Helm chart](https://github.com/helm/charts/tree/master/stable/chartmuseum):
```
helm install stable/chartmuseum
```
and also as a [Docker image](https://hub.docker.com/r/chartmuseum/chartmuseum/tags):
```
docker run --rm -it \
-p 8080:8080 \
-v $(pwd)/charts:/charts \
-e DEBUG=true \
-e STORAGE=local \
-e STORAGE_LOCAL_ROOTDIR=/charts \
chartmuseum/chartmuseum
```
You can then add the repo to your local repository list:
```
helm repo add chartmuseum http://localhost:8080
```
ChartMuseum provides other features, such as an API for chart uploads. Please see the [README](https://github.com/helm/chartmuseum) for more info.
### Google Cloud Storage ### Google Cloud Storage
The first step is to **create your GCS bucket**. We'll call ours The first step is to **create your GCS bucket**. We'll call ours
@ -153,6 +182,10 @@ Charts repository hosts its charts, so you may want to take a
You can also set up chart repositories using JFrog Artifactory. You can also set up chart repositories using JFrog Artifactory.
Read more about chart repositories with JFrog Artifactory [here](https://www.jfrog.com/confluence/display/RTF/Helm+Chart+Repositories) Read more about chart repositories with JFrog Artifactory [here](https://www.jfrog.com/confluence/display/RTF/Helm+Chart+Repositories)
### ProGet
Helm chart repositories are supported by ProGet. For more information, visit the [Helm repository documentation](https://inedo.com/support/documentation/proget/feeds/helm) on the Inedo website.
### Github Pages example ### Github Pages example
In a similar way you can create charts repository using GitHub Pages. In a similar way you can create charts repository using GitHub Pages.

@ -329,7 +329,7 @@ data:
- "Onions" - "Onions"
``` ```
Now, in this example we've done something tricky. The `toppings: |-` line is declaring a multi-line string. So our list of toppings is actually not a YAML list. It's a big string. Why would we do this? Because the data in ConfigMaps `data` is composed of key/value pairs, where both the key and the value are simple strings. To understand why this is the case, take a look at the [Kubernetes ConfigMap docs](http://kubernetes.io/docs/user-guide/configmap/). For us, though, this detail doesn't matter much. Now, in this example we've done something tricky. The `toppings: |-` line is declaring a multi-line string. So our list of toppings is actually not a YAML list. It's a big string. Why would we do this? Because the data in ConfigMaps `data` is composed of key/value pairs, where both the key and the value are simple strings. To understand why this is the case, take a look at the [Kubernetes ConfigMap docs](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/). For us, though, this detail doesn't matter much.
> The `|-` marker in YAML takes a multi-line string. This can be a useful technique for embedding big blocks of data inside of your manifests, as exemplified here. > The `|-` marker in YAML takes a multi-line string. This can be a useful technique for embedding big blocks of data inside of your manifests, as exemplified here.

@ -150,7 +150,7 @@ Template functions and pipelines are a powerful way to transform information and
## Operators are functions ## Operators are functions
Operators are implemented as functions that return a boolean value. To use `eq`, `ne`, `lt`, `gt`, `and`, `or`, `not` etcetera place the operator at the front of the statement followed by its parameters just as you would a function. To chain multiple operations together, separate individual functions by surrounding them with paranthesis. Operators are implemented as functions that return a boolean value. To use `eq`, `ne`, `lt`, `gt`, `and`, `or`, `not` etcetera place the operator at the front of the statement followed by its parameters just as you would a function. To chain multiple operations together, separate individual functions by surrounding them with parentheses.
```yaml ```yaml
{{/* include the body of this if statement when the variable .Values.fooString exists and is set to "foo" */}} {{/* include the body of this if statement when the variable .Values.fooString exists and is set to "foo" */}}

@ -51,8 +51,8 @@ already there.
- `NOTES.txt`: The "help text" for your chart. This will be displayed to your users - `NOTES.txt`: The "help text" for your chart. This will be displayed to your users
when they run `helm install`. when they run `helm install`.
- `deployment.yaml`: A basic manifest for creating a Kubernetes [deployment](http://kubernetes.io/docs/user-guide/deployments/) - `deployment.yaml`: A basic manifest for creating a Kubernetes [deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)
- `service.yaml`: A basic manifest for creating a [service endpoint](http://kubernetes.io/docs/user-guide/services/) for your deployment - `service.yaml`: A basic manifest for creating a [service endpoint](https://kubernetes.io/docs/concepts/services-networking/service/) for your deployment
- `_helpers.tpl`: A place to put template helpers that you can re-use throughout the chart - `_helpers.tpl`: A place to put template helpers that you can re-use throughout the chart
And what we're going to do is... _remove them all!_ That way we can work through our tutorial from scratch. We'll actually create our own `NOTES.txt` and `_helpers.tpl` as we go. And what we're going to do is... _remove them all!_ That way we can work through our tutorial from scratch. We'll actually create our own `NOTES.txt` and `_helpers.tpl` as we go.

@ -4,7 +4,7 @@ The `.helmignore` file is used to specify files you don't want to include in you
If this file exists, the `helm package` command will ignore all the files that match the pattern specified in the `.helmignore` file while packaging your application. If this file exists, the `helm package` command will ignore all the files that match the pattern specified in the `.helmignore` file while packaging your application.
This can help in avoiding unncessary or sensitive files or directories from being added in your helm chart. This can help in avoiding unnecessary or sensitive files or directories from being added in your helm chart.
The `.helmignore` file supports Unix shell glob matching, relative path matching, and negation (prefixed with !). Only one pattern per line is considered. The `.helmignore` file supports Unix shell glob matching, relative path matching, and negation (prefixed with !). Only one pattern per line is considered.

@ -215,7 +215,7 @@ data:
myvalue: "Hello World" myvalue: "Hello World"
drink: "coffee" drink: "coffee"
food: "pizza" food: "pizza"
app_name: mychart app_name: mychart
app_version: "0.1.0+1478129847" app_version: "0.1.0+1478129847"
``` ```

@ -1,6 +1,6 @@
# Creating a NOTES.txt File # Creating a NOTES.txt File
In this section we are going to look at Helm's tool for providing instructions to your chart users. At the end of a `chart install` or `chart upgrade`, Helm can print out a block of helpful information for users. This information is highly customizable using templates. In this section we are going to look at Helm's tool for providing instructions to your chart users. At the end of a `helm install` or `helm upgrade`, Helm can print out a block of helpful information for users. This information is highly customizable using templates.
To add installation notes to your chart, simply create a `templates/NOTES.txt` file. This file is plain text, but it is processed like as a template, and has all the normal template functions and objects available. To add installation notes to your chart, simply create a `templates/NOTES.txt` file. This file is plain text, but it is processed like as a template, and has all the normal template functions and objects available.

@ -29,7 +29,7 @@ data:
drink: {{ .Values.favoriteDrink }} drink: {{ .Values.favoriteDrink }}
``` ```
Notice on the last line we access `favoriteDrink` as an attribute of `Values`: `{{ .Values.favoriteDrink}}`. Notice on the last line we access `favoriteDrink` as an attribute of `Values`: `{{ .Values.favoriteDrink }}`.
Let's see how this renders. Let's see how this renders.

@ -114,6 +114,8 @@ metadata:
# I cannot reference .Chart.Name, but I can do $.Chart.Name # I cannot reference .Chart.Name, but I can do $.Chart.Name
helm.sh/chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}" helm.sh/chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"
app.kubernetes.io/instance: "{{ $.Release.Name }}" app.kubernetes.io/instance: "{{ $.Release.Name }}"
# Value from appVersion in Chart.yaml
app.kubernetes.io/version: "{{ $.Chart.AppVersion }}"
app.kubernetes.io/managed-by: "{{ $.Release.Service }}" app.kubernetes.io/managed-by: "{{ $.Release.Service }}"
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:

@ -5,7 +5,7 @@ This guide is intended to give you, the chart developer, a strong understanding
But there are many things this guide has not covered when it comes to the practical day-to-day development of charts. Here are some useful pointers to other documentation that will help you as you create new charts: But there are many things this guide has not covered when it comes to the practical day-to-day development of charts. Here are some useful pointers to other documentation that will help you as you create new charts:
- The [Helm Charts project](https://github.com/helm/charts) is an indispensable source of charts. That project is also sets the standard for best practices in chart development. - The [Helm Charts project](https://github.com/helm/charts) is an indispensable source of charts. That project is also sets the standard for best practices in chart development.
- The Kubernetes [User's Guide](http://kubernetes.io/docs/user-guide/) provides detailed examples of the various resource kinds that you can use, from ConfigMaps and Secrets to DaemonSets and Deployments. - The Kubernetes [Documentation](https://kubernetes.io/docs/home/) provides detailed examples of the various resource kinds that you can use, from ConfigMaps and Secrets to DaemonSets and Deployments.
- The Helm [Charts Guide](../charts.md) explains the workflow of using charts. - The Helm [Charts Guide](../charts.md) explains the workflow of using charts.
- The Helm [Chart Hooks Guide](../charts_hooks.md) explains how to create lifecycle hooks. - The Helm [Chart Hooks Guide](../charts_hooks.md) explains how to create lifecycle hooks.
- The Helm [Charts Tips and Tricks](../charts_tips_and_tricks.md) article provides some useful tips for writing charts. - The Helm [Charts Tips and Tricks](../charts_tips_and_tricks.md) article provides some useful tips for writing charts.

@ -7,7 +7,7 @@ to read.
## Scalars and Collections ## Scalars and Collections
According to the [YAML spec](http://yaml.org/spec/1.2/spec.html), there are two According to the [YAML spec](https://yaml.org/spec/1.2/spec.html), there are two
types of collections, and many scalar types. types of collections, and many scalar types.
The two types of collections are maps and sequences: The two types of collections are maps and sequences:

@ -71,7 +71,7 @@ Other fields will be silently ignored.
### Charts and Versioning ### Charts and Versioning
Every chart must have a version number. A version must follow the Every chart must have a version number. A version must follow the
[SemVer 2](http://semver.org/) standard. Unlike Helm Classic, Kubernetes [SemVer 2](https://semver.org/) standard. Unlike Helm Classic, Kubernetes
Helm uses version numbers as release markers. Packages in repositories Helm uses version numbers as release markers. Packages in repositories
are identified by name plus version. are identified by name plus version.
@ -191,7 +191,7 @@ Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository ...Successfully got an update from the "stable" chart repository
...Successfully got an update from the "example" chart repository ...Successfully got an update from the "example" chart repository
...Successfully got an update from the "another" chart repository ...Successfully got an update from the "another" chart repository
Update Complete. Happy Helming! Update Complete.
Saving 2 charts Saving 2 charts
Downloading apache from repo http://example.com/charts Downloading apache from repo http://example.com/charts
Downloading mysql from repo http://another.example.com/charts Downloading mysql from repo http://another.example.com/charts
@ -492,7 +492,7 @@ create/update all of the above Kubernetes objects in the following order:
This is because when Helm installs/upgrades charts, This is because when Helm installs/upgrades charts,
the Kubernetes objects from the charts and all its dependencies are the Kubernetes objects from the charts and all its dependencies are
- aggregrated into a single set; then - aggregated into a single set; then
- sorted by type followed by name; and then - sorted by type followed by name; and then
- created/updated in that order. - created/updated in that order.
@ -792,7 +792,7 @@ standard references that will help you out.
- [Go templates](https://godoc.org/text/template) - [Go templates](https://godoc.org/text/template)
- [Extra template functions](https://godoc.org/github.com/Masterminds/sprig) - [Extra template functions](https://godoc.org/github.com/Masterminds/sprig)
- [The YAML format](http://yaml.org/spec/) - [The YAML format](https://yaml.org/spec/)
## Using Helm to Manage Charts ## Using Helm to Manage Charts

@ -76,7 +76,7 @@ hooks, the lifecycle is altered like this:
5. Tiller sorts hooks by weight (assigning a weight of 0 by default) and by name for those hooks with the same weight in ascending order. 5. Tiller sorts hooks by weight (assigning a weight of 0 by default) and by name for those hooks with the same weight in ascending order.
6. Tiller then loads the hook with the lowest weight first (negative to positive) 6. Tiller then loads the hook with the lowest weight first (negative to positive)
7. Tiller waits until the hook is "Ready" (except for CRDs) 7. Tiller waits until the hook is "Ready" (except for CRDs)
8. Tiller loads the resulting resources into Kubernetes. Note that if the `--wait` 8. Tiller loads the resulting resources into Kubernetes. Note that if the `--wait`
flag is set, Tiller will wait until all resources are in a ready state flag is set, Tiller will wait until all resources are in a ready state
and will not run the `post-install` hook until they are ready. and will not run the `post-install` hook until they are ready.
9. Tiller executes the `post-install` hook (loading hook resources) 9. Tiller executes the `post-install` hook (loading hook resources)
@ -129,6 +129,7 @@ metadata:
labels: labels:
app.kubernetes.io/managed-by: {{.Release.Service | quote }} app.kubernetes.io/managed-by: {{.Release.Service | quote }}
app.kubernetes.io/instance: {{.Release.Name | quote }} app.kubernetes.io/instance: {{.Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}" helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}"
annotations: annotations:
# This is what defines this resource as a hook. Without this line, the # This is what defines this resource as a hook. Without this line, the
@ -246,12 +247,10 @@ annotated.
### Automatically delete hook from previous release ### Automatically delete hook from previous release
When helm release being updated it is possible, that hook resource already exists in cluster. By default helm will try to create resource and fail with `"... already exists"` error. When a helm release, that uses a hook, is being updated, it is possible that the hook resource might already exist in the cluster. In such circumstances, by default, helm will fail trying to install the hook resource with an `"... already exists"` error.
One might choose `"helm.sh/hook-delete-policy": "before-hook-creation"` over `"helm.sh/hook-delete-policy": "hook-succeeded,hook-failed"` because: A common reason why the hook resource might already exist is that it was not deleted following use on a previous install/upgrade. There are, in fact, good reasons why one might want to keep the hook: for example, to aid manual debugging in case something went wrong. In this case, the recommended way of ensuring subsequent attempts to create the hook do not fail is to define a `"hook-delete-policy"` that can handle this: `"helm.sh/hook-delete-policy": "before-hook-creation"`. This hook annotation causes any existing hook to be removed, before the new hook is installed.
If it is preferred to actually delete the hook after each use (rather than have to handle it on a subsequent use, as shown above), then this can be achieved using a delete policy of `"helm.sh/hook-delete-policy": "hook-succeeded,hook-failed"`.
* It is convenient to keep failed hook job resource in kubernetes for example for manual debug.
* It may be necessary to keep succeeded hook resource in kubernetes for some reason.
* At the same time it is not desirable to do manual resource deletion before helm release upgrade.
`"helm.sh/hook-delete-policy": "before-hook-creation"` annotation on hook causes tiller to remove the hook from previous release if there is one before the new hook is launched and can be used with another policy.

@ -235,6 +235,9 @@ orphaned. Helm will no longer manage it in any way. This can lead to problems
if using `helm install --replace` on a release that has already been deleted, but if using `helm install --replace` on a release that has already been deleted, but
has kept resources. has kept resources.
To explicitly opt in to resource deletion, for example when overriding a chart's
default annotations, set the resource policy annotation value to `delete`.
## Using "Partials" and Template Includes ## Using "Partials" and Template Includes
Sometimes you want to create some reusable parts in your chart, whether Sometimes you want to create some reusable parts in your chart, whether
@ -281,7 +284,7 @@ According to the YAML specification, YAML is a superset of JSON. That
means that any valid JSON structure ought to be valid in YAML. means that any valid JSON structure ought to be valid in YAML.
This has an advantage: Sometimes template developers may find it easier This has an advantage: Sometimes template developers may find it easier
to express a datastructure with a JSON-like syntax rather than deal with to express a data structure with a JSON-like syntax rather than deal with
YAML's whitespace sensitivity. YAML's whitespace sensitivity.
As a best practice, templates should follow a YAML-like syntax _unless_ As a best practice, templates should follow a YAML-like syntax _unless_

@ -32,7 +32,7 @@ docker-test`.
To run Helm and Tiller locally, you can run `bin/helm` or `bin/tiller`. To run Helm and Tiller locally, you can run `bin/helm` or `bin/tiller`.
- Helm and Tiller are known to run on macOS and most Linuxes, including - Helm and Tiller are known to run on macOS and most Linux distributions, including
Alpine. Alpine.
- Tiller must have access to a Kubernetes cluster. It learns about the - Tiller must have access to a Kubernetes cluster. It learns about the
cluster by examining the Kube config files that `kubectl` uses. cluster by examining the Kube config files that `kubectl` uses.
@ -170,7 +170,7 @@ workflow for doing this is as follows:
5. When you are ready for us to review, sign your commit, push your branch to GitHub, and 5. When you are ready for us to review, sign your commit, push your branch to GitHub, and
then open a new pull request with us. then open a new pull request with us.
For Git commit messages, we follow the [Semantic Commit Messages](http://karma-runner.github.io/0.13/dev/git-commit-msg.html): For Git commit messages, we follow the [Semantic Commit Messages](https://karma-runner.github.io/0.13/dev/git-commit-msg.html):
``` ```
fix(helm): add --foo flag to 'helm install' fix(helm): add --foo flag to 'helm install'
@ -201,7 +201,7 @@ Common scopes:
Read more: Read more:
- The [Deis Guidelines](https://github.com/deis/workflow/blob/master/src/contributing/submitting-a-pull-request.md) - The [Deis Guidelines](https://github.com/deis/workflow/blob/master/src/contributing/submitting-a-pull-request.md)
were the inspiration for this section. were the inspiration for this section.
- Karma Runner [defines](http://karma-runner.github.io/0.13/dev/git-commit-msg.html) the semantic commit message idea. - Karma Runner [defines](https://karma-runner.github.io/0.13/dev/git-commit-msg.html) the semantic commit message idea.
### Go Conventions ### Go Conventions

@ -10,6 +10,7 @@ metadata:
# The "app.kubernetes.io/instance" convention makes it easy to tie a release to all of the # The "app.kubernetes.io/instance" convention makes it easy to tie a release to all of the
# Kubernetes resources that were created as part of that release. # Kubernetes resources that were created as part of that release.
app.kubernetes.io/instance: {{ .Release.Name | quote }} app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
# This makes it easy to audit chart usage. # This makes it easy to audit chart usage.
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }} helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
app.kubernetes.io/name: {{ template "alpine.name" . }} app.kubernetes.io/name: {{ template "alpine.name" . }}

@ -37,7 +37,7 @@ are bundled with it.
## Chart Version ## Chart Version
Charts are versioned according to the [SemVer 2 Charts are versioned according to the [SemVer 2
spec](http://semver.org). A version number is required on every chart. spec](https://semver.org). A version number is required on every chart.
## Chart.yaml ## Chart.yaml

@ -21,18 +21,19 @@ Common actions from this point include:
- helm list: list releases of charts - helm list: list releases of charts
Environment: Environment:
$HELM_HOME set an alternative location for Helm files. By default, these are stored in ~/.helm
$HELM_HOST set an alternative Tiller host. The format is host:port - $HELM_HOME: set an alternative location for Helm files. By default, these are stored in ~/.helm
$HELM_NO_PLUGINS disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. - $HELM_HOST: set an alternative Tiller host. The format is host:port
$TILLER_NAMESPACE set an alternative Tiller namespace (default "kube-system") - $HELM_NO_PLUGINS: disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.
$KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config") - $TILLER_NAMESPACE: set an alternative Tiller namespace (default "kube-system")
$HELM_TLS_CA_CERT path to TLS CA certificate used to verify the Helm client and Tiller server certificates (default "$HELM_HOME/ca.pem") - $KUBECONFIG: set an alternative Kubernetes configuration file (default "~/.kube/config")
$HELM_TLS_CERT path to TLS client certificate file for authenticating to Tiller (default "$HELM_HOME/cert.pem") - $HELM_TLS_CA_CERT: path to TLS CA certificate used to verify the Helm client and Tiller server certificates (default "$HELM_HOME/ca.pem")
$HELM_TLS_KEY path to TLS client key file for authenticating to Tiller (default "$HELM_HOME/key.pem") - $HELM_TLS_CERT: path to TLS client certificate file for authenticating to Tiller (default "$HELM_HOME/cert.pem")
$HELM_TLS_VERIFY enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false") - $HELM_TLS_KEY: path to TLS client key file for authenticating to Tiller (default "$HELM_HOME/key.pem")
$HELM_TLS_ENABLE enable TLS connection between Helm and Tiller (default "false") - $HELM_TLS_ENABLE: enable TLS connection between Helm and Tiller (default "false")
$HELM_KEY_PASSPHRASE set HELM_KEY_PASSPHRASE to the passphrase of your PGP private key. If set, you will not be prompted for - $HELM_TLS_VERIFY: enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false")
the passphrase while signing helm charts - $HELM_TLS_HOSTNAME: the hostname or IP address used to verify the Tiller server certificate (default "127.0.0.1")
- $HELM_KEY_PASSPHRASE: set HELM_KEY_PASSPHRASE to the passphrase of your PGP private key. If set, you will not be prompted for the passphrase while signing helm charts
@ -78,4 +79,4 @@ Environment:
* [helm verify](helm_verify.md) - verify that a chart at the given path has been signed and is valid * [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 * [helm version](helm_version.md) - print the client/server version information
###### Auto generated by spf13/cobra on 16-Oct-2018 ###### Auto generated by spf13/cobra on 25-Apr-2019

@ -49,7 +49,7 @@ the dependency charts stored locally. The path should start with a prefix of
repository: "file://../dependency_chart/nginx" repository: "file://../dependency_chart/nginx"
If the dependency chart is retrieved locally, it is not required to have the If the dependency chart is retrieved locally, it is not required to have the
repository added to helm by "helm add repo". Version matching is also supported repository added to helm by "helm repo add". Version matching is also supported
for this case. for this case.
@ -78,4 +78,4 @@ for this case.
* [helm dependency list](helm_dependency_list.md) - list the dependencies for the given chart * [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 * [helm dependency update](helm_dependency_update.md) - update charts/ based on the contents of requirements.yaml
###### Auto generated by spf13/cobra on 1-Aug-2018 ###### Auto generated by spf13/cobra on 26-Mar-2019

@ -8,12 +8,11 @@ rebuild the charts/ directory based on the requirements.lock file
Build out the charts/ directory from the requirements.lock file. Build out the charts/ directory from the requirements.lock file.
Build is used to reconstruct a chart's dependencies to the state specified in Build is used to reconstruct a chart's dependencies to the state specified in
the lock file. This will not re-negotiate dependencies, as 'helm dependency update' the lock file.
does.
If no lock file is found, 'helm dependency build' will mirror the behavior
of 'helm dependency update'.
If no lock file is found, 'helm dependency build' will mirror the behavior of
the 'helm dependency update' command. This means it will update the on-disk
dependencies to mirror the requirements.yaml file and generate a lock file.
``` ```
helm dependency build [flags] CHART helm dependency build [flags] CHART

@ -26,6 +26,7 @@ helm get [flags] RELEASE_NAME
``` ```
-h, --help help for get -h, --help help for get
--revision int32 get the named release with revision --revision int32 get the named release with revision
--template string go template for formatting the output, eg: {{.Release.Name}}
--tls enable TLS for request --tls enable TLS for request
--tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
--tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem")
@ -54,4 +55,4 @@ helm get [flags] RELEASE_NAME
* [helm get notes](helm_get_notes.md) - displays the notes of the named release * [helm get notes](helm_get_notes.md) - displays the notes of the named release
* [helm get values](helm_get_values.md) - download the values file 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 1-Sep-2018 ###### Auto generated by spf13/cobra on 25-Mar-2019

@ -20,6 +20,7 @@ helm rollback [flags] [RELEASE] [REVISION]
### Options ### Options
``` ```
--cleanup-on-fail allow deletion of new resources created in this rollback when rollback failed
--description string specify a description for the release --description string specify a description for the release
--dry-run simulate a rollback --dry-run simulate a rollback
--force force resource update through delete/recreate if needed --force force resource update through delete/recreate if needed
@ -52,4 +53,4 @@ helm rollback [flags] [RELEASE] [REVISION]
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 29-Jan-2019 ###### Auto generated by spf13/cobra on 5-Feb-2019

@ -68,6 +68,7 @@ helm upgrade [RELEASE] [CHART] [flags]
--atomic if set, upgrade process rolls back changes made in case of failed upgrade, also sets --wait flag --atomic if set, upgrade process rolls back changes made in case of failed upgrade, also sets --wait flag
--ca-file string verify certificates of HTTPS-enabled servers using this CA bundle --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle
--cert-file string identify HTTPS client using this SSL certificate file --cert-file string identify HTTPS client using this SSL certificate file
--cleanup-on-fail allow deletion of new resources created in this upgrade when upgrade failed
--description string specify the description to use for the upgrade, rather than the default --description string specify the description to use for the upgrade, rather than the default
--devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored. --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
--dry-run simulate an upgrade --dry-run simulate an upgrade
@ -117,4 +118,4 @@ helm upgrade [RELEASE] [CHART] [flags]
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 28-Jan-2019 ###### Auto generated by spf13/cobra on 5-Feb-2019

@ -7,7 +7,7 @@ verify that a chart at the given path has been signed and is valid
Verify that the given chart has a valid provenance file. Verify that the given chart has a valid provenance file.
Provenance files provide crytographic verification that a chart has not been Provenance files provide cryptographic verification that a chart has not been
tampered with, and was packaged by a trusted provider. tampered with, and was packaged by a trusted provider.
This command can be used to verify a local chart. Several other commands provide This command can be used to verify a local chart. Several other commands provide
@ -42,4 +42,4 @@ helm verify [flags] PATH
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 1-Aug-2018 ###### Auto generated by spf13/cobra on 25-Feb-2019

@ -12,7 +12,7 @@ Differences from Helm Classic:
- Helm's chart format has changed for the better: - Helm's chart format has changed for the better:
- Dependencies are immutable and stored inside of a chart's `charts/` - Dependencies are immutable and stored inside of a chart's `charts/`
directory. directory.
- Charts are strongly versioned using [SemVer 2](http://semver.org/spec/v2.0.0.html) - Charts are strongly versioned using [SemVer 2](https://semver.org/spec/v2.0.0.html)
- Charts can be loaded from directories or from chart archive files - Charts can be loaded from directories or from chart archive files
- Helm supports Go templates without requiring you to run `generate` - Helm supports Go templates without requiring you to run `generate`
or `template` commands. or `template` commands.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 53 KiB

@ -60,21 +60,21 @@ The binary can also be installed via [`scoop`](https://scoop.sh) command-line in
scoop install helm scoop install helm
``` ```
## From Script ### From Script
Helm now has an installer script that will automatically grab the latest version Helm now has an installer script that will automatically grab the latest version
of the Helm client and [install it locally](https://raw.githubusercontent.com/helm/helm/master/scripts/get). of the Helm client and [install it locally](https://git.io/get_helm.sh).
You can fetch that script, and then execute it locally. It's well documented so You can fetch that script, and then execute it locally. It's well documented so
that you can read through it and understand what it is doing before you run it. that you can read through it and understand what it is doing before you run it.
``` ```
$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get > get_helm.sh $ curl -LO https://git.io/get_helm.sh
$ chmod 700 get_helm.sh $ chmod 700 get_helm.sh
$ ./get_helm.sh $ ./get_helm.sh
``` ```
Yes, you can `curl https://raw.githubusercontent.com/helm/helm/master/scripts/get | bash` that if you want to live on the edge. Yes, you can `curl -L https://git.io/get_helm.sh | bash` that if you want to live on the edge.
### From Canary Builds ### From Canary Builds
@ -353,10 +353,13 @@ in JSON format.
### Storage backends ### Storage backends
By default, `tiller` stores release information in `ConfigMaps` in the namespace By default, `tiller` stores release information in `ConfigMaps` in the namespace
where it is running. As of Helm 2.7.0, there is now a beta storage backend that where it is running.
#### Secret storage backend
As of Helm 2.7.0, there is now a beta storage backend that
uses `Secrets` for storing release information. This was added for additional uses `Secrets` for storing release information. This was added for additional
security in protecting charts in conjunction with the release of `Secret` security in protecting charts in conjunction with the release of `Secret`
encryption in Kubernetes. encryption in Kubernetes.
To enable the secrets backend, you'll need to init Tiller with the following To enable the secrets backend, you'll need to init Tiller with the following
options: options:
@ -369,6 +372,31 @@ Currently, if you want to switch from the default backend to the secrets
backend, you'll have to do the migration for this on your own. When this backend backend, you'll have to do the migration for this on your own. When this backend
graduates from beta, there will be a more official path of migration graduates from beta, there will be a more official path of migration
#### SQL storage backend
As of Helm 2.14.0 there is now a beta SQL storage backend that stores release
information in an SQL database (only postgres has been tested so far).
Using such a storage backend is particularly useful if your release information
weighs more than 1MB (in which case, it can't be stored in ConfigMaps/Secrets
because of internal limits in Kubernetes' underlying etcd key-value store).
To enable the SQL backend, you'll need to deploy a SQL database and init Tiller
with the following options:
```shell
helm init \
--override \
'spec.template.spec.containers[0].args'='{--storage=sql,--sql-dialect=postgres,--sql-connection-string=postgresql://tiller-postgres:5432/helm?user=helm&password=changeme}'
```
**PRODUCTION NOTES**: it's recommended to change the username and password of
the SQL database in production deployments. Enabling SSL is also a good idea.
Last, but not least, perform regular backups/snapshots of your SQL database.
Currently, if you want to switch from the default backend to the SQL backend,
you'll have to do the migration for this on your own. When this backend
graduates from beta, there will be a more official migration path.
## Conclusion ## Conclusion
In most cases, installation is as simple as getting a pre-built `helm` binary In most cases, installation is as simple as getting a pre-built `helm` binary

@ -19,13 +19,12 @@ Build out the charts/ directory from the requirements.lock file.
.PP .PP
Build is used to reconstruct a chart's dependencies to the state specified in Build is used to reconstruct a chart's dependencies to the state specified in
the lock file. This will not re\-negotiate dependencies, as 'helm dependency update' the lock file.
does.
.PP .PP
If no lock file is found, 'helm dependency build' will mirror the behavior If no lock file is found, 'helm dependency build' will mirror the behavior of
of 'helm dependency update'. the 'helm dependency update' command. This means it will update the on-disk
dependencies to mirror the requirements.yaml file and generate a lock file.
.SH OPTIONS .SH OPTIONS
.PP .PP

@ -80,7 +80,7 @@ the '\-\-debug' and '\-\-dry\-run' flags can be combined. This will still requir
round\-trip to the Tiller server. round\-trip to the Tiller server.
.PP .PP
If \-\-verify is set, the chart MUST have a provenance file, and the provenenace If \-\-verify is set, the chart MUST have a provenance file, and the provenance
fall MUST pass all verification steps. fall MUST pass all verification steps.
.PP .PP

@ -18,7 +18,7 @@ helm\-verify \- verify that a chart at the given path has been signed and is val
Verify that the given chart has a valid provenance file. Verify that the given chart has a valid provenance file.
.PP .PP
Provenance files provide crytographic verification that a chart has not been Provenance files provide cryptographic verification that a chart has not been
tampered with, and was packaged by a trusted provider. tampered with, and was packaged by a trusted provider.
.PP .PP

@ -180,7 +180,7 @@ The following pieces of provenance data are added:
* The signature (SHA256, just like Docker) of the chart package (the .tgz file) * The signature (SHA256, just like Docker) of the chart package (the .tgz file)
is included, and may be used to verify the integrity of the chart package. is included, and may be used to verify the integrity of the chart package.
* The entire body is signed using the algorithm used by PGP (see * The entire body is signed using the algorithm used by PGP (see
[http://keybase.io] for an emerging way of making crypto signing and [https://keybase.io] for an emerging way of making crypto signing and
verification easy). verification easy).
The combination of this gives users the following assurances: The combination of this gives users the following assurances:
@ -202,7 +202,7 @@ keywords:
- proxy - proxy
source: source:
- https://github.com/foo/bar - https://github.com/foo/bar
home: http://nginx.com home: https://nginx.com
... ...
files: files:
@ -221,7 +221,7 @@ first is the Chart.yaml. The second is the checksums, a map of filenames to
SHA-256 digests (value shown is fake/truncated) SHA-256 digests (value shown is fake/truncated)
The signature block is a standard PGP signature, which provides [tamper The signature block is a standard PGP signature, which provides [tamper
resistance](http://www.rossde.com/PGP/pgp_signatures.html). resistance](https://www.rossde.com/PGP/pgp_signatures.html).
## Chart Repositories ## Chart Repositories

@ -54,9 +54,11 @@ Once you have Helm ready, you can initialize the local CLI and also
install Tiller into your Kubernetes cluster in one step: install Tiller into your Kubernetes cluster in one step:
```console ```console
$ helm init $ helm init --history-max 200
``` ```
**TIP:** Setting `--history-max` on helm init is recommended as configmaps and other objects in helm history can grow large in number if not purged by max limit. Without a max history set the history is kept indefinitely, leaving a large number of records for helm and tiller to maintain.
This will install Tiller into the Kubernetes cluster you saw with This will install Tiller into the Kubernetes cluster you saw with
`kubectl config current-context`. `kubectl config current-context`.

@ -43,7 +43,7 @@ _Note: The cluster-admin role is created by default in a Kubernetes cluster, so
$ kubectl create -f rbac-config.yaml $ kubectl create -f rbac-config.yaml
serviceaccount "tiller" created serviceaccount "tiller" created
clusterrolebinding "tiller" created clusterrolebinding "tiller" created
$ helm init --service-account tiller $ helm init --service-account tiller --history-max 200
``` ```
### Example: Deploy Tiller in a namespace, restricted to deploying resources only in that namespace ### Example: Deploy Tiller in a namespace, restricted to deploying resources only in that namespace
@ -106,7 +106,6 @@ $ helm init --service-account tiller --tiller-namespace tiller-world
$HELM_HOME has been configured at /Users/awesome-user/.helm. $HELM_HOME has been configured at /Users/awesome-user/.helm.
Tiller (the Helm server side component) has been installed into your Kubernetes Cluster. Tiller (the Helm server side component) has been installed into your Kubernetes Cluster.
Happy Helming!
$ helm install nginx --tiller-namespace tiller-world --namespace tiller-world $ helm install nginx --tiller-namespace tiller-world --namespace tiller-world
NAME: wayfaring-yak NAME: wayfaring-yak

@ -8,9 +8,9 @@ or [pull request](https://github.com/helm/helm/pulls).
## Article, Blogs, How-Tos, and Extra Documentation ## Article, Blogs, How-Tos, and Extra Documentation
- [Awesome Helm](https://github.com/cdwv/awesome-helm) - List of awesome Helm resources - [Awesome Helm](https://github.com/cdwv/awesome-helm) - List of awesome Helm resources
- [CI/CD with Kubernetes, Helm & Wercker ](http://www.slideshare.net/Diacode/cicd-with-kubernetes-helm-wercker-madscalability) - [CI/CD with Kubernetes, Helm & Wercker ](https://www.slideshare.net/Diacode/cicd-with-kubernetes-helm-wercker-madscalability)
- [Creating a Helm Plugin in 3 Steps](http://technosophos.com/2017/03/21/creating-a-helm-plugin.html) - [Creating a Helm Plugin in 3 Steps](http://technosophos.com/2017/03/21/creating-a-helm-plugin.html)
- [Deploying Kubernetes Applications with Helm](http://cloudacademy.com/blog/deploying-kubernetes-applications-with-helm/) - [Deploying Kubernetes Applications with Helm](https://cloudacademy.com/blog/deploying-kubernetes-applications-with-helm/)
- [GitLab, Consumer Driven Contracts, Helm and Kubernetes](https://medium.com/@enxebre/gitlab-consumer-driven-contracts-helm-and-kubernetes-b7235a60a1cb#.xwp1y4tgi) - [GitLab, Consumer Driven Contracts, Helm and Kubernetes](https://medium.com/@enxebre/gitlab-consumer-driven-contracts-helm-and-kubernetes-b7235a60a1cb#.xwp1y4tgi)
- [Honestbee's Helm Chart Conventions](https://gist.github.com/so0k/f927a4b60003cedd101a0911757c605a) - [Honestbee's Helm Chart Conventions](https://gist.github.com/so0k/f927a4b60003cedd101a0911757c605a)
- [Releasing backward-incompatible changes: Kubernetes, Jenkins, Prometheus Operator, Helm and Traefik](https://medium.com/@enxebre/releasing-backward-incompatible-changes-kubernetes-jenkins-plugin-prometheus-operator-helm-self-6263ca61a1b1#.e0c7elxhq) - [Releasing backward-incompatible changes: Kubernetes, Jenkins, Prometheus Operator, Helm and Traefik](https://medium.com/@enxebre/releasing-backward-incompatible-changes-kubernetes-jenkins-plugin-prometheus-operator-helm-self-6263ca61a1b1#.e0c7elxhq)
@ -19,6 +19,7 @@ or [pull request](https://github.com/helm/helm/pulls).
- [Writing a Helm Chart](https://www.influxdata.com/packaged-kubernetes-deployments-writing-helm-chart/) - [Writing a Helm Chart](https://www.influxdata.com/packaged-kubernetes-deployments-writing-helm-chart/)
- [A basic walk through Kubernetes Helm](https://github.com/muffin87/helm-tutorial) - [A basic walk through Kubernetes Helm](https://github.com/muffin87/helm-tutorial)
- [Tillerless Helm v2](https://rimusz.net/tillerless-helm/) - [Tillerless Helm v2](https://rimusz.net/tillerless-helm/)
- [Generating Certificate Authorities and Certificates using Terraform](https://github.com/jbussdieker/tiller-ssl-terraform)
## Video, Audio, and Podcast ## Video, Audio, and Podcast
@ -68,6 +69,7 @@ Tools layered on top of Helm or Tiller.
- [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. - [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.
- [ChartMuseum](https://github.com/chartmuseum/chartmuseum) - Helm Chart Repository with support for Amazon S3 and Google Cloud Storage - [ChartMuseum](https://github.com/chartmuseum/chartmuseum) - Helm Chart Repository with support for Amazon S3 and Google Cloud Storage
- [Chartify](https://github.com/appscode/chartify) - Generate Helm charts from existing Kubernetes resources. - [Chartify](https://github.com/appscode/chartify) - Generate Helm charts from existing Kubernetes resources.
- [Cloudsmith](https://cloudsmith.io/l/helm-repository/) - Fully managed SaaS offering private Helm Chart Repositories
- [Codefresh](https://codefresh.io) - Kubernetes native CI/CD and management platform with UI dashboards for managing Helm charts and releases - [Codefresh](https://codefresh.io) - Kubernetes native CI/CD and management platform with UI dashboards for managing Helm charts and releases
- [Cog](https://github.com/ohaiwalt/cog-helm) - Helm chart to deploy Cog on Kubernetes - [Cog](https://github.com/ohaiwalt/cog-helm) - Helm chart to deploy Cog on Kubernetes
- [Drone.io Helm Plugin](http://plugins.drone.io/ipedrazas/drone-helm/) - Run Helm inside of the Drone CI/CD system - [Drone.io Helm Plugin](http://plugins.drone.io/ipedrazas/drone-helm/) - Run Helm inside of the Drone CI/CD system
@ -90,7 +92,7 @@ Tools layered on top of Helm or Tiller.
Platforms, distributions, and services that include Helm support. Platforms, distributions, and services that include Helm support.
- [Fabric8](https://fabric8.io) - Integrated development platform for Kubernetes - [Fabric8](https://fabric8.io) - Integrated development platform for Kubernetes
- [Jenkins X](http://jenkins-x.io/) - open source automated CI/CD for Kubernetes which uses Helm for [promoting](http://jenkins-x.io/about/features/#promotion) applications through [environments via GitOps](http://jenkins-x.io/about/features/#environments) - [Jenkins X](https://jenkins-x.io/) - open source automated CI/CD for Kubernetes which uses Helm for [promoting](https://jenkins-x.io/about/features/#promotion) applications through [environments via GitOps](https://jenkins-x.io/about/features/#environments)
- [Kubernetic](https://kubernetic.com/) - Kubernetes Desktop Client - [Kubernetic](https://kubernetic.com/) - Kubernetes Desktop Client
- [Qstack](https://qstack.com) - [Qstack](https://qstack.com)

@ -41,7 +41,7 @@ Just kidding! :trollface:
All releases will be of the form vX.Y.Z where X is the major version number, Y All releases will be of the form vX.Y.Z where X is the major version number, Y
is the minor version number and Z is the patch release number. This project is the minor version number and Z is the patch release number. This project
strictly follows [semantic versioning](http://semver.org/) so following this strictly follows [semantic versioning](https://semver.org/) so following this
step is critical. step is critical.
It is important to note that this document assumes that the git remote in your It is important to note that this document assumes that the git remote in your
@ -147,6 +147,24 @@ git add .
git commit -m "bump version to $RELEASE_CANDIDATE_NAME" git commit -m "bump version to $RELEASE_CANDIDATE_NAME"
``` ```
This will update it for the $RELEASE_BRANCH_NAME only. You will also need to pull
this change into the master branch for when the next release is being created.
```shell
# get the last commit id i.e. commit to bump the version
git log --format="%H" -n 1
# create new branch off master
git checkout master
git checkout -b bump-version-<release_version>
# cherry pick the commit using id from first command
git cherry-pick -x <commit-id>
# commit the change
git push origin bump-version-<release-version>
```
## 3. Commit and Push the Release Branch ## 3. Commit and Push the Release Branch
In order for others to start testing, we can now push the release branch In order for others to start testing, we can now push the release branch
@ -250,7 +268,25 @@ git tag --sign --annotate "${RELEASE_NAME}" --message "Helm release ${RELEASE_NA
git push upstream $RELEASE_NAME git push upstream $RELEASE_NAME
``` ```
## 7. Write the Release Notes ## 7. PGP Sign the downloads
While hashes provide a signature that the content of the downloads is what it
was generated, signed packages provide traceability of where the package came
from.
To do this, run the following `make` commands:
```shell
make clean
make fetch-dist
make sign
```
This will generate ascii armored signature files for each of the files pushed by CI.
All of the signature files need to be uploaded to the release on GitHub.
## 8. Write the Release Notes
We will auto-generate a changelog based on the commits that occurred during a We will auto-generate a changelog based on the commits that occurred during a
release cycle, but it is usually more beneficial to the end-user if the release release cycle, but it is usually more beneficial to the end-user if the release
@ -286,14 +322,14 @@ The community keeps growing, and we'd love to see you there!
Download Helm X.Y. The common platform binaries are here: Download Helm X.Y. The common platform binaries are here:
- [MacOS amd64](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-darwin-amd64.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-darwin-amd64.tar.gz.sha256)) - [MacOS amd64](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-darwin-amd64.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-darwin-amd64.tar.gz.sha256) / CHECKSUM_VAL)
- [Linux amd64](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-amd64.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-amd64.tar.gz.sha256)) - [Linux amd64](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-amd64.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-amd64.tar.gz.sha256) / CHECKSUM_VAL)
- [Linux arm](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-arm.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-arm.tar.gz.sha256)) - [Linux arm](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-arm.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-arm.tar.gz.sha256) / CHECKSUM_VAL)
- [Linux arm64](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-arm64.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-arm64.tar.gz.sha256)) - [Linux arm64](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-arm64.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-arm64.tar.gz.sha256) / CHECKSUM_VAL)
- [Linux i386](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-386.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-386.tar.gz.sha256)) - [Linux i386](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-386.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-386.tar.gz.sha256) / CHECKSUM_VAL)
- [Linux ppc64le](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-ppc64le.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-ppc64le.tar.gz.sha256)) - [Linux ppc64le](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-ppc64le.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-ppc64le.tar.gz.sha256) / CHECKSUM_VAL)
- [Linux s390x](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-s390x.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-s390x.tar.gz.sha256)) - [Linux s390x](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-s390x.tar.gz) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-s390x.tar.gz.sha256) / CHECKSUM_VAL)
- [Windows amd64](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-windows-amd64.zip) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-windows-amd64.zip.sha256)) - [Windows amd64](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-windows-amd64.zip) ([checksum](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-windows-amd64.zip.sha256) / CHECKSUM_VAL)
Once you have the client installed, upgrade Tiller with `helm init --upgrade`. Once you have the client installed, upgrade Tiller with `helm init --upgrade`.
@ -308,7 +344,7 @@ The [Quickstart Guide](https://docs.helm.sh/using_helm/#quickstart-guide) will g
### Features ### Features
- ref(*): kubernetes v1.11 support efadbd88035654b2951f3958167afed014c46bc6 (Adam Reese) - ref(*): kubernetes v1.11 support efadbd88035654b2951f3958167afed014c46bc6 (Adam Reese)
- feat(helm): add $HELM_KEY_PASSPHRASE environment variable for signing helm charts (#4778) 1e26b5300b5166fabb90002535aacd2f9cc7d787 - feat(helm): add $HELM_KEY_PASSPHRASE environment variable for signing helm charts (#4778) 1e26b5300b5166fabb90002535aacd2f9cc7d787
### Bug fixes ### Bug fixes
- fix circle not building tags f4f932fabd197f7e6d608c8672b33a483b4b76fa (Matthew Fisher) - fix circle not building tags f4f932fabd197f7e6d608c8672b33a483b4b76fa (Matthew Fisher)
@ -332,10 +368,11 @@ git log --no-merges --pretty=format:'- %s %H (%aN)' $PREVIOUS_RELEASE..$RELEASE_
After generating the changelog, you will need to categorize the changes as shown After generating the changelog, you will need to categorize the changes as shown
in the example above. in the example above.
Once finished, go into GitHub and edit the release notes for the tagged release Once finished, go into GitHub and edit the release notes for the tagged release with the notes written here.
with the notes written here.
Remember to attach the ascii armored signatures generated in the previous step to the release notes.
## 8. Evangelize ## 9. Evangelize
Congratulations! You're done. Go grab yourself a $DRINK_OF_CHOICE. You've earned Congratulations! You're done. Go grab yourself a $DRINK_OF_CHOICE. You've earned
it. it.

@ -42,6 +42,8 @@ on getting ready within a small amount of time. For production configurations,
we urge readers to read [the official documentation](https://www.openssl.org) and we urge readers to read [the official documentation](https://www.openssl.org) and
consult other resources. consult other resources.
There are other alternative ways to generating SSL CAs in addition to `openssl`, for example Terraform. They are not documented here but you can find links to these alternative means in [Related Projects and Documentation](https://helm.sh/docs/related/).
### Generate a Certificate Authority ### Generate a Certificate Authority
The simplest way to generate a certificate authority is to run two commands: The simplest way to generate a certificate authority is to run two commands:
@ -288,7 +290,7 @@ not available for public resolution.
By default, the Helm client connects to Tiller via tunnel (i.e. kube proxy) at 127.0.0.1. During the TLS handshake, By default, the Helm client connects to Tiller via tunnel (i.e. kube proxy) at 127.0.0.1. During the TLS handshake,
a target, usually provided as a hostname (e.g. example.com), is checked against the subject and subject alternative a target, usually provided as a hostname (e.g. example.com), is checked against the subject and subject alternative
names of the certificate (i.e. hostname verficiation). However, because of the tunnel, the target is an IP address. names of the certificate (i.e. hostname verification). However, because of the tunnel, the target is an IP address.
Therefore, to validate the certificate, the IP address 127.0.0.1 must be listed as an IP subject alternative name Therefore, to validate the certificate, the IP address 127.0.0.1 must be listed as an IP subject alternative name
(IP SAN) in the Tiller certificate. (IP SAN) in the Tiller certificate.

@ -17,9 +17,9 @@ cluster. Think of it like the Kubernetes equivalent of a Homebrew formula,
an Apt dpkg, or a Yum RPM file. an Apt dpkg, or a Yum RPM file.
A *Repository* is the place where charts can be collected and shared. A *Repository* is the place where charts can be collected and shared.
It's like Perl's [CPAN archive](http://www.cpan.org) or the It's like Perl's [CPAN archive](https://www.cpan.org) or the
[Fedora Package Database](https://admin.fedoraproject.org/pkgdb/), but for [Fedora Package Database](https://apps.fedoraproject.org/packages/s/pkgdb), but
Kubernetes packages. for Kubernetes packages.
A *Release* is an instance of a chart running in a Kubernetes cluster. A *Release* is an instance of a chart running in a Kubernetes cluster.
One chart can often be installed many times into the same cluster. And One chart can often be installed many times into the same cluster. And
@ -190,7 +190,7 @@ imageTag: 10.1.14-r3
## Specify a imagePullPolicy ## Specify a imagePullPolicy
## Default to 'Always' if imageTag is 'latest', else set to 'IfNotPresent' ## Default to 'Always' if imageTag is 'latest', else set to 'IfNotPresent'
## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images ## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images
## ##
# imagePullPolicy: # imagePullPolicy:
@ -359,7 +359,7 @@ update things that have changed since the last release.
```console ```console
$ helm upgrade -f panda.yaml happy-panda stable/mariadb $ helm upgrade -f panda.yaml happy-panda stable/mariadb
Fetched stable/mariadb-0.3.0.tgz to /Users/mattbutcher/Code/Go/src/k8s.io/helm/mariadb-0.3.0.tgz Fetched stable/mariadb-0.3.0.tgz to /Users/mattbutcher/Code/Go/src/k8s.io/helm/mariadb-0.3.0.tgz
happy-panda has been upgraded. Happy Helming! happy-panda has been upgraded.
Last Deployed: Wed Sep 28 12:47:54 2016 Last Deployed: Wed Sep 28 12:47:54 2016
Namespace: default Namespace: default
Status: DEPLOYED Status: DEPLOYED

185
glide.lock generated

@ -1,13 +1,11 @@
hash: 2af9a5c4f891a0f44109a929a494b5aeaaffa3a87cd1f3881f25f79845703d5b hash: 7571b58bbda7d85993d2b737b50d0c52f5fadce0c63e7fac064bc0a99faaefab
updated: 2018-12-14T21:39:31.112097Z updated: 2019-05-07T10:43:27.329085-04:00
imports: imports:
- name: cloud.google.com/go - name: cloud.google.com/go
version: 3b1ae45394a234c385be014e9a488f2bb6eef821 version: 3b1ae45394a234c385be014e9a488f2bb6eef821
subpackages: subpackages:
- compute/metadata - compute/metadata
- internal - internal
- name: github.com/aokoli/goutils
version: 9c37978a95bd5c709a15883b6242714ea6709e64
- name: github.com/asaskevich/govalidator - name: github.com/asaskevich/govalidator
version: 7664702784775e51966f0885f5cd27435916517b version: 7664702784775e51966f0885f5cd27435916517b
- name: github.com/Azure/go-ansiterm - name: github.com/Azure/go-ansiterm
@ -86,14 +84,18 @@ imports:
version: 449fdfce4d962303d702fec724ef0ad181c92528 version: 449fdfce4d962303d702fec724ef0ad181c92528
subpackages: subpackages:
- spdy - spdy
- name: github.com/emicklei/go-restful
version: ff4f55a206334ef123e4f79bbf348980da81ca46
subpackages:
- log
- name: github.com/evanphx/json-patch - name: github.com/evanphx/json-patch
version: 36442dbdb585210f8d5a1b45e67aa323c197d5c4 version: 5858425f75500d40c52783dce87d085a483ce135
- name: github.com/exponent-io/jsonpath - name: github.com/exponent-io/jsonpath
version: d6023ce2651d8eafb5c75bb0c7167536102ec9f5 version: d6023ce2651d8eafb5c75bb0c7167536102ec9f5
- name: github.com/fatih/camelcase - name: github.com/fatih/camelcase
version: f6a740d52f961c60348ebb109adde9f4635d7540 version: f6a740d52f961c60348ebb109adde9f4635d7540
- name: github.com/ghodss/yaml - name: github.com/ghodss/yaml
version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee version: c7ce16629ff4cd059ed96ed06419dd3856fd3577
- name: github.com/go-openapi/jsonpointer - name: github.com/go-openapi/jsonpointer
version: ef5f0afec364d3b9396b7b77b43dbe26bf1f8004 version: ef5f0afec364d3b9396b7b77b43dbe26bf1f8004
- name: github.com/go-openapi/jsonreference - name: github.com/go-openapi/jsonreference
@ -122,7 +124,7 @@ imports:
subpackages: subpackages:
- lru - lru
- name: github.com/golang/protobuf - name: github.com/golang/protobuf
version: 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9 version: aa810b61a9c79d51363740d207bb46cf8e620ed5
subpackages: subpackages:
- proto - proto
- ptypes - ptypes
@ -132,7 +134,7 @@ imports:
- name: github.com/google/btree - name: github.com/google/btree
version: 7d79101e329e5a3adf994758c578dab82b90c017 version: 7d79101e329e5a3adf994758c578dab82b90c017
- name: github.com/google/gofuzz - name: github.com/google/gofuzz
version: 44d81051d367757e1c7c6a5a86423ece9afcf63c version: 24818f796faf91cd76ec7bddd72458fbced7a6c1
- name: github.com/google/uuid - name: github.com/google/uuid
version: 064e2069ce9c359c118179501254f67d7d37ba24 version: 064e2069ce9c359c118179501254f67d7d37ba24
- name: github.com/googleapis/gnostic - name: github.com/googleapis/gnostic
@ -142,7 +144,7 @@ imports:
- compiler - compiler
- extensions - extensions
- name: github.com/gophercloud/gophercloud - name: github.com/gophercloud/gophercloud
version: 781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d version: c818fa66e4c88b30db28038fe3f18f2f4a0db9a8
subpackages: subpackages:
- openstack - openstack
- openstack/identity/v2/tenants - openstack/identity/v2/tenants
@ -162,17 +164,27 @@ imports:
- name: github.com/grpc-ecosystem/go-grpc-prometheus - name: github.com/grpc-ecosystem/go-grpc-prometheus
version: 0c1b191dbfe51efdabe3c14b9f6f3b96429e0722 version: 0c1b191dbfe51efdabe3c14b9f6f3b96429e0722
- name: github.com/hashicorp/golang-lru - name: github.com/hashicorp/golang-lru
version: a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4 version: 20f1fb78b0740ba8c3cb143a61e86ba5c8669768
subpackages: subpackages:
- simplelru - simplelru
- name: github.com/huandu/xstrings - name: github.com/huandu/xstrings
version: 3959339b333561bf62a38b424fd41517c2c90f40 version: f02667b379e2fb5916c3cda2cf31e0eb885d79f8
- name: github.com/imdario/mergo - name: github.com/imdario/mergo
version: 9316a62528ac99aaecb4e47eadd6dc8aa6533d58 version: 9316a62528ac99aaecb4e47eadd6dc8aa6533d58
- name: github.com/inconshreveable/mousetrap - name: github.com/inconshreveable/mousetrap
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
- name: github.com/jmoiron/sqlx
version: d161d7a76b5661016ad0b085869f77fd410f3e6a
subpackages:
- reflectx
- name: github.com/json-iterator/go - name: github.com/json-iterator/go
version: ab8a2e0c74be9d3be70b3184d9acc634935ded82 version: ab8a2e0c74be9d3be70b3184d9acc634935ded82
- name: github.com/liggitt/tabwriter
version: 89fcab3d43de07060e4fd4c1547430ed57e87f24
- name: github.com/lib/pq
version: 88edab0803230a3898347e77b474f8c1820a1f20
subpackages:
- oid
- name: github.com/mailru/easyjson - name: github.com/mailru/easyjson
version: 2f5df55504ebc322e4d52d34df6a1f5b503bf26d version: 2f5df55504ebc322e4d52d34df6a1f5b503bf26d
subpackages: subpackages:
@ -181,10 +193,12 @@ imports:
- jwriter - jwriter
- name: github.com/MakeNowJust/heredoc - name: github.com/MakeNowJust/heredoc
version: bb23615498cded5e105af4ce27de75b089cbe851 version: bb23615498cded5e105af4ce27de75b089cbe851
- name: github.com/Masterminds/goutils
version: 41ac8693c5c10a92ea1ff5ac3a7f95646f6123b0
- name: github.com/Masterminds/semver - name: github.com/Masterminds/semver
version: 517734cc7d6470c0d07130e40fd40bdeb9bcd3fd version: c7af12943936e8c39859482e61f0574c2fd7fc75
- name: github.com/Masterminds/sprig - name: github.com/Masterminds/sprig
version: 15f9564e7e9cf0da02a48e0d25f12a7b83559aa6 version: 9f8fceff796fb9f4e992cd2bece016be0121ab74
- name: github.com/Masterminds/vcs - name: github.com/Masterminds/vcs
version: 3084677c2c188840777bff30054f2b553729d329 version: 3084677c2c188840777bff30054f2b553729d329
- name: github.com/mattn/go-runewidth - name: github.com/mattn/go-runewidth
@ -206,16 +220,17 @@ imports:
- name: github.com/pkg/errors - name: github.com/pkg/errors
version: 645ef00459ed84a119197bfb8d8205042c6df63d version: 645ef00459ed84a119197bfb8d8205042c6df63d
- name: github.com/prometheus/client_golang - name: github.com/prometheus/client_golang
version: c5b7fccd204277076155f10851dad72b76a49317 version: 505eaef017263e299324067d40ca2c48f6a2cf50
subpackages: subpackages:
- prometheus - prometheus
- prometheus/internal
- prometheus/promhttp - prometheus/promhttp
- name: github.com/prometheus/client_model - name: github.com/prometheus/client_model
version: fa8ad6fec33561be4280a8f0514318c79d7f6cb6 version: fa8ad6fec33561be4280a8f0514318c79d7f6cb6
subpackages: subpackages:
- go - go
- name: github.com/prometheus/common - name: github.com/prometheus/common
version: 13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207 version: cfeb6f9992ffa54aaa4f2170ade4067ee478b250
subpackages: subpackages:
- expfmt - expfmt
- internal/bitbucket.org/ww/goautoneg - internal/bitbucket.org/ww/goautoneg
@ -228,6 +243,10 @@ imports:
version: 8a290539e2e8629dbc4e6bad948158f790ec31f4 version: 8a290539e2e8629dbc4e6bad948158f790ec31f4
- name: github.com/PuerkitoBio/urlesc - name: github.com/PuerkitoBio/urlesc
version: 5bd2802263f21d8788851d5305584c82a5c75d7e version: 5bd2802263f21d8788851d5305584c82a5c75d7e
- name: github.com/rubenv/sql-migrate
version: 1007f53448d75fe14190968f5de4d95ed63ebb83
subpackages:
- sqlparse
- name: github.com/russross/blackfriday - name: github.com/russross/blackfriday
version: 300106c228d52c8941d4b3de6054a6062a86dda3 version: 300106c228d52c8941d4b3de6054a6062a86dda3
- name: github.com/shurcooL/sanitized_anchor_name - name: github.com/shurcooL/sanitized_anchor_name
@ -259,15 +278,15 @@ imports:
- scrypt - scrypt
- ssh/terminal - ssh/terminal
- name: golang.org/x/net - name: golang.org/x/net
version: 0ed95abb35c445290478a5348a7b38bb154135fd version: 65e2d4e15006aab9813ff8769e768bbf4bb667a0
subpackages: subpackages:
- context - context
- context/ctxhttp - context/ctxhttp
- http/httpguts
- http2 - http2
- http2/hpack - http2/hpack
- idna - idna
- internal/timeseries - internal/timeseries
- lex/httplex
- trace - trace
- name: golang.org/x/oauth2 - name: golang.org/x/oauth2
version: a6bd8cefa1811bd24b86f8902872e4e8225f74c4 version: a6bd8cefa1811bd24b86f8902872e4e8225f74c4
@ -281,7 +300,7 @@ imports:
subpackages: subpackages:
- semaphore - semaphore
- name: golang.org/x/sys - name: golang.org/x/sys
version: 95c6576299259db960f6c5b9b69ea52422860fce version: b90733256f2e882e81d52f9126de08df5615afd9
subpackages: subpackages:
- unix - unix
- windows - windows
@ -325,26 +344,42 @@ imports:
subpackages: subpackages:
- googleapis/rpc/status - googleapis/rpc/status
- name: google.golang.org/grpc - name: google.golang.org/grpc
version: 5ffe3083946d5603a0578721101dc8165b1d5b5f version: a02b0774206b209466313a0b525d2c738fe407eb
subpackages: subpackages:
- balancer - balancer
- balancer/base
- balancer/roundrobin
- binarylog/grpc_binarylog_v1
- codes - codes
- connectivity - connectivity
- credentials - credentials
- grpclb/grpc_lb_v1/messages - credentials/internal
- encoding
- encoding/proto
- grpclog - grpclog
- health - health
- health/grpc_health_v1 - health/grpc_health_v1
- internal - internal
- internal/backoff
- internal/binarylog
- internal/channelz
- internal/envconfig
- internal/grpcrand
- internal/grpcsync
- internal/syscall
- internal/transport
- keepalive - keepalive
- metadata - metadata
- naming - naming
- peer - peer
- resolver - resolver
- resolver/dns
- resolver/passthrough
- stats - stats
- status - status
- tap - tap
- transport - name: gopkg.in/gorp.v1
version: 6a667da9c028871f98598d85413e3fc4c6daa52e
- name: gopkg.in/inf.v0 - name: gopkg.in/inf.v0
version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
- name: gopkg.in/square/go-jose.v2 - name: gopkg.in/square/go-jose.v2
@ -354,12 +389,11 @@ imports:
- json - json
- jwt - jwt
- name: gopkg.in/yaml.v2 - name: gopkg.in/yaml.v2
version: 670d4cfef0544295bc27a114dbac37980d83185a version: 5420a8b6744d3b0345ab293f6fcba19c978f1183
- name: k8s.io/api - name: k8s.io/api
version: 05914d821849570fba9eacfb29466f2d8d3cd229 version: 6e4e0e4f393bf5e8bbff570acd13217aa5a770cd
subpackages: subpackages:
- admission/v1beta1 - admission/v1beta1
- admissionregistration/v1alpha1
- admissionregistration/v1beta1 - admissionregistration/v1beta1
- apps/v1 - apps/v1
- apps/v1beta1 - apps/v1beta1
@ -376,16 +410,21 @@ imports:
- batch/v1beta1 - batch/v1beta1
- batch/v2alpha1 - batch/v2alpha1
- certificates/v1beta1 - certificates/v1beta1
- coordination/v1
- coordination/v1beta1 - coordination/v1beta1
- core/v1 - core/v1
- events/v1beta1 - events/v1beta1
- extensions/v1beta1 - extensions/v1beta1
- imagepolicy/v1alpha1 - imagepolicy/v1alpha1
- networking/v1 - networking/v1
- networking/v1beta1
- node/v1alpha1
- node/v1beta1
- policy/v1beta1 - policy/v1beta1
- rbac/v1 - rbac/v1
- rbac/v1alpha1 - rbac/v1alpha1
- rbac/v1beta1 - rbac/v1beta1
- scheduling/v1
- scheduling/v1alpha1 - scheduling/v1alpha1
- scheduling/v1beta1 - scheduling/v1beta1
- settings/v1alpha1 - settings/v1alpha1
@ -393,11 +432,13 @@ imports:
- storage/v1alpha1 - storage/v1alpha1
- storage/v1beta1 - storage/v1beta1
- name: k8s.io/apiextensions-apiserver - name: k8s.io/apiextensions-apiserver
version: 0fe22c71c47604641d9aa352c785b7912c200562 version: 727a075fdec8319bf095330e344b3ccc668abc73
subpackages: subpackages:
- pkg/apis/apiextensions
- pkg/apis/apiextensions/v1beta1
- pkg/features - pkg/features
- name: k8s.io/apimachinery - name: k8s.io/apimachinery
version: 2b1284ed4c93a43499e781493253e2ac5959c4fd version: 6a84e37a896db9780c75367af8d2ed2bb944022e
subpackages: subpackages:
- pkg/api/equality - pkg/api/equality
- pkg/api/errors - pkg/api/errors
@ -453,7 +494,7 @@ imports:
- third_party/forked/golang/netutil - third_party/forked/golang/netutil
- third_party/forked/golang/reflect - third_party/forked/golang/reflect
- name: k8s.io/apiserver - name: k8s.io/apiserver
version: 3ccfe8365421eb08e334b195786a2973460741d8 version: 1ec86e4da56ce0573788fc12bb3a5530600c0e5d
subpackages: subpackages:
- pkg/authentication/authenticator - pkg/authentication/authenticator
- pkg/authentication/serviceaccount - pkg/authentication/serviceaccount
@ -461,23 +502,31 @@ imports:
- pkg/features - pkg/features
- pkg/util/feature - pkg/util/feature
- name: k8s.io/cli-runtime - name: k8s.io/cli-runtime
version: 835b10687cb6556f6b113099ef925146a56d5981 version: d644b00f3b79346b7627329269bb25f2135f941c
subpackages: subpackages:
- pkg/genericclioptions - pkg/genericclioptions
- pkg/genericclioptions/printers - pkg/kustomize
- pkg/genericclioptions/resource - pkg/kustomize/k8sdeps
- pkg/kustomize/k8sdeps/configmapandsecret
- pkg/kustomize/k8sdeps/kunstruct
- pkg/kustomize/k8sdeps/kv
- pkg/kustomize/k8sdeps/transformer
- pkg/kustomize/k8sdeps/transformer/hash
- pkg/kustomize/k8sdeps/transformer/patch
- pkg/kustomize/k8sdeps/validator
- pkg/printers
- pkg/resource
- name: k8s.io/client-go - name: k8s.io/client-go
version: 8d9ed539ba3134352c586810e749e58df4e94e4f version: 1a26190bd76a9017e289958b9fba936430aa3704
subpackages: subpackages:
- discovery - discovery
- discovery/cached/disk
- discovery/fake - discovery/fake
- dynamic - dynamic
- dynamic/fake - dynamic/fake
- kubernetes - kubernetes
- kubernetes/fake - kubernetes/fake
- kubernetes/scheme - kubernetes/scheme
- kubernetes/typed/admissionregistration/v1alpha1
- kubernetes/typed/admissionregistration/v1alpha1/fake
- kubernetes/typed/admissionregistration/v1beta1 - kubernetes/typed/admissionregistration/v1beta1
- kubernetes/typed/admissionregistration/v1beta1/fake - kubernetes/typed/admissionregistration/v1beta1/fake
- kubernetes/typed/apps/v1 - kubernetes/typed/apps/v1
@ -510,6 +559,8 @@ imports:
- kubernetes/typed/batch/v2alpha1/fake - kubernetes/typed/batch/v2alpha1/fake
- kubernetes/typed/certificates/v1beta1 - kubernetes/typed/certificates/v1beta1
- kubernetes/typed/certificates/v1beta1/fake - kubernetes/typed/certificates/v1beta1/fake
- kubernetes/typed/coordination/v1
- kubernetes/typed/coordination/v1/fake
- kubernetes/typed/coordination/v1beta1 - kubernetes/typed/coordination/v1beta1
- kubernetes/typed/coordination/v1beta1/fake - kubernetes/typed/coordination/v1beta1/fake
- kubernetes/typed/core/v1 - kubernetes/typed/core/v1
@ -520,6 +571,12 @@ imports:
- kubernetes/typed/extensions/v1beta1/fake - kubernetes/typed/extensions/v1beta1/fake
- kubernetes/typed/networking/v1 - kubernetes/typed/networking/v1
- kubernetes/typed/networking/v1/fake - kubernetes/typed/networking/v1/fake
- kubernetes/typed/networking/v1beta1
- kubernetes/typed/networking/v1beta1/fake
- kubernetes/typed/node/v1alpha1
- kubernetes/typed/node/v1alpha1/fake
- kubernetes/typed/node/v1beta1
- kubernetes/typed/node/v1beta1/fake
- kubernetes/typed/policy/v1beta1 - kubernetes/typed/policy/v1beta1
- kubernetes/typed/policy/v1beta1/fake - kubernetes/typed/policy/v1beta1/fake
- kubernetes/typed/rbac/v1 - kubernetes/typed/rbac/v1
@ -528,6 +585,8 @@ imports:
- kubernetes/typed/rbac/v1alpha1/fake - kubernetes/typed/rbac/v1alpha1/fake
- kubernetes/typed/rbac/v1beta1 - kubernetes/typed/rbac/v1beta1
- kubernetes/typed/rbac/v1beta1/fake - kubernetes/typed/rbac/v1beta1/fake
- kubernetes/typed/scheduling/v1
- kubernetes/typed/scheduling/v1/fake
- kubernetes/typed/scheduling/v1alpha1 - kubernetes/typed/scheduling/v1alpha1
- kubernetes/typed/scheduling/v1alpha1/fake - kubernetes/typed/scheduling/v1alpha1/fake
- kubernetes/typed/scheduling/v1beta1 - kubernetes/typed/scheduling/v1beta1
@ -574,30 +633,35 @@ imports:
- tools/pager - tools/pager
- tools/portforward - tools/portforward
- tools/record - tools/record
- tools/record/util
- tools/reference - tools/reference
- tools/remotecommand - tools/remotecommand
- tools/watch - tools/watch
- transport - transport
- transport/spdy - transport/spdy
- util/buffer
- util/cert - util/cert
- util/connrotation - util/connrotation
- util/exec - util/exec
- util/flowcontrol - util/flowcontrol
- util/homedir - util/homedir
- util/integer
- util/jsonpath - util/jsonpath
- util/keyutil
- util/retry - util/retry
- name: k8s.io/cloud-provider
version: 9c9d72d1bf90eb62005f5112f3eea019b272c44b
subpackages:
- features
- name: k8s.io/klog - name: k8s.io/klog
version: 8139d8cb77af419532b33dfa7dd09fbc5f1d344f version: 8e90cee79f823779174776412c13478955131846
- name: k8s.io/kube-openapi - name: k8s.io/kube-openapi
version: c59034cc13d587f5ef4e85ca0ade0c1866ae8e1d version: b3a7cee44a305be0a69e1b9ac03018307287e1b0
subpackages: subpackages:
- pkg/common
- pkg/util/proto - pkg/util/proto
- pkg/util/proto/testing - pkg/util/proto/testing
- pkg/util/proto/validation - pkg/util/proto/validation
- name: k8s.io/kubernetes - name: k8s.io/kubernetes
version: f2c8f1cadf1808ec28476682e49a3cce2b09efbf version: b7394102d6ef778017f2ca4046abbaa23b88c290
subpackages: subpackages:
- pkg/api/legacyscheme - pkg/api/legacyscheme
- pkg/api/service - pkg/api/service
@ -630,6 +694,7 @@ imports:
- pkg/apis/certificates/v1beta1 - pkg/apis/certificates/v1beta1
- pkg/apis/coordination - pkg/apis/coordination
- pkg/apis/coordination/install - pkg/apis/coordination/install
- pkg/apis/coordination/v1
- pkg/apis/coordination/v1beta1 - pkg/apis/coordination/v1beta1
- pkg/apis/core - pkg/apis/core
- pkg/apis/core/helper - pkg/apis/core/helper
@ -645,6 +710,7 @@ imports:
- pkg/apis/extensions/install - pkg/apis/extensions/install
- pkg/apis/extensions/v1beta1 - pkg/apis/extensions/v1beta1
- pkg/apis/networking - pkg/apis/networking
- pkg/apis/node
- pkg/apis/policy - pkg/apis/policy
- pkg/apis/policy/install - pkg/apis/policy/install
- pkg/apis/policy/v1beta1 - pkg/apis/policy/v1beta1
@ -655,6 +721,7 @@ imports:
- pkg/apis/rbac/v1beta1 - pkg/apis/rbac/v1beta1
- pkg/apis/scheduling - pkg/apis/scheduling
- pkg/apis/scheduling/install - pkg/apis/scheduling/install
- pkg/apis/scheduling/v1
- pkg/apis/scheduling/v1alpha1 - pkg/apis/scheduling/v1alpha1
- pkg/apis/scheduling/v1beta1 - pkg/apis/scheduling/v1beta1
- pkg/apis/settings - pkg/apis/settings
@ -699,30 +766,54 @@ imports:
- pkg/kubectl/util/templates - pkg/kubectl/util/templates
- pkg/kubectl/util/term - pkg/kubectl/util/term
- pkg/kubectl/validation - pkg/kubectl/validation
- pkg/kubelet/apis
- pkg/kubelet/types - pkg/kubelet/types
- pkg/master/ports - pkg/master/ports
- pkg/printers - pkg/printers
- pkg/printers/internalversion - pkg/printers/internalversion
- pkg/scheduler/api
- pkg/security/apparmor - pkg/security/apparmor
- pkg/serviceaccount - pkg/serviceaccount
- pkg/util/file
- pkg/util/hash - pkg/util/hash
- pkg/util/interrupt - pkg/util/interrupt
- pkg/util/labels - pkg/util/labels
- pkg/util/net/sets
- pkg/util/node - pkg/util/node
- pkg/util/parsers - pkg/util/parsers
- pkg/util/taints - pkg/util/taints
- pkg/version - pkg/version
- name: k8s.io/utils - name: k8s.io/utils
version: 66066c83e385e385ccc3c964b44fd7dcd413d0ed version: c2654d5206da6b7b6ace12841e8f359bb89b443c
subpackages: subpackages:
- clock - buffer
- exec - exec
- exec/testing - integer
- net
- path
- pointer - pointer
- trace
- name: sigs.k8s.io/kustomize
version: a6f65144121d1955266b0cd836ce954c04122dc8
subpackages:
- pkg/commands/build
- pkg/constants
- pkg/expansion
- pkg/factory
- pkg/fs
- pkg/git
- pkg/gvk
- pkg/ifc
- pkg/ifc/transformer
- pkg/image
- pkg/internal/error
- pkg/loader
- pkg/patch
- pkg/patch/transformer
- pkg/resid
- pkg/resmap
- pkg/resource
- pkg/target
- pkg/transformers
- pkg/transformers/config
- pkg/transformers/config/defaultconfig
- pkg/types
- name: sigs.k8s.io/yaml - name: sigs.k8s.io/yaml
version: fd68e9863619f6ec2fdd8625fe1f02e7c877e480 version: fd68e9863619f6ec2fdd8625fe1f02e7c877e480
- name: vbom.ml/util - name: vbom.ml/util
@ -730,8 +821,10 @@ imports:
subpackages: subpackages:
- sortorder - sortorder
testImports: testImports:
- name: github.com/DATA-DOG/go-sqlmock
version: 472e287dbafe67e526a3797165b64cb14f34705a
- name: github.com/pmezard/go-difflib - name: github.com/pmezard/go-difflib
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d version: 5d4384ee4fb2527b0a1256a821ebfc92f91efefc
subpackages: subpackages:
- difflib - difflib
- name: github.com/stretchr/testify - name: github.com/stretchr/testify

@ -2,67 +2,76 @@ package: k8s.io/helm
import: import:
- package: golang.org/x/net - package: golang.org/x/net
subpackages: subpackages:
- context - context
- package: golang.org/x/sync - package: golang.org/x/sync
subpackages: subpackages:
- semaphore - semaphore
- package: golang.org/x/sys
version: b90733256f2e882e81d52f9126de08df5615afd9
subpackages:
- unix
- windows
- package: github.com/spf13/cobra - package: github.com/spf13/cobra
version: fe5e611709b0c57fa4a89136deaa8e1d4004d053 version: fe5e611709b0c57fa4a89136deaa8e1d4004d053
- package: github.com/spf13/pflag - package: github.com/spf13/pflag
version: ~1.0.1 version: ~1.0.1
- package: github.com/Masterminds/vcs - package: github.com/Masterminds/vcs
# Pin version of mergo that is compatible with both sprig and Kubernetes
- package: github.com/imdario/mergo - package: github.com/imdario/mergo
version: v0.3.5 version: v0.3.5
- package: github.com/Masterminds/sprig - package: github.com/Masterminds/sprig
version: ^2.16.0 version: ^2.19.0
- package: github.com/ghodss/yaml - package: github.com/ghodss/yaml
- package: github.com/Masterminds/semver - package: github.com/Masterminds/semver
version: ~1.3.1 version: ~1.4.2
- package: github.com/technosophos/moniker - package: github.com/technosophos/moniker
version: ~0.2 version: ~0.2
- package: github.com/golang/protobuf - package: github.com/golang/protobuf
version: 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9 version: 1.2.0
subpackages: subpackages:
- proto - proto
- ptypes/any - ptypes/any
- ptypes/timestamp - ptypes/timestamp
- package: google.golang.org/grpc - package: google.golang.org/grpc
version: 1.7.2 version: 1.18.0
- package: github.com/gosuri/uitable - package: github.com/gosuri/uitable
- package: github.com/asaskevich/govalidator - package: github.com/asaskevich/govalidator
version: ^4.0.0 version: ^4.0.0
- package: golang.org/x/crypto - package: golang.org/x/crypto
subpackages: subpackages:
- openpgp - openpgp
- ssh/terminal - ssh/terminal
- package: github.com/gobwas/glob - package: github.com/gobwas/glob
version: ^0.2.1 version: ^0.2.1
- package: github.com/evanphx/json-patch - package: github.com/evanphx/json-patch
- package: github.com/BurntSushi/toml - package: github.com/BurntSushi/toml
version: ~0.3.0 version: ~0.3.0
- package: github.com/prometheus/client_golang - package: github.com/prometheus/client_golang
version: 0.8.0 version: 0.9.2
- package: github.com/grpc-ecosystem/go-grpc-prometheus - package: github.com/grpc-ecosystem/go-grpc-prometheus
- package: k8s.io/kubernetes - package: k8s.io/kubernetes
version: release-1.13 version: v1.14.1
- package: k8s.io/client-go - package: k8s.io/client-go
version: kubernetes-1.13.1 version: kubernetes-1.14.1
- package: k8s.io/api - package: k8s.io/api
version: kubernetes-1.13.1 version: kubernetes-1.14.1
- package: k8s.io/apimachinery - package: k8s.io/apimachinery
version: kubernetes-1.13.1 version: kubernetes-1.14.1
- package: k8s.io/apiserver - package: k8s.io/apiserver
version: kubernetes-1.13.1 version: kubernetes-1.14.1
- package: k8s.io/cli-runtime - package: k8s.io/cli-runtime
version: kubernetes-1.13.1 version: kubernetes-1.14.1
- package: k8s.io/apiextensions-apiserver - package: k8s.io/apiextensions-apiserver
version: kubernetes-1.13.1 version: kubernetes-1.14.1
- package: github.com/cyphar/filepath-securejoin - package: github.com/cyphar/filepath-securejoin
version: ^0.2.1 version: ^0.2.1
- package: github.com/jmoiron/sqlx
version: ^1.2.0
- package: github.com/rubenv/sql-migrate
testImports: testImports:
- package: github.com/stretchr/testify - package: github.com/stretchr/testify
version: ^1.1.4 version: ^1.1.4
subpackages: subpackages:
- assert - assert
- package: github.com/DATA-DOG/go-sqlmock
version: ^1.3.2

@ -40,7 +40,7 @@ var (
// Capabilities describes the capabilities of the Kubernetes cluster that Tiller is attached to. // Capabilities describes the capabilities of the Kubernetes cluster that Tiller is attached to.
type Capabilities struct { type Capabilities struct {
// List of all supported API versions // APIVersions list of all supported API versions
APIVersions VersionSet APIVersions VersionSet
// KubeVersion is the Kubernetes version // KubeVersion is the Kubernetes version
KubeVersion *version.Info KubeVersion *version.Info

@ -72,6 +72,7 @@ image:
tag: stable tag: stable
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: "" nameOverride: ""
fullnameOverride: "" fullnameOverride: ""
@ -176,10 +177,7 @@ kind: Ingress
metadata: metadata:
name: {{ $fullName }} name: {{ $fullName }}
labels: labels:
app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }} {{ include "<CHARTNAME>.labels" . | indent 4 }}
helm.sh/chart: {{ include "<CHARTNAME>.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with .Values.ingress.annotations }} {{- with .Values.ingress.annotations }}
annotations: annotations:
{{- toYaml . | nindent 4 }} {{- toYaml . | nindent 4 }}
@ -215,10 +213,7 @@ kind: Deployment
metadata: metadata:
name: {{ include "<CHARTNAME>.fullname" . }} name: {{ include "<CHARTNAME>.fullname" . }}
labels: labels:
app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }} {{ include "<CHARTNAME>.labels" . | indent 4 }}
helm.sh/chart: {{ include "<CHARTNAME>.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec: spec:
replicas: {{ .Values.replicaCount }} replicas: {{ .Values.replicaCount }}
selector: selector:
@ -235,6 +230,10 @@ spec:
{{- toYaml .Values.podSecurityContext | nindent 8 }} {{- toYaml .Values.podSecurityContext | nindent 8 }}
volumes: volumes:
{{- toYaml .Values.volumes | nindent 8 }} {{- toYaml .Values.volumes | nindent 8 }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers: containers:
- name: {{ .Chart.Name }} - name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
@ -306,10 +305,7 @@ kind: Service
metadata: metadata:
name: {{ include "<CHARTNAME>.fullname" . }} name: {{ include "<CHARTNAME>.fullname" . }}
labels: labels:
app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }} {{ include "<CHARTNAME>.labels" . | indent 4 }}
helm.sh/chart: {{ include "<CHARTNAME>.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec: spec:
type: {{ .Values.service.type }} type: {{ .Values.service.type }}
ports: ports:
@ -377,6 +373,19 @@ Create chart name and version as used by the chart label.
{{- define "<CHARTNAME>.chart" -}} {{- define "<CHARTNAME>.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}} {{- end -}}
{{/*
Common labels
*/}}
{{- define "<CHARTNAME>.labels" -}}
app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }}
helm.sh/chart: {{ include "<CHARTNAME>.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
` `
const defaultTestConnection = `apiVersion: v1 const defaultTestConnection = `apiVersion: v1
@ -384,10 +393,7 @@ kind: Pod
metadata: metadata:
name: "{{ include "<CHARTNAME>.fullname" . }}-test-connection" name: "{{ include "<CHARTNAME>.fullname" . }}-test-connection"
labels: labels:
app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }} {{ include "<CHARTNAME>.labels" . | indent 4 }}
helm.sh/chart: {{ include "<CHARTNAME>.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
annotations: annotations:
"helm.sh/hook": test-success "helm.sh/hook": test-success
spec: spec:

@ -85,7 +85,7 @@ type Requirements struct {
// //
// It represents the state that the dependencies should be in. // It represents the state that the dependencies should be in.
type RequirementsLock struct { type RequirementsLock struct {
// Genderated is the date the lock file was last generated. // Generated is the date the lock file was last generated.
Generated time.Time `json:"generated"` Generated time.Time `json:"generated"`
// Digest is a hash of the requirements file used to generate it. // Digest is a hash of the requirements file used to generate it.
Digest string `json:"digest"` Digest string `json:"digest"`

@ -63,6 +63,12 @@ func SaveDir(c *chart.Chart, dest string) error {
// Save templates // Save templates
for _, f := range c.Templates { for _, f := range c.Templates {
n := filepath.Join(outdir, f.Name) n := filepath.Join(outdir, f.Name)
d := filepath.Dir(n)
if err := os.MkdirAll(d, 0755); err != nil {
return err
}
if err := ioutil.WriteFile(n, f.Data, 0644); err != nil { if err := ioutil.WriteFile(n, f.Data, 0644); err != nil {
return err return err
} }

@ -48,6 +48,9 @@ func TestSave(t *testing.T) {
Files: []*any.Any{ Files: []*any.Any{
{TypeUrl: "scheherazade/shahryar.txt", Value: []byte("1,001 Nights")}, {TypeUrl: "scheherazade/shahryar.txt", Value: []byte("1,001 Nights")},
}, },
Templates: []*chart.Template{
{Name: "templates/scheherazade/shahryar.txt.tmpl", Data: []byte("{{ \"1,001 Nights\" }}")},
},
} }
where, err := Save(c, tmp) where, err := Save(c, tmp)
@ -75,6 +78,9 @@ func TestSave(t *testing.T) {
if len(c2.Files) != 1 || c2.Files[0].TypeUrl != "scheherazade/shahryar.txt" { if len(c2.Files) != 1 || c2.Files[0].TypeUrl != "scheherazade/shahryar.txt" {
t.Fatal("Files data did not match") t.Fatal("Files data did not match")
} }
if len(c2.Templates) != 1 || c2.Templates[0].Name != "templates/scheherazade/shahryar.txt.tmpl" {
t.Fatal("Templates data did not match")
}
} }
func TestSavePreservesTimestamps(t *testing.T) { func TestSavePreservesTimestamps(t *testing.T) {
@ -100,6 +106,9 @@ func TestSavePreservesTimestamps(t *testing.T) {
Files: []*any.Any{ Files: []*any.Any{
{TypeUrl: "scheherazade/shahryar.txt", Value: []byte("1,001 Nights")}, {TypeUrl: "scheherazade/shahryar.txt", Value: []byte("1,001 Nights")},
}, },
Templates: []*chart.Template{
{Name: "templates/scheherazade/shahryar.txt.tmpl", Data: []byte("{{ \"1,001 Nights\" }}")},
},
} }
where, err := Save(c, tmp) where, err := Save(c, tmp)
@ -171,6 +180,9 @@ func TestSaveDir(t *testing.T) {
Files: []*any.Any{ Files: []*any.Any{
{TypeUrl: "scheherazade/shahryar.txt", Value: []byte("1,001 Nights")}, {TypeUrl: "scheherazade/shahryar.txt", Value: []byte("1,001 Nights")},
}, },
Templates: []*chart.Template{
{Name: "templates/scheherazade/shahryar.txt.tmpl", Data: []byte("{{ \"1,001 Nights\" }}")},
},
} }
if err := SaveDir(c, tmp); err != nil { if err := SaveDir(c, tmp); err != nil {
@ -191,4 +203,7 @@ func TestSaveDir(t *testing.T) {
if len(c2.Files) != 1 || c2.Files[0].TypeUrl != "scheherazade/shahryar.txt" { if len(c2.Files) != 1 || c2.Files[0].TypeUrl != "scheherazade/shahryar.txt" {
t.Fatal("Files data did not match") t.Fatal("Files data did not match")
} }
if len(c2.Templates) != 1 || c2.Templates[0].Name != "templates/scheherazade/shahryar.txt.tmpl" {
t.Fatal("Templates data did not match")
}
} }

@ -65,11 +65,11 @@ type ChartDownloader struct {
Keyring string Keyring string
// HelmHome is the $HELM_HOME. // HelmHome is the $HELM_HOME.
HelmHome helmpath.Home HelmHome helmpath.Home
// Getter collection for the operation // Getters collection for the operation
Getters getter.Providers Getters getter.Providers
// Chart repository username // Username chart repository username
Username string Username string
// Chart repository password // Password chart repository password
Password string Password string
} }
@ -213,7 +213,7 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, ge
cv, err := i.Get(chartName, version) cv, err := i.Get(chartName, version)
if err != nil { if err != nil {
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) return u, r.Client, fmt.Errorf("chart %q matching version %q not found in %s index. (try 'helm repo update'). %s", chartName, version, r.Config.Name, err)
} }
if len(cv.URLs) == 0 { if len(cv.URLs) == 0 {
@ -243,14 +243,14 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, ge
return u, r.Client, nil return u, r.Client, nil
} }
// If HttpGetter is used, this method sets the configured repository credentials on the HttpGetter. // setCredentials if HttpGetter is used, this method sets the configured repository credentials on the HttpGetter.
func (c *ChartDownloader) setCredentials(r *repo.ChartRepository) { func (c *ChartDownloader) setCredentials(r *repo.ChartRepository) {
if t, ok := r.Client.(*getter.HttpGetter); ok { if t, ok := r.Client.(*getter.HttpGetter); ok {
t.SetCredentials(c.getRepoCredentials(r)) t.SetCredentials(c.getRepoCredentials(r))
} }
} }
// If this ChartDownloader is not configured to use credentials, and the chart repository sent as an argument is, // getRepoCredentials if this ChartDownloader is not configured to use credentials, and the chart repository sent as an argument is,
// then the repository's configured credentials are returned. // then the repository's configured credentials are returned.
// Else, this ChartDownloader's credentials are returned. // Else, this ChartDownloader's credentials are returned.
func (c *ChartDownloader) getRepoCredentials(r *repo.ChartRepository) (username, password string) { func (c *ChartDownloader) getRepoCredentials(r *repo.ChartRepository) (username, password string) {

@ -371,6 +371,9 @@ func (m *Manager) getRepoNames(deps []*chartutil.Dependency) (map[string]string,
// by Helm. // by Helm.
missing := []string{} missing := []string{}
for _, dd := range deps { for _, dd := range deps {
if dd.Repository == "" {
return nil, fmt.Errorf("no 'repository' field specified for dependency: %q", dd.Name)
}
// if dep chart is from local path, verify the path is valid // if dep chart is from local path, verify the path is valid
if strings.HasPrefix(dd.Repository, "file://") { if strings.HasPrefix(dd.Repository, "file://") {
if _, err := resolver.GetLocalPath(dd.Repository, m.ChartPath); err != nil { if _, err := resolver.GetLocalPath(dd.Repository, m.ChartPath); err != nil {
@ -462,7 +465,7 @@ func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) error {
}(r) }(r)
} }
wg.Wait() wg.Wait()
fmt.Fprintln(out, "Update Complete. ⎈Happy Helming!⎈") fmt.Fprintln(out, "Update Complete.")
return nil return nil
} }
@ -601,7 +604,7 @@ func writeLock(chartpath string, lock *chartutil.RequirementsLock) error {
return ioutil.WriteFile(dest, data, 0644) return ioutil.WriteFile(dest, data, 0644)
} }
// archive a dep chart from local directory and save it into charts/ // tarFromLocalDir archive a dep chart from local directory and save it into charts/
func tarFromLocalDir(chartpath string, name string, repo string, version string) (string, error) { func tarFromLocalDir(chartpath string, name string, repo string, version string) (string, error) {
destPath := filepath.Join(chartpath, "charts") destPath := filepath.Join(chartpath, "charts")

@ -18,6 +18,7 @@ package downloader
import ( import (
"bytes" "bytes"
"reflect" "reflect"
"strings"
"testing" "testing"
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
@ -99,10 +100,11 @@ func TestGetRepoNames(t *testing.T) {
HelmHome: helmpath.Home("testdata/helmhome"), HelmHome: helmpath.Home("testdata/helmhome"),
} }
tests := []struct { tests := []struct {
name string name string
req []*chartutil.Dependency req []*chartutil.Dependency
expect map[string]string expect map[string]string
err bool err bool
expectedErr string
}{ }{
{ {
name: "no repo definition failure", name: "no repo definition failure",
@ -118,6 +120,14 @@ func TestGetRepoNames(t *testing.T) {
}, },
err: true, err: true,
}, },
{
name: "dependency entry missing 'repository' field -- e.g. spelled 'repo'",
req: []*chartutil.Dependency{
{Name: "dependency-missing-repository-field"},
},
err: true,
expectedErr: "no 'repository' field specified for dependency: \"dependency-missing-repository-field\"",
},
{ {
name: "no repo definition failure", name: "no repo definition failure",
req: []*chartutil.Dependency{ req: []*chartutil.Dependency{
@ -152,6 +162,9 @@ func TestGetRepoNames(t *testing.T) {
l, err := m.getRepoNames(tt.req) l, err := m.getRepoNames(tt.req)
if err != nil { if err != nil {
if tt.err { if tt.err {
if !strings.Contains(err.Error(), tt.expectedErr) {
t.Fatalf("%s: expected error: %s, got: %s", tt.name, tt.expectedErr, err.Error())
}
continue continue
} }
t.Fatal(err) t.Fatal(err)

@ -130,7 +130,7 @@ type renderable struct {
tpl string tpl string
// vals are the values to be supplied to the template. // vals are the values to be supplied to the template.
vals chartutil.Values vals chartutil.Values
// namespace prefix to the templates of the current chart // basePath namespace prefix to the templates of the current chart
basePath string basePath string
} }

@ -334,7 +334,7 @@ func (h *Client) connect(ctx context.Context) (conn *grpc.ClientConn, err error)
return conn, nil return conn, nil
} }
// Executes tiller.ListReleases RPC. // list executes tiller.ListReleases RPC.
func (h *Client) list(ctx context.Context, req *rls.ListReleasesRequest) (*rls.ListReleasesResponse, error) { func (h *Client) list(ctx context.Context, req *rls.ListReleasesRequest) (*rls.ListReleasesResponse, error) {
c, err := h.connect(ctx) c, err := h.connect(ctx)
if err != nil { if err != nil {
@ -365,7 +365,7 @@ func (h *Client) list(ctx context.Context, req *rls.ListReleasesRequest) (*rls.L
return resp, nil return resp, nil
} }
// Executes tiller.InstallRelease RPC. // install executes tiller.InstallRelease RPC.
func (h *Client) install(ctx context.Context, req *rls.InstallReleaseRequest) (*rls.InstallReleaseResponse, error) { func (h *Client) install(ctx context.Context, req *rls.InstallReleaseRequest) (*rls.InstallReleaseResponse, error) {
c, err := h.connect(ctx) c, err := h.connect(ctx)
if err != nil { if err != nil {
@ -377,7 +377,7 @@ func (h *Client) install(ctx context.Context, req *rls.InstallReleaseRequest) (*
return rlc.InstallRelease(ctx, req) return rlc.InstallRelease(ctx, req)
} }
// Executes tiller.UninstallRelease RPC. // delete executes tiller.UninstallRelease RPC.
func (h *Client) delete(ctx context.Context, req *rls.UninstallReleaseRequest) (*rls.UninstallReleaseResponse, error) { func (h *Client) delete(ctx context.Context, req *rls.UninstallReleaseRequest) (*rls.UninstallReleaseResponse, error) {
c, err := h.connect(ctx) c, err := h.connect(ctx)
if err != nil { if err != nil {
@ -389,7 +389,7 @@ func (h *Client) delete(ctx context.Context, req *rls.UninstallReleaseRequest) (
return rlc.UninstallRelease(ctx, req) return rlc.UninstallRelease(ctx, req)
} }
// Executes tiller.UpdateRelease RPC. // update executes tiller.UpdateRelease RPC.
func (h *Client) update(ctx context.Context, req *rls.UpdateReleaseRequest) (*rls.UpdateReleaseResponse, error) { func (h *Client) update(ctx context.Context, req *rls.UpdateReleaseRequest) (*rls.UpdateReleaseResponse, error) {
c, err := h.connect(ctx) c, err := h.connect(ctx)
if err != nil { if err != nil {
@ -401,7 +401,7 @@ func (h *Client) update(ctx context.Context, req *rls.UpdateReleaseRequest) (*rl
return rlc.UpdateRelease(ctx, req) return rlc.UpdateRelease(ctx, req)
} }
// Executes tiller.RollbackRelease RPC. // rollback executes tiller.RollbackRelease RPC.
func (h *Client) rollback(ctx context.Context, req *rls.RollbackReleaseRequest) (*rls.RollbackReleaseResponse, error) { func (h *Client) rollback(ctx context.Context, req *rls.RollbackReleaseRequest) (*rls.RollbackReleaseResponse, error) {
c, err := h.connect(ctx) c, err := h.connect(ctx)
if err != nil { if err != nil {
@ -413,7 +413,7 @@ func (h *Client) rollback(ctx context.Context, req *rls.RollbackReleaseRequest)
return rlc.RollbackRelease(ctx, req) return rlc.RollbackRelease(ctx, req)
} }
// Executes tiller.GetReleaseStatus RPC. // status executes tiller.GetReleaseStatus RPC.
func (h *Client) status(ctx context.Context, req *rls.GetReleaseStatusRequest) (*rls.GetReleaseStatusResponse, error) { func (h *Client) status(ctx context.Context, req *rls.GetReleaseStatusRequest) (*rls.GetReleaseStatusResponse, error) {
c, err := h.connect(ctx) c, err := h.connect(ctx)
if err != nil { if err != nil {
@ -425,7 +425,7 @@ func (h *Client) status(ctx context.Context, req *rls.GetReleaseStatusRequest) (
return rlc.GetReleaseStatus(ctx, req) return rlc.GetReleaseStatus(ctx, req)
} }
// Executes tiller.GetReleaseContent RPC. // content executes tiller.GetReleaseContent RPC.
func (h *Client) content(ctx context.Context, req *rls.GetReleaseContentRequest) (*rls.GetReleaseContentResponse, error) { func (h *Client) content(ctx context.Context, req *rls.GetReleaseContentRequest) (*rls.GetReleaseContentResponse, error) {
c, err := h.connect(ctx) c, err := h.connect(ctx)
if err != nil { if err != nil {
@ -437,7 +437,7 @@ func (h *Client) content(ctx context.Context, req *rls.GetReleaseContentRequest)
return rlc.GetReleaseContent(ctx, req) return rlc.GetReleaseContent(ctx, req)
} }
// Executes tiller.GetVersion RPC. // version executes tiller.GetVersion RPC.
func (h *Client) version(ctx context.Context, req *rls.GetVersionRequest) (*rls.GetVersionResponse, error) { func (h *Client) version(ctx context.Context, req *rls.GetVersionRequest) (*rls.GetVersionResponse, error) {
c, err := h.connect(ctx) c, err := h.connect(ctx)
if err != nil { if err != nil {
@ -449,7 +449,7 @@ func (h *Client) version(ctx context.Context, req *rls.GetVersionRequest) (*rls.
return rlc.GetVersion(ctx, req) return rlc.GetVersion(ctx, req)
} }
// Executes tiller.GetHistory RPC. // history executes tiller.GetHistory RPC.
func (h *Client) history(ctx context.Context, req *rls.GetHistoryRequest) (*rls.GetHistoryResponse, error) { func (h *Client) history(ctx context.Context, req *rls.GetHistoryRequest) (*rls.GetHistoryResponse, error) {
c, err := h.connect(ctx) c, err := h.connect(ctx)
if err != nil { if err != nil {
@ -461,7 +461,7 @@ func (h *Client) history(ctx context.Context, req *rls.GetHistoryRequest) (*rls.
return rlc.GetHistory(ctx, req) return rlc.GetHistory(ctx, req)
} }
// Executes tiller.TestRelease RPC. // test executes tiller.TestRelease RPC.
func (h *Client) test(ctx context.Context, req *rls.TestReleaseRequest) (<-chan *rls.TestReleaseResponse, <-chan error) { func (h *Client) test(ctx context.Context, req *rls.TestReleaseRequest) (<-chan *rls.TestReleaseResponse, <-chan error) {
errc := make(chan error, 1) errc := make(chan error, 1)
c, err := h.connect(ctx) c, err := h.connect(ctx)
@ -499,7 +499,7 @@ func (h *Client) test(ctx context.Context, req *rls.TestReleaseRequest) (<-chan
return ch, errc return ch, errc
} }
// Executes tiller.Ping RPC. // ping executes tiller.Ping RPC.
func (h *Client) ping(ctx context.Context) error { func (h *Client) ping(ctx context.Context) error {
c, err := h.connect(ctx) c, err := h.connect(ctx)
if err != nil { if err != nil {

@ -26,7 +26,8 @@ import (
rls "k8s.io/helm/pkg/proto/hapi/services" rls "k8s.io/helm/pkg/proto/hapi/services"
) )
const cmInputTemplate = `kind: ConfigMap const (
cmInputTemplate = `kind: ConfigMap
apiVersion: v1 apiVersion: v1
metadata: metadata:
name: example name: example
@ -34,7 +35,7 @@ data:
Release: Release:
{{.Release | toYaml | indent 4}} {{.Release | toYaml | indent 4}}
` `
const cmOutputTemplate = ` cmOutputTemplate = `
--- ---
# Source: installChart/templates/cm.yaml # Source: installChart/templates/cm.yaml
kind: ConfigMap kind: ConfigMap
@ -53,6 +54,7 @@ data:
seconds: 242085845 seconds: 242085845
` `
)
var installChart *chart.Chart var installChart *chart.Chart

@ -297,6 +297,20 @@ func DeleteDescription(description string) DeleteOption {
} }
} }
// UpgradeCleanupOnFail allows deletion of new resources created in this upgrade when upgrade failed
func UpgradeCleanupOnFail(cleanupOnFail bool) UpdateOption {
return func(opts *options) {
opts.updateReq.CleanupOnFail = cleanupOnFail
}
}
// RollbackCleanupOnFail allows deletion of new resources created in this rollback when rollback failed
func RollbackCleanupOnFail(cleanupOnFail bool) RollbackOption {
return func(opts *options) {
opts.rollbackReq.CleanupOnFail = cleanupOnFail
}
}
// DeleteDisableHooks will disable hooks for a deletion operation. // DeleteDisableHooks will disable hooks for a deletion operation.
func DeleteDisableHooks(disable bool) DeleteOption { func DeleteDisableHooks(disable bool) DeleteOption {
return func(opts *options) { return func(opts *options) {

@ -27,6 +27,7 @@ import (
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
"k8s.io/helm/pkg/kube" "k8s.io/helm/pkg/kube"
"k8s.io/helm/pkg/tiller/environment"
) )
var ( var (
@ -39,8 +40,7 @@ func New(namespace string, client kubernetes.Interface, config *rest.Config) (*k
if err != nil { if err != nil {
return nil, err return nil, err
} }
const tillerPort = 44134 t := kube.NewTunnel(client.CoreV1().RESTClient(), config, namespace, podName, environment.DefaultTillerPort)
t := kube.NewTunnel(client.CoreV1().RESTClient(), config, namespace, podName, tillerPort)
return t, t.ForwardPort() return t, t.ForwardPort()
} }

@ -20,14 +20,14 @@ import (
"k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/proto/hapi/release"
) )
// HookAnno is the label name for a hook const (
const HookAnno = "helm.sh/hook" // HookAnno is the label name for a hook
HookAnno = "helm.sh/hook"
// HookWeightAnno is the label name for a hook weight // HookWeightAnno is the label name for a hook weight
const HookWeightAnno = "helm.sh/hook-weight" HookWeightAnno = "helm.sh/hook-weight"
// HookDeleteAnno is the label name for the delete policy for a hook
// HookDeleteAnno is the label name for the delete policy for a hook HookDeleteAnno = "helm.sh/hook-delete-policy"
const HookDeleteAnno = "helm.sh/hook-delete-policy" )
// Types of hooks // Types of hooks
const ( const (

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save