From 24578a6411d58e59df8ca633c88d2828652b47a1 Mon Sep 17 00:00:00 2001 From: Torsten Walter Date: Mon, 20 May 2019 10:46:42 +0200 Subject: [PATCH] support --output-dir option for helm3 template Signed-off-by: Torsten Walter --- cmd/helm/template.go | 6 +++++ pkg/action/install.go | 53 ++++++++++++++++++++++++++++++++++++++++--- pkg/action/upgrade.go | 2 +- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/cmd/helm/template.go b/cmd/helm/template.go index 5dd723abe..aa61d0e43 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -23,6 +23,7 @@ import ( "strings" "github.com/spf13/cobra" + "github.com/spf13/pflag" "helm.sh/helm/cmd/helm/require" "helm.sh/helm/pkg/action" @@ -77,6 +78,11 @@ func newTemplateCmd(out io.Writer) *cobra.Command { } addInstallFlags(cmd.Flags(), client) + addTemplateFlags(cmd.Flags(), client) return cmd } + +func addTemplateFlags(f *pflag.FlagSet, client *action.Install) { + f.StringVar(&client.OutputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout") +} diff --git a/pkg/action/install.go b/pkg/action/install.go index 33cd6b53a..2722d31bd 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -61,6 +61,8 @@ const releaseNameMaxLen = 53 // since there can be filepath in front of it. const notesFileSuffix = "NOTES.txt" +const defaultDirectoryPermission = 0755 + // Install performs an installation operation. type Install struct { cfg *Configuration @@ -79,6 +81,7 @@ type Install struct { ReleaseName string GenerateName bool NameTemplate string + OutputDir string } type ValueOptions struct { @@ -132,7 +135,7 @@ func (i *Install) Run(chrt *chart.Chart) (*release.Release, error) { rel := i.createRelease(chrt, i.rawValues) var manifestDoc *bytes.Buffer - rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender) + rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.OutputDir) // Even for errors, attach this if available if manifestDoc != nil { rel.Manifest = manifestDoc.String() @@ -305,7 +308,7 @@ func (i *Install) replaceRelease(rel *release.Release) error { } // renderResources renders the templates in a chart -func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values) ([]*release.Hook, *bytes.Buffer, string, error) { +func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, outputDir string) ([]*release.Hook, *bytes.Buffer, string, error) { hs := []*release.Hook{} b := bytes.NewBuffer(nil) @@ -363,12 +366,56 @@ func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values // Aggregate all valid manifests into one big doc. for _, m := range manifests { - fmt.Fprintf(b, "---\n# Source: %s\n%s\n", m.Name, m.Content) + if outputDir == "" { + fmt.Fprintf(b, "---\n# Source: %s\n%s\n", m.Name, m.Content) + } else { + err = writeToFile("build", m.Name, m.Content) + if err != nil { + return hs, b, "", err + } + } } return hs, b, notes, nil } +// write the to / +func writeToFile(outputDir string, name string, data string) error { + outfileName := strings.Join([]string{outputDir, name}, string(filepath.Separator)) + + err := ensureDirectoryForFile(outfileName) + if err != nil { + return err + } + + f, err := os.Create(outfileName) + if err != nil { + return err + } + + defer f.Close() + + _, err = f.WriteString(fmt.Sprintf("---\n# Source: %s\n%s", name, data)) + + if err != nil { + return err + } + + fmt.Printf("wrote %s\n", outfileName) + return nil +} + +// check if the directory exists to create file. creates if don't exists +func ensureDirectoryForFile(file string) error { + baseDir := path.Dir(file) + _, err := os.Stat(baseDir) + if err != nil && !os.IsNotExist(err) { + return err + } + + return os.MkdirAll(baseDir, defaultDirectoryPermission) +} + // validateManifest checks to see whether the given manifest is valid for the current Kubernetes func (i *Install) validateManifest(manifest io.Reader) error { _, err := i.cfg.KubeClient.BuildUnstructured(manifest) diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index eddacc6ea..7e79d3971 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -159,7 +159,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart) (*release.Rele return nil, nil, err } - hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender) + hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "") if err != nil { return nil, nil, err }