From 7cf9d23f28d45e2e39338cd10d097ccb433795cc Mon Sep 17 00:00:00 2001 From: Chance Zibolski Date: Wed, 11 Apr 2018 14:46:18 -0700 Subject: [PATCH] Update helm template -x to support children chart manifests in more cases The previous code validated the manifests exist within the file system, which only works when a chart is unpacked, meaning children charts stored as tgz's in the parent chart's `charts/` directory don't exist as individual files in the filesystem, causing validation to file. Instead, we validate against the paths within the chart itself rather than the filesystem, handling both chart.tgz's and charts that are unpacked as directories in the chart/ directory. --- cmd/helm/template.go | 78 ++++++++++++++++++++------------------- cmd/helm/template_test.go | 7 ++++ 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/cmd/helm/template.go b/cmd/helm/template.go index c04bc2dc8..fc1f44392 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -117,31 +117,10 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error { } else { return err } - // verify specified templates exist relative to chart - rf := []string{} - var af string - var err error - if len(t.renderFiles) > 0 { - for _, f := range t.renderFiles { - if !filepath.IsAbs(f) { - af, err = filepath.Abs(filepath.Join(t.chartPath, f)) - if err != nil { - return fmt.Errorf("could not resolve template path: %s", err) - } - } else { - af = f - } - rf = append(rf, af) - - if _, err := os.Stat(af); err != nil { - return fmt.Errorf("could not resolve template path: %s", err) - } - } - } // verify that output-dir exists if provided if t.outputDir != "" { - _, err = os.Stat(t.outputDir) + _, err := os.Stat(t.outputDir) if os.IsNotExist(err) { return fmt.Errorf("output-dir '%s' does not exist", t.outputDir) } @@ -232,19 +211,7 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error { m := tiller.Manifest{Name: k, Content: v, Head: &util.SimpleHead{Kind: h}} listManifests = append(listManifests, m) } - in := func(needle string, haystack []string) bool { - // make needle path absolute - d := strings.Split(needle, string(os.PathSeparator)) - dd := d[1:] - an := filepath.Join(t.chartPath, strings.Join(dd, string(os.PathSeparator))) - - for _, h := range haystack { - if h == an { - return true - } - } - return false - } + if settings.Debug { rel := &release.Release{ Name: t.releaseName, @@ -257,10 +224,45 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error { printRelease(os.Stdout, rel) } - for _, m := range tiller.SortByKind(listManifests) { - if len(t.renderFiles) > 0 && !in(m.Name, rf) { - continue + var manifestsToRender []tiller.Manifest + + // if we have a list of files to render, then check that each of the + // provided files exists in the chart. + if len(t.renderFiles) > 0 { + for _, f := range t.renderFiles { + missing := true + if !filepath.IsAbs(f) { + newF, err := filepath.Abs(filepath.Join(t.chartPath, f)) + if err != nil { + return fmt.Errorf("could not turn template path %s into absolute path: %s", f, err) + } + f = newF + } + + for _, manifest := range listManifests { + manifestPathSplit := strings.Split(manifest.Name, string(filepath.Separator)) + // remove the chart name from the path + manifestPathSplit = manifestPathSplit[1:] + toJoin := append([]string{t.chartPath}, manifestPathSplit...) + manifestPath := filepath.Join(toJoin...) + + // if the filepath provided matches a manifest path in the + // chart, render that manifest + if f == manifestPath { + manifestsToRender = append(manifestsToRender, manifest) + missing = false + } + } + if missing { + return fmt.Errorf("could not find template %s in chart", f) + } } + } else { + // no renderFiles provided, render all manifests in the chart + manifestsToRender = listManifests + } + + for _, m := range tiller.SortByKind(manifestsToRender) { data := m.Content b := filepath.Base(m.Name) if !t.showNotes && b == "NOTES.txt" { diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index eefa46774..bbcc9f3af 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -69,6 +69,13 @@ func TestTemplateCmd(t *testing.T) { expectKey: "subchart1/templates/service.yaml", expectValue: "protocol: TCP\n name: apache", }, + { + name: "check_execute_subchart_template", + desc: "verify --execute single template on a subchart template", + args: []string{chartPath, "-x", "charts/subcharta/templates/service.yaml", "--set", "subcharta.service.name=foobar"}, + expectKey: "subchart1/charts/subcharta/templates/service.yaml", + expectValue: "protocol: TCP\n name: foobar", + }, { name: "check_namespace", desc: "verify --namespace",