Merge branch 'master' into feat/app-version

Signed-off-by: Kevin Labesse <kevin@labesse.me>
pull/5492/head
Kevin Labesse 7 years ago
commit 542b0a1d55

@ -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 dep
- dep ensure -v
cache:
- vendor -> Gopkg.lock
build: "off"
deploy: "off"
test_script:
- go build .\cmd\...
- go test .\...

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

@ -0,0 +1,12 @@
<!-- Thanks for sending a pull request! Here are some tips for you:
1. Make sure to read the Contributing Guide before submitting your PR: https://github.com/helm/helm/blob/master/CONTRIBUTING.md
2. If this PR closes another issue, add 'closes #<issue number>' somewhere in the PR summary. GitHub will automatically close that issue when this PR gets merged. Alternatively, adding 'refs #<issue number>' will not close the issue, but help provide the reviewer more context.-->
**What this PR does / why we need it**:
**Special notes for your reviewer**:
**If applicable**:
- [ ] this PR contains documentation
- [ ] this PR contains unit tests
- [ ] this PR has been tested for backwards compatibility

6
.gitignore vendored

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

@ -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
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,
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
@ -84,12 +84,12 @@ your PR will be rejected by the automated DCO check.
Whether you are a user or contributor, official support channels include:
- GitHub [issues](https://github.com/helm/helm/issues/new)
- Slack [Kubernetes Slack](http://slack.kubernetes.io/):
- User: #helm-users
- Contributor: #helm-dev
- [Issues](https://github.com/helm/helm/issues)
- Slack:
- User: [#helm-users](https://kubernetes.slack.com/messages/C0NH30761/details/)
- Contributor: [#helm-dev](https://kubernetes.slack.com/messages/C51E88VDG/)
Before opening a new issue or submitting a new pull request, it's helpful to search the project - it's likely that another user has already reported the issue you're facing, or it's a known issue that we're already aware of.
Before opening a new issue or submitting a new pull request, it's helpful to search the project - it's likely that another user has already reported the issue you're facing, or it's a known issue that we're already aware of. It is also worth asking on the Slack channels.
## Milestones
@ -178,35 +178,35 @@ contributing to Helm. All issue types follow the same general lifecycle. Differe
1. Submit a pull request.
Coding conventions and standards are explained in the official developer docs:
https://github.com/helm/helm/blob/master/docs/developers.md
[Developers Guide](docs/developers.md)
The next section contains more information on the workflow followed for PRs
The next section contains more information on the workflow followed for Pull Requests.
## Pull Requests
Like any good open source project, we use Pull Requests to track code changes
Like any good open source project, we use Pull Requests (PRs) to track code changes.
### PR Lifecycle
1. PR creation
- PRs are usually created to fix or else be a subset of other PRs that fix a particular issue.
- We more than welcome PRs that are currently in progress. They are a great way to keep track of
important work that is in-flight, but useful for others to see. If a PR is a work in progress,
it **must** be prefaced with "WIP: [title]". Once the PR is ready for review, remove "WIP" from
the title.
- It is preferred, but not required, to have a PR tied to a specific issue.
- It is preferred, but not required, to have a PR tied to a specific issue. There can be
circumstances where if it is a quick fix then an issue might be overkill. The details provided
in the PR description would suffice in this case.
2. Triage
- The maintainer in charge of triaging will apply the proper labels for the issue. This should
include at least a size label, `bug` or `feature`, and `awaiting review` once all labels are applied.
See the [Labels section](#labels) for full details on the definitions of labels
See the [Labels section](#labels) for full details on the definitions of labels.
- Add the PR to the correct milestone. This should be the same as the issue the PR closes.
3. Assigning reviews
- Once a review has the `awaiting review` label, maintainers will review them as schedule permits.
The maintainer who takes the issue should self-request a review.
- Reviews from others in the community, especially those who have encountered a bug or have
requested a feature, are highly encouraged, but not required. Maintainer reviews **are** required
before any merge
- Any PR with the `size/large` label requires 2 review approvals from maintainers before it can be
merged. Those with `size/medium` are per the judgement of the maintainers
merged. Those with `size/medium` or `size/small` are per the judgement of the maintainers.
4. Reviewing/Discussion
- Once a maintainer begins reviewing a PR, they will remove the `awaiting review` label and add
the `in progress` label so the person submitting knows that it is being worked on. This is
@ -214,17 +214,24 @@ Like any good open source project, we use Pull Requests to track code changes
- All reviews will be completed using Github review tool.
- A "Comment" review should be used when there are questions about the code that should be
answered, but that don't involve code changes. This type of review does not count as approval.
- A "Changes Requested" review indicates that changes to the code need to be made before they will be merged.
- Reviewers should update labels as needed (such as `needs rebase`)
5. Address comments by answering questions or changing code
- A "Changes Requested" review indicates that changes to the code need to be made before they will be
merged.
- Reviewers (maintainers) should update labels as needed (such as `needs rebase`).
- Reviews are also welcome from others in the community, especially those who have encountered a bug or
have requested a feature. In the code review, a message can be added, as well as `LGTM` if the PR is
good to merge. Its also possible to add comments to specific lines in a file, for giving context
to the comment.
5. PR owner should try to be responsive to comments by answering questions or changing code. If the
owner is unsure of any comment, reach out to the person who added the comment in
[#helm-dev](https://kubernetes.slack.com/messages/C51E88VDG/). Once all comments have been addressed,
the PR is ready to be merged.
6. Merge or close
- PRs should stay open until merged or if they have not been active for more than 30 days.
This will help keep the PR queue to a manageable size and reduce noise. Should the PR need
to stay open (like in the case of a WIP), the `keep open` label can be added.
- If the owner of the PR is listed in `OWNERS`, that user **must** merge their own PRs
or explicitly request another OWNER do that for them.
- If the owner of a PR is _not_ listed in `OWNERS`, any core committer may
merge the PR once it is approved.
- If the owner of the PR is listed in `OWNERS`, that user **must** merge their own PRs or explicitly
request another OWNER do that for them.
- If the owner of a PR is _not_ listed in `OWNERS`, any maintainer may merge the PR once it is approved.
#### Documentation PRs
@ -235,7 +242,7 @@ Documentation PRs will follow the same lifecycle as other PRs. They will also be
## The Triager
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.
## Labels

@ -1,9 +1,10 @@
DOCKER_REGISTRY ?= gcr.io
IMAGE_PREFIX ?= kubernetes-helm
DEV_IMAGE ?= golang:1.11
DEV_IMAGE ?= golang:1.12
SHORT_NAME ?= tiller
SHORT_NAME_RUDDER ?= rudder
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
# go option
@ -44,10 +45,25 @@ dist:
$(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
checksum:
for f in _dist/*.{gz,zip} ; do \
shasum -a 256 "$${f}" | awk '{print $$1}' > "$${f}.sha256" ; \
echo -n "Checksum: " && cat $${f}.sha256 ; \
done
.PHONY: check-docker

@ -32,6 +32,7 @@ Think of it like apt/yum/homebrew for Kubernetes.
## Install
Binary downloads of the Helm client can be found on [the Releases page](https://github.com/helm/helm/releases/latest).
Unpack the `helm` binary and add it to your PATH and you are good to go!
@ -40,6 +41,7 @@ If you want to use a package manager:
- [Homebrew](https://brew.sh/) users can use `brew install kubernetes-helm`.
- [Chocolatey](https://chocolatey.org/) users can use `choco install kubernetes-helm`.
- [Scoop](https://scoop.sh/) users can use `scoop install helm`.
- [GoFish](https://gofi.sh/) users can use `gofish install helm`.
To rapidly get Helm up and running, start with the [Quick Start Guide](https://docs.helm.sh/using_helm/#quickstart-guide).

@ -3,8 +3,8 @@ Protobuf3 type declarations for the Helm API
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.services.rudder` Definition for the ReleaseModuleService used by Tiller to manipulate releases on a given node
- `hapi.services.tiller` Definition of the ReleaseService provoded 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

@ -29,7 +29,7 @@ message Status {
UNKNOWN = 0;
// Status_DEPLOYED indicates that the release has been pushed to Kubernetes.
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;
// Status_SUPERSEDED indicates that this release object is outdated and a newer one exists.
SUPERSEDED = 3;

@ -76,7 +76,7 @@ service ReleaseService {
rpc RollbackRelease(RollbackReleaseRequest) returns (RollbackReleaseResponse) {
}
// ReleaseHistory retrieves a releasse's history.
// ReleaseHistory retrieves a release's history.
rpc GetHistory(GetHistoryRequest) returns (GetHistoryResponse) {
}
@ -212,6 +212,8 @@ message UpdateReleaseRequest {
bool force = 11;
// Description, if set, will set the description for the updated release
string description = 12;
// Render subchart notes if enabled
bool subNotes = 13;
}
// UpdateReleaseResponse is the response to an update request.
@ -281,6 +283,9 @@ message InstallReleaseRequest {
// Description, if set, will set the description for the installed release
string description = 11;
bool subNotes = 12;
}
// InstallReleaseResponse is the response from a release installation.
@ -298,7 +303,7 @@ message UninstallReleaseRequest {
bool purge = 3;
// timeout specifies the max amount of time any kubernetes client command can run.
int64 timeout = 4;
// Description, if set, will set the description for the uninnstalled release
// Description, if set, will set the description for the uninstalled release
string description = 5;
}
@ -339,6 +344,8 @@ message TestReleaseRequest {
int64 timeout = 2;
// cleanup specifies whether or not to attempt pod deletion after test completes
bool cleanup = 3;
// parallel specifies whether or not to run test pods in parallel
bool parallel = 4;
}
// TestReleaseResponse represents a message from executing a test

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

@ -75,6 +75,9 @@ func newCreateCmd(out io.Writer) *cobra.Command {
if len(args) == 0 {
return errors.New("the name of the new chart is required")
}
if len(args) > 1 {
return errors.New("command 'create' doesn't support multiple arguments")
}
cc.name = args[0]
return cc.run()
},

@ -143,8 +143,9 @@ func TestCreateStarterCmd(t *testing.T) {
t.Errorf("Wrong API version: %q", c.Metadata.ApiVersion)
}
if l := len(c.Templates); l != 7 {
t.Errorf("Expected 6 templates, got %d", l)
expectedTemplateCount := 7
if l := len(c.Templates); l != expectedTemplateCount {
t.Errorf("Expected %d templates, got %d", expectedTemplateCount, l)
}
found := false

@ -29,11 +29,11 @@ const dependencyBuildDesc = `
Build out the charts/ directory from the requirements.lock file.
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'
does.
the lock file.
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.
`
type dependencyBuildCmd struct {

@ -69,8 +69,9 @@ Environment:
$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_CERT path to TLS client certificate file for authenticating to Tiller (default "$HELM_HOME/cert.pem")
$HELM_TLS_KEY path to TLS client key file for authenticating to Tiller (default "$HELM_HOME/key.pem")
$HELM_TLS_VERIFY enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false")
$HELM_TLS_ENABLE enable TLS connection between Helm and Tiller (default "false")
$HELM_TLS_VERIFY enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false")
$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

@ -29,6 +29,8 @@ import (
"github.com/spf13/cobra"
"k8s.io/client-go/util/homedir"
"k8s.io/helm/cmd/helm/installer"
"k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/helm/helmpath"
@ -136,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 {
i := repo.NewIndexFile()
if err := i.WriteFile(localRepoIndexFile, 0644); err != nil {
@ -167,7 +169,7 @@ func TestRootCmd(t *testing.T) {
{
name: "defaults",
args: []string{"home"},
home: filepath.Join(os.Getenv("HOME"), "/.helm"),
home: filepath.Join(homedir.HomeDir(), ".helm"),
},
{
name: "with --home set",
@ -236,7 +238,7 @@ func TestTLSFlags(t *testing.T) {
homePath := os.Getenv("HELM_HOME")
if homePath == "" {
homePath = filepath.Join(os.Getenv("HOME"), ".helm")
homePath = filepath.Join(homedir.HomeDir(), ".helm")
}
home := helmpath.Home(homePath)

@ -31,11 +31,10 @@ import (
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/helm/cmd/helm/installer"
"k8s.io/helm/pkg/getter"
"k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/helm/helmpath"
"k8s.io/helm/pkg/helm/portforwarder"
"k8s.io/helm/pkg/repo"
"k8s.io/helm/pkg/version"
)
const initDesc = `
@ -59,12 +58,6 @@ To dump a manifest containing the Tiller deployment YAML, combine the
'--dry-run' and '--debug' flags.
`
const (
stableRepository = "stable"
localRepository = "local"
localRepositoryIndexFile = "index.yaml"
)
var (
stableRepositoryURL = "https://kubernetes-charts.storage.googleapis.com"
// This is the IPv4 loopback, not localhost, because we have to force IPv4
@ -265,14 +258,8 @@ func (i *initCmd) run() error {
return nil
}
if err := ensureDirectories(i.home, i.out); err != nil {
return 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
if err := installer.Initialize(i.home, i.out, i.skipRefresh, settings, stableRepositoryURL, localRepositoryURL); err != nil {
return fmt.Errorf("error initializing: %s", err)
}
fmt.Fprintf(i.out, "$HELM_HOME has been configured at %s.\n", settings.Home)
@ -315,6 +302,14 @@ func (i *initCmd) run() error {
fmt.Fprintln(i.out, "Not installing Tiller due to 'client-only' flag having been set")
}
needsDefaultImage := !i.clientOnly && !i.opts.UseCanary && len(i.opts.ImageSpec) == 0 && version.BuildMetadata == "unreleased"
if needsDefaultImage {
fmt.Fprintf(i.out, "\nWarning: You appear to be using an unreleased version of Helm. Please either use the\n"+
"--canary-image flag, or specify your desired tiller version with --tiller-image.\n\n"+
"Ex:\n"+
"$ helm init --tiller-image gcr.io/kubernetes-helm/tiller:v2.8.2\n\n")
}
fmt.Fprintln(i.out, "Happy Helming!")
return nil
}
@ -342,117 +337,6 @@ func (i *initCmd) ping(image string) error {
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
// want to wait before we call New().
//

@ -28,7 +28,7 @@ import (
"github.com/ghodss/yaml"
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
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) {
const testDir = "../../testdata"

@ -18,15 +18,13 @@ package main
import (
"fmt"
"io"
"strings"
"github.com/ghodss/yaml"
"github.com/golang/protobuf/ptypes/any"
"github.com/spf13/cobra"
"io"
"strings"
"k8s.io/helm/pkg/chartutil"
"k8s.io/kubernetes/pkg/util/slice"
)
const inspectDesc = `
@ -61,6 +59,7 @@ type inspectCmd struct {
repoURL string
username string
password string
devel bool
certFile string
keyFile string
@ -90,12 +89,9 @@ func newInspectCmd(out io.Writer) *cobra.Command {
if err := checkArgsLength(len(args), "chart name"); err != nil {
return err
}
cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring,
insp.certFile, insp.keyFile, insp.caFile)
if err != nil {
if err := insp.prepare(args[0]); err != nil {
return err
}
insp.chartpath = cp
return insp.run()
},
}
@ -109,12 +105,9 @@ func newInspectCmd(out io.Writer) *cobra.Command {
if err := checkArgsLength(len(args), "chart name"); err != nil {
return err
}
cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring,
insp.certFile, insp.keyFile, insp.caFile)
if err != nil {
if err := insp.prepare(args[0]); err != nil {
return err
}
insp.chartpath = cp
return insp.run()
},
}
@ -128,12 +121,9 @@ func newInspectCmd(out io.Writer) *cobra.Command {
if err := checkArgsLength(len(args), "chart name"); err != nil {
return err
}
cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring,
insp.certFile, insp.keyFile, insp.caFile)
if err != nil {
if err := insp.prepare(args[0]); err != nil {
return err
}
insp.chartpath = cp
return insp.run()
},
}
@ -147,12 +137,9 @@ func newInspectCmd(out io.Writer) *cobra.Command {
if err := checkArgsLength(len(args), "chart name"); err != nil {
return err
}
cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring,
insp.certFile, insp.keyFile, insp.caFile)
if err != nil {
if err := insp.prepare(args[0]); err != nil {
return err
}
insp.chartpath = cp
return insp.run()
},
}
@ -195,6 +182,12 @@ func newInspectCmd(out io.Writer) *cobra.Command {
valuesSubCmd.Flags().StringVar(&insp.password, password, "", passworddesc)
chartSubCmd.Flags().StringVar(&insp.password, password, "", passworddesc)
develFlag := "devel"
develDesc := "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored."
for _, subCmd := range cmds {
subCmd.Flags().BoolVar(&insp.devel, develFlag, false, develDesc)
}
certFile := "cert-file"
certFiledesc := "verify certificates of HTTPS-enabled servers using this CA bundle"
for _, subCmd := range cmds {
@ -220,6 +213,22 @@ func newInspectCmd(out io.Writer) *cobra.Command {
return inspectCommand
}
func (i *inspectCmd) prepare(chart string) error {
debug("Original chart version: %q", i.version)
if i.version == "" && i.devel {
debug("setting version to >0.0.0-0")
i.version = ">0.0.0-0"
}
cp, err := locateChartPath(i.repoURL, i.username, i.password, chart, i.version, i.verify, i.keyring,
i.certFile, i.keyFile, i.caFile)
if err != nil {
return err
}
i.chartpath = cp
return nil
}
func (i *inspectCmd) run() error {
chrt, err := chartutil.Load(i.chartpath)
if err != nil {
@ -256,9 +265,23 @@ func (i *inspectCmd) run() error {
func findReadme(files []*any.Any) (file *any.Any) {
for _, file := range files {
if slice.ContainsString(readmeFileNames, strings.ToLower(file.TypeUrl), nil) {
if containsString(readmeFileNames, strings.ToLower(file.TypeUrl), nil) {
return file
}
}
return nil
}
// containsString checks if a given slice of strings contains the provided string.
// If a modifier func is provided, it is called with the slice item before the comparison.
func containsString(slice []string, s string, modifier func(s string) string) bool {
for _, item := range slice {
if item == s {
return true
}
if modifier != nil && modifier(item) == s {
return true
}
}
return false
}

@ -19,8 +19,11 @@ package main
import (
"bytes"
"io/ioutil"
"os"
"strings"
"testing"
"k8s.io/helm/pkg/repo/repotest"
)
func TestInspect(t *testing.T) {
@ -78,3 +81,66 @@ func TestInspect(t *testing.T) {
t.Errorf("expected empty values buffer, got %q", b.String())
}
}
func TestInspectPreReleaseChart(t *testing.T) {
hh, err := tempHelmHome(t)
if err != nil {
t.Fatal(err)
}
cleanup := resetEnv()
defer func() {
os.RemoveAll(hh.String())
cleanup()
}()
settings.Home = hh
srv := repotest.NewServer(hh.String())
defer srv.Stop()
if _, err := srv.CopyCharts("testdata/testcharts/*.tgz*"); err != nil {
t.Fatal(err)
}
if err := srv.LinkIndices(); err != nil {
t.Fatal(err)
}
tests := []struct {
name string
args []string
flags []string
fail bool
expectedErr string
}{
{
name: "inspect pre-release chart",
args: []string{"prerelease"},
fail: true,
expectedErr: "chart \"prerelease\" not found",
},
{
name: "inspect pre-release chart with 'devel' flag",
args: []string{"prerelease"},
flags: []string{"--devel"},
fail: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.flags = append(tt.flags, "--repo", srv.URL())
cmd := newInspectCmd(ioutil.Discard)
cmd.SetArgs(tt.args)
cmd.ParseFlags(tt.flags)
if err := cmd.RunE(cmd, tt.args); err != nil {
if tt.fail {
if !strings.Contains(err.Error(), tt.expectedErr) {
t.Errorf("%q expected error: %s, got: %s", tt.name, tt.expectedErr, err.Error())
}
return
}
t.Errorf("%q reported error: %s", tt.name, err)
}
})
}
}

@ -132,11 +132,13 @@ type installCmd struct {
appVersion string
timeout int64
wait bool
atomic bool
repoURL string
username string
password string
devel bool
depUp bool
subNotes bool
description string
certFile string
@ -190,6 +192,8 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
}
inst.chartPath = cp
inst.client = ensureHelmClient(inst.client)
inst.wait = inst.wait || inst.atomic
return inst.run()
},
}
@ -213,6 +217,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
f.StringVar(&inst.appVersion, "app-version", "", "specify an app version for the release")
f.Int64Var(&inst.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&inst.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
f.BoolVar(&inst.atomic, "atomic", false, "if set, installation process purges chart on fail, also sets --wait flag")
f.StringVar(&inst.repoURL, "repo", "", "chart repository url where to locate the requested chart")
f.StringVar(&inst.username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&inst.password, "password", "", "chart repository password where to locate the requested chart")
@ -221,6 +226,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
f.StringVar(&inst.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&inst.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
f.BoolVar(&inst.depUp, "dep-up", false, "run helm dependency update before installing the chart")
f.BoolVar(&inst.subNotes, "render-subchart-notes", false, "render subchart notes along with the parent")
f.StringVar(&inst.description, "description", "", "specify a description for the release")
// set defaults from environment
@ -251,8 +257,8 @@ func (i *installCmd) run() error {
fmt.Printf("FINAL NAME: %s\n", i.name)
}
if msgs := validation.IsDNS1123Label(i.name); i.name != "" && len(msgs) > 0 {
return fmt.Errorf("release name %s is not a valid DNS label: %s", i.name, strings.Join(msgs, ";"))
if msgs := validation.IsDNS1123Subdomain(i.name); i.name != "" && len(msgs) > 0 {
return fmt.Errorf("release name %s is invalid: %s", i.name, strings.Join(msgs, ";"))
}
// Check chart requirements to make sure all dependencies are present in /charts
@ -310,10 +316,28 @@ func (i *installCmd) run() error {
helm.InstallReuseName(i.replace),
helm.InstallDisableHooks(i.disableHooks),
helm.InstallDisableCRDHook(i.disableCRDHook),
helm.InstallSubNotes(i.subNotes),
helm.InstallTimeout(i.timeout),
helm.InstallWait(i.wait),
helm.InstallDescription(i.description))
if err != nil {
if i.atomic {
fmt.Fprintf(os.Stdout, "INSTALL FAILED\nPURGING CHART\nError: %v\n", prettyError(err))
deleteSideEffects := &deleteCmd{
name: i.name,
disableHooks: i.disableHooks,
purge: true,
timeout: i.timeout,
description: "",
dryRun: i.dryRun,
out: i.out,
client: i.client,
}
if err := deleteSideEffects.run(); err != nil {
return err
}
fmt.Fprintf(os.Stdout, "Successfully purged a chart!\n")
}
return prettyError(err)
}

@ -113,6 +113,14 @@ func TestInstall(t *testing.T) {
expected: "apollo",
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "apollo"}),
},
// Install, with atomic
{
name: "install with a atomic",
args: []string{"testdata/testcharts/alpine"},
flags: strings.Split("--name apollo", " "),
expected: "apollo",
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "apollo"}),
},
// Install, using the name-template
{
name: "install with name-template",
@ -169,7 +177,6 @@ func TestInstall(t *testing.T) {
name: "install chart with release name using periods",
args: []string{"testdata/testcharts/alpine"},
flags: []string{"--name", "foo.bar"},
err: true,
},
{
name: "install chart with release name using underscores",

@ -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.
*/
package main
package installer // import "k8s.io/helm/cmd/helm/installer"
import (
"os"

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

@ -183,7 +183,7 @@ func generateLabels(labels map[string]string) map[string]string {
return labels
}
// parseNodeSelectors parses a comma delimited list of key=values pairs into a map.
// parseNodeSelectorsInto parses a comma delimited list of key=values pairs into a map.
func parseNodeSelectorsInto(labels string, m map[string]string) error {
kv := strings.Split(labels, ",")
for _, v := range kv {

@ -53,6 +53,10 @@ func TestDeployment(t *testing.T) {
t.Fatalf("%s: error %q", tt.name, err)
}
// Unreleased versions of helm don't have a release image. See issue 3370
if tt.name == "default" && version.BuildMetadata == "unreleased" {
tt.expect = "gcr.io/kubernetes-helm/tiller:canary"
}
if got := dep.Spec.Template.Spec.Containers[0].Image; got != tt.expect {
t.Errorf("%s: expected image %q, got %q", tt.name, tt.expect, got)
}

@ -50,7 +50,7 @@ type Options struct {
// AutoMountServiceAccountToken determines whether or not the service account should be added to Tiller.
AutoMountServiceAccountToken bool
// Force allows to force upgrading tiller if deployed version is greater than current version
// ForceUpgrade allows to force upgrading tiller if deployed version is greater than current version
ForceUpgrade bool
// ImageSpec identifies the image Tiller will use when deployed.
@ -105,6 +105,9 @@ func (opts *Options) SelectImage() string {
case opts.UseCanary:
return defaultImage + ":canary"
case opts.ImageSpec == "":
if version.BuildMetadata == "unreleased" {
return defaultImage + ":canary"
}
return fmt.Sprintf("%s:%s", defaultImage, version.Version)
default:
return opts.ImageSpec

@ -47,10 +47,11 @@ func deleteService(client corev1.ServicesGetter, namespace string) error {
}
// deleteDeployment deletes the Tiller Deployment resource
// We need to use the reaper instead of the kube API because GC for deployment dependents
// is not yet supported at the k8s server level (<= 1.5)
func deleteDeployment(client kubernetes.Interface, namespace string) error {
err := client.Extensions().Deployments(namespace).Delete(deploymentName, &metav1.DeleteOptions{})
policy := metav1.DeletePropagationBackground
err := client.AppsV1().Deployments(namespace).Delete(deploymentName, &metav1.DeleteOptions{
PropagationPolicy: &policy,
})
return ingoreNotFound(err)
}

@ -17,10 +17,12 @@ package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"runtime"
"testing"
"github.com/spf13/cobra"
@ -53,6 +55,13 @@ func TestSetVersion(t *testing.T) {
func TestPackage(t *testing.T) {
statExe := "stat"
statFileMsg := "no such file or directory"
if runtime.GOOS == "windows" {
statExe = "FindFirstFile"
statFileMsg = "The system cannot find the file specified."
}
tests := []struct {
name string
flags map[string]string
@ -106,7 +115,7 @@ func TestPackage(t *testing.T) {
name: "package --destination does-not-exist",
args: []string{"testdata/testcharts/alpine"},
flags: map[string]string{"destination": "does-not-exist"},
expect: "stat does-not-exist: no such file or directory",
expect: fmt.Sprintf("Failed to save: %s does-not-exist: %s", statExe, statFileMsg),
err: true,
},
{

@ -34,11 +34,12 @@ The tests to be run are defined in the chart that was installed.
`
type releaseTestCmd struct {
name string
out io.Writer
client helm.Interface
timeout int64
cleanup bool
name string
out io.Writer
client helm.Interface
timeout int64
cleanup bool
parallel bool
}
func newReleaseTestCmd(c helm.Interface, out io.Writer) *cobra.Command {
@ -67,6 +68,7 @@ func newReleaseTestCmd(c helm.Interface, out io.Writer) *cobra.Command {
settings.AddFlagsTLS(f)
f.Int64Var(&rlsTest.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&rlsTest.cleanup, "cleanup", false, "delete test pods upon completion")
f.BoolVar(&rlsTest.parallel, "parallel", false, "run test pods in parallel")
// set defaults from environment
settings.InitTLS(f)
@ -79,6 +81,7 @@ func (t *releaseTestCmd) run() (err error) {
t.name,
helm.ReleaseTestTimeout(t.timeout),
helm.ReleaseTestCleanup(t.cleanup),
helm.ReleaseTestParallel(t.parallel),
)
testErr := &testErr{}

@ -24,6 +24,7 @@ import (
"github.com/spf13/cobra"
"k8s.io/helm/cmd/helm/installer"
"k8s.io/helm/pkg/getter"
"k8s.io/helm/pkg/helm/helmpath"
"k8s.io/helm/pkg/repo"
@ -93,21 +94,28 @@ func updateCharts(repos []*repo.ChartRepository, out io.Writer, home helmpath.Ho
var (
errorCounter int
wg sync.WaitGroup
mu sync.Mutex
)
for _, re := range repos {
wg.Add(1)
go func(re *repo.ChartRepository) {
defer wg.Done()
if re.Config.Name == localRepository {
if re.Config.Name == installer.LocalRepository {
mu.Lock()
fmt.Fprintf(out, "...Skip %s chart repository\n", re.Config.Name)
mu.Unlock()
return
}
err := re.DownloadIndexFile(home.Cache())
if err != nil {
mu.Lock()
errorCounter++
fmt.Fprintf(out, "...Unable to get an update from the %q chart repository (%s):\n\t%s\n", re.Config.Name, re.Config.URL, err)
mu.Unlock()
} else {
mu.Lock()
fmt.Fprintf(out, "...Successfully got an update from the %q chart repository\n", re.Config.Name)
mu.Unlock()
}
}(re)
}
@ -117,6 +125,6 @@ func updateCharts(repos []*repo.ChartRepository, out io.Writer, home helmpath.Ho
return errors.New("Update Failed. Check log for details")
}
fmt.Fprintln(out, "Update Complete. ⎈ Happy Helming! ")
fmt.Fprintln(out, "Update Complete. ⎈ Happy Helming! ")
return nil
}

@ -105,3 +105,30 @@ func TestUpdateCharts(t *testing.T) {
t.Error("Update was not successful")
}
}
func TestUpdateCmdStrictFlag(t *testing.T) {
thome, err := tempHelmHome(t)
if err != nil {
t.Fatal(err)
}
cleanup := resetEnv()
defer func() {
os.RemoveAll(thome.String())
cleanup()
}()
settings.Home = thome
out := bytes.NewBuffer(nil)
cmd := newRepoUpdateCmd(out)
cmd.ParseFlags([]string{"--strict"})
if err := cmd.RunE(cmd, []string{}); err == nil {
t.Fatal("expected error due to strict flag")
}
if got := out.String(); !strings.Contains(got, "Unable to get an update") {
t.Errorf("Expected 'Unable to get an update', got %q", got)
}
}

@ -31,7 +31,8 @@ This command rolls back a release to a previous revision.
The first argument of the rollback command is the name of a release, and the
second is a revision (version) number. To see revision numbers, run
'helm history RELEASE'.
'helm history RELEASE'. If you'd like to rollback to the previous release use
'helm rollback [RELEASE] 0'.
`
type rollbackCmd struct {

@ -154,7 +154,7 @@ func (s *searchCmd) buildIndex() (*search.Index, error) {
f := s.helmhome.CacheIndex(n)
ind, err := repo.LoadIndexFile(f)
if err != nil {
fmt.Fprintf(s.out, "WARNING: Repo %q is corrupt or missing. Try 'helm repo update'.", n)
fmt.Fprintf(s.out, "WARNING: Repo %q is corrupt or missing. Try 'helm repo update'.\n", n)
continue
}

@ -147,8 +147,8 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
}
}
if msgs := validation.IsDNS1123Label(t.releaseName); t.releaseName != "" && len(msgs) > 0 {
return fmt.Errorf("release name %s is not a valid DNS label: %s", t.releaseName, strings.Join(msgs, ";"))
if msgs := validation.IsDNS1123Subdomain(t.releaseName); t.releaseName != "" && len(msgs) > 0 {
return fmt.Errorf("release name %s is invalid: %s", t.releaseName, strings.Join(msgs, ";"))
}
// Check chart requirements to make sure all dependencies are present in /charts

@ -75,7 +75,7 @@ func TestTemplateCmd(t *testing.T) {
{
name: "check_execute_absolute",
desc: "verify --execute single template",
args: []string{subchart1ChartPath, "-x", subchart1AbsChartPath + "/" + "templates/service.yaml", "--set", "service.name=apache"},
args: []string{subchart1ChartPath, "-x", filepath.Join(subchart1AbsChartPath, "templates", "service.yaml"), "--set", "service.name=apache"},
expectKey: "subchart1/templates/service.yaml",
expectValue: "protocol: TCP\n name: apache",
},
@ -112,21 +112,21 @@ func TestTemplateCmd(t *testing.T) {
desc: "verify the release name using capitals is invalid",
args: []string{subchart1ChartPath, "--name", "FOO"},
expectKey: "subchart1/templates/service.yaml",
expectError: "is not a valid DNS label",
expectError: "is invalid",
},
{
name: "check_invalid_name_uppercase",
desc: "verify the release name using periods is invalid",
args: []string{subchart1ChartPath, "--name", "foo.bar"},
expectKey: "subchart1/templates/service.yaml",
expectError: "is not a valid DNS label",
expectValue: "release-name: \"foo.bar\"",
},
{
name: "check_invalid_name_uppercase",
desc: "verify the release name using underscores is invalid",
args: []string{subchart1ChartPath, "--name", "foo_bar"},
expectKey: "subchart1/templates/service.yaml",
expectError: "is not a valid DNS label",
expectError: "is invalid",
},
{
name: "check_release_is_install",
@ -160,7 +160,7 @@ func TestTemplateCmd(t *testing.T) {
name: "check_invalid_name_template",
desc: "verify the relase name generate by template is invalid",
args: []string{subchart1ChartPath, "--name-template", "foobar-{{ b64enc \"abc\" }}-baz"},
expectError: "is not a valid DNS label",
expectError: "is invalid",
},
{
name: "check_name_template",

@ -0,0 +1,6 @@
description: Deploy a basic Alpine Linux pod
home: https://k8s.io/helm
name: prerelease
sources:
- https://github.com/helm/helm
version: 0.2.0-pre-release

@ -0,0 +1,13 @@
#Alpine: A simple Helm chart
Run a single pod of Alpine Linux.
This example was generated using the command `helm create alpine`.
The `templates/` directory contains a very simple pod resource with a
couple of parameters.
The `values.yaml` file contains the default values for the
`alpine-pod.yaml` template.
You can install this example using `helm install docs/examples/alpine`.

@ -0,0 +1,26 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{.Release.Name}}-{{.Values.Name}}"
labels:
# The "heritage" label is used to track which tool deployed a given chart.
# It is useful for admins who want to see what releases a particular tool
# is responsible for.
app.kubernetes.io/managed-by: {{.Release.Service | quote }}
# The "release" convention makes it easy to tie a release to all of the
# Kubernetes resources that were created as part of that release.
app.kubernetes.io/instance: {{.Release.Name | quote }}
# This makes it easy to audit chart usage.
helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}"
annotations:
"helm.sh/created": {{.Release.Time.Seconds | quote }}
spec:
# This shows how to use a simple value. This will look for a passed-in value
# called restartPolicy. If it is not found, it will use the default value.
# {{default "Never" .restartPolicy}} is a slightly optimized version of the
# more conventional syntax: {{.restartPolicy | default "Never"}}
restartPolicy: {{default "Never" .Values.restartPolicy}}
containers:
- name: waiter
image: "alpine:3.3"
command: ["/bin/sleep","9000"]

@ -44,7 +44,7 @@ To customize the chart values, use any of
- '--set-string' to provide key=val forcing val to be stored as a string,
- '--set-file' to provide key=path to read a single large value from a file at path.
To edit or append to the existing customized values, add the
To edit or append to the existing customized values, add the
'--reuse-values' flag, otherwise any existing customized values are ignored.
If no chart value arguments are provided on the command line, any existing customized values are carried
@ -106,10 +106,12 @@ type upgradeCmd struct {
resetValues bool
reuseValues bool
wait bool
atomic bool
repoURL string
username string
password string
devel bool
subNotes bool
description string
certFile string
@ -142,6 +144,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
upgrade.release = args[0]
upgrade.chart = args[1]
upgrade.client = ensureHelmClient(upgrade.client)
upgrade.wait = upgrade.wait || upgrade.atomic
return upgrade.run()
},
@ -168,6 +171,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&upgrade.resetValues, "reset-values", false, "when upgrading, reset the values to the ones built into the chart")
f.BoolVar(&upgrade.reuseValues, "reuse-values", false, "when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored.")
f.BoolVar(&upgrade.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
f.BoolVar(&upgrade.atomic, "atomic", false, "if set, upgrade process rolls back changes made in case of failed upgrade, also sets --wait flag")
f.StringVar(&upgrade.repoURL, "repo", "", "chart repository url where to locate the requested chart")
f.StringVar(&upgrade.username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&upgrade.password, "password", "", "chart repository password where to locate the requested chart")
@ -175,6 +179,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.StringVar(&upgrade.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&upgrade.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&upgrade.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
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.MarkDeprecated("disable-hooks", "use --no-hooks instead")
@ -191,6 +196,8 @@ func (u *upgradeCmd) run() error {
return err
}
releaseHistory, err := u.client.ReleaseHistory(u.release, helm.WithMaxHistory(1))
if u.install {
// If a release does not exist, install it. If another error occurs during
// the check, ignore the error and continue with the upgrade.
@ -198,7 +205,6 @@ func (u *upgradeCmd) run() error {
// The returned error is a grpc.rpcError that wraps the message from the original error.
// So we're stuck doing string matching against the wrapped error, which is nested somewhere
// inside of the grpc.rpcError message.
releaseHistory, err := u.client.ReleaseHistory(u.release, helm.WithMaxHistory(1))
if err == nil {
if u.namespace == "" {
@ -232,6 +238,7 @@ func (u *upgradeCmd) run() error {
timeout: u.timeout,
wait: u.wait,
description: u.description,
atomic: u.atomic,
}
return ic.run()
}
@ -276,9 +283,29 @@ func (u *upgradeCmd) run() error {
helm.UpgradeTimeout(u.timeout),
helm.ResetValues(u.resetValues),
helm.ReuseValues(u.reuseValues),
helm.UpgradeSubNotes(u.subNotes),
helm.UpgradeWait(u.wait),
helm.UpgradeDescription(u.description))
if err != nil {
fmt.Fprintf(u.out, "UPGRADE FAILED\nROLLING BACK\nError: %v\n", prettyError(err))
if u.atomic {
rollback := &rollbackCmd{
out: u.out,
client: u.client,
name: u.release,
dryRun: u.dryRun,
recreate: u.recreate,
force: u.force,
timeout: u.timeout,
wait: u.wait,
description: "",
revision: releaseHistory.Releases[0].Version,
disableHooks: u.disableHooks,
}
if err := rollback.run(); err != nil {
return err
}
}
return fmt.Errorf("UPGRADE FAILED: %v", prettyError(err))
}

@ -123,6 +123,14 @@ func TestUpgradeCmd(t *testing.T) {
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 5, Chart: ch2})},
},
{
name: "install a release with 'upgrade --atomic'",
args: []string{"funny-bunny", chartPath},
flags: []string{"--atomic"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 6, Chart: ch}),
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 6, Chart: ch})},
},
{
name: "install a release with 'upgrade --install'",
args: []string{"zany-bunny", chartPath},

@ -27,7 +27,7 @@ import (
const verifyDesc = `
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.
This command can be used to verify a local chart. Several other commands provide

@ -28,7 +28,7 @@ func TestVerifyCmd(t *testing.T) {
statPathMsg := "no such file or directory"
statFileMsg := statPathMsg
if runtime.GOOS == "windows" {
statExe = "GetFileAttributesEx"
statExe = "FindFirstFile"
statPathMsg = "The system cannot find the path specified."
statFileMsg = "The system cannot find the file specified."
}

@ -36,6 +36,7 @@ import (
"google.golang.org/grpc/health"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/keepalive"
"k8s.io/klog"
// Import to initialize client auth plugins.
_ "k8s.io/client-go/plugin/pkg/client/auth"
@ -100,6 +101,7 @@ var (
)
func main() {
klog.InitFlags(nil)
// TODO: use spf13/cobra for tiller instead of flags
flag.Parse()

@ -24,6 +24,7 @@
- [Variables](chart_template_guide/variables.md)
- [Named Templates (Partials)](chart_template_guide/named_templates.md)
- [Accessing Files Inside Templates](chart_template_guide/accessing_files.md)
- [Ignoring unwanted files and folders](chart_template_guide/helm_ignore_file.md)
- [Creating a NOTES.txt File](chart_template_guide/notes_files.md)
- [Subcharts and Global Values](chart_template_guide/subcharts_and_globals.md)
- [Debugging Templates](chart_template_guide/debugging.md)

@ -22,7 +22,7 @@ The directory that contains a chart MUST have the same name as the chart. Thus,
## 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.

@ -28,10 +28,10 @@ resources that use that CRD in _another_ chart.
In this method, each chart must be installed separately.
### Method 2: Pre-install Hooks
### Method 2: Crd-install Hooks
To package the two together, add a `pre-install` hook to the CRD definition so
To package the two together, add a `crd-install` hook to the CRD definition so
that it is fully installed before the rest of the chart is executed.
Note that if you create the CRD with a `pre-install` hook, that CRD definition
Note that if you create the CRD with a `crd-install` hook, that CRD definition
will not be deleted when `helm delete` is run.

@ -123,6 +123,35 @@ startup.
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
The first step is to **create your GCS bucket**. We'll call ours

@ -20,7 +20,7 @@ The first control structure we'll look at is for conditionally including blocks
The basic structure for a conditional looks like this:
```
```yaml
{{ if PIPELINE }}
# Do something
{{ else if OTHER PIPELINE }}
@ -53,7 +53,7 @@ data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
{{ if and (.Values.favorite.drink) (eq .Values.favorite.drink "coffee") }}mug: true{{ end }}
{{ if and .Values.favorite.drink (eq .Values.favorite.drink "coffee") }}mug: true{{ end }}
```
Note that `.Values.favorite.drink` must be defined or else it will throw an error when comparing it to "coffee". Since we commented out `drink: coffee` in our last example, the output should not include a `mug: true` flag. But if we add that line back into our `values.yaml` file, the output should look like this:
@ -115,7 +115,7 @@ data:
`mug` is incorrectly indented. Let's simply out-dent that one line, and re-run:
```
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
@ -224,7 +224,7 @@ The next control structure to look at is the `with` action. This controls variab
The syntax for `with` is similar to a simple `if` statement:
```
```yaml
{{ with PIPELINE }}
# restricted scope
{{ end }}
@ -329,7 +329,7 @@ data:
- "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.

@ -12,7 +12,7 @@ When your YAML is failing to parse, but you want to see what is generated, one
easy way to retrieve the YAML is to comment out the problem section in the template,
and then re-run `helm install --dry-run --debug`:
```YAML
```yaml
apiVersion: v1
# some: problem section
# {{ .Values.foo | quote }}
@ -20,7 +20,7 @@ apiVersion: v1
The above will be rendered and returned with the comments intact:
```YAML
```yaml
apiVersion: v1
# some: problem section
# "bar"

@ -4,7 +4,7 @@ So far, we've seen how to place information into a template. But that informatio
Let's start with a best practice: When injecting strings from the `.Values` object into the template, we ought to quote these strings. We can do that by calling the `quote` function in the template directive:
```
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
@ -104,7 +104,7 @@ drink: {{ .Values.favorite.drink | default "tea" | quote }}
If we run this as normal, we'll get our `coffee`:
```
```yaml
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
@ -150,6 +150,19 @@ Template functions and pipelines are a powerful way to transform information and
## Operators are functions
For templates, the operators (`eq`, `ne`, `lt`, `gt`, `and`, `or` and so on) are all implemented as functions. In pipelines, operations can be grouped with parentheses (`(`, and `)`).
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
{{/* include the body of this if statement when the variable .Values.fooString exists and is set to "foo" */}}
{{ if and .Values.fooString (eq .Values.fooString "foo") }}
{{ ... }}
{{ end }}
{{/* do not include the body of this if statement because unset variables evaluate to false and .Values.setVariable was negated with the not function. */}}
{{ if or .Values.anUnsetVariable (not .Values.aSetVariable) }}
{{ ... }}
{{ end }}
```
Now we can turn from functions and pipelines to flow control with conditions, loops, and scope modifiers.

@ -51,8 +51,8 @@ already there.
- `NOTES.txt`: The "help text" for your chart. This will be displayed to your users
when they run `helm install`.
- `deployment.yaml`: A basic manifest for creating a Kubernetes [deployment](http://kubernetes.io/docs/user-guide/deployments/)
- `service.yaml`: A basic manifest for creating a [service endpoint](http://kubernetes.io/docs/user-guide/services/) for your deployment
- `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](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
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.

@ -0,0 +1,23 @@
# The .helmignore file
The `.helmignore` file is used to specify files you don't want to include in your helm chart.
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 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.
Here is an example `.helmignore` file:
```
# comment
.git
*/temp*
*/*/temp*
temp?
```
**We'd love your help** making this document better. To add, correct, or remove
information, [file an issue](https://github.com/helm/helm/issues) or
send us a pull request.

@ -63,7 +63,7 @@ data:
dessert: cake
```
## Overriding Values from a Parent Chart
## Overriding Values of a Child Chart
Our original chart, `mychart` is now the _parent_ chart of `mysubchart`. This relationship is based entirely on the fact that `mysubchart` is within `mychart/charts`.

@ -54,7 +54,7 @@ data:
Because `favoriteDrink` is set in the default `values.yaml` file to `coffee`, that's the value displayed in the template. We can easily override that by adding a `--set` flag in our call to `helm install`:
```
```console
helm install --dry-run --debug --set favoriteDrink=slurm ./mychart
SERVER: "localhost:44134"
CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart
@ -85,7 +85,7 @@ favorite:
Now we would have to modify the template slightly:
```
```yaml
apiVersion: v1
kind: ConfigMap
metadata:

@ -98,10 +98,7 @@ data:
Variables are normally not "global". They are scoped to the block in which they are declared. Earlier, we assigned `$relname` in the top level of the template. That variable will be in scope for the entire template. But in our last example, `$key` and `$val` will only be in scope inside of the `{{range...}}{{end}}` block.
However, there is one variable that is always global - `$` - this
variable will always point to the root context. This can be very
useful when you are looping in a range need to know the chart's release
name.
However, there is one variable that is always global - `$` - this variable will always point to the root context. This can be very useful when you are looping in a range and need to know the chart's release name.
An example illustrating this:
```yaml
@ -111,8 +108,8 @@ kind: Secret
metadata:
name: {{ .name }}
labels:
# Many helm templates would use `.` below, but that will not work,
# however `$` will work here
# Many helm templates would use `.` below, but that will not work,
# however `$` will work here
app.kubernetes.io/name: {{ template "fullname" $ }}
# I cannot reference .Chart.Name, but I can do $.Chart.Name
helm.sh/chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"

@ -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:
- 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 [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.

@ -7,7 +7,7 @@ to read.
## 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.
The two types of collections are maps and sequences:
@ -177,7 +177,7 @@ Now the value of `coffee` will be `Latte\nCappuccino\nEspresso\n\n\n`.
Indentation inside of a text block is preserved, and results in the preservation
of line breaks, too:
```
```yaml
coffee: |-
Latte
12 oz
@ -336,7 +336,7 @@ reference is expanded and then discarded.
So if we were to decode and then re-encode the example above, the resulting
YAML would be:
```YAML
```yaml
coffee: yes, please
favorite: Cappucino
coffees:

@ -64,7 +64,7 @@ spec:
```
## Steps to Run a Test Suite on a Release
1. `$ helm install wordpress`
1. `$ helm install stable/wordpress`
```
NAME: quirky-walrus
LAST DEPLOYED: Mon Feb 13 13:50:43 2017

@ -71,7 +71,7 @@ Other fields will be silently ignored.
### Charts and Versioning
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
are identified by name plus version.
@ -116,15 +116,22 @@ be deprecated. The chart name can later be reused by publishing a newer version
that is not marked as deprecated. The workflow for deprecating charts, as
followed by the [helm/charts](https://github.com/helm/charts)
project is:
- Update chart's `Chart.yaml` to mark the chart as deprecated, bumping the
version
- Release the new chart version in the Chart Repository
- Remove the chart from the source repository (e.g. git)
- Update chart's `Chart.yaml` to mark the chart as deprecated, bumping the version
- Release the new chart version in the Chart Repository
- Remove the chart from the source repository (e.g. git)
## Chart LICENSE, README and NOTES
Charts can also contain files that describe the installation, configuration, usage and license of a
chart. A README for a chart should be formatted in Markdown (README.md), and should generally
chart.
A LICENSE is a plain text file containing the [license](https://en.wikipedia.org/wiki/Software_license)
for the chart. The chart can contain a license as it may have programming logic in the templates and
would therefore not be configuration only. There can also be separate license(s) for the application
installed by the chart, if required.
A README for a chart should be formatted in Markdown (README.md), and should generally
contain:
- A description of the application or service the chart provides
@ -153,7 +160,6 @@ the preferred method of declaring dependencies is by using a
**Note:** The `dependencies:` section of the `Chart.yaml` from Helm
Classic has been completely removed.
### Managing Dependencies with `requirements.yaml`
A `requirements.yaml` file is a simple file for listing your
@ -233,6 +239,7 @@ dependencies:
```
In the above example we will get 3 dependencies in all for `parentchart`
```
subchart
new-subchart-1
@ -259,27 +266,28 @@ Tags - The tags field is a YAML list of labels to associate with this chart.
In the top parent's values, all charts with tags can be enabled or disabled by
specifying the tag and a boolean value.
````
```yaml
# parentchart/requirements.yaml
dependencies:
- name: subchart1
repository: http://localhost:10191
version: 0.1.0
condition: subchart1.enabled,global.subchart1.enabled
tags:
- front-end
- subchart1
- name: subchart2
repository: http://localhost:10191
version: 0.1.0
condition: subchart2.enabled,global.subchart2.enabled
tags:
- back-end
- subchart2
- name: subchart1
repository: http://localhost:10191
version: 0.1.0
condition: subchart1.enabled,global.subchart1.enabled
tags:
- front-end
- subchart1
````
````
- name: subchart2
repository: http://localhost:10191
version: 0.1.0
condition: subchart2.enabled,global.subchart2.enabled
tags:
- back-end
- subchart2
```
```yaml
# parentchart/values.yaml
subchart1:
@ -287,7 +295,7 @@ subchart1:
tags:
front-end: false
back-end: true
````
```
In the above example all charts with the tag `front-end` would be disabled but since the
`subchart1.enabled` path evaluates to 'true' in the parent's values, the condition will override the
@ -307,12 +315,11 @@ helm install --set tags.front-end=true --set subchart2.enabled=false
##### Tags and Condition Resolution
* **Conditions (when set in values) always override tags.** The first condition
path that exists wins and subsequent ones for that chart are ignored.
* Tags are evaluated as 'if any of the chart's tags are true then enable the chart'.
* Tags and conditions values must be set in the top parent's values.
* The `tags:` key in values must be a top level key. Globals and nested `tags:` tables
- **Conditions (when set in values) always override tags.**
- The first condition path that exists wins and subsequent ones for that chart are ignored.
- Tags are evaluated as 'if any of the chart's tags are true then enable the chart'.
- Tags and conditions values must be set in the top parent's values.
- The `tags:` key in values must be a top level key. Globals and nested `tags:` tables
are not currently supported.
#### Importing Child Values via requirements.yaml
@ -338,6 +345,7 @@ directly into the parent's values by specifying the keys to import as in the exa
import-values:
- data
```
```yaml
# child's values.yaml file
...
@ -381,6 +389,7 @@ dependencies:
- child: default.data
parent: myimports
```
In the above example, values found at `default.data` in the subchart1's values will be imported
to the `myimports` key in the parent chart's values as detailed below:
@ -393,6 +402,7 @@ myimports:
mystring: "helm rocks!"
```
```yaml
# subchart1's values.yaml file
@ -402,6 +412,7 @@ default:
mybool: true
```
The parent chart's resulting values would be:
```yaml
@ -481,7 +492,7 @@ create/update all of the above Kubernetes objects in the following order:
This is because when Helm installs/upgrades charts,
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
- created/updated in that order.
@ -504,10 +515,10 @@ through the template engine.
Values for the templates are supplied two ways:
- Chart developers may supply a file called `values.yaml` inside of a
chart. This file can contain default values.
- Chart users may supply a YAML file that contains values. This can be
provided on the command line with `helm install`.
- Chart developers may supply a file called `values.yaml` inside of a
chart. This file can contain default values.
- Chart users may supply a YAML file that contains values. This can be
provided on the command line with `helm install`.
When a user supplies custom values, these values will override the
values in the chart's `values.yaml` file.
@ -781,7 +792,7 @@ standard references that will help you out.
- [Go templates](https://godoc.org/text/template)
- [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

@ -246,12 +246,10 @@ annotated.
### 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.

@ -36,6 +36,12 @@ is required, and will print an error message when that entry is missing:
value: {{ required "A valid .Values.who entry required!" .Values.who }}
```
When using the `include` function, you can pass it a custom object tree built from the current context by using the `dict` function:
```yaml
{{- include "mytpl" (dict "key1" .Values.originalKey1 "key2" .Values.originalKey2) }}
```
## Quote Strings, Don't Quote Integers
When you are working with string data, you are always safer quoting the
@ -229,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
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
Sometimes you want to create some reusable parts in your chart, whether
@ -255,9 +264,9 @@ embed each of the components.
Two strong design patterns are illustrated by these projects:
**SAP's [OpenStack chart](https://github.com/sapcc/openstack-helm):** This chart
installs a full OpenStack IaaS on Kubernetes. All of the charts are collected
together in one GitHub repository.
**SAP's [Converged charts](https://github.com/sapcc/helm-charts):** These charts
install SAP Converged Cloud a full OpenStack IaaS on Kubernetes. All of the charts are collected
together in one GitHub repository, except for a few submodules.
**Deis's [Workflow](https://github.com/deis/workflow/tree/master/charts/workflow):**
This chart exposes the entire Deis PaaS system with one chart. But it's different
@ -275,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.
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.
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`.
- 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.
- Tiller must have access to a Kubernetes cluster. It learns about the
cluster by examining the Kube config files that `kubectl` uses.
@ -167,10 +167,10 @@ workflow for doing this is as follows:
3. Add your repository as a remote for `$GOPATH/src/k8s.io/helm`
4. Create a new working branch (`git checkout -b feat/my-feature`) and
do your work on that branch.
5. When you are ready for us to review, 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.
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'
@ -201,7 +201,7 @@ Common scopes:
Read more:
- The [Deis Guidelines](https://github.com/deis/workflow/blob/master/src/contributing/submitting-a-pull-request.md)
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

@ -1,6 +1,6 @@
image:
repository: alpine
tag: 3.3
tag: latest
pullPolicy: IfNotPresent
restartPolicy: Never

@ -32,6 +32,6 @@ spec:
restartPolicy: {{ .Values.restartPolicy }}
containers:
- name: post-install-job
image: "alpine:3.3"
image: "alpine:latest"
# All we're going to do is sleep for a while, then exit.
command: ["/bin/sleep", "{{ .Values.sleepyTime }}"]

@ -14,7 +14,7 @@ index: >-
image:
repository: nginx
tag: 1.11.0
tag: alpine
pullPolicy: IfNotPresent
service:

@ -37,7 +37,7 @@ are bundled with it.
## Chart Version
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

@ -29,8 +29,9 @@ Environment:
$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_CERT path to TLS client certificate file for authenticating to Tiller (default "$HELM_HOME/cert.pem")
$HELM_TLS_KEY path to TLS client key file for authenticating to Tiller (default "$HELM_HOME/key.pem")
$HELM_TLS_VERIFY enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false")
$HELM_TLS_ENABLE enable TLS connection between Helm and Tiller (default "false")
$HELM_TLS_VERIFY enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false")
$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 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 4-Feb-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 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'
does.
If no lock file is found, 'helm dependency build' will mirror the behavior
of 'helm dependency update'.
the lock file.
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

@ -20,6 +20,7 @@ helm inspect [CHART] [flags]
```
--ca-file string chart repository url where to locate the requested chart
--cert-file string verify certificates of HTTPS-enabled servers using this CA bundle
--devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
-h, --help help for inspect
--key-file string identify HTTPS client using this SSL key file
--keyring string path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
@ -49,4 +50,4 @@ helm inspect [CHART] [flags]
* [helm inspect readme](helm_inspect_readme.md) - shows inspect readme
* [helm inspect values](helm_inspect_values.md) - shows inspect values
###### Auto generated by spf13/cobra on 1-Aug-2018
###### Auto generated by spf13/cobra on 8-Jan-2019

@ -18,6 +18,7 @@ helm inspect chart [CHART] [flags]
```
--ca-file string chart repository url where to locate the requested chart
--cert-file string verify certificates of HTTPS-enabled servers using this CA bundle
--devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
-h, --help help for chart
--key-file string identify HTTPS client using this SSL key file
--keyring string path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
@ -44,4 +45,4 @@ helm inspect chart [CHART] [flags]
* [helm inspect](helm_inspect.md) - inspect a chart
###### Auto generated by spf13/cobra on 1-Aug-2018
###### Auto generated by spf13/cobra on 8-Jan-2019

@ -18,6 +18,7 @@ helm inspect readme [CHART] [flags]
```
--ca-file string chart repository url where to locate the requested chart
--cert-file string verify certificates of HTTPS-enabled servers using this CA bundle
--devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
-h, --help help for readme
--key-file string identify HTTPS client using this SSL key file
--keyring string path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
@ -42,4 +43,4 @@ helm inspect readme [CHART] [flags]
* [helm inspect](helm_inspect.md) - inspect a chart
###### Auto generated by spf13/cobra on 1-Aug-2018
###### Auto generated by spf13/cobra on 8-Jan-2019

@ -18,6 +18,7 @@ helm inspect values [CHART] [flags]
```
--ca-file string chart repository url where to locate the requested chart
--cert-file string verify certificates of HTTPS-enabled servers using this CA bundle
--devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
-h, --help help for values
--key-file string identify HTTPS client using this SSL key file
--keyring string path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
@ -44,4 +45,4 @@ helm inspect values [CHART] [flags]
* [helm inspect](helm_inspect.md) - inspect a chart
###### Auto generated by spf13/cobra on 1-Aug-2018
###### Auto generated by spf13/cobra on 8-Jan-2019

@ -78,7 +78,11 @@ helm install [CHART] [flags]
### Options
```
<<<<<<< HEAD
--app-version string specify an app version for the release
=======
--atomic if set, installation process purges chart on fail, also sets --wait flag
>>>>>>> master
--ca-file string verify certificates of HTTPS-enabled servers using this CA bundle
--cert-file string identify HTTPS client using this SSL certificate file
--dep-up run helm dependency update before installing the chart
@ -94,6 +98,7 @@ helm install [CHART] [flags]
--no-crd-hook prevent CRD hooks from running, but run other hooks
--no-hooks prevent hooks from running during install
--password string chart repository password where to locate the requested chart
--render-subchart-notes render subchart notes along with the parent
--replace re-use the given name, even if that name is already used. This is unsafe in production
--repo string chart repository url where to locate the requested chart
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
@ -129,4 +134,4 @@ helm install [CHART] [flags]
* [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 21-Mar-2019
###### Auto generated by spf13/cobra on 28-Jan-2019

@ -9,7 +9,8 @@ This command rolls back a release to a previous revision.
The first argument of the rollback command is the name of a release, and the
second is a revision (version) number. To see revision numbers, run
'helm history RELEASE'.
'helm history RELEASE'. If you'd like to rollback to the previous release use
'helm rollback [RELEASE] 0'.
```
@ -51,4 +52,4 @@ helm rollback [flags] [RELEASE] [REVISION]
* [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 10-Aug-2018
###### Auto generated by spf13/cobra on 29-Jan-2019

@ -20,6 +20,7 @@ helm test [RELEASE] [flags]
```
--cleanup delete test pods upon completion
-h, --help help for test
--parallel run test pods in parallel
--timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
--tls enable TLS for request
--tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
@ -45,4 +46,4 @@ helm test [RELEASE] [flags]
* [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 10-Aug-2018
###### Auto generated by spf13/cobra on 9-Nov-2018

@ -19,7 +19,7 @@ To customize the chart values, use any of
- '--set-string' to provide key=val forcing val to be stored as a string,
- '--set-file' to provide key=path to read a single large value from a file at path.
To edit or append to the existing customized values, add the
To edit or append to the existing customized values, add the
'--reuse-values' flag, otherwise any existing customized values are ignored.
If no chart value arguments are provided on the command line, any existing customized values are carried
@ -65,7 +65,11 @@ helm upgrade [RELEASE] [CHART] [flags]
### Options
```
<<<<<<< HEAD
--app-version string specify the app version to use for the upgrade
=======
--atomic if set, upgrade process rolls back changes made in case of failed upgrade, also sets --wait flag
>>>>>>> master
--ca-file string verify certificates of HTTPS-enabled servers using this CA bundle
--cert-file string identify HTTPS client using this SSL certificate file
--description string specify the description to use for the upgrade, rather than the default
@ -80,6 +84,7 @@ helm upgrade [RELEASE] [CHART] [flags]
--no-hooks disable pre/post upgrade hooks
--password string chart repository password where to locate the requested chart
--recreate-pods performs pods restart for the resource if applicable
--render-subchart-notes render subchart notes along with parent
--repo string chart repository url where to locate the requested chart
--reset-values when upgrading, reset the values to the ones built into the chart
--reuse-values when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored.

@ -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.
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.
This command can be used to verify a local chart. Several other commands provide

@ -12,7 +12,7 @@ Differences from Helm Classic:
- Helm's chart format has changed for the better:
- Dependencies are immutable and stored inside of a chart's `charts/`
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
- Helm supports Go templates without requiring you to run `generate`
or `template` commands.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 53 KiB

@ -45,7 +45,7 @@ brew install kubernetes-helm
(Note: There is also a formula for emacs-helm, which is a different
project.)
### From Chocolatey (Windows)
### From Chocolatey or scoop (Windows)
Members of the Kubernetes community have contributed a [Helm package](https://chocolatey.org/packages/kubernetes-helm) build to
[Chocolatey](https://chocolatey.org/). This package is generally up to date.
@ -54,6 +54,12 @@ Members of the Kubernetes community have contributed a [Helm package](https://ch
choco install kubernetes-helm
```
The binary can also be installed via [`scoop`](https://scoop.sh) command-line installer.
```
scoop install helm
```
## From Script
Helm now has an installer script that will automatically grab the latest version

@ -19,13 +19,12 @@ Build out the charts/ directory from the requirements.lock file.
.PP
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'
does.
the lock file.
.PP
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.
.SH OPTIONS
.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.
.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.
.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)
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
[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).
The combination of this gives users the following assurances:
@ -202,7 +202,7 @@ keywords:
- proxy
source:
- https://github.com/foo/bar
home: http://nginx.com
home: https://nginx.com
...
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)
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

@ -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:
```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
`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
serviceaccount "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

@ -8,9 +8,9 @@ or [pull request](https://github.com/helm/helm/pulls).
## Article, Blogs, How-Tos, and Extra Documentation
- [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)
- [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)
- [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)
@ -53,6 +53,7 @@ or [pull request](https://github.com/helm/helm/pulls).
- [helm-stop](https://github.com/IBM/helm-stop) - Plugin for stopping a release pods
- [helm-template](https://github.com/technosophos/helm-template) - Debug/render templates client-side
- [helm-tiller](https://github.com/adamreese/helm-tiller) - Additional commands to work with Tiller
- [helm-tiller-info](https://github.com/maorfr/helm-tiller-info) - Plugin which prints information about Tiller
- [helm-unittest](https://github.com/lrills/helm-unittest) - Plugin for unit testing chart locally with YAML
- [Tillerless Helm v2](https://github.com/rimusz/helm-tiller) - Helm plugin for using Tiller locally and in CI/CD pipelines
@ -65,7 +66,6 @@ Tools layered on top of Helm or Tiller.
- [AppsCode Swift](https://github.com/appscode/swift) - Ajax friendly Helm Tiller Proxy using [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway)
- [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.
- [Autohelm](https://github.com/reactiveops/autohelm) - Autohelm is _another_ simple declarative spec for deploying helm charts. Written in python and supports git urls as a source for helm charts.
- [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.
- [Codefresh](https://codefresh.io) - Kubernetes native CI/CD and management platform with UI dashboards for managing Helm charts and releases
@ -77,19 +77,20 @@ Tools layered on top of Helm or Tiller.
- [Helmsman](https://github.com/Praqma/helmsman) - Helmsman is a helm-charts-as-code tool which enables installing/upgrading/protecting/moving/deleting releases from version controlled desired state files (described in a simple TOML format).
- [Landscaper](https://github.com/Eneco/landscaper/) - "Landscaper takes a set of Helm Chart references with values (a desired state), and realizes this in a Kubernetes cluster."
- [Monocular](https://github.com/helm/monocular) - Web UI for Helm Chart repositories
- [Orca](https://github.com/maorfr/orca) - Advanced CI\CD tool for Kubernetes and Helm made simple.
- [Orca](https://github.com/nuvo/orca) - Advanced CI\CD tool for Kubernetes and Helm made simple.
- [Quay App Registry](https://coreos.com/blog/quay-application-registry-for-kubernetes.html) - Open Kubernetes application registry, including a Helm access client
- [Reckoner](https://github.com/reactiveops/reckoner) - Reckoner (formerly Autohelm) is a tool for declarative management of helm releases. Written in python and supports git urls as a source for helm charts.
- [Rudder](https://github.com/AcalephStorage/rudder) - RESTful (JSON) proxy for Tiller's API
- [Schelm](https://github.com/databus23/schelm) - Render a Helm manifest to a directory
- [Shipper](https://github.com/bookingcom/shipper) - Multi-cluster canary or blue-green rollouts using Helm
- [VIM-Kubernetes](https://github.com/andrewstuart/vim-kubernetes) - VIM plugin for Kubernetes and Helm
## Helm Included
Platforms, distributions, and services that include Helm support.
- [Cabin](http://www.skippbox.com/cabin/) - Mobile App for Managing 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
- [Qstack](https://qstack.com)

@ -3,8 +3,8 @@
**IMPORTANT**: If your experience deviates from this document, please document the changes to keep it up-to-date.
## Release Meetings
As part of the release process, two of the weekly developer calls will be co-opted
as "release meetings."
As part of the release process, two of the weekly developer calls will be
co-opted as "release meetings."
### Start of the Release Cycle
The first developer call after a release will be used as the release meeting to
@ -17,17 +17,19 @@ identified:
- Any other important details for the community
All of this information should be added to the GitHub milestone for the given
release. This should give the community and maintainers a clear set of guidelines
to follow when choosing whether or not to add issues and PRs to a given release.
release. This should give the community and maintainers a clear set of
guidelines to follow when choosing whether or not to add issues and PRs to a
given release.
### End (almost) of the Release Cycle
The developer call closest to two weeks before the scheduled release date will
be used to review any remaining PRs that should be pulled into the release. This
is the place to debate whether or not we should wait before cutting a release and
any other concerns. At the end of this meeting, if the release date has not been
pushed out, the first RC should be cut. Subsequent developer calls in between this
meeting and the release date should have some time set aside to see if any bugs
were found. Once the release date is reached, the final release can be cut
is the place to debate whether or not we should wait before cutting a release
and any other concerns. At the end of this meeting, if the release date has not
been pushed out, the first RC should be cut. Subsequent developer calls in
between this meeting and the release date should have some time set aside to see
if any bugs were found. Once the release date is reached, the final release can
be cut
## A Maintainer's Guide to Releasing Helm
@ -37,17 +39,28 @@ So you're in charge of a new release for Helm? Cool. Here's what to do...
Just kidding! :trollface:
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 strictly follows [semantic versioning](http://semver.org/) so following this step is critical.
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
strictly follows [semantic versioning](https://semver.org/) so following this
step is critical.
It is important to note that this document assumes that the git remote in your repository that corresponds to "https://github.com/helm/helm" is named "upstream". If yours is not (for example, if you've chosen to name it "origin" or something similar instead), be sure to adjust the listed snippets for your local environment accordingly. If you are not sure what your upstream remote is named, use a command like `git remote -v` to find out.
It is important to note that this document assumes that the git remote in your
repository that corresponds to "https://github.com/helm/helm" is named
"upstream". If yours is not (for example, if you've chosen to name it "origin"
or something similar instead), be sure to adjust the listed snippets for your
local environment accordingly. If you are not sure what your upstream remote is
named, use a command like `git remote -v` to find out.
If you don't have an upstream remote, you can add one easily using something like:
If you don't have an upstream remote, you can add one easily using something
like:
```shell
git remote add upstream git@github.com:helm/helm.git
```
In this doc, we are going to reference a few environment variables as well, which you may want to set for convenience. For major/minor releases, use the following:
In this doc, we are going to reference a few environment variables as well,
which you may want to set for convenience. For major/minor releases, use the
following:
```shell
export RELEASE_NAME=vX.Y.0
@ -68,7 +81,10 @@ export RELEASE_CANDIDATE_NAME="$RELEASE_NAME-rc.1"
### Major/Minor Releases
Major releases are for new feature additions and behavioral changes *that break backwards compatibility*. Minor releases are for new feature additions that do not break backwards compatibility. To create a major or minor release, start by creating a `release-vX.Y.0` branch from master.
Major releases are for new feature additions and behavioral changes *that break
backwards compatibility*. Minor releases are for new feature additions that do
not break backwards compatibility. To create a major or minor release, start by
creating a `release-vX.Y.0` branch from master.
```shell
git fetch upstream
@ -76,11 +92,13 @@ git checkout upstream/master
git checkout -b $RELEASE_BRANCH_NAME
```
This new branch is going to be the base for the release, which we are going to iterate upon later.
This new branch is going to be the base for the release, which we are going to
iterate upon later.
### Patch releases
Patch releases are a few critical cherry-picked fixes to existing releases. Start by creating a `release-vX.Y.Z` branch from the latest patch release.
Patch releases are a few critical cherry-picked fixes to existing releases.
Start by creating a `release-vX.Y.Z` branch from the latest patch release.
```shell
git fetch upstream --tags
@ -88,7 +106,8 @@ git checkout $PREVIOUS_PATCH_RELEASE
git checkout -b $RELEASE_BRANCH_NAME
```
From here, we can cherry-pick the commits we want to bring into the patch release:
From here, we can cherry-pick the commits we want to bring into the patch
release:
```shell
# get the commits ids we want to cherry-pick
@ -98,11 +117,13 @@ git cherry-pick -x <commit-id>
git cherry-pick -x <commit-id>
```
This new branch is going to be the base for the release, which we are going to iterate upon later.
This new branch is going to be the base for the release, which we are going to
iterate upon later.
## 2. Change the Version Number in Git
When doing a minor release, make sure to update pkg/version/version.go with the new release version.
When doing a minor release, make sure to update pkg/version/version.go with the
new release version.
```shell
$ git diff pkg/version/version.go
@ -128,28 +149,36 @@ git commit -m "bump version to $RELEASE_CANDIDATE_NAME"
## 3. Commit and Push the Release Branch
In order for others to start testing, we can now push the release branch upstream and start the test process.
In order for others to start testing, we can now push the release branch
upstream and start the test process.
```shell
git push upstream $RELEASE_BRANCH_NAME
```
Make sure to check [helm on CircleCI](https://circleci.com/gh/helm/helm) and make sure the release passed CI before proceeding.
Make sure to check [helm on CircleCI](https://circleci.com/gh/helm/helm) and
make sure the release passed CI before proceeding.
If anyone is available, let others peer-review the branch before continuing to ensure that all the proper changes have been made and all of the commits for the release are there.
If anyone is available, let others peer-review the branch before continuing to
ensure that all the proper changes have been made and all of the commits for the
release are there.
## 4. Create a Release Candidate
Now that the release branch is out and ready, it is time to start creating and iterating on release candidates.
Now that the release branch is out and ready, it is time to start creating and
iterating on release candidates.
```shell
git tag --sign --annotate "${RELEASE_CANDIDATE_NAME}" --message "Helm release ${RELEASE_CANDIDATE_NAME}"
git push upstream $RELEASE_CANDIDATE_NAME
```
CircleCI will automatically create a tagged release image and client binary to test with.
CircleCI will automatically create a tagged release image and client binary to
test with.
For testers, the process to start testing after CircleCI finishes building the artifacts involves the following steps to grab the client from Google Cloud Storage:
For testers, the process to start testing after CircleCI finishes building the
artifacts involves the following steps to grab the client from Google Cloud
Storage:
linux/amd64, using /bin/bash:
@ -169,21 +198,35 @@ windows/amd64, using PowerShell:
PS C:\> Invoke-WebRequest -Uri "https://kubernetes-helm.storage.googleapis.com/helm-$RELEASE_CANDIDATE_NAME-windows-amd64.zip" -OutFile "helm-$ReleaseCandidateName-windows-amd64.zip"
```
Then, unpack and move the binary to somewhere on your $PATH, or move it somewhere and add it to your $PATH (e.g. /usr/local/bin/helm for linux/macOS, C:\Program Files\helm\helm.exe for Windows).
Then, unpack and move the binary to somewhere on your $PATH, or move it
somewhere and add it to your $PATH (e.g. /usr/local/bin/helm for linux/macOS,
C:\Program Files\helm\helm.exe for Windows).
## 5. Iterate on Successive Release Candidates
Spend several days explicitly investing time and resources to try and break helm in every possible way, documenting any findings pertinent to the release. This time should be spent testing and finding ways in which the release might have caused various features or upgrade environments to have issues, not coding. During this time, the release is in code freeze, and any additional code changes will be pushed out to the next release.
Spend several days explicitly investing time and resources to try and break helm
in every possible way, documenting any findings pertinent to the release. This
time should be spent testing and finding ways in which the release might have
caused various features or upgrade environments to have issues, not coding.
During this time, the release is in code freeze, and any additional code changes
will be pushed out to the next release.
During this phase, the $RELEASE_BRANCH_NAME branch will keep evolving as you will produce new release candidates. The frequency of new candidates is up to the release manager: use your best judgement taking into account the severity of reported issues, testers' availability, and the release deadline date. Generally speaking, it is better to let a release roll over the deadline than to ship a broken release.
During this phase, the $RELEASE_BRANCH_NAME branch will keep evolving as you
will produce new release candidates. The frequency of new candidates is up to
the release manager: use your best judgement taking into account the severity of
reported issues, testers' availability, and the release deadline date. Generally
speaking, it is better to let a release roll over the deadline than to ship a
broken release.
Each time you'll want to produce a new release candidate, you will start by adding commits to the branch by cherry-picking from master:
Each time you'll want to produce a new release candidate, you will start by
adding commits to the branch by cherry-picking from master:
```shell
git cherry-pick -x <commit_id>
```
You will also want to update the release version number and the CHANGELOG as we did in steps 2 and 3 as separate commits.
You will also want to update the release version number and the CHANGELOG as we
did in steps 2 and 3 as separate commits.
After that, tag it and notify users of the new release candidate:
@ -197,7 +240,9 @@ From here on just repeat this process, continuously testing until you're happy w
## 6. Finalize the Release
When you're finally happy with the quality of a release candidate, you can move on and create the real thing. Double-check one last time to make sure everything is in order, then finally push the release tag.
When you're finally happy with the quality of a release candidate, you can move
on and create the real thing. Double-check one last time to make sure everything
is in order, then finally push the release tag.
```shell
git checkout $RELEASE_BRANCH_NAME
@ -205,11 +250,33 @@ git tag --sign --annotate "${RELEASE_NAME}" --message "Helm release ${RELEASE_NA
git push upstream $RELEASE_NAME
```
## 7. Write the Release Notes
## 7. PGP Sign the downloads
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 notes are hand-written by a human being/marketing team/dog.
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.
If you're releasing a major/minor release, listing notable user-facing features is usually sufficient. For patch releases, do the same, but make note of the symptoms and who is affected.
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
release cycle, but it is usually more beneficial to the end-user if the release
notes are hand-written by a human being/marketing team/dog.
If you're releasing a major/minor release, listing notable user-facing features
is usually sufficient. For patch releases, do the same, but make note of the
symptoms and who is affected.
An example release note for a minor release would look like this:
@ -226,18 +293,25 @@ The community keeps growing, and we'd love to see you there!
- Hang out at the Public Developer Call: Thursday, 9:30 Pacific via [Zoom](https://zoom.us/j/696660622)
- Test, debug, and contribute charts: [GitHub/helm/charts](https://github.com/helm/charts)
## Features and Changes
- Major
- features
- list
- here
## Installation and Upgrading
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))
- [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 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 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 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 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 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))
- [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))
- [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) / 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) / 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) / 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) / 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) / 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) / 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) / CHECKSUM_VAL)
Once you have the client installed, upgrade Tiller with `helm init --upgrade`.
@ -250,23 +324,46 @@ The [Quickstart Guide](https://docs.helm.sh/using_helm/#quickstart-guide) will g
## Changelog
- chore(*): bump version to v2.7.0 08c1144f5eb3e3b636d9775617287cc26e53dba4 (Adam Reese)
### Features
- ref(*): kubernetes v1.11 support efadbd88035654b2951f3958167afed014c46bc6 (Adam Reese)
- feat(helm): add $HELM_KEY_PASSPHRASE environment variable for signing helm charts (#4778) 1e26b5300b5166fabb90002535aacd2f9cc7d787
### Bug fixes
- fix circle not building tags f4f932fabd197f7e6d608c8672b33a483b4b76fa (Matthew Fisher)
### Code cleanup
- ref(kube): Gets rid of superfluous Sprintf call 3071a16f5eb3a2b646d9795617287cc26e53dba4 (Taylor Thomas)
- chore(*): bump version to v2.7.0 08c1144f5eb3e3b636d9775617287cc26e53dba4 (Adam Reese)
### Documentation Changes
- docs(release_checklist): fix changelog generation command (#4694) 8442851a5c566a01d9b4c69b368d64daa04f6a7f (Matthew Fisher)
```
The changelog at the bottom of the release notes can be generated with this command:
The changelog at the bottom of the release notes can be generated with this
command:
```shell
PREVIOUS_RELEASE=vX.Y.Z
git log --no-merges --pretty=format:'- %s %H (%aN)' $PREVIOUS_RELEASE..$RELEASE_NAME
```
After generating the changelog, you will need to categorize the changes as shown
in the example above.
Once finished, go into GitHub and edit the release notes for the tagged release with the notes written here.
## 8. Evangelize
Remember to attach the ascii armored signatures generated in the previous step to the release notes.
## 9. Evangelize
Congratulations! You're done. Go grab yourself a $DRINK_OF_CHOICE. You've earned it.
Congratulations! You're done. Go grab yourself a $DRINK_OF_CHOICE. You've earned
it.
After enjoying a nice $DRINK_OF_CHOICE, go forth and announce the glad tidings of the new release in Slack and on Twitter. You should also notify any key partners in the helm community such as the homebrew formula maintainers, the owners of incubator projects (e.g. ChartMuseum) and any other interested parties.
After enjoying a nice $DRINK_OF_CHOICE, go forth and announce the glad tidings
of the new release in Slack and on Twitter. You should also notify any key
partners in the helm community such as the homebrew formula maintainers, the
owners of incubator projects (e.g. ChartMuseum) and any other interested
parties.
Optionally, write a blog post about the new release and showcase some of the new features on there!
Optionally, write a blog post about the new release and showcase some of the new
features on there!

@ -69,9 +69,10 @@ When Helm clients are connecting from outside of the cluster, the security betwe
Contrary to the previous [Enabling TLS](#enabling-tls) section, this section does not involve running a tiller server pod in your cluster (for what it's worth, that lines up with the current [helm v3 proposal](https://github.com/helm/community/blob/master/helm-v3/000-helm-v3.md)), thus there is no gRPC endpoint (and thus there's no need to create & manage TLS certificates to secure each gRPC endpoint).
Steps:
* Fetch the latest helm release tarball from the [GitHub release page](https://github.com/helm/helm/releases), and extract and move `helm` and `tiller` somewhere on your `$PATH`.
* "Server": Run `tiller --storage=secret`. (Note that `tiller` has a default value of ":44134" for the `--listen` argument.)
* Client: In another terminal (and on the same host that the aforementioned `tiller` command was run for the previous bullet): Run `export HELM_HOST=:44134`, and then run `helm` commands as usual.
- Fetch the latest helm release tarball from the [GitHub release page](https://github.com/helm/helm/releases), and extract and move `helm` and `tiller` somewhere on your `$PATH`.
- "Server": Run `tiller --storage=secret`. (Note that `tiller` has a default value of ":44134" for the `--listen` argument.)
- Client: In another terminal (and on the same host that the aforementioned `tiller` command was run for the previous bullet): Run `export HELM_HOST=:44134`, and then run `helm` commands as usual.
### Tiller's Release Information

@ -288,7 +288,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,
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
(IP SAN) in the Tiller certificate.

@ -1,4 +1,4 @@
# Using Helm
# Using Helm
This guide explains the basics of using Helm (and Tiller) to manage
packages on your Kubernetes cluster. It assumes that you have already
@ -17,9 +17,9 @@ cluster. Think of it like the Kubernetes equivalent of a Homebrew formula,
an Apt dpkg, or a Yum RPM file.
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
[Fedora Package Database](https://admin.fedoraproject.org/pkgdb/), but for
Kubernetes packages.
It's like Perl's [CPAN archive](https://www.cpan.org) or the
[Fedora Package Database](https://apps.fedoraproject.org/packages/s/pkgdb), but
for Kubernetes packages.
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
@ -190,7 +190,7 @@ imageTag: 10.1.14-r3
## Specify a imagePullPolicy
## 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:
@ -215,7 +215,10 @@ You can then override any of these settings in a YAML formatted file,
and then pass that file during installation.
```console
$ echo '{mariadbUser: user0, mariadbDatabase: user0db}' > config.yaml
$ cat << EOF > config.yaml
mariadbUser: user0
mariadbDatabase: user0db
EOF
$ helm install -f config.yaml stable/mariadb
```

163
glide.lock generated

@ -1,13 +1,11 @@
hash: fcbba2207c6511df365dfe355dfe601a862d340bbf15db47938a404fd0ec58d0
updated: 2018-11-11T19:26:29.631232-05:00
hash: f86919aea9f9b6df70967eb0b00d8a3807a2f5e924d7bd82d317f7969fddb3ef
updated: 2019-03-17T20:36:59.222397-07:00
imports:
- name: cloud.google.com/go
version: 3b1ae45394a234c385be014e9a488f2bb6eef821
subpackages:
- compute/metadata
- internal
- name: github.com/aokoli/goutils
version: 9c37978a95bd5c709a15883b6242714ea6709e64
- name: github.com/asaskevich/govalidator
version: 7664702784775e51966f0885f5cd27435916517b
- name: github.com/Azure/go-ansiterm
@ -15,12 +13,13 @@ imports:
subpackages:
- winterm
- name: github.com/Azure/go-autorest
version: bca49d5b51a50dc5bb17bbf6204c711c6dbded06
version: ea233b6412b0421a65dc6160e16c893364664a95
subpackages:
- autorest
- autorest/adal
- autorest/azure
- autorest/date
- logger
- version
- name: github.com/beorn7/perks
version: 3ac7bf7a47d159a033b107610db8a1b6575507a4
@ -81,20 +80,12 @@ imports:
- pkg/sysinfo
- pkg/term
- pkg/term/windows
- name: github.com/docker/go-connections
version: 3ede32e2033de7505e6500d6c868c2b9ed9f169d
subpackages:
- nat
- sockets
- tlsconfig
- name: github.com/docker/go-units
version: 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
- name: github.com/docker/spdystream
version: 449fdfce4d962303d702fec724ef0ad181c92528
subpackages:
- spdy
- name: github.com/evanphx/json-patch
version: 36442dbdb585210f8d5a1b45e67aa323c197d5c4
version: 5858425f75500d40c52783dce87d085a483ce135
- name: github.com/exponent-io/jsonpath
version: d6023ce2651d8eafb5c75bb0c7167536102ec9f5
- name: github.com/fatih/camelcase
@ -102,13 +93,13 @@ imports:
- name: github.com/ghodss/yaml
version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee
- name: github.com/go-openapi/jsonpointer
version: 46af16f9f7b149af66e5d1bd010e3574dc06de98
version: ef5f0afec364d3b9396b7b77b43dbe26bf1f8004
- name: github.com/go-openapi/jsonreference
version: 13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272
version: 8483a886a90412cd6858df4ea3483dce9c8e35a3
- name: github.com/go-openapi/spec
version: 1de3e0542de65ad8d75452a595886fdd0befb363
version: 5bae59e25b21498baea7f9d46e9c147ec106a42e
- name: github.com/go-openapi/swag
version: f3f9494671f93fcff853e3c6e9e948b3eb71e590
version: 5899d5c5e619fda5fa86e14795a835f473ca284c
- name: github.com/gobwas/glob
version: 5ccd90ef52e1e632236f7326478d4faa74f99438
subpackages:
@ -120,18 +111,16 @@ imports:
- util/runes
- util/strings
- name: github.com/gogo/protobuf
version: c0656edd0d9eab7c66d1eb0c568f9039345796f7
version: 342cbe0a04158f6dcb03ca0079991a51a4248c02
subpackages:
- proto
- sortkeys
- name: github.com/golang/glog
version: 44145f04b68cf362d9c4df2182967c2275eaefed
- name: github.com/golang/groupcache
version: 02826c3e79038b59d737d3b1c0a1d937f71a4433
subpackages:
- lru
- name: github.com/golang/protobuf
version: 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9
version: aa810b61a9c79d51363740d207bb46cf8e620ed5
subpackages:
- proto
- ptypes
@ -175,13 +164,13 @@ imports:
subpackages:
- simplelru
- name: github.com/huandu/xstrings
version: 3959339b333561bf62a38b424fd41517c2c90f40
version: f02667b379e2fb5916c3cda2cf31e0eb885d79f8
- name: github.com/imdario/mergo
version: 9316a62528ac99aaecb4e47eadd6dc8aa6533d58
- name: github.com/inconshreveable/mousetrap
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
- name: github.com/json-iterator/go
version: f2b4162afba35581b6d4a50d3b8f34e33c144682
version: ab8a2e0c74be9d3be70b3184d9acc634935ded82
- name: github.com/mailru/easyjson
version: 2f5df55504ebc322e4d52d34df6a1f5b503bf26d
subpackages:
@ -190,10 +179,12 @@ imports:
- jwriter
- name: github.com/MakeNowJust/heredoc
version: bb23615498cded5e105af4ce27de75b089cbe851
- name: github.com/Masterminds/goutils
version: 41ac8693c5c10a92ea1ff5ac3a7f95646f6123b0
- name: github.com/Masterminds/semver
version: 517734cc7d6470c0d07130e40fd40bdeb9bcd3fd
- name: github.com/Masterminds/sprig
version: 15f9564e7e9cf0da02a48e0d25f12a7b83559aa6
version: 9f8fceff796fb9f4e992cd2bece016be0121ab74
- name: github.com/Masterminds/vcs
version: 3084677c2c188840777bff30054f2b553729d329
- name: github.com/mattn/go-runewidth
@ -207,14 +198,9 @@ imports:
- name: github.com/modern-go/concurrent
version: bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94
- name: github.com/modern-go/reflect2
version: 05fbef0ca5da472bbf96c9322b84a53edc03c9fd
version: 94122c33edd36123c84d5368cfb2b69df93a0ec8
- name: github.com/opencontainers/go-digest
version: a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb
- name: github.com/opencontainers/image-spec
version: 372ad780f63454fbbbbcc7cf80e5b90245c13e13
subpackages:
- specs-go
- specs-go/v1
- name: github.com/peterbourgon/diskv
version: 5f041e8faa004a95c88a202771f4cc3e991971e6
- name: github.com/pkg/errors
@ -273,7 +259,7 @@ imports:
- scrypt
- ssh/terminal
- name: golang.org/x/net
version: 1c05540f6879653db88113bc4a2b70aec4bd491f
version: 0ed95abb35c445290478a5348a7b38bb154135fd
subpackages:
- context
- context/ctxhttp
@ -290,8 +276,12 @@ imports:
- internal
- jws
- jwt
- name: golang.org/x/sync
version: 1d60e4601c6fd243af51cc01ddf169918a5407ca
subpackages:
- semaphore
- name: golang.org/x/sys
version: 95c6576299259db960f6c5b9b69ea52422860fce
version: b90733256f2e882e81d52f9126de08df5615afd9
subpackages:
- unix
- windows
@ -335,26 +325,40 @@ imports:
subpackages:
- googleapis/rpc/status
- name: google.golang.org/grpc
version: 5ffe3083946d5603a0578721101dc8165b1d5b5f
version: a02b0774206b209466313a0b525d2c738fe407eb
subpackages:
- balancer
- balancer/base
- balancer/roundrobin
- binarylog/grpc_binarylog_v1
- codes
- connectivity
- credentials
- grpclb/grpc_lb_v1/messages
- credentials/internal
- encoding
- encoding/proto
- grpclog
- health
- health/grpc_health_v1
- internal
- internal/backoff
- internal/binarylog
- internal/channelz
- internal/envconfig
- internal/grpcrand
- internal/grpcsync
- internal/syscall
- internal/transport
- keepalive
- metadata
- naming
- peer
- resolver
- resolver/dns
- resolver/passthrough
- stats
- status
- tap
- transport
- name: gopkg.in/inf.v0
version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
- name: gopkg.in/square/go-jose.v2
@ -366,7 +370,7 @@ imports:
- name: gopkg.in/yaml.v2
version: 670d4cfef0544295bc27a114dbac37980d83185a
- name: k8s.io/api
version: fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc
version: 5cb15d34447165a97c76ed5a60e4e99c8a01ecfe
subpackages:
- admission/v1beta1
- admissionregistration/v1alpha1
@ -374,6 +378,7 @@ imports:
- apps/v1
- apps/v1beta1
- apps/v1beta2
- auditregistration/v1alpha1
- authentication/v1
- authentication/v1beta1
- authorization/v1
@ -402,11 +407,11 @@ imports:
- storage/v1alpha1
- storage/v1beta1
- name: k8s.io/apiextensions-apiserver
version: 05e89e265cc594459a3d33a63e779d94e6614c63
version: d002e88f6236312f0289d9d1deab106751718ff0
subpackages:
- pkg/features
- name: k8s.io/apimachinery
version: 6dd46049f39503a1fc8d65de4bd566829e95faff
version: 86fb29eff6288413d76bd8506874fddd9fccdff0
subpackages:
- pkg/api/equality
- pkg/api/errors
@ -414,7 +419,6 @@ imports:
- pkg/api/meta/testrestmapper
- pkg/api/resource
- pkg/api/validation
- pkg/api/validation/path
- pkg/apis/meta/internalversion
- pkg/apis/meta/v1
- pkg/apis/meta/v1/unstructured
@ -463,23 +467,21 @@ imports:
- third_party/forked/golang/netutil
- third_party/forked/golang/reflect
- name: k8s.io/apiserver
version: e85ad7b666fef0476185731329f4cff1536efff8
version: 79427f02047f9189a75b8cdaadccaf65a126853e
subpackages:
- pkg/apis/audit
- pkg/authentication/authenticator
- pkg/authentication/serviceaccount
- pkg/authentication/user
- pkg/endpoints/request
- pkg/features
- pkg/util/feature
- name: k8s.io/cli-runtime
version: 79bf4e0b64544d8c490247abae089bea572ddae6
version: a9e421a7932607ce4623ff45add8274499cca193
subpackages:
- pkg/genericclioptions
- pkg/genericclioptions/printers
- pkg/genericclioptions/resource
- name: k8s.io/client-go
version: 1638f8970cefaa404ff3a62950f88b08292b2696
version: b40b2a5939e43f7ffe0028ad67586b7ce50bb675
subpackages:
- discovery
- discovery/fake
@ -498,6 +500,8 @@ imports:
- kubernetes/typed/apps/v1beta1/fake
- kubernetes/typed/apps/v1beta2
- kubernetes/typed/apps/v1beta2/fake
- kubernetes/typed/auditregistration/v1alpha1
- kubernetes/typed/auditregistration/v1alpha1/fake
- kubernetes/typed/authentication/v1
- kubernetes/typed/authentication/v1/fake
- kubernetes/typed/authentication/v1beta1
@ -598,30 +602,20 @@ imports:
- util/integer
- util/jsonpath
- util/retry
- name: k8s.io/klog
version: 8139d8cb77af419532b33dfa7dd09fbc5f1d344f
- name: k8s.io/kube-openapi
version: 0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803
version: c59034cc13d587f5ef4e85ca0ade0c1866ae8e1d
subpackages:
- pkg/util/proto
- pkg/util/proto/testing
- pkg/util/proto/validation
- name: k8s.io/kubernetes
version: 54a352dda957bce0f88e49b65a6ee8bba8c0ba74
version: f2c8f1cadf1808ec28476682e49a3cce2b09efbf
subpackages:
- pkg/api/events
- pkg/api/legacyscheme
- pkg/api/pod
- pkg/api/ref
- pkg/api/resource
- pkg/api/service
- pkg/api/testapi
- pkg/api/v1/pod
- pkg/apis/admission
- pkg/apis/admission/install
- pkg/apis/admission/v1beta1
- pkg/apis/admissionregistration
- pkg/apis/admissionregistration/install
- pkg/apis/admissionregistration/v1alpha1
- pkg/apis/admissionregistration/v1beta1
- pkg/apis/apps
- pkg/apis/apps/install
- pkg/apis/apps/v1
@ -653,7 +647,6 @@ imports:
- pkg/apis/coordination/v1beta1
- pkg/apis/core
- pkg/apis/core/helper
- pkg/apis/core/helper/qos
- pkg/apis/core/install
- pkg/apis/core/pods
- pkg/apis/core/v1
@ -665,12 +658,7 @@ imports:
- pkg/apis/extensions
- pkg/apis/extensions/install
- pkg/apis/extensions/v1beta1
- pkg/apis/imagepolicy
- pkg/apis/imagepolicy/install
- pkg/apis/imagepolicy/v1alpha1
- pkg/apis/networking
- pkg/apis/networking/install
- pkg/apis/networking/v1
- pkg/apis/policy
- pkg/apis/policy/install
- pkg/apis/policy/v1beta1
@ -693,45 +681,36 @@ imports:
- pkg/apis/storage/v1alpha1
- pkg/apis/storage/v1beta1
- pkg/capabilities
- pkg/client/clientset_generated/internalclientset
- pkg/client/clientset_generated/internalclientset/scheme
- pkg/client/clientset_generated/internalclientset/typed/admissionregistration/internalversion
- pkg/client/clientset_generated/internalclientset/typed/apps/internalversion
- pkg/client/clientset_generated/internalclientset/typed/authentication/internalversion
- pkg/client/clientset_generated/internalclientset/typed/authorization/internalversion
- pkg/client/clientset_generated/internalclientset/typed/autoscaling/internalversion
- pkg/client/clientset_generated/internalclientset/typed/batch/internalversion
- pkg/client/clientset_generated/internalclientset/typed/certificates/internalversion
- pkg/client/clientset_generated/internalclientset/typed/coordination/internalversion
- pkg/client/clientset_generated/internalclientset/typed/core/internalversion
- pkg/client/clientset_generated/internalclientset/typed/events/internalversion
- pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion
- pkg/client/clientset_generated/internalclientset/typed/networking/internalversion
- pkg/client/clientset_generated/internalclientset/typed/policy/internalversion
- pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion
- pkg/client/clientset_generated/internalclientset/typed/scheduling/internalversion
- pkg/client/clientset_generated/internalclientset/typed/settings/internalversion
- pkg/client/clientset_generated/internalclientset/typed/storage/internalversion
- pkg/controller
- pkg/controller/deployment/util
- pkg/credentialprovider
- pkg/features
- pkg/fieldpath
- pkg/generated
- pkg/kubectl
- pkg/kubectl/apps
- pkg/kubectl/cmd/get
- pkg/kubectl/cmd/templates
- pkg/kubectl/cmd/testing
- pkg/kubectl/cmd/util
- pkg/kubectl/cmd/util/openapi
- pkg/kubectl/cmd/util/openapi/testing
- pkg/kubectl/cmd/util/openapi/validation
- pkg/kubectl/describe
- pkg/kubectl/describe/versioned
- pkg/kubectl/generated
- pkg/kubectl/scheme
- pkg/kubectl/util
- pkg/kubectl/util/hash
- pkg/kubectl/util/certificate
- pkg/kubectl/util/deployment
- pkg/kubectl/util/event
- pkg/kubectl/util/fieldpath
- pkg/kubectl/util/i18n
- pkg/kubectl/util/podutils
- pkg/kubectl/util/printers
- pkg/kubectl/util/qos
- pkg/kubectl/util/rbac
- pkg/kubectl/util/resource
- pkg/kubectl/util/slice
- pkg/kubectl/util/storage
- pkg/kubectl/util/templates
- pkg/kubectl/util/term
- pkg/kubectl/validation
- pkg/kubelet/apis
@ -739,12 +718,7 @@ imports:
- pkg/master/ports
- pkg/printers
- pkg/printers/internalversion
- pkg/registry/rbac/validation
- pkg/scheduler/algorithm
- pkg/scheduler/algorithm/priorities/util
- pkg/scheduler/api
- pkg/scheduler/cache
- pkg/scheduler/util
- pkg/security/apparmor
- pkg/serviceaccount
- pkg/util/file
@ -754,7 +728,6 @@ imports:
- pkg/util/net/sets
- pkg/util/node
- pkg/util/parsers
- pkg/util/slice
- pkg/util/taints
- pkg/version
- name: k8s.io/utils
@ -764,6 +737,8 @@ imports:
- exec
- exec/testing
- pointer
- name: sigs.k8s.io/yaml
version: fd68e9863619f6ec2fdd8625fe1f02e7c877e480
- name: vbom.ml/util
version: db5cfe13f5cc80a4990d98e2e1b0707a4d1a5394
subpackages:

@ -3,6 +3,15 @@ import:
- package: golang.org/x/net
subpackages:
- context
- package: golang.org/x/sync
subpackages:
- semaphore
# This is temporary and can probably be removed the next time gRPC is updated
- package: golang.org/x/sys
version: b90733256f2e882e81d52f9126de08df5615afd9
subpackages:
- unix
- windows
- package: github.com/spf13/cobra
version: fe5e611709b0c57fa4a89136deaa8e1d4004d053
- package: github.com/spf13/pflag
@ -12,20 +21,20 @@ import:
- package: github.com/imdario/mergo
version: v0.3.5
- package: github.com/Masterminds/sprig
version: ^2.16.0
version: ^2.19.0
- package: github.com/ghodss/yaml
- package: github.com/Masterminds/semver
version: ~1.3.1
- package: github.com/technosophos/moniker
version: ~0.2
- package: github.com/golang/protobuf
version: 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9
version: 1.2.0
subpackages:
- proto
- ptypes/any
- ptypes/timestamp
- package: google.golang.org/grpc
version: 1.7.2
version: 1.18.0
- package: github.com/gosuri/uitable
- package: github.com/asaskevich/govalidator
version: ^4.0.0
@ -41,19 +50,20 @@ import:
- package: github.com/prometheus/client_golang
version: 0.8.0
- package: github.com/grpc-ecosystem/go-grpc-prometheus
- package: k8s.io/kubernetes
version: release-1.12
version: release-1.13
- package: k8s.io/client-go
version: kubernetes-1.12.0
version: kubernetes-1.13.4
- package: k8s.io/api
version: kubernetes-1.12.0
version: kubernetes-1.13.4
- package: k8s.io/apimachinery
version: kubernetes-1.12.0
version: kubernetes-1.13.4
- package: k8s.io/apiserver
version: kubernetes-1.12.0
version: kubernetes-1.13.4
- package: k8s.io/cli-runtime
version: kubernetes-1.12.0
version: kubernetes-1.13.4
- package: k8s.io/apiextensions-apiserver
version: kubernetes-1.13.4
- package: github.com/cyphar/filepath-securejoin
version: ^0.2.1

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

@ -75,9 +75,10 @@ ingress:
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
paths: []
hosts:
- chart-example.local
- host: chart-example.local
paths: []
tls: []
# - secretName: chart-example-tls
# hosts:
@ -89,11 +90,11 @@ resources: {}
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
@ -128,7 +129,6 @@ const defaultIgnore = `# Patterns to ignore when building packages.
const defaultIngress = `{{- if .Values.ingress.enabled -}}
{{- $fullName := include "<CHARTNAME>.fullname" . -}}
{{- $ingressPaths := .Values.ingress.paths -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
@ -155,15 +155,15 @@ spec:
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ . | quote }}
- host: {{ .host | quote }}
http:
paths:
{{- range $ingressPaths }}
{{- range .paths }}
- path: {{ . }}
backend:
serviceName: {{ $fullName }}
servicePort: http
{{- end }}
{{- end }}
{{- end }}
{{- end }}
`
@ -245,8 +245,8 @@ spec:
const defaultNotes = `1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range $.Values.ingress.paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host }}{{ . }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
@ -255,7 +255,7 @@ const defaultNotes = `1. Get the application URL by running these commands:
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc -w {{ include "<CHARTNAME>.fullname" . }}'
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "<CHARTNAME>.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "<CHARTNAME>.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}

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

Loading…
Cancel
Save