diff --git a/cmd/helm/template.go b/cmd/helm/template.go index 0ddd0c551..a42cdda87 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -79,6 +79,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { client.ClientOnly = !validate client.APIVersions = chartutil.VersionSet(extraAPIs) client.IncludeCRDs = includeCrds + client.ShowFiles = showFiles rel, err := runInstall(args, client, valueOpts, out) if err != nil && !settings.Debug { @@ -133,7 +134,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { sort.Sort(releaseutil.BySplitManifestsOrder(manifestsKeys)) manifestNameRegex := regexp.MustCompile("# Source: [^/]+/(.+)") - var manifestsToRender []string + manifestsToRender := map[string]string{} for _, f := range showFiles { missing := true // Use linux-style filepath separators to unify user's input path @@ -157,15 +158,29 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { if matched, _ := filepath.Match(f, manifestPath); !matched { continue } - manifestsToRender = append(manifestsToRender, manifest) + manifestsToRender[manifestName] = manifest missing = false } if missing { - return fmt.Errorf("could not find template %s in chart", f) + fmt.Printf("could not find template %s in chart\n", f) } } - for _, m := range manifestsToRender { - fmt.Fprintf(out, "---\n%s\n", m) + + for fileName, manifest := range manifestsToRender { + if client.OutputDir == "" { + fmt.Fprintf(out, "---\n%s\n", manifest) + } else { + fileWritten := make(map[string]bool) + newDir := client.OutputDir + if client.UseReleaseName { + newDir = filepath.Join(client.OutputDir, client.ReleaseName) + } + err = writeToFile(newDir, fileName, manifest, fileWritten[fileName]) + if err != nil { + return err + } + fileWritten[fileName] = true + } } } else { fmt.Fprintf(out, "%s", manifests.String()) diff --git a/pkg/action/action.go b/pkg/action/action.go index 82760250f..915cf07a4 100644 --- a/pkg/action/action.go +++ b/pkg/action/action.go @@ -101,8 +101,9 @@ type Configuration struct { // // TODO: This function is badly in need of a refactor. // TODO: As part of the refactor the duplicate code in cmd/helm/template.go should be removed -// This code has to do with writing files to disk. -func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrender.PostRenderer, dryRun bool) ([]*release.Hook, *bytes.Buffer, string, error) { +// +// This code has to do with writing files to disk. +func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName, outputDir string, showFiles []string, subNotes, useReleaseName, includeCrds bool, pr postrender.PostRenderer, dryRun bool) ([]*release.Hook, *bytes.Buffer, string, error) { hs := []*release.Hook{} b := bytes.NewBuffer(nil) @@ -183,8 +184,8 @@ func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Valu if includeCrds { for _, crd := range ch.CRDObjects() { - if outputDir == "" { - fmt.Fprintf(b, "---\n# Source: %s\n%s\n", crd.Name, string(crd.File.Data[:])) + if outputDir == "" || len(showFiles) > 0 { + fmt.Fprintf(b, "---\n# Source: %s\n%s\n", crd.Filename, string(crd.File.Data[:])) } else { err = writeToFile(outputDir, crd.Filename, string(crd.File.Data[:]), fileWritten[crd.Name]) if err != nil { @@ -196,7 +197,7 @@ func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Valu } for _, m := range manifests { - if outputDir == "" { + if outputDir == "" || len(showFiles) > 0 { fmt.Fprintf(b, "---\n# Source: %s\n%s\n", m.Name, m.Content) } else { newDir := outputDir diff --git a/pkg/action/install.go b/pkg/action/install.go index 425b66f69..7323ce92f 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -90,6 +90,8 @@ type Install struct { SubNotes bool DisableOpenAPIValidation bool IncludeCRDs bool + // ShowFiles allows only show manifests rendered from the given templates + ShowFiles []string // KubeVersion allows specifying a custom kubernetes version to use and // APIVersions allows a manual set of supported API Versions to be passed // (for things like templating). These are ignored if ClientOnly is false @@ -257,7 +259,7 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma rel := i.createRelease(chrt, vals) var manifestDoc *bytes.Buffer - rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, i.DryRun) + rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.ShowFiles, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, i.DryRun) // Even for errors, attach this if available if manifestDoc != nil { rel.Manifest = manifestDoc.String() @@ -457,10 +459,10 @@ func (i *Install) failRelease(rel *release.Release, err error) (*release.Release // // Roughly, this will return an error if name is // -// - empty -// - too long -// - already in use, and not deleted -// - used by a deleted release, and i.Replace is false +// - empty +// - too long +// - already in use, and not deleted +// - used by a deleted release, and i.Replace is false func (i *Install) availableName() error { start := i.ReleaseName diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index 690397d4a..75595b15d 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -231,7 +231,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin return nil, nil, err } - hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, u.DryRun) + hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", []string{}, u.SubNotes, false, false, u.PostRenderer, u.DryRun) if err != nil { return nil, nil, err }