From b74fee715ee1d660be8fea8bf35942fc447a6a7e Mon Sep 17 00:00:00 2001 From: Martin Hickey Date: Wed, 13 Mar 2019 11:44:41 +0000 Subject: [PATCH] Add capability for application charts to be used as library charts Signed-off-by: Martin Hickey --- cmd/helm/template_test.go | 10 + ...te-chart-with-template-lib-archive-dep.txt | 62 ++ .../template-chart-with-template-lib-dep.txt | 62 ++ .../.helmignore | 21 + .../Chart.yaml | 6 + .../charts/common-0.0.5.tgz | Bin 0 -> 8446 bytes .../templates/NOTES.txt | 19 + .../templates/_helpers.tpl | 32 + .../templates/deployment.yaml | 51 ++ .../templates/ingress.yaml | 38 + .../templates/service.yaml | 10 + .../values.yaml | 48 + .../chart-with-template-lib-dep/.helmignore | 21 + .../chart-with-template-lib-dep/Chart.yaml | 6 + .../charts/common/.helmignore | 21 + .../charts/common/Chart.yaml | 12 + .../charts/common/README.md | 831 ++++++++++++++++++ .../charts/common/templates/_chartref.tpl | 14 + .../charts/common/templates/_configmap.yaml | 9 + .../charts/common/templates/_container.yaml | 15 + .../charts/common/templates/_deployment.yaml | 18 + .../charts/common/templates/_envvar.tpl | 31 + .../charts/common/templates/_fullname.tpl | 39 + .../charts/common/templates/_ingress.yaml | 27 + .../charts/common/templates/_metadata.yaml | 10 + .../templates/_metadata_annotations.tpl | 18 + .../common/templates/_metadata_labels.tpl | 28 + .../charts/common/templates/_name.tpl | 29 + .../templates/_persistentvolumeclaim.yaml | 24 + .../charts/common/templates/_secret.yaml | 10 + .../charts/common/templates/_service.yaml | 17 + .../charts/common/templates/_util.tpl | 15 + .../charts/common/templates/_volume.tpl | 22 + .../charts/common/templates/configmap.yaml | 6 + .../charts/common/values.yaml | 4 + .../templates/NOTES.txt | 19 + .../templates/_helpers.tpl | 32 + .../templates/deployment.yaml | 51 ++ .../templates/ingress.yaml | 38 + .../templates/service.yaml | 10 + .../chart-with-template-lib-dep/values.yaml | 48 + docs/charts.md | 4 + pkg/chart/loader/archive.go | 43 +- pkg/chart/loader/load.go | 57 +- pkg/registry/cache.go | 2 +- 45 files changed, 1883 insertions(+), 7 deletions(-) create mode 100644 cmd/helm/testdata/output/template-chart-with-template-lib-archive-dep.txt create mode 100644 cmd/helm/testdata/output/template-chart-with-template-lib-dep.txt create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/.helmignore create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/Chart.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/charts/common-0.0.5.tgz create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/templates/NOTES.txt create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/templates/_helpers.tpl create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/templates/deployment.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/templates/ingress.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/templates/service.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/values.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/.helmignore create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/Chart.yaml create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/.helmignore create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/Chart.yaml create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/README.md create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_chartref.tpl create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_configmap.yaml create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_container.yaml create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_deployment.yaml create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_envvar.tpl create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_fullname.tpl create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_ingress.yaml create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_metadata.yaml create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_metadata_annotations.tpl create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_metadata_labels.tpl create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_name.tpl create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_persistentvolumeclaim.yaml create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_secret.yaml create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_service.yaml create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_util.tpl create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_volume.tpl create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/configmap.yaml create mode 100755 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/values.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/templates/NOTES.txt create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/templates/_helpers.tpl create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/templates/deployment.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/templates/ingress.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/templates/service.yaml create mode 100644 cmd/helm/testdata/testcharts/chart-with-template-lib-dep/values.yaml diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index 65586c394..d4131acd3 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -64,6 +64,16 @@ func TestTemplateCmd(t *testing.T) { wantError: true, golden: "output/install-chart-bad-type.txt", }, + { + name: "check chart with dependency which is an app chart acting as a library chart", + cmd: fmt.Sprintf("template '%s'", "testdata/testcharts/chart-with-template-lib-dep"), + golden: "output/template-chart-with-template-lib-dep.txt", + }, + { + name: "check chart with dependency which is an app chart archive acting as a library chart", + cmd: fmt.Sprintf("template '%s'", "testdata/testcharts/chart-with-template-lib-archive-dep"), + golden: "output/template-chart-with-template-lib-archive-dep.txt", + }, } runTestCmd(t, tests) } diff --git a/cmd/helm/testdata/output/template-chart-with-template-lib-archive-dep.txt b/cmd/helm/testdata/output/template-chart-with-template-lib-archive-dep.txt new file mode 100644 index 000000000..d92f71308 --- /dev/null +++ b/cmd/helm/testdata/output/template-chart-with-template-lib-archive-dep.txt @@ -0,0 +1,62 @@ +--- +# Source: chart-with-template-lib-archive-dep/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + labels: + app: chart-with-template-lib-archive-dep + chart: chart-with-template-lib-archive-dep-0.1.0 + heritage: Helm + release: RELEASE-NAME + name: release-name-chart-with-template-lib-archive-dep +spec: + ports: + - name: http + port: 80 + targetPort: http + selector: + app: chart-with-template-lib-archive-dep + release: RELEASE-NAME + type: ClusterIP +--- +# Source: chart-with-template-lib-archive-dep/templates/deployment.yaml +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: RELEASE-NAME-chart-with-template-lib-archive-dep + labels: + app: chart-with-template-lib-archive-dep + chart: chart-with-template-lib-archive-dep-0.1.0 + release: RELEASE-NAME + heritage: Helm +spec: + replicas: 1 + selector: + matchLabels: + app: chart-with-template-lib-archive-dep + release: RELEASE-NAME + template: + metadata: + labels: + app: chart-with-template-lib-archive-dep + release: RELEASE-NAME + spec: + containers: + - name: chart-with-template-lib-archive-dep + image: "nginx:stable" + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 80 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {} + diff --git a/cmd/helm/testdata/output/template-chart-with-template-lib-dep.txt b/cmd/helm/testdata/output/template-chart-with-template-lib-dep.txt new file mode 100644 index 000000000..64a6b305d --- /dev/null +++ b/cmd/helm/testdata/output/template-chart-with-template-lib-dep.txt @@ -0,0 +1,62 @@ +--- +# Source: chart-with-template-lib-dep/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + labels: + app: chart-with-template-lib-dep + chart: chart-with-template-lib-dep-0.1.0 + heritage: Helm + release: RELEASE-NAME + name: release-name-chart-with-template-lib-dep +spec: + ports: + - name: http + port: 80 + targetPort: http + selector: + app: chart-with-template-lib-dep + release: RELEASE-NAME + type: ClusterIP +--- +# Source: chart-with-template-lib-dep/templates/deployment.yaml +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: RELEASE-NAME-chart-with-template-lib-dep + labels: + app: chart-with-template-lib-dep + chart: chart-with-template-lib-dep-0.1.0 + release: RELEASE-NAME + heritage: Helm +spec: + replicas: 1 + selector: + matchLabels: + app: chart-with-template-lib-dep + release: RELEASE-NAME + template: + metadata: + labels: + app: chart-with-template-lib-dep + release: RELEASE-NAME + spec: + containers: + - name: chart-with-template-lib-dep + image: "nginx:stable" + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 80 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {} + diff --git a/cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/.helmignore b/cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/.helmignore new file mode 100644 index 000000000..f0c131944 --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/Chart.yaml b/cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/Chart.yaml new file mode 100644 index 000000000..de53ce5e3 --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +appVersion: "1.0" +description: A Helm chart for Kubernetes +name: chart-with-template-lib-archive-dep +type: application +version: 0.1.0 diff --git a/cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/charts/common-0.0.5.tgz b/cmd/helm/testdata/testcharts/chart-with-template-lib-archive-dep/charts/common-0.0.5.tgz new file mode 100644 index 0000000000000000000000000000000000000000..465517824e7a2e6492cede07e7233e7120506185 GIT binary patch literal 8446 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