├── pkg ├── ignore │ └── testdata │ │ ├── a.txt │ │ ├── helm.txt │ │ ├── cargo │ │ ├── a.txt │ │ ├── b.txt │ │ └── c.txt │ │ ├── mast │ │ ├── a.txt │ │ ├── b.txt │ │ └── c.txt │ │ ├── rudder.txt │ │ ├── tiller.txt │ │ ├── templates │ │ └── .dotfile │ │ └── .helmignore ├── chartutil │ ├── testdata │ │ ├── frobnitz │ │ │ ├── ignore │ │ │ │ └── me.txt │ │ │ ├── .helmignore │ │ │ ├── LICENSE │ │ │ ├── docs │ │ │ │ └── README.md │ │ │ ├── templates │ │ │ │ └── template.tpl │ │ │ ├── charts │ │ │ │ ├── alpine │ │ │ │ │ ├── values.yaml │ │ │ │ │ ├── charts │ │ │ │ │ │ ├── mast1 │ │ │ │ │ │ │ ├── Chart.yaml │ │ │ │ │ │ │ └── values.yaml │ │ │ │ │ │ └── mast2-0.1.0.tgz │ │ │ │ │ ├── Chart.yaml │ │ │ │ │ ├── README.md │ │ │ │ │ └── templates │ │ │ │ │ │ └── alpine-pod.yaml │ │ │ │ └── mariner-4.3.2.tgz │ │ │ ├── INSTALL.txt │ │ │ ├── values.yaml │ │ │ ├── README.md │ │ │ ├── requirements.yaml │ │ │ ├── requirements.lock │ │ │ ├── icon.svg │ │ │ └── Chart.yaml │ │ ├── moby │ │ │ ├── charts │ │ │ │ ├── spouter │ │ │ │ │ ├── values.yaml │ │ │ │ │ └── Chart.yaml │ │ │ │ └── pequod │ │ │ │ │ ├── values.yaml │ │ │ │ │ ├── charts │ │ │ │ │ └── ahab │ │ │ │ │ │ ├── values.yaml │ │ │ │ │ │ └── Chart.yaml │ │ │ │ │ └── Chart.yaml │ │ │ ├── values.yaml │ │ │ └── Chart.yaml │ │ ├── mariner │ │ │ ├── templates │ │ │ │ └── placeholder.tpl │ │ │ ├── Chart.yaml │ │ │ ├── charts │ │ │ │ └── albatross-0.1.0.tgz │ │ │ ├── requirements.yaml │ │ │ └── values.yaml │ │ ├── albatross │ │ │ ├── values.yaml │ │ │ └── Chart.yaml │ │ ├── frobnitz-1.2.3.tgz │ │ ├── coleridge.yaml │ │ ├── genfrob.sh │ │ └── chartfiletest.yaml │ ├── requirements_test.go │ ├── files_test.go │ ├── doc.go │ ├── save_test.go │ ├── files.go │ ├── chartfile.go │ ├── create_test.go │ └── expand.go ├── lint │ ├── rules │ │ ├── testdata │ │ │ ├── albatross │ │ │ │ ├── values.yaml │ │ │ │ ├── templates │ │ │ │ │ ├── fail.yaml │ │ │ │ │ ├── _helpers.tpl │ │ │ │ │ └── svc.yaml │ │ │ │ └── Chart.yaml │ │ │ ├── goodone │ │ │ │ ├── values.yaml │ │ │ │ ├── templates │ │ │ │ │ └── goodone.yaml │ │ │ │ └── Chart.yaml │ │ │ ├── badchartfile │ │ │ │ ├── values.yaml │ │ │ │ └── Chart.yaml │ │ │ └── badvaluesfile │ │ │ │ ├── templates │ │ │ │ └── badvaluesfile.yaml │ │ │ │ ├── Chart.yaml │ │ │ │ └── values.yaml │ │ └── values.go │ ├── support │ │ ├── doc.go │ │ └── message.go │ └── lint.go ├── provenance │ ├── testdata │ │ ├── hashtest │ │ │ ├── Chart.yaml │ │ │ ├── values.yaml │ │ │ └── .helmignore │ │ ├── hashtest.sha256 │ │ ├── hashtest-1.2.3.tgz │ │ ├── helm-test-key.pub │ │ ├── regen-hashtest.sh │ │ ├── helm-test-key.secret │ │ ├── msgblock.yaml │ │ ├── msgblock.yaml.asc │ │ └── msgblock.yaml.tampered │ └── doc.go ├── repo │ ├── repotest │ │ ├── testdata │ │ │ ├── examplechart │ │ │ │ ├── Chart.yaml │ │ │ │ ├── values.yaml │ │ │ │ └── .helmignore │ │ │ └── examplechart-0.1.0.tgz │ │ └── doc.go │ └── testdata │ │ ├── repository │ │ ├── frobnitz-1.2.3.tgz │ │ └── sprocket-1.2.0.tgz │ │ ├── old-repositories.yaml │ │ ├── repositories.yaml │ │ ├── local-index.yaml │ │ └── unversioned-index.yaml ├── version │ ├── doc.go │ ├── compatible.go │ ├── compatible_test.go │ └── version.go ├── storage │ ├── doc.go │ ├── driver │ │ ├── labels_test.go │ │ ├── labels.go │ │ └── records_test.go │ └── filter.go ├── kube │ ├── tunnel_test.go │ └── log.go ├── engine │ └── doc.go ├── timeconv │ ├── doc.go │ ├── timeconv_test.go │ └── timeconv.go ├── helm │ └── interface.go └── proto │ └── hapi │ └── chart │ └── template.pb.go ├── cmd ├── helm │ ├── downloader │ │ ├── testdata │ │ │ ├── signtest │ │ │ │ ├── values.yaml │ │ │ │ ├── alpine │ │ │ │ │ ├── values.yaml │ │ │ │ │ ├── Chart.yaml │ │ │ │ │ ├── README.md │ │ │ │ │ └── templates │ │ │ │ │ │ └── alpine-pod.yaml │ │ │ │ ├── Chart.yaml │ │ │ │ ├── .helmignore │ │ │ │ └── templates │ │ │ │ │ └── pod.yaml │ │ │ ├── helmhome │ │ │ │ └── repository │ │ │ │ │ ├── local │ │ │ │ │ └── index.yaml │ │ │ │ │ ├── cache │ │ │ │ │ ├── testing-index.yaml │ │ │ │ │ ├── local-index.yaml │ │ │ │ │ └── kubernetes-charts-index.yaml │ │ │ │ │ └── repositories.yaml │ │ │ ├── helm-test-key.pub │ │ │ ├── signtest-0.1.0.tgz │ │ │ ├── helm-test-key.secret │ │ │ └── signtest-0.1.0.tgz.prov │ │ └── doc.go │ ├── testdata │ │ ├── testcharts │ │ │ ├── signtest │ │ │ │ ├── values.yaml │ │ │ │ ├── alpine │ │ │ │ │ ├── values.yaml │ │ │ │ │ ├── Chart.yaml │ │ │ │ │ ├── README.md │ │ │ │ │ └── templates │ │ │ │ │ │ └── alpine-pod.yaml │ │ │ │ ├── Chart.yaml │ │ │ │ ├── .helmignore │ │ │ │ └── templates │ │ │ │ │ └── pod.yaml │ │ │ ├── alpine │ │ │ │ ├── values.yaml │ │ │ │ ├── Chart.yaml │ │ │ │ ├── README.md │ │ │ │ └── templates │ │ │ │ │ └── alpine-pod.yaml │ │ │ ├── reqtest │ │ │ │ ├── Chart.yaml │ │ │ │ ├── charts │ │ │ │ │ ├── reqsubchart │ │ │ │ │ │ ├── Chart.yaml │ │ │ │ │ │ ├── values.yaml │ │ │ │ │ │ └── .helmignore │ │ │ │ │ └── reqsubchart2 │ │ │ │ │ │ ├── Chart.yaml │ │ │ │ │ │ ├── values.yaml │ │ │ │ │ │ └── .helmignore │ │ │ │ ├── requirements.lock │ │ │ │ ├── values.yaml │ │ │ │ ├── requirements.yaml │ │ │ │ └── .helmignore │ │ │ ├── reqtest-0.1.0.tgz │ │ │ ├── signtest-0.1.0.tgz │ │ │ ├── decompressedchart │ │ │ │ ├── Chart.yaml │ │ │ │ ├── values.yaml │ │ │ │ └── .helmignore │ │ │ ├── compressedchart-0.1.0.tgz │ │ │ ├── novals │ │ │ │ ├── Chart.yaml │ │ │ │ ├── README.md │ │ │ │ └── templates │ │ │ │ │ └── alpine-pod.yaml │ │ │ └── signtest-0.1.0.tgz.prov │ │ ├── helmhome │ │ │ └── repository │ │ │ │ ├── local │ │ │ │ └── index.yaml │ │ │ │ ├── repositories.yaml │ │ │ │ └── cache │ │ │ │ └── testing-index.yaml │ │ ├── testserver │ │ │ ├── index.yaml │ │ │ └── repository │ │ │ │ └── repositories.yaml │ │ ├── helm-test-key.pub │ │ ├── helm-test-key.secret │ │ ├── repositories.yaml │ │ └── testcache │ │ │ ├── foobar-index.yaml │ │ │ └── local-index.yaml │ ├── lint_test.go │ ├── home.go │ ├── helmpath │ │ ├── helmhome_test.go │ │ └── helmhome.go │ ├── get_hooks_test.go │ ├── get_manifest_test.go │ ├── get_values_test.go │ ├── rollback_test.go │ ├── get_test.go │ ├── repo.go │ ├── repo_index_test.go │ ├── delete_test.go │ ├── init_test.go │ ├── repo_list.go │ ├── structure.go │ ├── repo_index.go │ ├── create_test.go │ ├── version.go │ ├── repo_remove_test.go │ ├── serve.go │ ├── verify.go │ ├── get_hooks.go │ ├── inspect_test.go │ ├── tunnel.go │ ├── dependency_test.go │ ├── get_manifest.go │ ├── tunnel_test.go │ ├── repo_remove.go │ ├── dependency_build.go │ └── repo_add_test.go └── tiller │ ├── probes.go │ ├── tiller_test.go │ ├── probes_test.go │ ├── release_history.go │ ├── kind_sorter_test.go │ └── kind_sorter.go ├── docs ├── examples │ ├── alpine │ │ ├── values.yaml │ │ ├── Chart.yaml │ │ ├── README.md │ │ └── templates │ │ │ └── alpine-pod.yaml │ ├── nginx │ │ ├── .helmignore │ │ ├── Chart.yaml │ │ ├── values.yaml │ │ ├── templates │ │ │ ├── _helpers.tpl │ │ │ ├── configmap.yaml │ │ │ ├── pre-install-secret.yaml │ │ │ ├── svc.yaml │ │ │ ├── post-install-job.yaml │ │ │ └── deployment.yaml │ │ └── README.md │ └── README.md ├── images │ ├── set-a-gh-page.png │ ├── create-a-bucket.png │ ├── edit-permissions.png │ ├── make-bucket-public.png │ └── create-a-gh-page-button.png ├── logos │ └── helm_logo_transparent.png └── history.md ├── .gitignore ├── rootfs ├── README.md └── Dockerfile ├── _proto ├── hapi │ ├── version │ │ └── version.proto │ ├── chart │ │ ├── config.proto │ │ ├── template.proto │ │ ├── chart.proto │ │ └── metadata.proto │ └── release │ │ ├── info.proto │ │ ├── hook.proto │ │ ├── status.proto │ │ └── release.proto └── Makefile ├── scripts ├── validate-license.sh ├── ci.sh ├── coverage.sh ├── validate-go.sh └── sync-repo.sh ├── versioning.mk └── glide.yaml /pkg/ignore/testdata/a.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/ignore/testdata/helm.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/ignore/testdata/cargo/a.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/ignore/testdata/cargo/b.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/ignore/testdata/cargo/c.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/ignore/testdata/mast/a.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/ignore/testdata/mast/b.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/ignore/testdata/mast/c.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/ignore/testdata/rudder.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/ignore/testdata/tiller.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/ignore/testdata/templates/.dotfile: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/ignore/me.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/signtest/values.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/signtest/values.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cmd/helm/testdata/helmhome/repository/local/index.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testserver/index.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/.helmignore: -------------------------------------------------------------------------------- 1 | ignore/ 2 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/helmhome/repository/local/index.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/LICENSE: -------------------------------------------------------------------------------- 1 | LICENSE placeholder. 2 | -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/albatross/values.yaml: -------------------------------------------------------------------------------- 1 | name: "mariner" 2 | -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/goodone/values.yaml: -------------------------------------------------------------------------------- 1 | name: "goodone here" 2 | -------------------------------------------------------------------------------- /docs/examples/alpine/values.yaml: -------------------------------------------------------------------------------- 1 | # The pod name 2 | Name: my-alpine 3 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/moby/charts/spouter/values.yaml: -------------------------------------------------------------------------------- 1 | scope: spouter 2 | -------------------------------------------------------------------------------- /pkg/ignore/testdata/.helmignore: -------------------------------------------------------------------------------- 1 | mast/a.txt 2 | .DS_Store 3 | .git 4 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/alpine/values.yaml: -------------------------------------------------------------------------------- 1 | # The pod name 2 | Name: my-alpine 3 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/mariner/templates/placeholder.tpl: -------------------------------------------------------------------------------- 1 | # This is a placeholder. 2 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/moby/charts/pequod/values.yaml: -------------------------------------------------------------------------------- 1 | scope: pequod 2 | name: pequod 3 | -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/albatross/templates/fail.yaml: -------------------------------------------------------------------------------- 1 | {{ deliberateSyntaxError }} 2 | -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/badchartfile/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for badchartfile. 2 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/helmhome/repository/cache/testing-index.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/docs/README.md: -------------------------------------------------------------------------------- 1 | This is a placeholder for documentation. 2 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/templates/template.tpl: -------------------------------------------------------------------------------- 1 | Hello {{.Name | default "world"}} 2 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/helmhome/repository/cache/local-index.yaml: -------------------------------------------------------------------------------- 1 | repository/local/index.yaml -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/signtest/alpine/values.yaml: -------------------------------------------------------------------------------- 1 | # The pod name 2 | name: my-alpine 3 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/signtest/alpine/values.yaml: -------------------------------------------------------------------------------- 1 | # The pod name 2 | name: my-alpine 3 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/charts/alpine/values.yaml: -------------------------------------------------------------------------------- 1 | # The pod name 2 | name: "my-alpine" 3 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/moby/charts/pequod/charts/ahab/values.yaml: -------------------------------------------------------------------------------- 1 | scope: ahab 2 | name: ahab 3 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/moby/values.yaml: -------------------------------------------------------------------------------- 1 | scope: moby 2 | name: moby 3 | override: bad 4 | top: nope 5 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/albatross/values.yaml: -------------------------------------------------------------------------------- 1 | albatross: "true" 2 | 3 | global: 4 | author: Coleridge 5 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/INSTALL.txt: -------------------------------------------------------------------------------- 1 | This is an install document. The client may display this. 2 | -------------------------------------------------------------------------------- /docs/images/set-a-gh-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/docs/images/set-a-gh-page.png -------------------------------------------------------------------------------- /docs/images/create-a-bucket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/docs/images/create-a-bucket.png -------------------------------------------------------------------------------- /docs/images/edit-permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/docs/images/edit-permissions.png -------------------------------------------------------------------------------- /pkg/chartutil/testdata/moby/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | name: moby 3 | version: 0.1.0 4 | -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/goodone/templates/goodone.yaml: -------------------------------------------------------------------------------- 1 | metadata: 2 | name: {{.name | default "foo" | title}} 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .coverage/ 3 | .vimrc 4 | _dist/ 5 | _proto/*.pb.go 6 | bin/ 7 | rootfs/tiller 8 | vendor/ 9 | -------------------------------------------------------------------------------- /cmd/helm/testdata/helm-test-key.pub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/cmd/helm/testdata/helm-test-key.pub -------------------------------------------------------------------------------- /docs/images/make-bucket-public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/docs/images/make-bucket-public.png -------------------------------------------------------------------------------- /pkg/provenance/testdata/hashtest/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: Test chart versioning 2 | name: hashtest 3 | version: 1.2.3 4 | -------------------------------------------------------------------------------- /docs/logos/helm_logo_transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/docs/logos/helm_logo_transparent.png -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/badchartfile/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | version: 0.0.0 3 | home: "" 4 | -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/badvaluesfile/templates/badvaluesfile.yaml: -------------------------------------------------------------------------------- 1 | metadata: 2 | name: {{.name | default "foo" | title}} 3 | -------------------------------------------------------------------------------- /pkg/provenance/testdata/hashtest.sha256: -------------------------------------------------------------------------------- 1 | 8e90e879e2a04b1900570e1c198755e46e4706d70b0e79f5edabfac7900e4e75 hashtest-1.2.3.tgz 2 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/signtest/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | name: signtest 3 | version: 0.1.0 4 | -------------------------------------------------------------------------------- /cmd/helm/testdata/helm-test-key.secret: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/cmd/helm/testdata/helm-test-key.secret -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/reqtest/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | name: reqtest 3 | version: 0.1.0 4 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/signtest/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | name: signtest 3 | version: 0.1.0 4 | -------------------------------------------------------------------------------- /docs/images/create-a-gh-page-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/docs/images/create-a-gh-page-button.png -------------------------------------------------------------------------------- /pkg/chartutil/testdata/moby/charts/pequod/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | name: pequod 3 | version: 0.1.0 4 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz-1.2.3.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/pkg/chartutil/testdata/frobnitz-1.2.3.tgz -------------------------------------------------------------------------------- /pkg/chartutil/testdata/mariner/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: mariner 2 | description: A Helm chart for Kubernetes 3 | version: 4.3.2 4 | home: "" 5 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/moby/charts/spouter/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | name: spouter 3 | version: 0.1.0 4 | -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/albatross/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: albatross 2 | description: testing chart 3 | version: 199.44.12345-Alpha.1+cafe009 4 | -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/goodone/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: goodone 2 | description: good testing chart 3 | version: 199.44.12345-Alpha.1+cafe009 4 | -------------------------------------------------------------------------------- /pkg/provenance/testdata/hashtest-1.2.3.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/pkg/provenance/testdata/hashtest-1.2.3.tgz -------------------------------------------------------------------------------- /pkg/provenance/testdata/helm-test-key.pub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/pkg/provenance/testdata/helm-test-key.pub -------------------------------------------------------------------------------- /pkg/provenance/testdata/regen-hashtest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | helm package hashtest 3 | shasum -a 256 hashtest-1.2.3.tgz > hashtest.sha256 4 | -------------------------------------------------------------------------------- /pkg/repo/repotest/testdata/examplechart/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | name: examplechart 3 | version: 0.1.0 4 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/albatross/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: albatross 2 | description: A Helm chart for Kubernetes 3 | version: 0.1.0 4 | home: "" 5 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/moby/charts/pequod/charts/ahab/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | name: ahab 3 | version: 0.1.0 4 | -------------------------------------------------------------------------------- /pkg/provenance/testdata/helm-test-key.secret: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/pkg/provenance/testdata/helm-test-key.secret -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/helm-test-key.pub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/cmd/helm/downloader/testdata/helm-test-key.pub -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/signtest-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/cmd/helm/downloader/testdata/signtest-0.1.0.tgz -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/reqtest-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/cmd/helm/testdata/testcharts/reqtest-0.1.0.tgz -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/signtest-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/cmd/helm/testdata/testcharts/signtest-0.1.0.tgz -------------------------------------------------------------------------------- /pkg/repo/testdata/repository/frobnitz-1.2.3.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/pkg/repo/testdata/repository/frobnitz-1.2.3.tgz -------------------------------------------------------------------------------- /pkg/repo/testdata/repository/sprocket-1.2.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/pkg/repo/testdata/repository/sprocket-1.2.0.tgz -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/helm-test-key.secret: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/cmd/helm/downloader/testdata/helm-test-key.secret -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/decompressedchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | name: decompressedchart 3 | version: 0.1.0 4 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/reqtest/charts/reqsubchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | name: reqsubchart 3 | version: 0.1.0 4 | -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/badvaluesfile/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: badvaluesfile 2 | description: A Helm chart for Kubernetes 3 | version: 0.0.1 4 | home: "" 5 | -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/badvaluesfile/values.yaml: -------------------------------------------------------------------------------- 1 | # Invalid value for badvaluesfile for testing lint fails with invalid yaml format 2 | name= "value" 3 | -------------------------------------------------------------------------------- /pkg/repo/repotest/testdata/examplechart-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/pkg/repo/repotest/testdata/examplechart-0.1.0.tgz -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/reqtest/charts/reqsubchart2/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Helm chart for Kubernetes 2 | name: reqsubchart2 3 | version: 0.2.0 4 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/reqtest/requirements.lock: -------------------------------------------------------------------------------- 1 | dependencies: [] 2 | digest: Not implemented 3 | generated: 2016-09-13T17:25:17.593788787-06:00 4 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/compressedchart-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/cmd/helm/testdata/testcharts/compressedchart-0.1.0.tgz -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/charts/alpine/charts/mast1/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: mast1 2 | description: A Helm chart for Kubernetes 3 | version: 0.1.0 4 | home: "" 5 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/charts/mariner-4.3.2.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/pkg/chartutil/testdata/frobnitz/charts/mariner-4.3.2.tgz -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/values.yaml: -------------------------------------------------------------------------------- 1 | # A values file contains configuration. 2 | 3 | name: "Some Name" 4 | 5 | section: 6 | name: "Name in a section" 7 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/mariner/charts/albatross-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/pkg/chartutil/testdata/mariner/charts/albatross-0.1.0.tgz -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/charts/alpine/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: alpine 2 | description: Deploy a basic Alpine Linux pod 3 | version: 0.1.0 4 | home: https://k8s.io/helm 5 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/mariner/requirements.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: albatross 3 | repository: https://example.com/mariner/charts 4 | version: "0.1.0" 5 | -------------------------------------------------------------------------------- /pkg/repo/testdata/old-repositories.yaml: -------------------------------------------------------------------------------- 1 | best-charts-ever: http://best-charts-ever.com 2 | okay-charts: http://okay-charts.org 3 | example123: http://examplecharts.net/charts/123 4 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/charts/alpine/charts/mast2-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/helm/master/pkg/chartutil/testdata/frobnitz/charts/alpine/charts/mast2-0.1.0.tgz -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/reqtest/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for reqtest. 2 | # This is a YAML-formatted file. 3 | # Declare name/value pairs to be passed into your templates. 4 | # name: value 5 | -------------------------------------------------------------------------------- /docs/examples/alpine/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: alpine 2 | description: Deploy a basic Alpine Linux pod 3 | version: 0.1.0 4 | home: https://k8s.io/helm 5 | sources: 6 | - https://github.com/kubernetes/helm 7 | -------------------------------------------------------------------------------- /pkg/provenance/testdata/hashtest/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for hashtest. 2 | # This is a YAML-formatted file. 3 | # Declare name/value pairs to be passed into your templates. 4 | # name: value 5 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testserver/repository/repositories.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | generated: 2016-10-04T13:50:02.87649685-06:00 3 | repositories: 4 | - cache: "" 5 | name: test 6 | url: http://127.0.0.1:49216 7 | -------------------------------------------------------------------------------- /pkg/repo/repotest/testdata/examplechart/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for examplechart. 2 | # This is a YAML-formatted file. 3 | # Declare name/value pairs to be passed into your templates. 4 | # name: value 5 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/alpine/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: Deploy a basic Alpine Linux pod 2 | home: https://k8s.io/helm 3 | name: alpine 4 | sources: 5 | - https://github.com/kubernetes/helm 6 | version: 0.1.0 7 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/novals/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: Deploy a basic Alpine Linux pod 2 | home: https://k8s.io/helm 3 | name: novals 4 | sources: 5 | - https://github.com/kubernetes/helm 6 | version: 0.2.0 7 | -------------------------------------------------------------------------------- /cmd/helm/testdata/repositories.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | repositories: 3 | - name: charts 4 | url: "http://storage.googleapis.com/kubernetes-charts" 5 | - name: local 6 | url: "http://localhost:8879/charts" 7 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/signtest/alpine/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: Deploy a basic Alpine Linux pod 2 | home: https://k8s.io/helm 3 | name: alpine 4 | sources: 5 | - https://github.com/kubernetes/helm 6 | version: 0.1.0 7 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/reqtest/charts/reqsubchart/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for reqsubchart. 2 | # This is a YAML-formatted file. 3 | # Declare name/value pairs to be passed into your templates. 4 | # name: value 5 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/reqtest/charts/reqsubchart2/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for reqsubchart. 2 | # This is a YAML-formatted file. 3 | # Declare name/value pairs to be passed into your templates. 4 | # name: value 5 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/signtest/alpine/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: Deploy a basic Alpine Linux pod 2 | home: https://k8s.io/helm 3 | name: alpine 4 | sources: 5 | - https://github.com/kubernetes/helm 6 | version: 0.1.0 7 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/charts/alpine/charts/mast1/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for mast1. 2 | # This is a YAML-formatted file. 3 | # Declare name/value pairs to be passed into your templates. 4 | # name = "value" 5 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/helmhome/repository/repositories.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | repositories: 3 | - name: testing 4 | url: "http://example.com" 5 | - name: kubernetes-charts 6 | url: "http://example.com/charts" 7 | -------------------------------------------------------------------------------- /cmd/helm/testdata/helmhome/repository/repositories.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | generated: 2016-10-03T16:03:10.640376913-06:00 3 | repositories: 4 | - cache: testing-index.yaml 5 | name: testing 6 | url: http://example.com/charts 7 | -------------------------------------------------------------------------------- /docs/examples/nginx/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | .git 6 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/mariner/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for mariner. 2 | # This is a YAML-formatted file. https://github.com/toml-lang/toml 3 | # Declare name/value pairs to be passed into your templates. 4 | # name: "value" 5 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/decompressedchart/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for decompressedchart. 2 | # This is a YAML-formatted file. 3 | # Declare name/value pairs to be passed into your templates. 4 | name: my-decompressed-chart 5 | -------------------------------------------------------------------------------- /pkg/provenance/testdata/msgblock.yaml: -------------------------------------------------------------------------------- 1 | description: Test chart versioning 2 | name: hashtest 3 | version: 1.2.3 4 | 5 | ... 6 | files: 7 | hashtest-1.2.3.tgz: sha256:8e90e879e2a04b1900570e1c198755e46e4706d70b0e79f5edabfac7900e4e75 8 | -------------------------------------------------------------------------------- /pkg/provenance/testdata/hashtest/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | .git 6 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/signtest/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | .git 6 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/signtest/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | .git 6 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/README.md: -------------------------------------------------------------------------------- 1 | # Frobnitz 2 | 3 | This is an example chart. 4 | 5 | ## Usage 6 | 7 | This is an example. It has no usage. 8 | 9 | ## Development 10 | 11 | For developer info, see the top-level repository. 12 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/requirements.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: alpine 3 | version: "0.1.0" 4 | repository: https://example.com/charts 5 | - name: mariner 6 | version: "4.3.2" 7 | repository: https://example.com/charts 8 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/decompressedchart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | .git 6 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/reqtest/requirements.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: reqsubchart 3 | version: 0.1.0 4 | repository: "https://example.com/charts" 5 | - name: reqsubchart2 6 | version: 0.2.0 7 | repository: "https://example.com/charts" 8 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/signtest/templates/pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: signtest 5 | spec: 6 | restartPolicy: Never 7 | containers: 8 | - name: waiter 9 | image: "alpine:3.3" 10 | command: ["/bin/sleep","9000"] 11 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/signtest/templates/pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: signtest 5 | spec: 6 | restartPolicy: Never 7 | containers: 8 | - name: waiter 9 | image: "alpine:3.3" 10 | command: ["/bin/sleep","9000"] 11 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/requirements.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: alpine 3 | version: "0.1.0" 4 | repository: https://example.com/charts 5 | - name: mariner 6 | version: "4.3.2" 7 | repository: https://example.com/charts 8 | digest: invalid 9 | -------------------------------------------------------------------------------- /pkg/repo/testdata/repositories.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | repositories: 3 | - name: stable 4 | url: https://example.com/stable/charts 5 | cache: stable-index.yaml 6 | - name: incubator 7 | url: https://example.com/incubator 8 | cache: incubator-index.yaml 9 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/coleridge.yaml: -------------------------------------------------------------------------------- 1 | poet: "Coleridge" 2 | title: "Rime of the Ancient Mariner" 3 | stanza: ["at", "length", "did", "cross", "an", "Albatross"] 4 | 5 | mariner: 6 | with: "crossbow" 7 | shot: "ALBATROSS" 8 | 9 | water: 10 | water: 11 | where: "everywhere" 12 | nor: "any drop to drink" 13 | -------------------------------------------------------------------------------- /docs/examples/nginx/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: nginx 2 | description: A basic NGINX HTTP server 3 | version: 0.1.0 4 | keywords: 5 | - http 6 | - nginx 7 | - www 8 | - web 9 | home: "https://github.com/kubernetes/helm" 10 | sources: 11 | - "https://hub.docker.com/_/nginx/" 12 | maintainers: 13 | - name: technosophos 14 | email: mbutcher@deis.com 15 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/signtest/alpine/README.md: -------------------------------------------------------------------------------- 1 | This example was generated using the command `helm create alpine`. 2 | 3 | The `templates/` directory contains a very simple pod resource with a 4 | couple of parameters. 5 | 6 | The `values.yaml` file contains the default values for the 7 | `alpine-pod.yaml` template. 8 | 9 | You can install this example using `helm install docs/examples/alpine`. 10 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/signtest/alpine/README.md: -------------------------------------------------------------------------------- 1 | This example was generated using the command `helm create alpine`. 2 | 3 | The `templates/` directory contains a very simple pod resource with a 4 | couple of parameters. 5 | 6 | The `values.yaml` file contains the default values for the 7 | `alpine-pod.yaml` template. 8 | 9 | You can install this example using `helm install docs/examples/alpine`. 10 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/charts/alpine/README.md: -------------------------------------------------------------------------------- 1 | This example was generated using the command `helm create alpine`. 2 | 3 | The `templates/` directory contains a very simple pod resource with a 4 | couple of parameters. 5 | 6 | The `values.toml` file contains the default values for the 7 | `alpine-pod.yaml` template. 8 | 9 | You can install this example using `helm install docs/examples/alpine`. 10 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | Example icon 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/genfrob.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Pack the albatross chart into the mariner chart. 4 | echo "Packing albatross into mariner" 5 | tar -zcvf mariner/charts/albatross-0.1.0.tgz albatross 6 | 7 | echo "Packing mariner into frobnitz" 8 | tar -zcvf frobnitz/charts/mariner-4.3.2.tgz mariner 9 | 10 | # Pack the frobnitz chart. 11 | echo "Packing frobnitz" 12 | tar --exclude=ignore/* -zcvf frobnitz-1.2.3.tgz frobnitz 13 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/chartfiletest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: frobnitz 3 | description: This is a frobnitz. 4 | version: "1.2.3" 5 | keywords: 6 | - frobnitz 7 | - sprocket 8 | - dodad 9 | maintainers: 10 | - name: The Helm Team 11 | email: helm@example.com 12 | - name: Someone Else 13 | email: nobody@example.com 14 | sources: 15 | - https://example.com/foo/bar 16 | home: http://example.com 17 | icon: https://example.com/64x64.png 18 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: frobnitz 3 | description: This is a frobnitz. 4 | version: "1.2.3" 5 | keywords: 6 | - frobnitz 7 | - sprocket 8 | - dodad 9 | maintainers: 10 | - name: The Helm Team 11 | email: helm@example.com 12 | - name: Someone Else 13 | email: nobody@example.com 14 | sources: 15 | - https://example.com/foo/bar 16 | home: http://example.com 17 | icon: https://example.com/64x64.png 18 | -------------------------------------------------------------------------------- /docs/examples/alpine/README.md: -------------------------------------------------------------------------------- 1 | #Alpine: A simple Helm chart 2 | 3 | Run a single pod of Alpine Linux. 4 | 5 | This example was generated using the command `helm create alpine`. 6 | 7 | The `templates/` directory contains a very simple pod resource with a 8 | couple of parameters. 9 | 10 | The `values.yaml` file contains the default values for the 11 | `alpine-pod.yaml` template. 12 | 13 | You can install this example using `helm install docs/examples/alpine`. 14 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/reqtest/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /pkg/repo/repotest/testdata/examplechart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/alpine/README.md: -------------------------------------------------------------------------------- 1 | #Alpine: A simple Helm chart 2 | 3 | Run a single pod of Alpine Linux. 4 | 5 | This example was generated using the command `helm create alpine`. 6 | 7 | The `templates/` directory contains a very simple pod resource with a 8 | couple of parameters. 9 | 10 | The `values.yaml` file contains the default values for the 11 | `alpine-pod.yaml` template. 12 | 13 | You can install this example using `helm install docs/examples/alpine`. 14 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/novals/README.md: -------------------------------------------------------------------------------- 1 | #Alpine: A simple Helm chart 2 | 3 | Run a single pod of Alpine Linux. 4 | 5 | This example was generated using the command `helm create alpine`. 6 | 7 | The `templates/` directory contains a very simple pod resource with a 8 | couple of parameters. 9 | 10 | The `values.yaml` file contains the default values for the 11 | `alpine-pod.yaml` template. 12 | 13 | You can install this example using `helm install docs/examples/alpine`. 14 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/reqtest/charts/reqsubchart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/reqtest/charts/reqsubchart2/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/signtest/alpine/templates/alpine-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: {{.Release.Name}}-{{.Chart.Name}} 5 | labels: 6 | heritage: {{.Release.Service}} 7 | chartName: {{.Chart.Name}} 8 | chartVersion: {{.Chart.Version | quote}} 9 | annotations: 10 | "helm.sh/created": "{{.Release.Time.Seconds}}" 11 | spec: 12 | restartPolicy: {{default "Never" .restart_policy}} 13 | containers: 14 | - name: waiter 15 | image: "alpine:3.3" 16 | command: ["/bin/sleep","9000"] 17 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/signtest/alpine/templates/alpine-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: {{.Release.Name}}-{{.Chart.Name}} 5 | labels: 6 | heritage: {{.Release.Service}} 7 | chartName: {{.Chart.Name}} 8 | chartVersion: {{.Chart.Version | quote}} 9 | annotations: 10 | "helm.sh/created": "{{.Release.Time.Seconds}}" 11 | spec: 12 | restartPolicy: {{default "Never" .restart_policy}} 13 | containers: 14 | - name: waiter 15 | image: "alpine:3.3" 16 | command: ["/bin/sleep","9000"] 17 | -------------------------------------------------------------------------------- /pkg/chartutil/testdata/frobnitz/charts/alpine/templates/alpine-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: {{.Release.Name}}-{{.Chart.Name}} 5 | labels: 6 | heritage: {{.Release.Service}} 7 | chartName: {{.Chart.Name}} 8 | chartVersion: {{.Chart.Version | quote}} 9 | annotations: 10 | "helm.sh/created": "{{.Release.Time.Seconds}}" 11 | spec: 12 | restartPolicy: {{default "Never" .restart_policy}} 13 | containers: 14 | - name: waiter 15 | image: "alpine:3.3" 16 | command: ["/bin/sleep","9000"] 17 | -------------------------------------------------------------------------------- /docs/examples/nginx/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for nginx. 2 | # This is a YAML-formatted file. 3 | # Declare name/value pairs to be passed into your templates. 4 | 5 | # See the list at https://hub.docker.com/r/library/nginx/tags/ 6 | imageTag: "1.11.0" 7 | 8 | # The port (defined on the service) to access the HTTP server. 9 | httpPort: 8888 10 | 11 | # Number of nginx instances to run 12 | replicaCount: 1 13 | 14 | # Evaluated by the post-install hook 15 | sleepyTime: "10" 16 | 17 | index: >- 18 |

Hello

19 |

This is a test

20 | -------------------------------------------------------------------------------- /docs/examples/nginx/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{define "name"}}{{default "nginx" .Values.nameOverride | trunc 24 }}{{end}} 6 | 7 | {{/* 8 | Create a default fully qualified app name. 9 | 10 | We truncate at 24 chars because some Kubernetes name fields are limited to this 11 | (by the DNS naming spec). 12 | */}} 13 | {{define "fullname"}} 14 | {{- $name := default "nginx" .Values.nameOverride -}} 15 | {{printf "%s-%s" .Release.Name $name | trunc 24 -}} 16 | {{end}} 17 | -------------------------------------------------------------------------------- /docs/examples/nginx/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | # This is a simple example of using a config map to create a single page 2 | # static site. 3 | apiVersion: v1 4 | kind: ConfigMap 5 | metadata: 6 | name: {{template "fullname" .}} 7 | labels: 8 | release: {{ .Release.Name | quote }} 9 | app: {{template "fullname" .}} 10 | heritage: {{.Release.Service | quote }} 11 | data: 12 | # When the config map is mounted as a volume, these will be created as 13 | # files. 14 | index.html: {{default "Hello" .Values.index | quote}} 15 | test.txt: test 16 | -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/albatross/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{define "name"}}{{default "nginx" .Values.nameOverride | trunc 24 }}{{end}} 6 | 7 | {{/* 8 | Create a default fully qualified app name. 9 | 10 | We truncate at 24 chars because some Kubernetes name fields are limited to this 11 | (by the DNS naming spec). 12 | */}} 13 | {{define "fullname"}} 14 | {{- $name := default "nginx" .Values.nameOverride -}} 15 | {{printf "%s-%s" .Release.Name $name | trunc 24 -}} 16 | {{end}} 17 | -------------------------------------------------------------------------------- /docs/examples/nginx/templates/pre-install-secret.yaml: -------------------------------------------------------------------------------- 1 | # This shows a secret as a pre-install hook. 2 | # A pre-install hook is run before the rest of the chart is loaded. 3 | apiVersion: v1 4 | kind: Secret 5 | metadata: 6 | name: "{{.Release.Name}}-secret" 7 | # This declares the resource to be a hook. By convention, we also name the 8 | # file "pre-install-XXX.yaml", but Helm itself doesn't care about file names. 9 | annotations: 10 | "helm.sh/hook": pre-install 11 | type: Opaque 12 | data: 13 | password: {{ b64enc "secret" }} 14 | username: {{ b64enc "user1" }} 15 | -------------------------------------------------------------------------------- /docs/examples/nginx/templates/svc.yaml: -------------------------------------------------------------------------------- 1 | # This is a service gateway to the replica set created by the deployment. 2 | # Take a look at the deployment.yaml for general notes about this chart. 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | name: {{template "fullname" .}} 7 | labels: 8 | heritage: {{ .Release.Service | quote }} 9 | release: {{ .Release.Name | quote }} 10 | chart: "{{.Chart.Name}}-{{.Chart.Version}}" 11 | spec: 12 | ports: 13 | - port: {{default 80 .Values.httpPort | quote}} 14 | targetPort: 80 15 | protocol: TCP 16 | name: http 17 | selector: 18 | app: {{template "fullname" .}} 19 | -------------------------------------------------------------------------------- /pkg/lint/rules/testdata/albatross/templates/svc.yaml: -------------------------------------------------------------------------------- 1 | # This is a service gateway to the replica set created by the deployment. 2 | # Take a look at the deployment.yaml for general notes about this chart. 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | name: "{{ .Values.name }}" 7 | labels: 8 | heritage: {{ .Release.Service | quote }} 9 | release: {{ .Release.Name | quote }} 10 | chart: "{{.Chart.Name}}-{{.Chart.Version}}" 11 | spec: 12 | ports: 13 | - port: {{default 80 .Values.httpPort | quote}} 14 | targetPort: 80 15 | protocol: TCP 16 | name: http 17 | selector: 18 | app: {{template "fullname" .}} 19 | -------------------------------------------------------------------------------- /docs/examples/README.md: -------------------------------------------------------------------------------- 1 | # Helm Examples 2 | 3 | This directory contains example charts to help you get started with 4 | chart development. 5 | 6 | ## Alpine 7 | 8 | The `alpine` chart is very simple, and is a good starting point. 9 | 10 | It simply deploys a single pod running Alpine Linux. 11 | 12 | ## Nginx 13 | 14 | The `nginx` chart shows how to compose several resources into one chart, 15 | and it illustrates more complex template usage. 16 | 17 | It deploys a `deployment` (which creates a `replica set`), a `config 18 | map`, and a `service`. The replica set starts an nginx pod. The config 19 | map stores the files that the nginx server can serve. 20 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcache/foobar-index.yaml: -------------------------------------------------------------------------------- 1 | foobar-0.1.0: 2 | url: http://storage.googleapis.com/kubernetes-charts/nginx-0.1.0.tgz 3 | name: foobar 4 | removed: false 5 | chartfile: 6 | name: foobar 7 | description: string 8 | version: 0.1.0 9 | home: https://github.com/foo 10 | keywords: 11 | - dummy 12 | - hokey 13 | oddness-1.2.3: 14 | url: http://storage.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz 15 | name: oddness 16 | removed: false 17 | chartfile: 18 | name: oddness 19 | description: string 20 | version: 1.2.3 21 | home: https://github.com/something 22 | keywords: 23 | - duck 24 | - sumtin 25 | -------------------------------------------------------------------------------- /rootfs/README.md: -------------------------------------------------------------------------------- 1 | # RootFS 2 | 3 | This directory stores all files that should be copied to the rootfs of a 4 | Docker container. The files should be stored according to the correct 5 | directory structure of the destination container. For example: 6 | 7 | ``` 8 | rootfs/bin -> /bin 9 | rootfs/usr/local/share -> /usr/local/share 10 | ``` 11 | 12 | ## Dockerfile 13 | 14 | A Dockerfile in the rootfs is used to build the image. Where possible, 15 | compilation should not be done in this Dockerfile, since we are 16 | interested in deploying the smallest possible images. 17 | 18 | Example: 19 | 20 | ```Dockerfile 21 | FROM alpine:3.2 22 | 23 | COPY . / 24 | 25 | ENTRYPOINT ["/usr/local/bin/boot"] 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcache/local-index.yaml: -------------------------------------------------------------------------------- 1 | nginx-0.1.0: 2 | url: http://storage.googleapis.com/kubernetes-charts/nginx-0.1.0.tgz 3 | name: nginx 4 | removed: false 5 | chartfile: 6 | name: nginx 7 | description: string 8 | version: 0.1.0 9 | home: https://github.com/something 10 | keywords: 11 | - popular 12 | - web server 13 | - proxy 14 | alpine-1.0.0: 15 | url: http://storage.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz 16 | name: alpine 17 | removed: false 18 | chartfile: 19 | name: alpine 20 | description: string 21 | version: 1.0.0 22 | home: https://github.com/something 23 | keywords: 24 | - linux 25 | - alpine 26 | - small 27 | - sumtin 28 | 29 | -------------------------------------------------------------------------------- /rootfs/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2016 The Kubernetes Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FROM alpine:3.3 16 | 17 | COPY . / 18 | 19 | EXPOSE 44134 20 | 21 | CMD ["/tiller"] 22 | 23 | -------------------------------------------------------------------------------- /pkg/version/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package version represents the current version of the project. 18 | package version // import "k8s.io/helm/pkg/version" 19 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/signtest-0.1.0.tgz.prov: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP SIGNED MESSAGE----- 2 | Hash: SHA512 3 | 4 | description: A Helm chart for Kubernetes 5 | name: signtest 6 | version: 0.1.0 7 | 8 | ... 9 | files: 10 | signtest-0.1.0.tgz: sha256:dee72947753628425b82814516bdaa37aef49f25e8820dd2a6e15a33a007823b 11 | -----BEGIN PGP SIGNATURE----- 12 | 13 | wsBcBAEBCgAQBQJXomNHCRCEO7+YH8GHYgAALywIAG1Me852Fpn1GYu8Q1GCcw4g 14 | l2k7vOFchdDwDhdSVbkh4YyvTaIO3iE2Jtk1rxw+RIJiUr0eLO/rnIJuxZS8WKki 15 | DR1LI9J1VD4dxN3uDETtWDWq7ScoPsRY5mJvYZXC8whrWEt/H2kfqmoA9LloRPWp 16 | flOE0iktA4UciZOblTj6nAk3iDyjh/4HYL4a6tT0LjjKI7OTw4YyHfjHad1ywVCz 17 | 9dMUc1rPgTnl+fnRiSPSrlZIWKOt1mcQ4fVrU3nwtRUwTId2k8FtygL0G6M+Y6t0 18 | S6yaU7qfk9uTxkdkUF7Bf1X3ukxfe+cNBC32vf4m8LY4NkcYfSqK2fGtQsnVr6s= 19 | =NyOM 20 | -----END PGP SIGNATURE----- -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/signtest-0.1.0.tgz.prov: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP SIGNED MESSAGE----- 2 | Hash: SHA512 3 | 4 | description: A Helm chart for Kubernetes 5 | name: signtest 6 | version: 0.1.0 7 | 8 | ... 9 | files: 10 | signtest-0.1.0.tgz: sha256:dee72947753628425b82814516bdaa37aef49f25e8820dd2a6e15a33a007823b 11 | -----BEGIN PGP SIGNATURE----- 12 | 13 | wsBcBAEBCgAQBQJXomNHCRCEO7+YH8GHYgAALywIAG1Me852Fpn1GYu8Q1GCcw4g 14 | l2k7vOFchdDwDhdSVbkh4YyvTaIO3iE2Jtk1rxw+RIJiUr0eLO/rnIJuxZS8WKki 15 | DR1LI9J1VD4dxN3uDETtWDWq7ScoPsRY5mJvYZXC8whrWEt/H2kfqmoA9LloRPWp 16 | flOE0iktA4UciZOblTj6nAk3iDyjh/4HYL4a6tT0LjjKI7OTw4YyHfjHad1ywVCz 17 | 9dMUc1rPgTnl+fnRiSPSrlZIWKOt1mcQ4fVrU3nwtRUwTId2k8FtygL0G6M+Y6t0 18 | S6yaU7qfk9uTxkdkUF7Bf1X3ukxfe+cNBC32vf4m8LY4NkcYfSqK2fGtQsnVr6s= 19 | =NyOM 20 | -----END PGP SIGNATURE----- -------------------------------------------------------------------------------- /pkg/provenance/testdata/msgblock.yaml.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP SIGNED MESSAGE----- 2 | Hash: SHA512 3 | 4 | description: Test chart versioning 5 | name: hashtest 6 | version: 1.2.3 7 | 8 | ... 9 | files: 10 | hashtest-1.2.3.tgz: sha256:8e90e879e2a04b1900570e1c198755e46e4706d70b0e79f5edabfac7900e4e75 11 | -----BEGIN PGP SIGNATURE----- 12 | Comment: GPGTools - https://gpgtools.org 13 | 14 | iQEcBAEBCgAGBQJXlp8KAAoJEIQ7v5gfwYdiE7sIAJYDiza+asekeooSXLvQiK+G 15 | PKnveqQpx49EZ6L7Y7UlW25SyH8EjXXHeJysDywCXF3w4luxN9n56ffU0KEW11IY 16 | F+JSjmgIWLS6ti7ZAGEi6JInQ/30rOAIpTEBRBL2IueW3m63mezrGK6XkBlGqpor 17 | C9WKeqLi+DWlMoBtsEy3Uk0XP6pn/qBFICYAbLQQU0sCCUT8CBA8f8aidxi7aw9t 18 | i404yYF+Dvc6i4JlSG77SV0ZJBWllUvsWoCd9Jli0NAuaMqmE7mzcEt/dE+Fm2Ql 19 | Bx3tr1WS4xTRiFQdcOttOl93H+OaHTh+Y0qqLTzzpCvqmttG0HfI6lMeCs7LeyA= 20 | =vEK+ 21 | -----END PGP SIGNATURE----- 22 | -------------------------------------------------------------------------------- /pkg/repo/repotest/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | /*Package repotest provides utilities for testing. 17 | 18 | The server provides a testing server that can be set up and torn down quickly. 19 | */ 20 | package repotest 21 | -------------------------------------------------------------------------------- /pkg/provenance/testdata/msgblock.yaml.tampered: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP SIGNED MESSAGE----- 2 | Hash: SHA512 3 | 4 | description: Test chart versioning 5 | name: hashtest 6 | version: 1.2.3+tampered 7 | 8 | ... 9 | files: 10 | hashtest-1.2.3.tgz: sha256:8e90e879e2a04b1900570e1c198755e46e4706d70b0e79f5edabfac7900e4e75 11 | -----BEGIN PGP SIGNATURE----- 12 | Comment: GPGTools - https://gpgtools.org 13 | 14 | iQEcBAEBCgAGBQJXlp8KAAoJEIQ7v5gfwYdiE7sIAJYDiza+asekeooSXLvQiK+G 15 | PKnveqQpx49EZ6L7Y7UlW25SyH8EjXXHeJysDywCXF3w4luxN9n56ffU0KEW11IY 16 | F+JSjmgIWLS6ti7ZAGEi6JInQ/30rOAIpTEBRBL2IueW3m63mezrGK6XkBlGqpor 17 | C9WKeqLi+DWlMoBtsEy3Uk0XP6pn/qBFICYAbLQQU0sCCUT8CBA8f8aidxi7aw9t 18 | i404yYF+Dvc6i4JlSG77SV0ZJBWllUvsWoCd9Jli0NAuaMqmE7mzcEt/dE+Fm2Ql 19 | Bx3tr1WS4xTRiFQdcOttOl93H+OaHTh+Y0qqLTzzpCvqmttG0HfI6lMeCs7LeyA= 20 | =vEK+ 21 | -----END PGP SIGNATURE----- 22 | -------------------------------------------------------------------------------- /pkg/lint/support/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /*Package support contains tools for linting charts. 18 | 19 | Linting is the process of testing charts for errors or warnings regarding 20 | formatting, compilation, or standards compliance. 21 | */ 22 | package support // import "k8s.io/helm/pkg/lint/support" 23 | -------------------------------------------------------------------------------- /pkg/storage/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | Package storage implements storage for Tiller objects.The backend storage 19 | mechanism may be implemented with different backends. This package and its 20 | subpackages provide storage layers for Tiller objects. 21 | */ 22 | package storage // import "k8s.io/helm/pkg/storage" 23 | -------------------------------------------------------------------------------- /_proto/hapi/version/version.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Kubernetes Authors All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package hapi.version; 18 | 19 | option go_package = "version"; 20 | 21 | message Version { 22 | // Sem ver string for the version 23 | string sem_ver = 1; 24 | string git_commit = 2; 25 | string git_tree_state = 3; 26 | } 27 | -------------------------------------------------------------------------------- /pkg/kube/tunnel_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package kube 18 | 19 | import ( 20 | "testing" 21 | ) 22 | 23 | func TestAvailablePort(t *testing.T) { 24 | port, err := getAvailablePort() 25 | if err != nil { 26 | t.Fatal(err) 27 | } 28 | if port < 1 { 29 | t.Fatalf("generated port should be > 1, got %d", port) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /pkg/kube/log.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package kube 18 | 19 | import ( 20 | "flag" 21 | "fmt" 22 | "os" 23 | ) 24 | 25 | func init() { 26 | if level := os.Getenv("KUBE_LOG_LEVEL"); level != "" { 27 | flag.Set("vmodule", fmt.Sprintf("loader=%s,round_trippers=%s,request=%s", level, level, level)) 28 | flag.Set("logtostderr", "true") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pkg/engine/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /*Package engine implements the Go template engine as a Tiller Engine. 18 | 19 | Tiller provides a simple interface for taking a Chart and rendering its templates. 20 | The 'engine' package implements this interface using Go's built-in 'text/template' 21 | package. 22 | */ 23 | package engine // import "k8s.io/helm/pkg/engine" 24 | -------------------------------------------------------------------------------- /pkg/timeconv/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /*Package timeconv contains utilities for converting time. 18 | 19 | The gRPC/Protobuf libraries contain time implementations that require conversion 20 | to and from Go times. This library provides utilities and convenience functions 21 | for performing conversions. 22 | */ 23 | package timeconv // import "k8s.io/helm/pkg/timeconv" 24 | -------------------------------------------------------------------------------- /cmd/helm/downloader/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | /*Package downloader provides a library for downloading charts. 17 | 18 | This package contains various tools for downloading charts from repository 19 | servers, and then storing them in Helm-specific directory structures (like 20 | HELM_HOME). This library contains many functions that depend on a specific 21 | filesystem layout. 22 | */ 23 | package downloader 24 | -------------------------------------------------------------------------------- /_proto/hapi/chart/config.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Kubernetes Authors All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package hapi.chart; 18 | 19 | option go_package = "chart"; 20 | 21 | // Config supplies values to the parametrizable templates of a chart. 22 | message Config { 23 | string raw = 1; 24 | 25 | map values = 2; 26 | } 27 | 28 | // Value describes a configuration value as a string. 29 | message Value { 30 | string value = 1; 31 | } 32 | -------------------------------------------------------------------------------- /cmd/helm/lint_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "testing" 21 | ) 22 | 23 | var ( 24 | archivedChartPath = "testdata/testcharts/compressedchart-0.1.0.tgz" 25 | chartDirPath = "testdata/testcharts/decompressedchart/" 26 | ) 27 | 28 | func TestLintChart(t *testing.T) { 29 | if _, err := lintChart(chartDirPath); err != nil { 30 | t.Errorf("%s", err) 31 | } 32 | 33 | if _, err := lintChart(archivedChartPath); err != nil { 34 | t.Errorf("%s", err) 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /_proto/hapi/chart/template.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Kubernetes Authors All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package hapi.chart; 18 | 19 | option go_package = "chart"; 20 | 21 | // Template represents a template as a name/value pair. 22 | // 23 | // By convention, name is a relative path within the scope of the chart's 24 | // base directory. 25 | message Template { 26 | // Name is the path-like name of the template. 27 | string name = 1; 28 | 29 | // Data is the template as byte data. 30 | bytes data = 2; 31 | } 32 | -------------------------------------------------------------------------------- /cmd/tiller/probes.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "net/http" 21 | ) 22 | 23 | func readinessProbe(w http.ResponseWriter, r *http.Request) { 24 | w.WriteHeader(http.StatusOK) 25 | } 26 | 27 | func livenessProbe(w http.ResponseWriter, r *http.Request) { 28 | w.WriteHeader(http.StatusOK) 29 | } 30 | 31 | func newProbesMux() *http.ServeMux { 32 | mux := http.NewServeMux() 33 | mux.HandleFunc("/readiness", readinessProbe) 34 | mux.HandleFunc("/liveness", livenessProbe) 35 | return mux 36 | } 37 | -------------------------------------------------------------------------------- /pkg/chartutil/requirements_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | package chartutil 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestLoadRequirements(t *testing.T) { 22 | c, err := Load("testdata/frobnitz") 23 | if err != nil { 24 | t.Fatalf("Failed to load testdata: %s", err) 25 | } 26 | verifyRequirements(t, c) 27 | } 28 | 29 | func TestLoadRequirementsLock(t *testing.T) { 30 | c, err := Load("testdata/frobnitz") 31 | if err != nil { 32 | t.Fatalf("Failed to load testdata: %s", err) 33 | } 34 | verifyRequirementsLock(t, c) 35 | } 36 | -------------------------------------------------------------------------------- /_proto/hapi/release/info.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Kubernetes Authors All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package hapi.release; 18 | 19 | import "google/protobuf/timestamp.proto"; 20 | import "hapi/release/status.proto"; 21 | 22 | option go_package = "release"; 23 | 24 | // Info describes release information. 25 | message Info { 26 | Status status = 1; 27 | 28 | google.protobuf.Timestamp first_deployed = 2; 29 | 30 | google.protobuf.Timestamp last_deployed = 3; 31 | 32 | // Deleted tracks when this object was deleted. 33 | google.protobuf.Timestamp deleted = 4; 34 | } 35 | -------------------------------------------------------------------------------- /pkg/lint/lint.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package lint // import "k8s.io/helm/pkg/lint" 18 | 19 | import ( 20 | "path/filepath" 21 | 22 | "k8s.io/helm/pkg/lint/rules" 23 | "k8s.io/helm/pkg/lint/support" 24 | ) 25 | 26 | // All runs all of the available linters on the given base directory. 27 | func All(basedir string) support.Linter { 28 | // Using abs path to get directory context 29 | chartDir, _ := filepath.Abs(basedir) 30 | 31 | linter := support.Linter{ChartDir: chartDir} 32 | rules.Chartfile(&linter) 33 | rules.Values(&linter) 34 | rules.Templates(&linter) 35 | return linter 36 | } 37 | -------------------------------------------------------------------------------- /cmd/helm/home.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | 23 | "github.com/spf13/cobra" 24 | ) 25 | 26 | var longHomeHelp = ` 27 | This command displays the location of HELM_HOME. This is where 28 | any helm configuration files live. 29 | ` 30 | 31 | func newHomeCmd(out io.Writer) *cobra.Command { 32 | cmd := &cobra.Command{ 33 | Use: "home", 34 | Short: "displays the location of HELM_HOME", 35 | Long: longHomeHelp, 36 | Run: func(cmd *cobra.Command, args []string) { 37 | fmt.Fprintf(out, homePath()+"\n") 38 | }, 39 | } 40 | return cmd 41 | } 42 | -------------------------------------------------------------------------------- /pkg/repo/testdata/local-index.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | entries: 3 | nginx: 4 | - urls: 5 | - http://storage.googleapis.com/kubernetes-charts/nginx-0.1.0.tgz 6 | name: nginx 7 | description: string 8 | version: 0.1.0 9 | home: https://github.com/something 10 | digest: "sha256:1234567890abcdef" 11 | keywords: 12 | - popular 13 | - web server 14 | - proxy 15 | - urls: 16 | - http://storage.googleapis.com/kubernetes-charts/nginx-0.2.0.tgz 17 | name: nginx 18 | description: string 19 | version: 0.2.0 20 | home: https://github.com/something/else 21 | digest: "sha256:1234567890abcdef" 22 | keywords: 23 | - popular 24 | - web server 25 | - proxy 26 | alpine: 27 | - urls: 28 | - http://storage.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz 29 | - http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz 30 | name: alpine 31 | description: string 32 | version: 1.0.0 33 | home: https://github.com/something 34 | keywords: 35 | - linux 36 | - alpine 37 | - small 38 | - sumtin 39 | digest: "sha256:1234567890abcdef" 40 | 41 | -------------------------------------------------------------------------------- /cmd/helm/helmpath/helmhome_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | package helmpath 17 | 18 | import ( 19 | "testing" 20 | ) 21 | 22 | func TestHelmHome(t *testing.T) { 23 | hh := Home("/r") 24 | isEq := func(t *testing.T, a, b string) { 25 | if a != b { 26 | t.Errorf("Expected %q, got %q", a, b) 27 | } 28 | } 29 | 30 | isEq(t, hh.String(), "/r") 31 | isEq(t, hh.Repository(), "/r/repository") 32 | isEq(t, hh.RepositoryFile(), "/r/repository/repositories.yaml") 33 | isEq(t, hh.LocalRepository(), "/r/repository/local") 34 | isEq(t, hh.Cache(), "/r/repository/cache") 35 | isEq(t, hh.CacheIndex("t"), "/r/repository/cache/t-index.yaml") 36 | } 37 | -------------------------------------------------------------------------------- /docs/examples/alpine/templates/alpine-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{.Release.Name}}-{{.Values.Name}}" 5 | labels: 6 | # The "heritage" label is used to track which tool deployed a given chart. 7 | # It is useful for admins who want to see what releases a particular tool 8 | # is responsible for. 9 | heritage: {{.Release.Service | quote }} 10 | # The "release" convention makes it easy to tie a release to all of the 11 | # Kubernetes resources that were created as part of that release. 12 | release: {{.Release.Name | quote }} 13 | # This makes it easy to audit chart usage. 14 | chart: "{{.Chart.Name}}-{{.Chart.Version}}" 15 | annotations: 16 | "helm.sh/created": {{.Release.Time.Seconds | quote }} 17 | spec: 18 | # This shows how to use a simple value. This will look for a passed-in value 19 | # called restartPolicy. If it is not found, it will use the default value. 20 | # {{default "Never" .restartPolicy}} is a slightly optimized version of the 21 | # more conventional syntax: {{.restartPolicy | default "Never"}} 22 | restartPolicy: {{default "Never" .Values.restartPolicy}} 23 | containers: 24 | - name: waiter 25 | image: "alpine:3.3" 26 | command: ["/bin/sleep","9000"] 27 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/alpine/templates/alpine-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{.Release.Name}}-{{.Values.Name}}" 5 | labels: 6 | # The "heritage" label is used to track which tool deployed a given chart. 7 | # It is useful for admins who want to see what releases a particular tool 8 | # is responsible for. 9 | heritage: {{.Release.Service | quote }} 10 | # The "release" convention makes it easy to tie a release to all of the 11 | # Kubernetes resources that were created as part of that release. 12 | release: {{.Release.Name | quote }} 13 | # This makes it easy to audit chart usage. 14 | chart: "{{.Chart.Name}}-{{.Chart.Version}}" 15 | annotations: 16 | "helm.sh/created": {{.Release.Time.Seconds | quote }} 17 | spec: 18 | # This shows how to use a simple value. This will look for a passed-in value 19 | # called restartPolicy. If it is not found, it will use the default value. 20 | # {{default "Never" .restartPolicy}} is a slightly optimized version of the 21 | # more conventional syntax: {{.restartPolicy | default "Never"}} 22 | restartPolicy: {{default "Never" .Values.restartPolicy}} 23 | containers: 24 | - name: waiter 25 | image: "alpine:3.3" 26 | command: ["/bin/sleep","9000"] 27 | -------------------------------------------------------------------------------- /cmd/helm/testdata/testcharts/novals/templates/alpine-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{.Release.Name}}-{{.Values.Name}}" 5 | labels: 6 | # The "heritage" label is used to track which tool deployed a given chart. 7 | # It is useful for admins who want to see what releases a particular tool 8 | # is responsible for. 9 | heritage: {{.Release.Service | quote }} 10 | # The "release" convention makes it easy to tie a release to all of the 11 | # Kubernetes resources that were created as part of that release. 12 | release: {{.Release.Name | quote }} 13 | # This makes it easy to audit chart usage. 14 | chart: "{{.Chart.Name}}-{{.Chart.Version}}" 15 | annotations: 16 | "helm.sh/created": {{.Release.Time.Seconds | quote }} 17 | spec: 18 | # This shows how to use a simple value. This will look for a passed-in value 19 | # called restartPolicy. If it is not found, it will use the default value. 20 | # {{default "Never" .restartPolicy}} is a slightly optimized version of the 21 | # more conventional syntax: {{.restartPolicy | default "Never"}} 22 | restartPolicy: {{default "Never" .Values.restartPolicy}} 23 | containers: 24 | - name: waiter 25 | image: "alpine:3.3" 26 | command: ["/bin/sleep","9000"] 27 | -------------------------------------------------------------------------------- /cmd/helm/get_hooks_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "io" 21 | "testing" 22 | 23 | "github.com/spf13/cobra" 24 | ) 25 | 26 | func TestGetHooks(t *testing.T) { 27 | tests := []releaseCase{ 28 | { 29 | name: "get hooks with release", 30 | args: []string{"aeneas"}, 31 | expected: mockHookTemplate, 32 | resp: releaseMock(&releaseOptions{name: "aeneas"}), 33 | }, 34 | { 35 | name: "get hooks without args", 36 | args: []string{}, 37 | err: true, 38 | }, 39 | } 40 | runReleaseCases(t, tests, func(c *fakeReleaseClient, out io.Writer) *cobra.Command { 41 | return newGetHooksCmd(c, out) 42 | }) 43 | } 44 | -------------------------------------------------------------------------------- /cmd/helm/get_manifest_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "io" 21 | "testing" 22 | 23 | "github.com/spf13/cobra" 24 | ) 25 | 26 | func TestGetManifest(t *testing.T) { 27 | tests := []releaseCase{ 28 | { 29 | name: "get manifest with release", 30 | args: []string{"juno"}, 31 | expected: mockManifest, 32 | resp: releaseMock(&releaseOptions{name: "juno"}), 33 | }, 34 | { 35 | name: "get manifest without args", 36 | args: []string{}, 37 | err: true, 38 | }, 39 | } 40 | runReleaseCases(t, tests, func(c *fakeReleaseClient, out io.Writer) *cobra.Command { 41 | return newGetManifestCmd(c, out) 42 | }) 43 | } 44 | -------------------------------------------------------------------------------- /scripts/validate-license.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2016 The Kubernetes Authors All rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | set -euo pipefail 17 | IFS=$'\n\t' 18 | 19 | find_files() { 20 | find . -not \( \ 21 | \( \ 22 | -wholename './vendor' \ 23 | -o -wholename './pkg/proto' \ 24 | -o -wholename '*testdata*' \ 25 | \) -prune \ 26 | \) \ 27 | \( -name '*.go' -o -name '*.sh' -o -name 'Dockerfile' \) 28 | } 29 | 30 | failed=($(find_files | xargs grep -L 'Licensed under the Apache License, Version 2.0 (the "License");')) 31 | if (( ${#failed[@]} > 0 )); then 32 | echo "Some source files are missing license headers." 33 | for f in "${failed[@]}"; do 34 | echo " $f" 35 | done 36 | exit 1 37 | fi 38 | -------------------------------------------------------------------------------- /cmd/helm/get_values_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "io" 21 | "testing" 22 | 23 | "github.com/spf13/cobra" 24 | ) 25 | 26 | func TestGetValuesCmd(t *testing.T) { 27 | tests := []releaseCase{ 28 | { 29 | name: "get values with a release", 30 | resp: releaseMock(&releaseOptions{name: "thomas-guide"}), 31 | args: []string{"thomas-guide"}, 32 | expected: "name: \"value\"", 33 | }, 34 | { 35 | name: "get values requires release name arg", 36 | err: true, 37 | }, 38 | } 39 | cmd := func(c *fakeReleaseClient, out io.Writer) *cobra.Command { 40 | return newGetValuesCmd(c, out) 41 | } 42 | runReleaseCases(t, tests, cmd) 43 | } 44 | -------------------------------------------------------------------------------- /docs/examples/nginx/templates/post-install-job.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: "{{template "fullname" . }}" 5 | labels: 6 | heritage: {{.Release.Service | quote }} 7 | release: {{.Release.Name | quote }} 8 | chart: "{{.Chart.Name}}-{{.Chart.Version}}" 9 | annotations: 10 | # This is what defines this resource as a hook. Without this line, the 11 | # job is considered part of the release. 12 | "helm.sh/hook": post-install 13 | spec: 14 | template: 15 | metadata: 16 | name: "{{template "fullname" . }}" 17 | labels: 18 | heritage: {{.Release.Service | quote }} 19 | release: {{.Release.Name | quote }} 20 | chart: "{{.Chart.Name}}-{{.Chart.Version}}" 21 | spec: 22 | # This shows how to use a simple value. This will look for a passed-in value 23 | # called restartPolicy. If it is not found, it will use the default value. 24 | # {{default "Never" .restartPolicy}} is a slightly optimized version of the 25 | # more conventional syntax: {{.restartPolicy | default "Never"}} 26 | restartPolicy: Never 27 | containers: 28 | - name: post-install-job 29 | image: "alpine:3.3" 30 | # All we're going to do is sleep for a minute, then exit. 31 | command: ["/bin/sleep","{{default "10" .Values.sleepyTime}}"] 32 | -------------------------------------------------------------------------------- /scripts/ci.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2016 The Kubernetes Authors All rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # Bash 'Strict Mode' 18 | # http://redsymbol.net/articles/unofficial-bash-strict-mode 19 | set -euo pipefail 20 | IFS=$'\n\t' 21 | 22 | HELM_ROOT="${BASH_SOURCE[0]%/*}/.." 23 | cd "$HELM_ROOT" 24 | 25 | run_unit_test() { 26 | if [[ "${CIRCLE_BRANCH-}" == "master" ]]; then 27 | echo "Running unit tests with coverage'" 28 | ./scripts/coverage.sh --coveralls 29 | else 30 | echo "Running unit tests'" 31 | make test-unit 32 | fi 33 | } 34 | 35 | run_style_check() { 36 | echo "Running 'make test-style'" 37 | make test-style 38 | } 39 | 40 | case "${CIRCLE_NODE_INDEX-0}" in 41 | 0) run_unit_test ;; 42 | 1) run_style_check ;; 43 | esac 44 | -------------------------------------------------------------------------------- /cmd/helm/rollback_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "io" 21 | "testing" 22 | 23 | "github.com/spf13/cobra" 24 | ) 25 | 26 | func TestRollbackCmd(t *testing.T) { 27 | 28 | tests := []releaseCase{ 29 | { 30 | name: "rollback a release", 31 | args: []string{"funny-honey"}, 32 | flags: []string{"revision", "1"}, 33 | expected: "Rollback was a success! Happy Helming!", 34 | }, 35 | { 36 | name: "rollback a release without version", 37 | args: []string{"funny-honey"}, 38 | expected: "Rollback was a success! Happy Helming!", 39 | }, 40 | } 41 | 42 | cmd := func(c *fakeReleaseClient, out io.Writer) *cobra.Command { 43 | return newRollbackCmd(c, out) 44 | } 45 | 46 | runReleaseCases(t, tests, cmd) 47 | 48 | } 49 | -------------------------------------------------------------------------------- /pkg/version/compatible.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package version // import "k8s.io/helm/pkg/version" 18 | 19 | import ( 20 | "fmt" 21 | 22 | "github.com/Masterminds/semver" 23 | ) 24 | 25 | // IsCompatible tests if a client and server version are compatible. 26 | func IsCompatible(client, server string) bool { 27 | cv, err := semver.NewVersion(client) 28 | if err != nil { 29 | return false 30 | } 31 | sv, err := semver.NewVersion(server) 32 | if err != nil { 33 | return false 34 | } 35 | 36 | constraint := fmt.Sprintf("^%d.%d.x", cv.Major(), cv.Minor()) 37 | if cv.Prerelease() != "" || sv.Prerelease() != "" { 38 | constraint = cv.String() 39 | } 40 | 41 | c, err := semver.NewConstraint(constraint) 42 | if err != nil { 43 | return false 44 | } 45 | return c.Check(sv) 46 | } 47 | -------------------------------------------------------------------------------- /cmd/tiller/tiller_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "testing" 21 | 22 | "k8s.io/helm/cmd/tiller/environment" 23 | "k8s.io/helm/pkg/engine" 24 | ) 25 | 26 | // These are canary tests to make sure that the default server actually 27 | // fulfills its requirements. 28 | var _ environment.Engine = &engine.Engine{} 29 | 30 | func TestInit(t *testing.T) { 31 | defer func() { 32 | if recover() != nil { 33 | t.Fatalf("Panic trapped. Check EngineYard.Default()") 34 | } 35 | }() 36 | 37 | // This will panic if it is not correct. 38 | env.EngineYard.Default() 39 | 40 | e, ok := env.EngineYard.Get(environment.GoTplEngine) 41 | if !ok { 42 | t.Fatalf("Could not find GoTplEngine") 43 | } 44 | if e == nil { 45 | t.Fatalf("Template engine GoTplEngine returned nil.") 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /versioning.mk: -------------------------------------------------------------------------------- 1 | MUTABLE_VERSION ?= canary 2 | 3 | GIT_COMMIT := $(shell git rev-parse HEAD) 4 | GIT_SHA := $(shell git rev-parse --short HEAD) 5 | GIT_TAG := $(shell git describe --tags --abbrev=0 2>/dev/null) 6 | GIT_DIRTY = $(shell test -n "`git status --porcelain`" && echo "dirty" || echo "clean") 7 | 8 | ifdef VERSION 9 | DOCKER_VERSION = $(VERSION) 10 | BINARY_VERSION = $(VERSION) 11 | endif 12 | 13 | DOCKER_VERSION ?= git-${GIT_SHA} 14 | BINARY_VERSION ?= ${GIT_TAG}-${GIT_SHA} 15 | 16 | IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${DOCKER_VERSION} 17 | MUTABLE_IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${MUTABLE_VERSION} 18 | 19 | LDFLAGS += -X k8s.io/helm/pkg/version.Version=${GIT_TAG} 20 | LDFLAGS += -X k8s.io/helm/pkg/version.GitCommit=${GIT_COMMIT} 21 | LDFLAGS += -X k8s.io/helm/pkg/version.GitTreeState=${GIT_DIRTY} 22 | 23 | DOCKER_PUSH = docker push 24 | ifeq ($(DOCKER_REGISTRY),gcr.io) 25 | DOCKER_PUSH = gcloud docker push 26 | endif 27 | 28 | info: 29 | @echo "Build tag: ${DOCKER_VERSION}" 30 | @echo "Registry: ${DOCKER_REGISTRY}" 31 | @echo "Immutable tag: ${IMAGE}" 32 | @echo "Mutable tag: ${MUTABLE_IMAGE}" 33 | 34 | .PHONY: docker-push 35 | docker-push: docker-mutable-push docker-immutable-push 36 | 37 | .PHONY: docker-immutable-push 38 | docker-immutable-push: 39 | ${DOCKER_PUSH} ${IMAGE} 40 | 41 | .PHONY: docker-mutable-push 42 | docker-mutable-push: 43 | ${DOCKER_PUSH} ${MUTABLE_IMAGE} 44 | -------------------------------------------------------------------------------- /cmd/helm/get_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "io" 21 | "testing" 22 | 23 | "github.com/spf13/cobra" 24 | ) 25 | 26 | func TestGetCmd(t *testing.T) { 27 | tests := []releaseCase{ 28 | { 29 | name: "get with a release", 30 | resp: releaseMock(&releaseOptions{name: "thomas-guide"}), 31 | args: []string{"thomas-guide"}, 32 | expected: "REVISION: 1\nRELEASED: (.*)\nCHART: foo-0.1.0-beta.1\nUSER-SUPPLIED VALUES:\nname: \"value\"\nCOMPUTED VALUES:\nname: value\n\nHOOKS:\n---\n# pre-install-hook\n" + mockHookTemplate + "\nMANIFEST:", 33 | }, 34 | { 35 | name: "get requires release name arg", 36 | err: true, 37 | }, 38 | } 39 | 40 | cmd := func(c *fakeReleaseClient, out io.Writer) *cobra.Command { 41 | return newGetCmd(c, out) 42 | } 43 | runReleaseCases(t, tests, cmd) 44 | } 45 | -------------------------------------------------------------------------------- /cmd/tiller/probes_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "net/http" 21 | "net/http/httptest" 22 | "testing" 23 | ) 24 | 25 | func TestProbesServer(t *testing.T) { 26 | mux := newProbesMux() 27 | srv := httptest.NewServer(mux) 28 | defer srv.Close() 29 | resp, err := http.Get(srv.URL + "/readiness") 30 | if err != nil { 31 | t.Fatalf("GET /readiness returned an error (%s)", err) 32 | } 33 | if resp.StatusCode != http.StatusOK { 34 | t.Fatalf("GET /readiness returned status code %d, expected %d", resp.StatusCode, http.StatusOK) 35 | } 36 | 37 | resp, err = http.Get(srv.URL + "/liveness") 38 | if err != nil { 39 | t.Fatalf("GET /liveness returned an error (%s)", err) 40 | } 41 | if resp.StatusCode != http.StatusOK { 42 | t.Fatalf("GET /liveness returned status code %d, expected %d", resp.StatusCode, http.StatusOK) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /pkg/storage/driver/labels_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package driver // import "k8s.io/helm/pkg/storage/driver" 18 | 19 | import ( 20 | "testing" 21 | ) 22 | 23 | func TestLabelsMatch(t *testing.T) { 24 | var tests = []struct { 25 | desc string 26 | set1 labels 27 | set2 labels 28 | expect bool 29 | }{ 30 | { 31 | "equal labels sets", 32 | labels(map[string]string{"KEY_A": "VAL_A", "KEY_B": "VAL_B"}), 33 | labels(map[string]string{"KEY_A": "VAL_A", "KEY_B": "VAL_B"}), 34 | true, 35 | }, 36 | { 37 | "disjoint label sets", 38 | labels(map[string]string{"KEY_C": "VAL_C", "KEY_D": "VAL_D"}), 39 | labels(map[string]string{"KEY_A": "VAL_A", "KEY_B": "VAL_B"}), 40 | false, 41 | }, 42 | } 43 | 44 | for _, tt := range tests { 45 | if !tt.set1.match(tt.set2) && tt.expect { 46 | t.Fatalf("Expected match '%s'\n", tt.desc) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pkg/version/compatible_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package version represents the current version of the project. 18 | package version // import "k8s.io/helm/pkg/version" 19 | 20 | import "testing" 21 | 22 | func TestIsCompatible(t *testing.T) { 23 | tests := []struct { 24 | client string 25 | server string 26 | expected bool 27 | }{ 28 | {"v2.0.0-alpha.4", "v2.0.0-alpha.4", true}, 29 | {"v2.0.0-alpha.3", "v2.0.0-alpha.4", false}, 30 | {"v2.0.0", "v2.0.0-alpha.4", false}, 31 | {"v2.0.0-alpha.4", "v2.0.0", false}, 32 | {"v2.0.0", "v2.0.1", true}, 33 | {"v2.0.1", "v2.0.0", true}, 34 | {"v2.0.0", "v2.1.1", true}, 35 | {"v2.1.0", "v2.0.1", false}, 36 | } 37 | 38 | for _, tt := range tests { 39 | if IsCompatible(tt.client, tt.server) != tt.expected { 40 | t.Errorf("expected client(%s) and server(%s) to be %v", tt.client, tt.server, tt.expected) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /docs/examples/nginx/README.md: -------------------------------------------------------------------------------- 1 | # nginx: An advanced example chart 2 | 3 | This Helm chart provides examples of some of Helm's more powerful 4 | features. 5 | 6 | **This is not a production-grade chart. It is an example.** 7 | 8 | The chart installs a simple nginx server according to the following 9 | pattern: 10 | 11 | - A `ConfigMap` is used to store the files the server will serve. 12 | ([templates/configmap.yaml](templates/configmap.yaml)) 13 | - A `Deployment` is used to create a Replica Set of nginx pods. 14 | ([templates/deployment.yaml](templates/deployment.yaml)) 15 | - A `Service` is used to create a gateway to the pods running in the 16 | replica set ([templates/svc.yaml](templates/svc.yaml)) 17 | 18 | The [values.yaml](values.yaml) exposes a few of the configuration options in the 19 | charts, though there are some that are not exposed there (like 20 | `.image`). 21 | 22 | The [templates/_helpers.tpl](templates/_helpers.tpl) file contains helper templates. The leading 23 | underscore (`_`) on the filename is semantic. It tells the template renderer 24 | that this file does not contain a manifest. That file declares some 25 | templates that are used elsewhere in the chart. 26 | 27 | Helpers (usually called "partials" in template languages) are an 28 | advanced way for developers to structure their templates for optimal 29 | reuse. 30 | 31 | You can deploy this chart with `helm install docs/examples/nginx`. Or 32 | you can see how this chart would render with `helm install --dry-run 33 | --debug docs/examples/nginx`. 34 | -------------------------------------------------------------------------------- /docs/history.md: -------------------------------------------------------------------------------- 1 | ## The History of the Project 2 | 3 | Kubernetes Helm is the merged result of [Helm 4 | Classic](https://github.com/helm/helm) and the Kubernetes port of GCS Deployment 5 | Manager. The project was jointly started by Google and Deis, though it 6 | is now part of the CNCF. 7 | 8 | Differences from Helm Classic: 9 | 10 | - Helm now has both a client (`helm`) and a server (`tiller`). The 11 | server runs inside of Kubernetes, and manages your resources. 12 | - Helm's chart format has changed for the better: 13 | - Dependencies are immutable and stored inside of a chart's `charts/` 14 | directory. 15 | - Charts are strongly versioned using [SemVer 2](http://semver.org/spec/v2.0.0.html) 16 | - Charts can be loaded from directories or from chart archive files 17 | - Helm supports Go templates without requiring you to run `generate` 18 | or `template` commands. 19 | - Helm makes it easy to configure your releases -- and share the 20 | configuration with the rest of your team. 21 | - Helm chart repositories now use plain HTTP instead of Git/GitHub. 22 | There is no longer any GitHub dependency. 23 | - A chart server is a simple HTTP server 24 | - Charts are referenced by version 25 | - The `helm serve` command will run a local chart server, though you 26 | can easily use object storage (S3, GCS) or a regular web server. 27 | - And you can still load charts from a local directory. 28 | - The Helm workspace is gone. You can now work anywhere on your 29 | filesystem that you want to work. 30 | -------------------------------------------------------------------------------- /cmd/helm/repo.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "io" 21 | 22 | "github.com/spf13/cobra" 23 | ) 24 | 25 | var repoHelm = ` 26 | This command consists of multiple subcommands to interact with chart repositories. 27 | 28 | It can be used to add, remove, list, and index chart repositories. 29 | Example usage: 30 | $ helm repo add [NAME] [REPO_URL] 31 | ` 32 | 33 | type repoCmd struct { 34 | out io.Writer 35 | } 36 | 37 | func newRepoCmd(out io.Writer) *cobra.Command { 38 | cmd := &cobra.Command{ 39 | Use: "repo [FLAGS] add|remove|list|index|update [ARGS]", 40 | Short: "add, list, remove, update, and index chart repositories", 41 | Long: repoHelm, 42 | } 43 | 44 | cmd.AddCommand(newRepoAddCmd(out)) 45 | cmd.AddCommand(newRepoListCmd(out)) 46 | cmd.AddCommand(newRepoRemoveCmd(out)) 47 | cmd.AddCommand(newRepoIndexCmd(out)) 48 | cmd.AddCommand(newRepoUpdateCmd(out)) 49 | 50 | return cmd 51 | } 52 | -------------------------------------------------------------------------------- /cmd/helm/testdata/helmhome/repository/cache/testing-index.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | entries: 3 | alpine: 4 | - name: alpine 5 | url: http://storage.googleapis.com/kubernetes-charts/alpine-0.1.0.tgz 6 | checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d 7 | home: https://k8s.io/helm 8 | sources: 9 | - https://github.com/kubernetes/helm 10 | version: 0.1.0 11 | description: Deploy a basic Alpine Linux pod 12 | keywords: [] 13 | maintainers: [] 14 | engine: "" 15 | icon: "" 16 | - name: alpine 17 | url: http://storage.googleapis.com/kubernetes-charts/alpine-0.2.0.tgz 18 | checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d 19 | home: https://k8s.io/helm 20 | sources: 21 | - https://github.com/kubernetes/helm 22 | version: 0.2.0 23 | description: Deploy a basic Alpine Linux pod 24 | keywords: [] 25 | maintainers: [] 26 | engine: "" 27 | icon: "" 28 | mariadb: 29 | - name: mariadb 30 | url: http://storage.googleapis.com/kubernetes-charts/mariadb-0.3.0.tgz 31 | checksum: 65229f6de44a2be9f215d11dbff311673fc8ba56 32 | home: https://mariadb.org 33 | sources: 34 | - https://github.com/bitnami/bitnami-docker-mariadb 35 | version: 0.3.0 36 | description: Chart for MariaDB 37 | keywords: 38 | - mariadb 39 | - mysql 40 | - database 41 | - sql 42 | maintainers: 43 | - name: Bitnami 44 | email: containers@bitnami.com 45 | engine: gotpl 46 | icon: "" 47 | -------------------------------------------------------------------------------- /cmd/helm/repo_index_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "bytes" 21 | "io/ioutil" 22 | "os" 23 | "path/filepath" 24 | "testing" 25 | 26 | "k8s.io/helm/pkg/repo" 27 | ) 28 | 29 | func TestRepoIndexCmd(t *testing.T) { 30 | 31 | dir, err := ioutil.TempDir("", "helm-") 32 | if err != nil { 33 | t.Fatal(err) 34 | } 35 | defer os.RemoveAll(dir) 36 | if err := os.Link("testdata/testcharts/compressedchart-0.1.0.tgz", filepath.Join(dir, "compressedchart-0.1.0.tgz")); err != nil { 37 | t.Fatal(err) 38 | } 39 | 40 | buf := bytes.NewBuffer(nil) 41 | c := newRepoIndexCmd(buf) 42 | 43 | if err := c.RunE(c, []string{dir}); err != nil { 44 | t.Errorf("%q", err) 45 | } 46 | 47 | index, err := repo.LoadIndexFile(filepath.Join(dir, "index.yaml")) 48 | if err != nil { 49 | t.Fatal(err) 50 | } 51 | 52 | if len(index.Entries) != 1 { 53 | t.Errorf("expected 1 entry, got %v: %#v", len(index.Entries), index.Entries) 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /_proto/hapi/chart/chart.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Kubernetes Authors All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package hapi.chart; 18 | 19 | import "hapi/chart/config.proto"; 20 | import "hapi/chart/metadata.proto"; 21 | import "hapi/chart/template.proto"; 22 | import "google/protobuf/any.proto"; 23 | 24 | option go_package = "chart"; 25 | 26 | // Chart is a helm package that contains metadata, a default config, zero or more 27 | // optionally parameterizable templates, and zero or more charts (dependencies). 28 | message Chart { 29 | // Contents of the Chartfile. 30 | hapi.chart.Metadata metadata = 1; 31 | 32 | // Templates for this chart. 33 | repeated hapi.chart.Template templates = 2; 34 | 35 | // Charts that this chart depends on. 36 | repeated Chart dependencies = 3; 37 | 38 | // Default config for this template. 39 | hapi.chart.Config values = 4; 40 | 41 | // Miscellaneous files in a chart archive, 42 | // e.g. README, LICENSE, etc. 43 | repeated google.protobuf.Any files = 5; 44 | } 45 | -------------------------------------------------------------------------------- /_proto/hapi/release/hook.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Kubernetes Authors All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package hapi.release; 18 | 19 | import "google/protobuf/timestamp.proto"; 20 | 21 | option go_package = "release"; 22 | 23 | // Hook defines a hook object. 24 | message Hook { 25 | enum Event { 26 | UNKNOWN = 0; 27 | PRE_INSTALL = 1; 28 | POST_INSTALL = 2; 29 | PRE_DELETE = 3; 30 | POST_DELETE = 4; 31 | PRE_UPGRADE = 5; 32 | POST_UPGRADE = 6; 33 | PRE_ROLLBACK = 7; 34 | POST_ROLLBACK = 8; 35 | } 36 | string name = 1; 37 | // Kind is the Kubernetes kind. 38 | string kind = 2; 39 | // Path is the chart-relative path to the template. 40 | string path = 3; 41 | // Manifest is the manifest contents. 42 | string manifest = 4; 43 | // Events are the events that this hook fires on. 44 | repeated Event events = 5; 45 | // LastRun indicates the date/time this was last run. 46 | google.protobuf.Timestamp last_run = 6; 47 | } 48 | -------------------------------------------------------------------------------- /cmd/helm/downloader/testdata/helmhome/repository/cache/kubernetes-charts-index.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | entries: 3 | alpine: 4 | - name: alpine 5 | urls: 6 | - http://storage.googleapis.com/kubernetes-charts/alpine-0.1.0.tgz 7 | checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d 8 | home: https://k8s.io/helm 9 | sources: 10 | - https://github.com/kubernetes/helm 11 | version: 0.1.0 12 | description: Deploy a basic Alpine Linux pod 13 | keywords: [] 14 | maintainers: [] 15 | engine: "" 16 | icon: "" 17 | - name: alpine 18 | urls: 19 | - http://storage.googleapis.com/kubernetes-charts/alpine-0.2.0.tgz 20 | checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d 21 | home: https://k8s.io/helm 22 | sources: 23 | - https://github.com/kubernetes/helm 24 | version: 0.2.0 25 | description: Deploy a basic Alpine Linux pod 26 | keywords: [] 27 | maintainers: [] 28 | engine: "" 29 | icon: "" 30 | mariadb: 31 | - name: mariadb 32 | urls: 33 | - http://storage.googleapis.com/kubernetes-charts/mariadb-0.3.0.tgz 34 | checksum: 65229f6de44a2be9f215d11dbff311673fc8ba56 35 | home: https://mariadb.org 36 | sources: 37 | - https://github.com/bitnami/bitnami-docker-mariadb 38 | version: 0.3.0 39 | description: Chart for MariaDB 40 | keywords: 41 | - mariadb 42 | - mysql 43 | - database 44 | - sql 45 | maintainers: 46 | - name: Bitnami 47 | email: containers@bitnami.com 48 | engine: gotpl 49 | icon: "" 50 | -------------------------------------------------------------------------------- /pkg/chartutil/files_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | package chartutil 17 | 18 | import ( 19 | "testing" 20 | 21 | "github.com/golang/protobuf/ptypes/any" 22 | ) 23 | 24 | func TestNewFiles(t *testing.T) { 25 | 26 | cases := []struct { 27 | path, data string 28 | }{ 29 | {"ship/captain.txt", "The Captain"}, 30 | {"ship/stowaway.txt", "Legatt"}, 31 | {"story/name.txt", "The Secret Sharer"}, 32 | {"story/author.txt", "Joseph Conrad"}, 33 | } 34 | 35 | a := []*any.Any{} 36 | for _, c := range cases { 37 | a = append(a, &any.Any{TypeUrl: c.path, Value: []byte(c.data)}) 38 | } 39 | 40 | files := NewFiles(a) 41 | if len(files) != len(cases) { 42 | t.Errorf("Expected len() = %d, got %d", len(cases), len(files)) 43 | } 44 | 45 | for i, f := range cases { 46 | if got := string(files.GetBytes(f.path)); got != f.data { 47 | t.Errorf("%d: expected %q, got %q", i, f.data, got) 48 | } 49 | if got := files.Get(f.path); got != f.data { 50 | t.Errorf("%d: expected %q, got %q", i, f.data, got) 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /scripts/coverage.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2016 The Kubernetes Authors All rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -euo pipefail 18 | 19 | covermode=${COVERMODE:-atomic} 20 | coverdir=$(mktemp -d /tmp/coverage.XXXXXXXXXX) 21 | profile="${coverdir}/cover.out" 22 | 23 | hash goveralls 2>/dev/null || go get github.com/mattn/goveralls 24 | hash godir 2>/dev/null || go get github.com/Masterminds/godir 25 | 26 | generate_cover_data() { 27 | for d in $(godir) ; do 28 | ( 29 | local output="${coverdir}/${d//\//-}.cover" 30 | go test -coverprofile="${output}" -covermode="$covermode" "$d" 31 | ) 32 | done 33 | 34 | echo "mode: $covermode" >"$profile" 35 | grep -h -v "^mode:" "$coverdir"/*.cover >>"$profile" 36 | } 37 | 38 | push_to_coveralls() { 39 | goveralls -coverprofile="${profile}" -service=circle-ci 40 | } 41 | 42 | generate_cover_data 43 | go tool cover -func "${profile}" 44 | 45 | case "${1-}" in 46 | --html) 47 | go tool cover -html "${profile}" 48 | ;; 49 | --coveralls) 50 | push_to_coveralls 51 | ;; 52 | esac 53 | 54 | -------------------------------------------------------------------------------- /glide.yaml: -------------------------------------------------------------------------------- 1 | package: k8s.io/helm 2 | import: 3 | - package: golang.org/x/net 4 | version: fb93926129b8ec0056f2f458b1f519654814edf0 5 | subpackages: 6 | - context 7 | - package: github.com/spf13/cobra 8 | - package: github.com/spf13/pflag 9 | version: 367864438f1b1a3c7db4da06a2f55b144e6784e0 10 | - package: github.com/Masterminds/sprig 11 | version: ^2.6 12 | - package: github.com/ghodss/yaml 13 | - package: github.com/Masterminds/semver 14 | version: 1.1.0 15 | - package: github.com/technosophos/moniker 16 | - package: github.com/golang/protobuf 17 | version: 8616e8ee5e20a1704615e6c8d7afcdac06087a67 18 | subpackages: 19 | - proto 20 | - ptypes/any 21 | - ptypes/timestamp 22 | - package: google.golang.org/grpc 23 | version: v1.0.1-GA 24 | - package: k8s.io/kubernetes 25 | version: ~1.4 26 | subpackages: 27 | - pkg/api 28 | - pkg/api/meta 29 | - pkg/api/error 30 | - pkg/api/unversioned 31 | - pkg/apimachinery/registered 32 | - pkg/client/restclient 33 | - pkg/client/unversioned 34 | - pkg/apis/batch 35 | - pkg/client/unversioned/clientcmd 36 | - pkg/client/unversioned/fake 37 | - pkg/client/unversioned/portforward 38 | - pkg/client/unversioned/remotecommand 39 | - pkg/kubectl 40 | - pkg/kubectl/cmd/util 41 | - pkg/kubectl/resource 42 | - pkg/labels 43 | - pkg/runtime 44 | - pkg/watch 45 | - pkg/util/strategicpatch 46 | - pkg/util/yaml 47 | - package: github.com/gosuri/uitable 48 | - package: github.com/asaskevich/govalidator 49 | version: ^4.0.0 50 | - package: google.golang.org/cloud 51 | vcs: git 52 | repo: https://code.googlesource.com/gocloud 53 | - package: golang.org/x/crypto 54 | subpackages: 55 | - openpgp 56 | -------------------------------------------------------------------------------- /pkg/helm/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package helm 18 | 19 | import ( 20 | rls "k8s.io/helm/pkg/proto/hapi/services" 21 | ) 22 | 23 | // Interface for helm client for mocking in tests 24 | type Interface interface { 25 | ListReleases(opts ...ReleaseListOption) (*rls.ListReleasesResponse, error) 26 | InstallRelease(chStr, namespace string, opts ...InstallOption) (*rls.InstallReleaseResponse, error) 27 | DeleteRelease(rlsName string, opts ...DeleteOption) (*rls.UninstallReleaseResponse, error) 28 | ReleaseStatus(rlsName string, opts ...StatusOption) (*rls.GetReleaseStatusResponse, error) 29 | UpdateRelease(rlsName, chStr string, opts ...UpdateOption) (*rls.UpdateReleaseResponse, error) 30 | RollbackRelease(rlsName string, opts ...RollbackOption) (*rls.RollbackReleaseResponse, error) 31 | ReleaseContent(rlsName string, opts ...ContentOption) (*rls.GetReleaseContentResponse, error) 32 | ReleaseHistory(rlsName string, opts ...HistoryOption) (*rls.GetHistoryResponse, error) 33 | GetVersion(opts ...VersionOption) (*rls.GetVersionResponse, error) 34 | } 35 | -------------------------------------------------------------------------------- /pkg/lint/rules/values.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package rules 18 | 19 | import ( 20 | "fmt" 21 | "os" 22 | "path/filepath" 23 | 24 | "k8s.io/helm/pkg/chartutil" 25 | "k8s.io/helm/pkg/lint/support" 26 | ) 27 | 28 | // Values lints a chart's values.yaml file. 29 | func Values(linter *support.Linter) { 30 | file := "values.yaml" 31 | vf := filepath.Join(linter.ChartDir, file) 32 | fileExists := linter.RunLinterRule(support.InfoSev, file, validateValuesFileExistence(linter, vf)) 33 | 34 | if !fileExists { 35 | return 36 | } 37 | 38 | linter.RunLinterRule(support.ErrorSev, file, validateValuesFile(linter, vf)) 39 | } 40 | 41 | func validateValuesFileExistence(linter *support.Linter, valuesPath string) error { 42 | _, err := os.Stat(valuesPath) 43 | if err != nil { 44 | return fmt.Errorf("file does not exist") 45 | } 46 | return nil 47 | } 48 | 49 | func validateValuesFile(linter *support.Linter, valuesPath string) error { 50 | _, err := chartutil.ReadValuesFile(valuesPath) 51 | if err != nil { 52 | return fmt.Errorf("unable to parse YAML\n\t%s", err) 53 | } 54 | return nil 55 | } 56 | -------------------------------------------------------------------------------- /pkg/timeconv/timeconv_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package timeconv 18 | 19 | import ( 20 | "testing" 21 | "time" 22 | ) 23 | 24 | func TestNow(t *testing.T) { 25 | now := time.Now() 26 | ts := Now() 27 | var drift int64 = 5 28 | if ts.Seconds < int64(now.Second())-drift { 29 | t.Errorf("Unexpected time drift: %d", ts.Seconds) 30 | } 31 | } 32 | 33 | func TestTimestamp(t *testing.T) { 34 | now := time.Now() 35 | ts := Timestamp(now) 36 | 37 | if now.Unix() != ts.Seconds { 38 | t.Errorf("Unexpected time drift: %d to %d", now.Second(), ts.Seconds) 39 | } 40 | 41 | if now.Nanosecond() != int(ts.Nanos) { 42 | t.Errorf("Unexpected nano drift: %d to %d", now.Nanosecond(), ts.Nanos) 43 | } 44 | } 45 | 46 | func TestTime(t *testing.T) { 47 | nowts := Now() 48 | now := Time(nowts) 49 | 50 | if now.Unix() != nowts.Seconds { 51 | t.Errorf("Unexpected time drift %d", now.Unix()) 52 | } 53 | } 54 | 55 | func TestFormat(t *testing.T) { 56 | now := time.Now() 57 | nowts := Timestamp(now) 58 | 59 | if now.Format(time.ANSIC) != Format(nowts, time.ANSIC) { 60 | t.Error("Format mismatch") 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /cmd/tiller/release_history.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "sort" 21 | 22 | "golang.org/x/net/context" 23 | rpb "k8s.io/helm/pkg/proto/hapi/release" 24 | tpb "k8s.io/helm/pkg/proto/hapi/services" 25 | ) 26 | 27 | func (s *releaseServer) GetHistory(ctx context.Context, req *tpb.GetHistoryRequest) (*tpb.GetHistoryResponse, error) { 28 | if !checkClientVersion(ctx) { 29 | return nil, errIncompatibleVersion 30 | } 31 | 32 | h, err := s.env.Releases.History(req.Name) 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | sort.Sort(sort.Reverse(byRev(h))) 38 | 39 | var resp tpb.GetHistoryResponse 40 | for i := 0; i < min(len(h), int(req.Max)); i++ { 41 | resp.Releases = append(resp.Releases, h[i]) 42 | } 43 | 44 | return &resp, nil 45 | } 46 | 47 | type byRev []*rpb.Release 48 | 49 | func (s byRev) Len() int { return len(s) } 50 | func (s byRev) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 51 | func (s byRev) Less(i, j int) bool { return s[i].Version < s[j].Version } 52 | 53 | func min(x, y int) int { 54 | if x < y { 55 | return x 56 | } 57 | return y 58 | } 59 | -------------------------------------------------------------------------------- /cmd/helm/delete_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "io" 21 | "testing" 22 | 23 | "github.com/spf13/cobra" 24 | ) 25 | 26 | func TestDelete(t *testing.T) { 27 | 28 | tests := []releaseCase{ 29 | { 30 | name: "basic delete", 31 | args: []string{"aeneas"}, 32 | flags: []string{}, 33 | expected: "", // Output of a delete is an empty string and exit 0. 34 | resp: releaseMock(&releaseOptions{name: "aeneas"}), 35 | }, 36 | { 37 | name: "delete without hooks", 38 | args: []string{"aeneas"}, 39 | flags: []string{"--no-hooks"}, 40 | expected: "", 41 | resp: releaseMock(&releaseOptions{name: "aeneas"}), 42 | }, 43 | { 44 | name: "purge", 45 | args: []string{"aeneas"}, 46 | flags: []string{"--purge"}, 47 | expected: "", 48 | resp: releaseMock(&releaseOptions{name: "aeneas"}), 49 | }, 50 | { 51 | name: "delete without release", 52 | args: []string{}, 53 | err: true, 54 | }, 55 | } 56 | runReleaseCases(t, tests, func(c *fakeReleaseClient, out io.Writer) *cobra.Command { 57 | return newDeleteCmd(c, out) 58 | }) 59 | } 60 | -------------------------------------------------------------------------------- /cmd/helm/init_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "bytes" 21 | "io/ioutil" 22 | "os" 23 | "testing" 24 | 25 | "k8s.io/helm/cmd/helm/helmpath" 26 | ) 27 | 28 | func TestEnsureHome(t *testing.T) { 29 | home, err := ioutil.TempDir("", "helm_home") 30 | if err != nil { 31 | t.Fatal(err) 32 | } 33 | defer os.Remove(home) 34 | 35 | b := bytes.NewBuffer(nil) 36 | hh := helmpath.Home(home) 37 | helmHome = home 38 | if err := ensureHome(hh, b); err != nil { 39 | t.Error(err) 40 | } 41 | 42 | expectedDirs := []string{hh.String(), hh.Repository(), hh.Cache(), hh.LocalRepository()} 43 | for _, dir := range expectedDirs { 44 | if fi, err := os.Stat(dir); err != nil { 45 | t.Errorf("%s", err) 46 | } else if !fi.IsDir() { 47 | t.Errorf("%s is not a directory", fi) 48 | } 49 | } 50 | 51 | if fi, err := os.Stat(hh.RepositoryFile()); err != nil { 52 | t.Error(err) 53 | } else if fi.IsDir() { 54 | t.Errorf("%s should not be a directory", fi) 55 | } 56 | 57 | if fi, err := os.Stat(localRepoDirectory(localRepoIndexFilePath)); err != nil { 58 | t.Errorf("%s", err) 59 | } else if fi.IsDir() { 60 | t.Errorf("%s should not be a directory", fi) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /cmd/tiller/kind_sorter_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "testing" 21 | ) 22 | 23 | func TestKindSorter(t *testing.T) { 24 | manifests := []manifest{ 25 | { 26 | name: "m", 27 | content: "", 28 | head: &simpleHead{Kind: "Deployment"}, 29 | }, 30 | { 31 | name: "l", 32 | content: "", 33 | head: &simpleHead{Kind: "Service"}, 34 | }, 35 | { 36 | name: "!", 37 | content: "", 38 | head: &simpleHead{Kind: "HonkyTonkSet"}, 39 | }, 40 | { 41 | name: "h", 42 | content: "", 43 | head: &simpleHead{Kind: "Namespace"}, 44 | }, 45 | { 46 | name: "e", 47 | content: "", 48 | head: &simpleHead{Kind: "ConfigMap"}, 49 | }, 50 | } 51 | 52 | res := sortByKind(manifests, InstallOrder) 53 | got := "" 54 | expect := "helm!" 55 | for _, r := range res { 56 | got += r.name 57 | } 58 | if got != expect { 59 | t.Errorf("Expected %q, got %q", expect, got) 60 | } 61 | 62 | expect = "lmeh!" 63 | got = "" 64 | res = sortByKind(manifests, UninstallOrder) 65 | for _, r := range res { 66 | got += r.name 67 | } 68 | if got != expect { 69 | t.Errorf("Expected %q, got %q", expect, got) 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /pkg/chartutil/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /*Package chartutil contains tools for working with charts. 18 | 19 | Charts are described in the protocol buffer definition (pkg/proto/hapi/charts). 20 | This packe provides utilities for serializing and deserializing charts. 21 | 22 | A chart can be represented on the file system in one of two ways: 23 | 24 | - As a directory that contains a Chart.yaml file and other chart things. 25 | - As a tarred gzipped file containing a directory that then contains a 26 | Chart.yaml file. 27 | 28 | This package provides utilitites for working with those file formats. 29 | 30 | The preferred way of loading a chart is using 'chartutil.Load`: 31 | 32 | chart, err := chartutil.Load(filename) 33 | 34 | This will attempt to discover whether the file at 'filename' is a directory or 35 | a chart archive. It will then load accordingly. 36 | 37 | For accepting raw compressed tar file data from an io.Reader, the 38 | 'chartutil.LoadArchive()' will read in the data, uncompress it, and unpack it 39 | into a Chart. 40 | 41 | When creating charts in memory, use the 'k8s.io/helm/pkg/proto/happy/chart' 42 | package directly. 43 | */ 44 | package chartutil // import "k8s.io/helm/pkg/chartutil" 45 | -------------------------------------------------------------------------------- /cmd/helm/repo_list.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "errors" 21 | "fmt" 22 | "io" 23 | 24 | "github.com/gosuri/uitable" 25 | "github.com/spf13/cobra" 26 | 27 | "k8s.io/helm/cmd/helm/helmpath" 28 | "k8s.io/helm/pkg/repo" 29 | ) 30 | 31 | type repoListCmd struct { 32 | out io.Writer 33 | home helmpath.Home 34 | } 35 | 36 | func newRepoListCmd(out io.Writer) *cobra.Command { 37 | list := &repoListCmd{ 38 | out: out, 39 | } 40 | 41 | cmd := &cobra.Command{ 42 | Use: "list [flags]", 43 | Short: "list chart repositories", 44 | RunE: func(cmd *cobra.Command, args []string) error { 45 | list.home = helmpath.Home(homePath()) 46 | return list.run() 47 | }, 48 | } 49 | 50 | return cmd 51 | } 52 | 53 | func (a *repoListCmd) run() error { 54 | f, err := repo.LoadRepositoriesFile(a.home.RepositoryFile()) 55 | if err != nil { 56 | return err 57 | } 58 | if len(f.Repositories) == 0 { 59 | return errors.New("no repositories to show") 60 | } 61 | table := uitable.New() 62 | table.MaxColWidth = 50 63 | table.AddRow("NAME", "URL") 64 | for _, re := range f.Repositories { 65 | table.AddRow(re.Name, re.URL) 66 | } 67 | fmt.Fprintln(a.out, table) 68 | return nil 69 | } 70 | -------------------------------------------------------------------------------- /pkg/chartutil/save_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package chartutil 18 | 19 | import ( 20 | "io/ioutil" 21 | "os" 22 | "strings" 23 | "testing" 24 | 25 | "k8s.io/helm/pkg/proto/hapi/chart" 26 | ) 27 | 28 | func TestSave(t *testing.T) { 29 | tmp, err := ioutil.TempDir("", "helm-") 30 | if err != nil { 31 | t.Fatal(err) 32 | } 33 | defer os.RemoveAll(tmp) 34 | 35 | c := &chart.Chart{ 36 | Metadata: &chart.Metadata{ 37 | Name: "ahab", 38 | Version: "1.2.3.4", 39 | }, 40 | Values: &chart.Config{ 41 | Raw: "ship: Pequod", 42 | }, 43 | } 44 | 45 | where, err := Save(c, tmp) 46 | if err != nil { 47 | t.Fatalf("Failed to save: %s", err) 48 | } 49 | if !strings.HasPrefix(where, tmp) { 50 | t.Fatalf("Expected %q to start with %q", where, tmp) 51 | } 52 | if !strings.HasSuffix(where, ".tgz") { 53 | t.Fatalf("Expected %q to end with .tgz", where) 54 | } 55 | 56 | c2, err := LoadFile(where) 57 | if err != nil { 58 | t.Fatal(err) 59 | } 60 | 61 | if c2.Metadata.Name != c.Metadata.Name { 62 | t.Fatalf("Expected chart archive to have %q, got %q", c.Metadata.Name, c2.Metadata.Name) 63 | } 64 | if c2.Values.Raw != c.Values.Raw { 65 | t.Fatal("Values data did not match") 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /cmd/helm/structure.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | "path/filepath" 22 | ) 23 | 24 | const ( 25 | repositoryDir string = "repository" 26 | repositoriesFilePath string = "repositories.yaml" 27 | cachePath string = "cache" 28 | localRepoPath string = "local" 29 | localRepoIndexFilePath string = "index.yaml" 30 | ) 31 | 32 | func homePath() string { 33 | return os.ExpandEnv(helmHome) 34 | } 35 | 36 | // All other directories go under the $HELM_HOME/repository. 37 | func repositoryDirectory() string { 38 | return homePath() + "/" + repositoryDir 39 | } 40 | 41 | func cacheDirectory(paths ...string) string { 42 | fragments := append([]string{repositoryDirectory(), cachePath}, paths...) 43 | return filepath.Join(fragments...) 44 | } 45 | 46 | func cacheIndexFile(repoName string) string { 47 | return cacheDirectory(repoName + "-index.yaml") 48 | } 49 | 50 | func localRepoDirectory(paths ...string) string { 51 | fragments := append([]string{repositoryDirectory(), localRepoPath}, paths...) 52 | return filepath.Join(fragments...) 53 | } 54 | 55 | func repositoriesFile() string { 56 | return filepath.Join(repositoryDirectory(), repositoriesFilePath) 57 | } 58 | -------------------------------------------------------------------------------- /scripts/validate-go.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2016 The Kubernetes Authors All rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | set -euo pipefail 17 | 18 | readonly reset=$(tput sgr0) 19 | readonly red=$(tput bold; tput setaf 1) 20 | readonly green=$(tput bold; tput setaf 2) 21 | readonly yellow=$(tput bold; tput setaf 3) 22 | 23 | exit_code=0 24 | 25 | find_go_files() { 26 | find . -type f -name "*.go" | grep -v vendor 27 | } 28 | 29 | hash golint 2>/dev/null || go get -u github.com/golang/lint/golint 30 | hash godir 2>/dev/null || go get -u github.com/Masterminds/godir 31 | 32 | echo "==> Running golint..." 33 | for pkg in $(godir pkgs | grep -v proto); do 34 | golint_out=$(golint "$pkg" 2>&1) 35 | if [[ -n "$golint_out" ]]; then 36 | echo "${yellow}${golint_out}${reset}" 37 | fi 38 | done 39 | 40 | echo "==> Running go vet..." 41 | echo -n "$red" 42 | go vet $(godir pkgs) 2>&1 | grep -v "^exit status " || exit_code=${PIPESTATUS[0]} 43 | echo -n "$reset" 44 | 45 | echo "==> Running gofmt..." 46 | failed_fmt=$(find_go_files | xargs gofmt -s -l) 47 | if [[ -n "${failed_fmt}" ]]; then 48 | echo -n "${red}" 49 | echo "gofmt check failed:" 50 | echo "$failed_fmt" 51 | gofmt -s -d "${failed_fmt}" 52 | echo -n "${reset}" 53 | exit_code=1 54 | fi 55 | 56 | exit ${exit_code} 57 | -------------------------------------------------------------------------------- /pkg/storage/driver/labels.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package driver 18 | 19 | import ( 20 | "bytes" 21 | "fmt" 22 | "io" 23 | ) 24 | 25 | // labels is a map of key value pairs to be included as metadata in a configmap object. 26 | type labels map[string]string 27 | 28 | func (lbs *labels) init() { *lbs = labels(make(map[string]string)) } 29 | func (lbs labels) get(key string) string { return lbs[key] } 30 | func (lbs labels) set(key, val string) { lbs[key] = val } 31 | 32 | func (lbs labels) keys() (ls []string) { 33 | for key := range lbs { 34 | ls = append(ls, key) 35 | } 36 | return 37 | } 38 | 39 | func (lbs labels) match(set labels) bool { 40 | for _, key := range set.keys() { 41 | if lbs.get(key) != set.get(key) { 42 | return false 43 | } 44 | } 45 | return true 46 | } 47 | 48 | func (lbs labels) toMap() map[string]string { return lbs } 49 | 50 | func (lbs *labels) fromMap(kvs map[string]string) { 51 | for k, v := range kvs { 52 | lbs.set(k, v) 53 | } 54 | } 55 | 56 | func (lbs labels) dump(w io.Writer) error { 57 | var b bytes.Buffer 58 | 59 | fmt.Fprintln(&b, "labels:") 60 | for k, v := range lbs { 61 | fmt.Fprintf(&b, "\t- %q -> %q\n", k, v) 62 | } 63 | 64 | _, err := w.Write(b.Bytes()) 65 | return err 66 | } 67 | -------------------------------------------------------------------------------- /_proto/Makefile: -------------------------------------------------------------------------------- 1 | space := $(empty) $(empty) 2 | comma := , 3 | empty := 4 | 5 | import_path = k8s.io/helm/pkg/proto/hapi 6 | 7 | dst = ../pkg/proto 8 | target = go 9 | plugins = grpc 10 | 11 | chart_ias = $(subst $(space),$(comma),$(addsuffix =$(import_path)/$(chart_pkg),$(addprefix M,$(chart_pbs)))) 12 | chart_pbs = $(sort $(wildcard hapi/chart/*.proto)) 13 | chart_pkg = chart 14 | 15 | release_ias = $(subst $(space),$(comma),$(addsuffix =$(import_path)/$(release_pkg),$(addprefix M,$(release_pbs)))) 16 | release_pbs = $(sort $(wildcard hapi/release/*.proto)) 17 | release_pkg = release 18 | 19 | services_ias = $(subst $(space),$(comma),$(addsuffix =$(import_path)/$(services_pkg),$(addprefix M,$(services_pbs)))) 20 | services_pbs = $(sort $(wildcard hapi/services/*.proto)) 21 | services_pkg = services 22 | 23 | version_ias = $(subst $(space),$(comma),$(addsuffix =$(import_path)/$(version_pkg),$(addprefix M,$(version_pbs)))) 24 | version_pbs = $(sort $(wildcard hapi/version/*.proto)) 25 | version_pkg = version 26 | 27 | google_deps = Mgoogle/protobuf/timestamp.proto=github.com/golang/protobuf/ptypes/timestamp,Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any 28 | 29 | .PHONY: all 30 | all: chart release services version 31 | 32 | chart: 33 | PATH=../bin:$(PATH) protoc --$(target)_out=plugins=$(plugins),$(google_deps),$(chart_ias):$(dst) $(chart_pbs) 34 | 35 | release: 36 | PATH=../bin:$(PATH) protoc --$(target)_out=plugins=$(plugins),$(google_deps),$(chart_ias),$(version_ias):$(dst) $(release_pbs) 37 | 38 | services: 39 | PATH=../bin:$(PATH) protoc --$(target)_out=plugins=$(plugins),$(google_deps),$(chart_ias),$(version_ias),$(release_ias):$(dst) $(services_pbs) 40 | 41 | version: 42 | PATH=../bin:$(PATH) protoc --$(target)_out=plugins=$(plugins),$(google_deps):$(dst) $(version_pbs) 43 | 44 | .PHONY: clean 45 | clean: 46 | @rm -rf $(dst)/hapi 2>/dev/null 47 | -------------------------------------------------------------------------------- /_proto/hapi/release/status.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Kubernetes Authors All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package hapi.release; 18 | 19 | import "google/protobuf/any.proto"; 20 | 21 | option go_package = "release"; 22 | 23 | // Status defines the status of a release. 24 | message Status { 25 | enum Code { 26 | // Status_UNKNOWN indicates that a release is in an uncertain state. 27 | UNKNOWN = 0; 28 | // Status_DEPLOYED indicates that the release has been pushed to Kubernetes. 29 | DEPLOYED = 1; 30 | // Status_DELETED indicates that a release has been deleted from Kubermetes. 31 | DELETED = 2; 32 | // Status_SUPERSEDED indicates that this release object is outdated and a newer one exists. 33 | SUPERSEDED = 3; 34 | // Status_FAILED indicates that the release was not successfully deployed. 35 | FAILED = 4; 36 | } 37 | 38 | Code code = 1; 39 | 40 | google.protobuf.Any details = 2; 41 | 42 | // Cluster resources as kubectl would print them. 43 | string resources = 3; 44 | 45 | // Contains the rendered templates/NOTES.txt if available 46 | string notes = 4; 47 | } 48 | -------------------------------------------------------------------------------- /pkg/chartutil/files.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | package chartutil 17 | 18 | import ( 19 | "github.com/golang/protobuf/ptypes/any" 20 | ) 21 | 22 | // Files is a map of files in a chart that can be accessed from a template. 23 | type Files map[string][]byte 24 | 25 | // NewFiles creates a new Files from chart files. 26 | // Given an []*any.Any (the format for files in a chart.Chart), extract a map of files. 27 | func NewFiles(from []*any.Any) Files { 28 | files := map[string][]byte{} 29 | for _, f := range from { 30 | files[f.TypeUrl] = f.Value 31 | } 32 | return files 33 | } 34 | 35 | // GetBytes gets a file by path. 36 | // 37 | // The returned data is raw. In a template context, this is identical to calling 38 | // {{index .Files $path}}. 39 | // 40 | // This is intended to be accessed from within a template, so a missed key returns 41 | // an empty []byte. 42 | func (f Files) GetBytes(name string) []byte { 43 | v, ok := f[name] 44 | if !ok { 45 | return []byte{} 46 | } 47 | return v 48 | } 49 | 50 | // Get returns a string representation of the given file. 51 | // 52 | // Fetch the contents of a file as a string. It is designed to be called in a 53 | // template. 54 | // 55 | // {{.Files.Get "foo"}} 56 | func (f Files) Get(name string) string { 57 | return string(f.GetBytes(name)) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/provenance/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | /*Package provenance provides tools for establishing the authenticity of a chart. 17 | 18 | In Helm, provenance is established via several factors. The primary factor is the 19 | cryptographic signature of a chart. Chart authors may sign charts, which in turn 20 | provide the necessary metadata to ensure the integrity of the chart file, the 21 | Chart.yaml, and the referenced Docker images. 22 | 23 | A provenance file is clear-signed. This provides cryptographic verification that 24 | a particular block of information (Chart.yaml, archive file, images) have not 25 | been tampered with or altered. To learn more, read the GnuPG documentation on 26 | clear signatures: 27 | https://www.gnupg.org/gph/en/manual/x135.html 28 | 29 | The cryptography used by Helm should be compatible with OpenGPG. For example, 30 | you should be able to verify a signature by importing the desired public key 31 | and using `gpg --verify`, `keybase pgp verify`, or similar: 32 | 33 | $ gpg --verify some.sig 34 | gpg: Signature made Mon Jul 25 17:23:44 2016 MDT using RSA key ID 1FC18762 35 | gpg: Good signature from "Helm Testing (This key should only be used for testing. DO NOT TRUST.) " [ultimate] 36 | */ 37 | package provenance // import "k8s.io/helm/pkg/provenance" 38 | -------------------------------------------------------------------------------- /cmd/helm/repo_index.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "io" 21 | "path/filepath" 22 | 23 | "github.com/spf13/cobra" 24 | 25 | "k8s.io/helm/pkg/repo" 26 | ) 27 | 28 | type repoIndexCmd struct { 29 | dir string 30 | url string 31 | out io.Writer 32 | } 33 | 34 | func newRepoIndexCmd(out io.Writer) *cobra.Command { 35 | index := &repoIndexCmd{ 36 | out: out, 37 | } 38 | 39 | cmd := &cobra.Command{ 40 | Use: "index [flags] [DIR]", 41 | Short: "generate an index file given a directory containing packaged charts", 42 | RunE: func(cmd *cobra.Command, args []string) error { 43 | if err := checkArgsLength(len(args), "path to a directory"); err != nil { 44 | return err 45 | } 46 | 47 | index.dir = args[0] 48 | 49 | return index.run() 50 | }, 51 | } 52 | 53 | f := cmd.Flags() 54 | f.StringVar(&index.url, "url", "", "url of chart repository") 55 | 56 | return cmd 57 | } 58 | 59 | func (i *repoIndexCmd) run() error { 60 | path, err := filepath.Abs(i.dir) 61 | if err != nil { 62 | return err 63 | } 64 | 65 | return index(path, i.url) 66 | } 67 | 68 | func index(dir, url string) error { 69 | chartRepo, err := repo.LoadChartRepository(dir, url) 70 | if err != nil { 71 | return err 72 | } 73 | 74 | return chartRepo.Index() 75 | } 76 | -------------------------------------------------------------------------------- /pkg/version/version.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package version // import "k8s.io/helm/pkg/version" 18 | 19 | import "k8s.io/helm/pkg/proto/hapi/version" 20 | 21 | var ( 22 | // Version is the current version of the Helm. 23 | // Update this whenever making a new release. 24 | // The version is of the format Major.Minor.Patch[-Prerelease][+BuildMetadata] 25 | // 26 | // Increment major number for new feature additions and behavioral changes. 27 | // Increment minor number for bug fixes and performance enhancements. 28 | // Increment patch number for critical fixes to existing releases. 29 | Version = "v2.0.0-alpha.4" 30 | 31 | // BuildMetadata is extra build time data 32 | BuildMetadata = "" 33 | // GitCommit is the git sha1 34 | GitCommit = "" 35 | // GitTreeState is the state of the git tree 36 | GitTreeState = "" 37 | ) 38 | 39 | // GetVersion returns the semver string of the version 40 | func GetVersion() string { 41 | if BuildMetadata == "" { 42 | return Version 43 | } 44 | return Version + "+" + BuildMetadata 45 | } 46 | 47 | // GetVersionProto returns protobuf representing the version 48 | func GetVersionProto() *version.Version { 49 | return &version.Version{ 50 | SemVer: GetVersion(), 51 | GitCommit: GitCommit, 52 | GitTreeState: GitTreeState, 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_proto/hapi/release/release.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Kubernetes Authors All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package hapi.release; 18 | 19 | import "hapi/release/hook.proto"; 20 | import "hapi/release/info.proto"; 21 | import "hapi/chart/config.proto"; 22 | import "hapi/chart/chart.proto"; 23 | 24 | option go_package = "release"; 25 | 26 | // Release describes a deployment of a chart, together with the chart 27 | // and the variables used to deploy that chart. 28 | message Release { 29 | // Name is the name of the release 30 | string name = 1; 31 | 32 | // Info provides information about a release 33 | hapi.release.Info info = 2; 34 | 35 | // Chart is the chart that was released. 36 | hapi.chart.Chart chart = 3; 37 | 38 | // Config is the set of extra Values added to the chart. 39 | // These values override the default values inside of the chart. 40 | hapi.chart.Config config = 4; 41 | 42 | // Manifest is the string representation of the rendered template. 43 | string manifest = 5; 44 | 45 | // Hooks are all of the hooks declared for this release. 46 | repeated hapi.release.Hook hooks = 6; 47 | 48 | // Version is an int32 which represents the version of the release. 49 | int32 version = 7; 50 | 51 | // Namespace is the kubernetes namespace of the release. 52 | string namespace = 8; 53 | } 54 | -------------------------------------------------------------------------------- /docs/examples/nginx/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | # This uses a "fullname" template (see _helpers) 5 | # Basing names on .Release.Name means that the same chart can be installed 6 | # multiple times into the same namespace. 7 | name: {{template "fullname" .}} 8 | labels: 9 | # The "heritage" label is used to track which tool deployed a given chart. 10 | # It is useful for admins who want to see what releases a particular tool 11 | # is responsible for. 12 | heritage: {{ .Release.Service | quote }} 13 | # This makes it easy to search for all components of a release using kubectl. 14 | release: {{ .Release.Name | quote }} 15 | # This makes it easy to audit chart usage. 16 | chart: "{{.Chart.Name}}-{{.Chart.Version}}" 17 | spec: 18 | replicas: {{default 1 .Values.replicaCount | quote}} 19 | template: 20 | metadata: 21 | labels: 22 | app: {{template "fullname" .}} 23 | release: {{.Release.Name | quote }} 24 | spec: 25 | containers: 26 | - name: nginx 27 | # Making image configurable is not necessary. Making imageTag configurable 28 | # is a nice option for the user. Especially in the strange cases like 29 | # nginx where the base distro is determined by the tag. Using :latest 30 | # is frowned upon, using :stable isn't that great either. 31 | image: "{{default "nginx" .Values.image}}:{{default "stable-alpine" .Values.imageTag}}" 32 | imagePullPolicy: {{default "IfNotPresent" .Values.pullPolicy}} 33 | ports: 34 | - containerPort: 80 35 | # This (and the volumes section below) mount the config map as a volume. 36 | volumeMounts: 37 | - mountPath: /usr/share/nginx/html 38 | name: wwwdata-volume 39 | volumes: 40 | - name: wwwdata-volume 41 | configMap: 42 | name: {{template "fullname" .}} 43 | -------------------------------------------------------------------------------- /pkg/chartutil/chartfile.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package chartutil 18 | 19 | import ( 20 | "io/ioutil" 21 | 22 | "github.com/ghodss/yaml" 23 | 24 | "k8s.io/helm/pkg/proto/hapi/chart" 25 | ) 26 | 27 | // ApiVersionV1 is the API version number for version 1. 28 | // 29 | // This is ApiVersionV1 instead of APIVersionV1 to match the protobuf-generated name. 30 | const ApiVersionV1 = "v1" 31 | 32 | // UnmarshalChartfile takes raw Chart.yaml data and unmarshals it. 33 | func UnmarshalChartfile(data []byte) (*chart.Metadata, error) { 34 | y := &chart.Metadata{} 35 | err := yaml.Unmarshal(data, y) 36 | if err != nil { 37 | return nil, err 38 | } 39 | return y, nil 40 | } 41 | 42 | // LoadChartfile loads a Chart.yaml file into a *chart.Metadata. 43 | func LoadChartfile(filename string) (*chart.Metadata, error) { 44 | b, err := ioutil.ReadFile(filename) 45 | if err != nil { 46 | return nil, err 47 | } 48 | return UnmarshalChartfile(b) 49 | } 50 | 51 | // SaveChartfile saves the given metadata as a Chart.yaml file at the given path. 52 | // 53 | // 'filename' should be the complete path and filename ('foo/Chart.yaml') 54 | func SaveChartfile(filename string, cf *chart.Metadata) error { 55 | out, err := yaml.Marshal(cf) 56 | if err != nil { 57 | return err 58 | } 59 | return ioutil.WriteFile(filename, out, 0755) 60 | } 61 | -------------------------------------------------------------------------------- /cmd/helm/create_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "io/ioutil" 21 | "os" 22 | "testing" 23 | 24 | "k8s.io/helm/pkg/chartutil" 25 | ) 26 | 27 | func TestCreateCmd(t *testing.T) { 28 | cname := "testchart" 29 | // Make a temp dir 30 | tdir, err := ioutil.TempDir("", "helm-create-") 31 | if err != nil { 32 | t.Fatal(err) 33 | } 34 | defer os.Remove(tdir) 35 | 36 | // CD into it 37 | pwd, err := os.Getwd() 38 | if err != nil { 39 | t.Fatal(err) 40 | } 41 | if err := os.Chdir(tdir); err != nil { 42 | t.Fatal(err) 43 | } 44 | defer os.Chdir(pwd) 45 | 46 | // Run a create 47 | cmd := newCreateCmd(os.Stdout) 48 | if err := cmd.RunE(cmd, []string{cname}); err != nil { 49 | t.Errorf("Failed to run create: %s", err) 50 | return 51 | } 52 | 53 | // Test that the chart is there 54 | if fi, err := os.Stat(cname); err != nil { 55 | t.Fatalf("no chart directory: %s", err) 56 | } else if !fi.IsDir() { 57 | t.Fatalf("chart is not directory") 58 | } 59 | 60 | c, err := chartutil.LoadDir(cname) 61 | if err != nil { 62 | t.Fatal(err) 63 | } 64 | 65 | if c.Metadata.Name != cname { 66 | t.Errorf("Expected %q name, got %q", cname, c.Metadata.Name) 67 | } 68 | if c.Metadata.ApiVersion != chartutil.ApiVersionV1 { 69 | t.Errorf("Wrong API version: %q", c.Metadata.ApiVersion) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /pkg/timeconv/timeconv.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package timeconv 18 | 19 | import ( 20 | "time" 21 | 22 | "github.com/golang/protobuf/ptypes/timestamp" 23 | ) 24 | 25 | // Now creates a timestamp.Timestamp representing the current time. 26 | func Now() *timestamp.Timestamp { 27 | return Timestamp(time.Now()) 28 | } 29 | 30 | // Timestamp converts a time.Time to a protobuf *timestamp.Timestamp. 31 | func Timestamp(t time.Time) *timestamp.Timestamp { 32 | return ×tamp.Timestamp{ 33 | Seconds: t.Unix(), 34 | Nanos: int32(t.Nanosecond()), 35 | } 36 | } 37 | 38 | // Time converts a protobuf *timestamp.Timestamp to a time.Time. 39 | func Time(ts *timestamp.Timestamp) time.Time { 40 | return time.Unix(ts.Seconds, int64(ts.Nanos)) 41 | } 42 | 43 | // Format formats a *timestamp.Timestamp into a string. 44 | // 45 | // This follows the rules for time.Time.Format(). 46 | func Format(ts *timestamp.Timestamp, layout string) string { 47 | return Time(ts).Format(layout) 48 | } 49 | 50 | // String formats the timestamp into a user-friendly string. 51 | // 52 | // Currently, this uses the 'time.ANSIC' format string, but there is no guarantee 53 | // that this will not change. 54 | // 55 | // This is a convenience function for formatting timestamps for user display. 56 | func String(ts *timestamp.Timestamp) string { 57 | return Format(ts, time.ANSIC) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/chartutil/create_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package chartutil 18 | 19 | import ( 20 | "io/ioutil" 21 | "os" 22 | "path/filepath" 23 | "testing" 24 | 25 | "k8s.io/helm/pkg/proto/hapi/chart" 26 | ) 27 | 28 | func TestCreate(t *testing.T) { 29 | tdir, err := ioutil.TempDir("", "helm-") 30 | if err != nil { 31 | t.Fatal(err) 32 | } 33 | defer os.RemoveAll(tdir) 34 | 35 | cf := &chart.Metadata{Name: "foo"} 36 | 37 | c, err := Create(cf, tdir) 38 | if err != nil { 39 | t.Fatal(err) 40 | } 41 | 42 | dir := filepath.Join(tdir, "foo") 43 | 44 | mychart, err := LoadDir(c) 45 | if err != nil { 46 | t.Fatalf("Failed to load newly created chart %q: %s", c, err) 47 | } 48 | 49 | if mychart.Metadata.Name != "foo" { 50 | t.Errorf("Expected name to be 'foo', got %q", mychart.Metadata.Name) 51 | } 52 | 53 | for _, d := range []string{TemplatesDir, ChartsDir} { 54 | if fi, err := os.Stat(filepath.Join(dir, d)); err != nil { 55 | t.Errorf("Expected %s dir: %s", d, err) 56 | } else if !fi.IsDir() { 57 | t.Errorf("Expected %s to be a directory.", d) 58 | } 59 | } 60 | 61 | for _, f := range []string{ChartfileName, ValuesfileName, IgnorefileName} { 62 | if fi, err := os.Stat(filepath.Join(dir, f)); err != nil { 63 | t.Errorf("Expected %s file: %s", f, err) 64 | } else if fi.IsDir() { 65 | t.Errorf("Expected %s to be a fle.", f) 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /cmd/helm/version.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "errors" 21 | "fmt" 22 | "io" 23 | 24 | "github.com/spf13/cobra" 25 | "google.golang.org/grpc" 26 | "google.golang.org/grpc/codes" 27 | 28 | "k8s.io/helm/pkg/helm" 29 | "k8s.io/helm/pkg/version" 30 | ) 31 | 32 | type versionCmd struct { 33 | out io.Writer 34 | client helm.Interface 35 | } 36 | 37 | func newVersionCmd(c helm.Interface, out io.Writer) *cobra.Command { 38 | version := &versionCmd{ 39 | client: c, 40 | out: out, 41 | } 42 | cmd := &cobra.Command{ 43 | Use: "version", 44 | Short: "print the client/server version information", 45 | PersistentPreRunE: setupConnection, 46 | RunE: func(cmd *cobra.Command, args []string) error { 47 | version.client = ensureHelmClient(version.client) 48 | return version.run() 49 | }, 50 | } 51 | return cmd 52 | } 53 | 54 | func (v *versionCmd) run() error { 55 | // Regardless of whether we can talk to server or not, just print the client 56 | // version. 57 | cv := version.GetVersionProto() 58 | fmt.Fprintf(v.out, "Client: %#v\n", cv) 59 | 60 | resp, err := v.client.GetVersion() 61 | if err != nil { 62 | if grpc.Code(err) == codes.Unimplemented { 63 | return errors.New("server is too old to know its version") 64 | } 65 | return err 66 | } 67 | fmt.Fprintf(v.out, "Server: %#v\n", resp.Version) 68 | return nil 69 | } 70 | -------------------------------------------------------------------------------- /pkg/repo/testdata/unversioned-index.yaml: -------------------------------------------------------------------------------- 1 | memcached-0.1.0: 2 | name: memcached 3 | url: https://mumoshu.github.io/charts/memcached-0.1.0.tgz 4 | created: 2016-08-04 02:05:02.259205055 +0000 UTC 5 | checksum: ce9b76576c4b4eb74286fa30a978c56d69e7a522 6 | chartfile: 7 | name: memcached 8 | home: http://https://hub.docker.com/_/memcached/ 9 | sources: [] 10 | version: 0.1.0 11 | description: A simple Memcached cluster 12 | keywords: [] 13 | maintainers: 14 | - name: Matt Butcher 15 | email: mbutcher@deis.com 16 | engine: "" 17 | mysql-0.2.0: 18 | name: mysql 19 | url: https://mumoshu.github.io/charts/mysql-0.2.0.tgz 20 | created: 2016-08-04 00:42:47.517342022 +0000 UTC 21 | checksum: aa5edd2904d639b0b6295f1c7cf4c0a8e4f77dd3 22 | chartfile: 23 | name: mysql 24 | home: https://www.mysql.com/ 25 | sources: [] 26 | version: 0.2.0 27 | description: Chart running MySQL. 28 | keywords: [] 29 | maintainers: 30 | - name: Matt Fisher 31 | email: mfisher@deis.com 32 | engine: "" 33 | mysql-0.2.1: 34 | name: mysql 35 | url: https://mumoshu.github.io/charts/mysql-0.2.1.tgz 36 | created: 2016-08-04 02:40:29.717829534 +0000 UTC 37 | checksum: 9d9f056171beefaaa04db75680319ca4edb6336a 38 | chartfile: 39 | name: mysql 40 | home: https://www.mysql.com/ 41 | sources: [] 42 | version: 0.2.1 43 | description: Chart running MySQL. 44 | keywords: [] 45 | maintainers: 46 | - name: Matt Fisher 47 | email: mfisher@deis.com 48 | engine: "" 49 | mysql-0.2.2: 50 | name: mysql 51 | url: https://mumoshu.github.io/charts/mysql-0.2.2.tgz 52 | created: 2016-08-04 02:40:29.71841952 +0000 UTC 53 | checksum: 6d6810e76a5987943faf0040ec22990d9fb141c7 54 | chartfile: 55 | name: mysql 56 | home: https://www.mysql.com/ 57 | sources: [] 58 | version: 0.2.2 59 | description: Chart running MySQL. 60 | keywords: [] 61 | maintainers: 62 | - name: Matt Fisher 63 | email: mfisher@deis.com 64 | engine: "" 65 | -------------------------------------------------------------------------------- /cmd/helm/repo_remove_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "bytes" 21 | "os" 22 | "strings" 23 | "testing" 24 | 25 | "k8s.io/helm/cmd/helm/helmpath" 26 | "k8s.io/helm/pkg/repo" 27 | ) 28 | 29 | func TestRepoRemove(t *testing.T) { 30 | testURL := "https://test-url.com" 31 | 32 | b := bytes.NewBuffer(nil) 33 | 34 | home, err := tempHelmHome(t) 35 | defer os.Remove(home) 36 | hh := helmpath.Home(home) 37 | 38 | if err := removeRepoLine(b, testName, hh); err == nil { 39 | t.Errorf("Expected error removing %s, but did not get one.", testName) 40 | } 41 | if err := insertRepoLine(testName, testURL, hh); err != nil { 42 | t.Error(err) 43 | } 44 | 45 | mf, _ := os.Create(hh.CacheIndex(testName)) 46 | mf.Close() 47 | 48 | b.Reset() 49 | if err := removeRepoLine(b, testName, hh); err != nil { 50 | t.Errorf("Error removing %s from repositories", testName) 51 | } 52 | if !strings.Contains(b.String(), "has been removed") { 53 | t.Errorf("Unexpected output: %s", b.String()) 54 | } 55 | 56 | if _, err := os.Stat(hh.CacheIndex(testName)); err == nil { 57 | t.Errorf("Error cache file was not removed for repository %s", testName) 58 | } 59 | 60 | f, err := repo.LoadRepositoriesFile(hh.RepositoryFile()) 61 | if err != nil { 62 | t.Error(err) 63 | } 64 | 65 | if f.Has(testName) { 66 | t.Errorf("%s was not successfully removed from repositories list", testName) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /cmd/helm/serve.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | "os" 23 | "path/filepath" 24 | 25 | "github.com/spf13/cobra" 26 | 27 | "k8s.io/helm/cmd/helm/helmpath" 28 | "k8s.io/helm/pkg/repo" 29 | ) 30 | 31 | const serveDesc = `This command starts a local chart repository server that serves charts from a local directory.` 32 | 33 | type serveCmd struct { 34 | out io.Writer 35 | home helmpath.Home 36 | address string 37 | repoPath string 38 | } 39 | 40 | func newServeCmd(out io.Writer) *cobra.Command { 41 | srv := &serveCmd{out: out} 42 | cmd := &cobra.Command{ 43 | Use: "serve", 44 | Short: "start a local http web server", 45 | Long: serveDesc, 46 | RunE: func(cmd *cobra.Command, args []string) error { 47 | srv.home = helmpath.Home(homePath()) 48 | return srv.run() 49 | }, 50 | } 51 | cmd.Flags().StringVar(&srv.repoPath, "repo-path", helmpath.Home(homePath()).LocalRepository(), "The local directory path from which to serve charts.") 52 | cmd.Flags().StringVar(&srv.address, "address", "localhost:8879", "The address to listen on.") 53 | 54 | return cmd 55 | } 56 | 57 | func (s *serveCmd) run() error { 58 | repoPath, err := filepath.Abs(s.repoPath) 59 | if err != nil { 60 | return err 61 | } 62 | if _, err := os.Stat(repoPath); os.IsNotExist(err) { 63 | return err 64 | } 65 | 66 | fmt.Fprintf(s.out, "Now serving you on %s\n", s.address) 67 | return repo.StartLocalRepo(repoPath, s.address) 68 | } 69 | -------------------------------------------------------------------------------- /pkg/proto/hapi/chart/template.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: hapi/chart/template.proto 3 | // DO NOT EDIT! 4 | 5 | package chart 6 | 7 | import proto "github.com/golang/protobuf/proto" 8 | import fmt "fmt" 9 | import math "math" 10 | 11 | // Reference imports to suppress errors if they are not otherwise used. 12 | var _ = proto.Marshal 13 | var _ = fmt.Errorf 14 | var _ = math.Inf 15 | 16 | // Template represents a template as a name/value pair. 17 | // 18 | // By convention, name is a relative path within the scope of the chart's 19 | // base directory. 20 | type Template struct { 21 | // Name is the path-like name of the template. 22 | Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` 23 | // Data is the template as byte data. 24 | Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` 25 | } 26 | 27 | func (m *Template) Reset() { *m = Template{} } 28 | func (m *Template) String() string { return proto.CompactTextString(m) } 29 | func (*Template) ProtoMessage() {} 30 | func (*Template) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} } 31 | 32 | func init() { 33 | proto.RegisterType((*Template)(nil), "hapi.chart.Template") 34 | } 35 | 36 | func init() { proto.RegisterFile("hapi/chart/template.proto", fileDescriptor3) } 37 | 38 | var fileDescriptor3 = []byte{ 39 | // 106 bytes of a gzipped FileDescriptorProto 40 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0x48, 0x2c, 0xc8, 41 | 0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0xd1, 0x2f, 0x49, 0xcd, 0x2d, 0xc8, 0x49, 0x2c, 0x49, 0xd5, 42 | 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x02, 0x49, 0xe9, 0x81, 0xa5, 0x94, 0x8c, 0xb8, 0x38, 43 | 0x42, 0xa0, 0xb2, 0x42, 0x42, 0x5c, 0x2c, 0x79, 0x89, 0xb9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 44 | 0x9c, 0x41, 0x60, 0x36, 0x48, 0x2c, 0x25, 0xb1, 0x24, 0x51, 0x82, 0x09, 0x28, 0xc6, 0x13, 0x04, 45 | 0x66, 0x3b, 0xb1, 0x47, 0xb1, 0x82, 0x35, 0x27, 0xb1, 0x81, 0xcd, 0x33, 0x06, 0x04, 0x00, 0x00, 46 | 0xff, 0xff, 0x53, 0xee, 0x0e, 0x67, 0x6c, 0x00, 0x00, 0x00, 47 | } 48 | -------------------------------------------------------------------------------- /pkg/storage/filter.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package storage // import "k8s.io/helm/pkg/storage" 18 | 19 | import rspb "k8s.io/helm/pkg/proto/hapi/release" 20 | 21 | // FilterFunc returns true if the release object satisfies 22 | // the predicate of the underlying func. 23 | type FilterFunc func(*rspb.Release) bool 24 | 25 | // Check applies the FilterFunc to the release object. 26 | func (fn FilterFunc) Check(rls *rspb.Release) bool { 27 | if rls == nil { 28 | return false 29 | } 30 | return fn(rls) 31 | } 32 | 33 | // Any returns a FilterFunc that filters a list of releases 34 | // determined by the predicate 'f0 || f1 || ... || fn'. 35 | func Any(filters ...FilterFunc) FilterFunc { 36 | return func(rls *rspb.Release) bool { 37 | for _, filter := range filters { 38 | if filter(rls) { 39 | return true 40 | } 41 | } 42 | return false 43 | } 44 | } 45 | 46 | // All returns a FilterFunc that filters a list of releases 47 | // determined by the predicate 'f0 && f1 && ... && fn'. 48 | func All(filters ...FilterFunc) FilterFunc { 49 | return func(rls *rspb.Release) bool { 50 | for _, filter := range filters { 51 | if !filter(rls) { 52 | return false 53 | } 54 | } 55 | return true 56 | } 57 | } 58 | 59 | // StatusFilter filters a set of releases by status code. 60 | func StatusFilter(status rspb.Status_Code) FilterFunc { 61 | return FilterFunc(func(rls *rspb.Release) bool { 62 | if rls == nil { 63 | return true 64 | } 65 | return rls.GetInfo().GetStatus().Code == status 66 | }) 67 | } 68 | -------------------------------------------------------------------------------- /cmd/helm/verify.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | package main 17 | 18 | import ( 19 | "errors" 20 | "io" 21 | 22 | "github.com/spf13/cobra" 23 | 24 | "k8s.io/helm/cmd/helm/downloader" 25 | ) 26 | 27 | const verifyDesc = ` 28 | Verify that the given chart has a valid provenance file. 29 | 30 | Provenance files provide crytographic verification that a chart has not been 31 | tampered with, and was packaged by a trusted provider. 32 | 33 | This command can be used to verify a local chart. Several other commands provide 34 | '--verify' flags that run the same validation. To generate a signed package, use 35 | the 'helm package --sign' command. 36 | ` 37 | 38 | type verifyCmd struct { 39 | keyring string 40 | chartfile string 41 | 42 | out io.Writer 43 | } 44 | 45 | func newVerifyCmd(out io.Writer) *cobra.Command { 46 | vc := &verifyCmd{out: out} 47 | 48 | cmd := &cobra.Command{ 49 | Use: "verify [flags] PATH", 50 | Short: "verify that a chart at the given path has been signed and is valid", 51 | Long: verifyDesc, 52 | RunE: func(cmd *cobra.Command, args []string) error { 53 | if len(args) == 0 { 54 | return errors.New("a path to a package file is required") 55 | } 56 | vc.chartfile = args[0] 57 | return vc.run() 58 | }, 59 | } 60 | 61 | f := cmd.Flags() 62 | f.StringVar(&vc.keyring, "keyring", defaultKeyring(), "the keyring containing public keys.") 63 | 64 | return cmd 65 | } 66 | 67 | func (v *verifyCmd) run() error { 68 | _, err := downloader.VerifyChart(v.chartfile, v.keyring) 69 | return err 70 | } 71 | -------------------------------------------------------------------------------- /cmd/helm/get_hooks.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | 23 | "github.com/spf13/cobra" 24 | 25 | "k8s.io/helm/pkg/helm" 26 | ) 27 | 28 | const getHooksHelp = ` 29 | This command downloads hooks for a given release. 30 | 31 | Hooks are formatted in YAML and separated by the YAML '---\n' separator. 32 | ` 33 | 34 | type getHooksCmd struct { 35 | release string 36 | out io.Writer 37 | client helm.Interface 38 | version int32 39 | } 40 | 41 | func newGetHooksCmd(client helm.Interface, out io.Writer) *cobra.Command { 42 | ghc := &getHooksCmd{ 43 | out: out, 44 | client: client, 45 | } 46 | cmd := &cobra.Command{ 47 | Use: "hooks [flags] RELEASE_NAME", 48 | Short: "download all hooks for a named release", 49 | Long: getHooksHelp, 50 | RunE: func(cmd *cobra.Command, args []string) error { 51 | if len(args) == 0 { 52 | return errReleaseRequired 53 | } 54 | ghc.release = args[0] 55 | ghc.client = ensureHelmClient(ghc.client) 56 | return ghc.run() 57 | }, 58 | } 59 | cmd.Flags().Int32Var(&ghc.version, "revision", 0, "get the named release with revision") 60 | return cmd 61 | } 62 | 63 | func (g *getHooksCmd) run() error { 64 | res, err := g.client.ReleaseContent(g.release, helm.ContentReleaseVersion(g.version)) 65 | if err != nil { 66 | fmt.Fprintln(g.out, g.release) 67 | return prettyError(err) 68 | } 69 | 70 | for _, hook := range res.Release.Hooks { 71 | fmt.Fprintf(g.out, "---\n# %s\n%s", hook.Name, hook.Manifest) 72 | } 73 | return nil 74 | } 75 | -------------------------------------------------------------------------------- /_proto/hapi/chart/metadata.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Kubernetes Authors All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package hapi.chart; 18 | 19 | option go_package = "chart"; 20 | 21 | // Maintainer describes a Chart maintainer. 22 | message Maintainer { 23 | // Name is a user name or organization name 24 | string name = 1; 25 | 26 | // Email is an optional email address to contact the named maintainer 27 | string email = 2; 28 | } 29 | 30 | // Metadata for a Chart file. This models the structure of a Chart.yaml file. 31 | // 32 | // Spec: https://k8s.io/helm/blob/master/docs/design/chart_format.md#the-chart-file 33 | message Metadata { 34 | enum Engine { 35 | UNKNOWN = 0; 36 | GOTPL = 1; 37 | } 38 | // The name of the chart 39 | string name = 1; 40 | 41 | // The URL to a relevant project page, git repo, or contact person 42 | string home = 2; 43 | 44 | // Source is the URL to the source code of this chart 45 | repeated string sources = 3; 46 | 47 | // A SemVer 2 conformant version string of the chart 48 | string version = 4; 49 | 50 | // A one-sentence description of the chart 51 | string description = 5; 52 | 53 | // A list of string keywords 54 | repeated string keywords = 6; 55 | 56 | // A list of name and URL/email address combinations for the maintainer(s) 57 | repeated Maintainer maintainers = 7; 58 | 59 | // The name of the template engine to use. Defaults to 'gotpl'. 60 | string engine = 8; 61 | 62 | // The URL to an icon file. 63 | string icon = 9; 64 | 65 | // The API Version of this chart. 66 | string apiVersion = 10; 67 | } 68 | -------------------------------------------------------------------------------- /cmd/helm/helmpath/helmhome.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | package helmpath 17 | 18 | import ( 19 | "fmt" 20 | "path/filepath" 21 | ) 22 | 23 | // Home describes the location of a CLI configuration. 24 | // 25 | // This helper builds paths relative to a Helm Home directory. 26 | type Home string 27 | 28 | // String returns Home as a string. 29 | // 30 | // Implements fmt.Stringer. 31 | func (h Home) String() string { 32 | return string(h) 33 | } 34 | 35 | // Repository returns the path to the local repository. 36 | func (h Home) Repository() string { 37 | return filepath.Join(string(h), "repository") 38 | } 39 | 40 | // RepositoryFile returns the path to the repositories.yaml file. 41 | func (h Home) RepositoryFile() string { 42 | return filepath.Join(string(h), "repository/repositories.yaml") 43 | } 44 | 45 | // Cache returns the path to the local cache. 46 | func (h Home) Cache() string { 47 | return filepath.Join(string(h), "repository/cache") 48 | } 49 | 50 | // CacheIndex returns the path to an index for the given named repository. 51 | func (h Home) CacheIndex(name string) string { 52 | target := fmt.Sprintf("repository/cache/%s-index.yaml", name) 53 | return filepath.Join(string(h), target) 54 | } 55 | 56 | // LocalRepository returns the location to the local repo. 57 | // 58 | // The local repo is the one used by 'helm serve' 59 | // 60 | // If additional path elements are passed, they are appended to the returned path. 61 | func (h Home) LocalRepository(paths ...string) string { 62 | frag := append([]string{string(h), "repository/local"}, paths...) 63 | return filepath.Join(frag...) 64 | } 65 | -------------------------------------------------------------------------------- /cmd/helm/inspect_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "bytes" 21 | "io/ioutil" 22 | "strings" 23 | "testing" 24 | ) 25 | 26 | func TestInspect(t *testing.T) { 27 | b := bytes.NewBuffer(nil) 28 | 29 | insp := &inspectCmd{ 30 | chartpath: "testdata/testcharts/alpine", 31 | output: "both", 32 | out: b, 33 | } 34 | insp.run() 35 | 36 | // Load the data from the textfixture directly. 37 | cdata, err := ioutil.ReadFile("testdata/testcharts/alpine/Chart.yaml") 38 | if err != nil { 39 | t.Fatal(err) 40 | } 41 | data, err := ioutil.ReadFile("testdata/testcharts/alpine/values.yaml") 42 | if err != nil { 43 | t.Fatal(err) 44 | } 45 | 46 | parts := strings.SplitN(b.String(), "---", 2) 47 | if len(parts) != 2 { 48 | t.Fatalf("Expected 2 parts, got %d", len(parts)) 49 | } 50 | 51 | expect := []string{ 52 | strings.TrimSpace(string(cdata)), 53 | strings.TrimSpace(string(data)), 54 | } 55 | 56 | // Problem: ghodss/yaml doesn't marshal into struct order. To solve, we 57 | // have to carefully craft the Chart.yaml to match. 58 | for i, got := range parts { 59 | got = strings.TrimSpace(got) 60 | if got != expect[i] { 61 | t.Errorf("Expected\n%q\nGot\n%q\n", expect[i], got) 62 | } 63 | } 64 | 65 | // Regression tests for missing values. See issue #1024. 66 | b.Reset() 67 | insp = &inspectCmd{ 68 | chartpath: "testdata/testcharts/novals", 69 | output: "values", 70 | out: b, 71 | } 72 | insp.run() 73 | if b.Len() != 0 { 74 | t.Errorf("expected empty values buffer, got %q", b.String()) 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /pkg/chartutil/expand.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package chartutil 18 | 19 | import ( 20 | "archive/tar" 21 | "compress/gzip" 22 | "io" 23 | "os" 24 | "path/filepath" 25 | ) 26 | 27 | // Expand uncompresses and extracts a chart into the specified directory. 28 | func Expand(dir string, r io.Reader) error { 29 | gr, err := gzip.NewReader(r) 30 | if err != nil { 31 | return err 32 | } 33 | defer gr.Close() 34 | tr := tar.NewReader(gr) 35 | for { 36 | header, err := tr.Next() 37 | if err == io.EOF { 38 | break 39 | } else if err != nil { 40 | return err 41 | } 42 | 43 | //split header name and create missing directories 44 | d, _ := filepath.Split(header.Name) 45 | fullDir := filepath.Join(dir, d) 46 | _, err = os.Stat(fullDir) 47 | if err != nil && d != "" { 48 | if err := os.MkdirAll(fullDir, 0700); err != nil { 49 | return err 50 | } 51 | } 52 | 53 | path := filepath.Clean(filepath.Join(dir, header.Name)) 54 | info := header.FileInfo() 55 | if info.IsDir() { 56 | if err = os.MkdirAll(path, info.Mode()); err != nil { 57 | return err 58 | } 59 | continue 60 | } 61 | 62 | file, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode()) 63 | if err != nil { 64 | return err 65 | } 66 | defer file.Close() 67 | _, err = io.Copy(file, tr) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | return nil 73 | } 74 | 75 | // ExpandFile expands the src file into the dest directroy. 76 | func ExpandFile(dest, src string) error { 77 | h, err := os.Open(src) 78 | if err != nil { 79 | return err 80 | } 81 | defer h.Close() 82 | return Expand(dest, h) 83 | } 84 | -------------------------------------------------------------------------------- /cmd/helm/tunnel.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | 22 | "k8s.io/kubernetes/pkg/api" 23 | "k8s.io/kubernetes/pkg/client/unversioned" 24 | "k8s.io/kubernetes/pkg/labels" 25 | 26 | "k8s.io/helm/pkg/kube" 27 | ) 28 | 29 | // TODO refactor out this global var 30 | var tunnel *kube.Tunnel 31 | 32 | func newTillerPortForwarder(namespace string) (*kube.Tunnel, error) { 33 | kc := kube.New(nil) 34 | client, err := kc.Client() 35 | if err != nil { 36 | return nil, err 37 | } 38 | 39 | podName, err := getTillerPodName(client, namespace) 40 | if err != nil { 41 | return nil, err 42 | } 43 | const tillerPort = 44134 44 | return kc.ForwardPort(namespace, podName, tillerPort) 45 | } 46 | 47 | func getTillerPodName(client unversioned.PodsNamespacer, namespace string) (string, error) { 48 | // TODO use a const for labels 49 | selector := labels.Set{"app": "helm", "name": "tiller"}.AsSelector() 50 | pod, err := getFirstRunningPod(client, namespace, selector) 51 | if err != nil { 52 | return "", err 53 | } 54 | return pod.ObjectMeta.GetName(), nil 55 | } 56 | 57 | func getFirstRunningPod(client unversioned.PodsNamespacer, namespace string, selector labels.Selector) (*api.Pod, error) { 58 | options := api.ListOptions{LabelSelector: selector} 59 | pods, err := client.Pods(namespace).List(options) 60 | if err != nil { 61 | return nil, err 62 | } 63 | if len(pods.Items) < 1 { 64 | return nil, fmt.Errorf("could not find tiller") 65 | } 66 | for _, p := range pods.Items { 67 | if api.IsPodReady(&p) { 68 | return &p, nil 69 | } 70 | } 71 | return nil, fmt.Errorf("could not find a ready tiller pod") 72 | } 73 | -------------------------------------------------------------------------------- /cmd/helm/dependency_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | package main 17 | 18 | import ( 19 | "bytes" 20 | "strings" 21 | "testing" 22 | ) 23 | 24 | func TestDependencyListCmd(t *testing.T) { 25 | 26 | tests := []struct { 27 | name string 28 | args []string 29 | expect string 30 | err bool 31 | }{ 32 | { 33 | name: "No such chart", 34 | args: []string{"/no/such/chart"}, 35 | err: true, 36 | }, 37 | { 38 | name: "No requirements.yaml", 39 | args: []string{"testdata/testcharts/alpine"}, 40 | expect: "WARNING: no requirements at ", 41 | }, 42 | { 43 | name: "Requirements in chart dir", 44 | args: []string{"testdata/testcharts/reqtest"}, 45 | expect: "NAME \tVERSION\tREPOSITORY \tSTATUS \nreqsubchart \t0.1.0 \thttps://example.com/charts\tunpacked\nreqsubchart2\t0.2.0 \thttps://example.com/charts\tunpacked\n", 46 | }, 47 | { 48 | name: "Requirements in chart archive", 49 | args: []string{"testdata/testcharts/reqtest-0.1.0.tgz"}, 50 | expect: "NAME \tVERSION\tREPOSITORY \tSTATUS \nreqsubchart \t0.1.0 \thttps://example.com/charts\tmissing\nreqsubchart2\t0.2.0 \thttps://example.com/charts\tmissing\n", 51 | }, 52 | } 53 | 54 | for _, tt := range tests { 55 | buf := bytes.NewBuffer(nil) 56 | dlc := newDependencyListCmd(buf) 57 | if err := dlc.RunE(dlc, tt.args); err != nil { 58 | if tt.err { 59 | continue 60 | } 61 | t.Errorf("Test %q: %s", tt.name, err) 62 | continue 63 | } 64 | 65 | got := buf.String() 66 | if !strings.Contains(got, tt.expect) { 67 | t.Errorf("Test: %q, Expected:\n%q\nGot:\n%q", tt.name, tt.expect, got) 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /cmd/helm/get_manifest.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | 23 | "github.com/spf13/cobra" 24 | 25 | "k8s.io/helm/pkg/helm" 26 | ) 27 | 28 | var getManifestHelp = ` 29 | This command fetches the generated manifest for a given release. 30 | 31 | A manifest is a YAML-encoded representation of the Kubernetes resources that 32 | were generated from this release's chart(s). If a chart is dependent on other 33 | charts, those resources will also be included in the manifest. 34 | ` 35 | 36 | type getManifestCmd struct { 37 | release string 38 | out io.Writer 39 | client helm.Interface 40 | version int32 41 | } 42 | 43 | func newGetManifestCmd(client helm.Interface, out io.Writer) *cobra.Command { 44 | get := &getManifestCmd{ 45 | out: out, 46 | client: client, 47 | } 48 | cmd := &cobra.Command{ 49 | Use: "manifest [flags] RELEASE_NAME", 50 | Short: "download the manifest for a named release", 51 | Long: getManifestHelp, 52 | RunE: func(cmd *cobra.Command, args []string) error { 53 | if len(args) == 0 { 54 | return errReleaseRequired 55 | } 56 | get.release = args[0] 57 | if get.client == nil { 58 | get.client = helm.NewClient(helm.Host(tillerHost)) 59 | } 60 | return get.run() 61 | }, 62 | } 63 | 64 | cmd.Flags().Int32Var(&get.version, "revision", 0, "get the named release with revision") 65 | return cmd 66 | } 67 | 68 | // getManifest implements 'helm get manifest' 69 | func (g *getManifestCmd) run() error { 70 | res, err := g.client.ReleaseContent(g.release, helm.ContentReleaseVersion(g.version)) 71 | if err != nil { 72 | return prettyError(err) 73 | } 74 | fmt.Fprintln(g.out, res.Release.Manifest) 75 | return nil 76 | } 77 | -------------------------------------------------------------------------------- /cmd/helm/tunnel_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "testing" 21 | 22 | "k8s.io/kubernetes/pkg/api" 23 | "k8s.io/kubernetes/pkg/client/unversioned/testclient" 24 | ) 25 | 26 | func mockTillerPod() api.Pod { 27 | return api.Pod{ 28 | ObjectMeta: api.ObjectMeta{ 29 | Name: "orca", 30 | Namespace: api.NamespaceDefault, 31 | Labels: map[string]string{"app": "helm", "name": "tiller"}, 32 | }, 33 | Status: api.PodStatus{ 34 | Phase: api.PodRunning, 35 | Conditions: []api.PodCondition{ 36 | { 37 | Status: api.ConditionTrue, 38 | Type: api.PodReady, 39 | }, 40 | }, 41 | }, 42 | } 43 | } 44 | 45 | func mockTillerPodPending() api.Pod { 46 | p := mockTillerPod() 47 | p.Name = "blue" 48 | p.Status.Conditions[0].Status = api.ConditionFalse 49 | return p 50 | } 51 | 52 | func TestGetFirstPod(t *testing.T) { 53 | tests := []struct { 54 | name string 55 | pods []api.Pod 56 | expected string 57 | err bool 58 | }{ 59 | { 60 | name: "with a ready pod", 61 | pods: []api.Pod{mockTillerPod()}, 62 | expected: "orca", 63 | }, 64 | { 65 | name: "without a ready pod", 66 | pods: []api.Pod{mockTillerPodPending()}, 67 | err: true, 68 | }, 69 | { 70 | name: "without a pod", 71 | pods: []api.Pod{}, 72 | err: true, 73 | }, 74 | } 75 | 76 | for _, tt := range tests { 77 | client := testclient.NewSimpleFake(&api.PodList{Items: tt.pods}) 78 | name, err := getTillerPodName(client, api.NamespaceDefault) 79 | if (err != nil) != tt.err { 80 | t.Errorf("%q. expected error: %v, got %v", tt.name, tt.err, err) 81 | } 82 | if name != tt.expected { 83 | t.Errorf("%q. expected %q, got %q", tt.name, tt.expected, name) 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /pkg/storage/driver/records_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package driver // import "k8s.io/helm/pkg/storage/driver" 18 | 19 | import ( 20 | "testing" 21 | 22 | rspb "k8s.io/helm/pkg/proto/hapi/release" 23 | ) 24 | 25 | func TestRecordsAdd(t *testing.T) { 26 | rs := records([]*record{ 27 | newRecord("rls-a.v1", releaseStub("rls-a", 1, rspb.Status_SUPERSEDED)), 28 | newRecord("rls-a.v2", releaseStub("rls-a", 2, rspb.Status_DEPLOYED)), 29 | }) 30 | 31 | var tests = []struct { 32 | desc string 33 | key string 34 | ok bool 35 | rec *record 36 | }{ 37 | { 38 | "add valid key", 39 | "rls-a.v3", 40 | false, 41 | newRecord("rls-a.v3", releaseStub("rls-a", 3, rspb.Status_SUPERSEDED)), 42 | }, 43 | { 44 | "add already existing key", 45 | "rls-a.v1", 46 | true, 47 | newRecord("rls-a.v1", releaseStub("rls-a", 1, rspb.Status_DEPLOYED)), 48 | }, 49 | } 50 | 51 | for _, tt := range tests { 52 | if err := rs.Add(tt.rec); err != nil { 53 | if !tt.ok { 54 | t.Fatalf("failed: %q: %s\n", tt.desc, err) 55 | } 56 | } 57 | } 58 | } 59 | 60 | func TestRecordsRemove(t *testing.T) { 61 | var tests = []struct { 62 | desc string 63 | key string 64 | ok bool 65 | }{ 66 | {"remove valid key", "rls-a.v1", false}, 67 | {"remove invalid key", "rls-a.v", true}, 68 | {"remove non-existent key", "rls-z.v1", true}, 69 | } 70 | 71 | rs := records([]*record{ 72 | newRecord("rls-a.v1", releaseStub("rls-a", 1, rspb.Status_SUPERSEDED)), 73 | newRecord("rls-a.v2", releaseStub("rls-a", 2, rspb.Status_DEPLOYED)), 74 | }) 75 | 76 | for _, tt := range tests { 77 | if r := rs.Remove(tt.key); r == nil { 78 | if !tt.ok { 79 | t.Fatalf("Failed to %q (key = %s). Expected nil, got %s", 80 | tt.desc, 81 | tt.key, 82 | r, 83 | ) 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /scripts/sync-repo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2016 The Kubernetes Authors All rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # Bash 'Strict Mode' 18 | # http://redsymbol.net/articles/unofficial-bash-strict-mode 19 | set -euo pipefail 20 | IFS=$'\n\t' 21 | 22 | # Helper Functions ------------------------------------------------------------- 23 | 24 | # Display error message and exit 25 | error_exit() { 26 | echo "error: ${1:-"unknown error"}" 1>&2 27 | exit 1 28 | } 29 | 30 | # Checks if a command exists. Returns 1 or 0 31 | command_exists() { 32 | hash "${1}" 2>/dev/null 33 | } 34 | 35 | # Program Functions ------------------------------------------------------------ 36 | 37 | verify_prereqs() { 38 | echo "Verifying Prerequisites...." 39 | if command_exists gsutil; then 40 | echo "Thumbs up! Looks like you have gsutil. Let's continue." 41 | else 42 | error_exit "Couldn't find gsutil. Bailing out." 43 | fi 44 | } 45 | 46 | confirm() { 47 | case $response in 48 | [yY][eE][sS]|[yY]) 49 | true 50 | ;; 51 | *) 52 | false 53 | ;; 54 | esac 55 | } 56 | 57 | # Main ------------------------------------------------------------------------- 58 | 59 | main() { 60 | if [ "$#" -ne 2 ]; then 61 | error_exit "Illegal number of parameters. You must pass in local directory path and a GCS bucket name" 62 | fi 63 | 64 | echo "Getting ready to sync your local directory ($1) to a remote repository at gs://$2" 65 | 66 | verify_prereqs 67 | 68 | # dry run of the command 69 | gsutil rsync -d -n $1 gs://$2 70 | 71 | read -p "Are you sure you would like to continue with these changes? [y/N]} " confirm 72 | if [[ $confirm =~ [yY](es)* ]]; then 73 | gsutil rsync -d $1 gs://$2 74 | else 75 | error_exit "Discontinuing sync process." 76 | fi 77 | 78 | echo "Your remote chart repository now matches the contents of the $1 directory!" 79 | 80 | } 81 | 82 | main "${@:-}" 83 | -------------------------------------------------------------------------------- /cmd/helm/repo_remove.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | "os" 23 | 24 | "github.com/spf13/cobra" 25 | 26 | "k8s.io/helm/cmd/helm/helmpath" 27 | "k8s.io/helm/pkg/repo" 28 | ) 29 | 30 | type repoRemoveCmd struct { 31 | out io.Writer 32 | name string 33 | home helmpath.Home 34 | } 35 | 36 | func newRepoRemoveCmd(out io.Writer) *cobra.Command { 37 | remove := &repoRemoveCmd{ 38 | out: out, 39 | } 40 | 41 | cmd := &cobra.Command{ 42 | Use: "remove [flags] [NAME]", 43 | Aliases: []string{"rm"}, 44 | Short: "remove a chart repository", 45 | RunE: func(cmd *cobra.Command, args []string) error { 46 | if err := checkArgsLength(len(args), "name of chart repository"); err != nil { 47 | return err 48 | } 49 | remove.name = args[0] 50 | remove.home = helmpath.Home(homePath()) 51 | 52 | return remove.run() 53 | }, 54 | } 55 | 56 | return cmd 57 | } 58 | 59 | func (r *repoRemoveCmd) run() error { 60 | return removeRepoLine(r.out, r.name, r.home) 61 | } 62 | 63 | func removeRepoLine(out io.Writer, name string, home helmpath.Home) error { 64 | repoFile := home.RepositoryFile() 65 | r, err := repo.LoadRepositoriesFile(repoFile) 66 | if err != nil { 67 | return err 68 | } 69 | 70 | if !r.Remove(name) { 71 | return fmt.Errorf("no repo named %q found", name) 72 | } 73 | if err := r.WriteFile(repoFile, 0644); err != nil { 74 | return err 75 | } 76 | 77 | if err := removeRepoCache(name, home); err != nil { 78 | return err 79 | } 80 | 81 | fmt.Fprintf(out, "%q has been removed from your repositories", name) 82 | 83 | return nil 84 | } 85 | 86 | func removeRepoCache(name string, home helmpath.Home) error { 87 | if _, err := os.Stat(home.CacheIndex(name)); err == nil { 88 | err = os.Remove(home.CacheIndex(name)) 89 | if err != nil { 90 | return err 91 | } 92 | } 93 | return nil 94 | } 95 | -------------------------------------------------------------------------------- /cmd/tiller/kind_sorter.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "sort" 21 | ) 22 | 23 | // SortOrder is an ordering of Kinds. 24 | type SortOrder []string 25 | 26 | // InstallOrder is the order in which manifests should be installed (by Kind) 27 | var InstallOrder SortOrder = []string{"Namespace", "Secret", "ConfigMap", "PersistentVolume", "ServiceAccount", "Service", "Pod", "ReplicationController", "Deployment", "DaemonSet", "Ingress", "Job"} 28 | 29 | // UninstallOrder is the order in which manifests should be uninstalled (by Kind) 30 | var UninstallOrder SortOrder = []string{"Service", "Pod", "ReplicationController", "Deployment", "DaemonSet", "ConfigMap", "Secret", "PersistentVolume", "ServiceAccount", "Ingress", "Job", "Namespace"} 31 | 32 | // sortByKind does an in-place sort of manifests by Kind. 33 | // 34 | // Results are sorted by 'ordering' 35 | func sortByKind(manifests []manifest, ordering SortOrder) []manifest { 36 | ks := newKindSorter(manifests, ordering) 37 | sort.Sort(ks) 38 | return ks.manifests 39 | } 40 | 41 | type kindSorter struct { 42 | ordering map[string]int 43 | manifests []manifest 44 | } 45 | 46 | func newKindSorter(m []manifest, s SortOrder) *kindSorter { 47 | o := make(map[string]int, len(s)) 48 | for v, k := range s { 49 | o[k] = v 50 | } 51 | 52 | return &kindSorter{ 53 | manifests: m, 54 | ordering: o, 55 | } 56 | } 57 | 58 | func (k *kindSorter) Len() int { return len(k.manifests) } 59 | 60 | func (k *kindSorter) Swap(i, j int) { k.manifests[i], k.manifests[j] = k.manifests[j], k.manifests[i] } 61 | 62 | func (k *kindSorter) Less(i, j int) bool { 63 | a := k.manifests[i] 64 | b := k.manifests[j] 65 | first, ok := k.ordering[a.head.Kind] 66 | if !ok { 67 | // Unknown is always last 68 | return false 69 | } 70 | second, ok := k.ordering[b.head.Kind] 71 | if !ok { 72 | return true 73 | } 74 | return first < second 75 | } 76 | -------------------------------------------------------------------------------- /cmd/helm/dependency_build.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | package main 17 | 18 | import ( 19 | "io" 20 | 21 | "github.com/spf13/cobra" 22 | 23 | "k8s.io/helm/cmd/helm/downloader" 24 | "k8s.io/helm/cmd/helm/helmpath" 25 | ) 26 | 27 | const dependencyBuildDesc = ` 28 | Build out the charts/ directory from the requirements.lock file. 29 | 30 | Build is used to reconstruct a chart's dependencies to the state specified in 31 | the lock file. This will not re-negotiate dependencies, as 'helm dependency update' 32 | does. 33 | 34 | If no lock file is found, 'helm dependency build' will mirror the behavior 35 | of 'helm dependency update'. 36 | ` 37 | 38 | type dependencyBuildCmd struct { 39 | out io.Writer 40 | chartpath string 41 | verify bool 42 | keyring string 43 | helmhome helmpath.Home 44 | } 45 | 46 | func newDependencyBuildCmd(out io.Writer) *cobra.Command { 47 | dbc := &dependencyBuildCmd{ 48 | out: out, 49 | } 50 | 51 | cmd := &cobra.Command{ 52 | Use: "build [flags] CHART", 53 | Short: "rebuild the charts/ directory based on the requirements.lock file", 54 | Long: dependencyBuildDesc, 55 | RunE: func(cmd *cobra.Command, args []string) error { 56 | dbc.helmhome = helmpath.Home(homePath()) 57 | dbc.chartpath = "." 58 | 59 | if len(args) > 0 { 60 | dbc.chartpath = args[0] 61 | } 62 | return dbc.run() 63 | }, 64 | } 65 | 66 | f := cmd.Flags() 67 | f.BoolVar(&dbc.verify, "verify", false, "Verify the packages against signatures.") 68 | f.StringVar(&dbc.keyring, "keyring", defaultKeyring(), "The keyring containing public keys.") 69 | 70 | return cmd 71 | } 72 | 73 | func (d *dependencyBuildCmd) run() error { 74 | man := &downloader.Manager{ 75 | Out: d.out, 76 | ChartPath: d.chartpath, 77 | HelmHome: d.helmhome, 78 | Keyring: d.keyring, 79 | } 80 | if d.verify { 81 | man.Verify = downloader.VerifyIfPossible 82 | } 83 | 84 | return man.Build() 85 | } 86 | -------------------------------------------------------------------------------- /pkg/lint/support/message.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package support 18 | 19 | import "fmt" 20 | 21 | // Severity indicatest the severity of a Message. 22 | const ( 23 | // UnknownSev indicates that the severity of the error is unknown, and should not stop processing. 24 | UnknownSev = iota 25 | // InfoSev indicates information, for example missing values.yaml file 26 | InfoSev 27 | // WarningSev indicates that something does not meet code standards, but will likely function. 28 | WarningSev 29 | // ErrorSev indicates that something will not likely function. 30 | ErrorSev 31 | ) 32 | 33 | // sev matches the *Sev states. 34 | var sev = []string{"UNKNOWN", "INFO", "WARNING", "ERROR"} 35 | 36 | // Linter encapsulates a linting run of a particular chart. 37 | type Linter struct { 38 | Messages []Message 39 | // The highest severity of all the failing lint rules 40 | HighestSeverity int 41 | ChartDir string 42 | } 43 | 44 | // Message describes an error encountered while linting. 45 | type Message struct { 46 | // Severity is one of the *Sev constants 47 | Severity int 48 | Path string 49 | Err error 50 | } 51 | 52 | func (m Message) Error() string { 53 | return fmt.Sprintf("[%s] %s: %s", sev[m.Severity], m.Path, m.Err.Error()) 54 | } 55 | 56 | // NewMessage creates a new Message struct 57 | func NewMessage(severity int, path string, err error) Message { 58 | return Message{Severity: severity, Path: path, Err: err} 59 | } 60 | 61 | // RunLinterRule returns true if the validation passed 62 | func (l *Linter) RunLinterRule(severity int, path string, err error) bool { 63 | // severity is out of bound 64 | if severity < 0 || severity >= len(sev) { 65 | return false 66 | } 67 | 68 | if err != nil { 69 | l.Messages = append(l.Messages, NewMessage(severity, path, err)) 70 | 71 | if severity > l.HighestSeverity { 72 | l.HighestSeverity = severity 73 | } 74 | } 75 | return err == nil 76 | } 77 | -------------------------------------------------------------------------------- /cmd/helm/repo_add_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "bytes" 21 | "os" 22 | "testing" 23 | 24 | "k8s.io/helm/cmd/helm/helmpath" 25 | "k8s.io/helm/pkg/repo" 26 | "k8s.io/helm/pkg/repo/repotest" 27 | ) 28 | 29 | var testName = "test-name" 30 | 31 | func TestRepoAddCmd(t *testing.T) { 32 | srv, thome, err := repotest.NewTempServer("testdata/testserver/*.*") 33 | if err != nil { 34 | t.Fatal(err) 35 | } 36 | 37 | oldhome := homePath() 38 | helmHome = thome 39 | defer func() { 40 | srv.Stop() 41 | helmHome = oldhome 42 | os.Remove(thome) 43 | }() 44 | if err := ensureTestHome(helmpath.Home(thome), t); err != nil { 45 | t.Fatal(err) 46 | } 47 | 48 | tests := []releaseCase{ 49 | { 50 | name: "add a repository", 51 | args: []string{testName, srv.URL()}, 52 | expected: testName + " has been added to your repositories", 53 | }, 54 | } 55 | 56 | for _, tt := range tests { 57 | buf := bytes.NewBuffer(nil) 58 | c := newRepoAddCmd(buf) 59 | if err := c.RunE(c, tt.args); err != nil { 60 | t.Errorf("%q: expected %q, got %q", tt.name, tt.expected, err) 61 | } 62 | } 63 | } 64 | 65 | func TestRepoAdd(t *testing.T) { 66 | ts, thome, err := repotest.NewTempServer("testdata/testserver/*.*") 67 | if err != nil { 68 | t.Fatal(err) 69 | } 70 | 71 | oldhome := homePath() 72 | helmHome = thome 73 | hh := helmpath.Home(thome) 74 | defer func() { 75 | ts.Stop() 76 | helmHome = oldhome 77 | os.Remove(thome) 78 | }() 79 | if err := ensureTestHome(hh, t); err != nil { 80 | t.Fatal(err) 81 | } 82 | 83 | if err := addRepository(testName, ts.URL(), hh); err != nil { 84 | t.Error(err) 85 | } 86 | 87 | f, err := repo.LoadRepositoriesFile(hh.RepositoryFile()) 88 | if err != nil { 89 | t.Error(err) 90 | } 91 | 92 | if !f.Has(testName) { 93 | t.Errorf("%s was not successfully inserted into %s", testName, hh.RepositoryFile()) 94 | } 95 | } 96 | --------------------------------------------------------------------------------