feat(template): Allow template output to use release name (#7503)

* Allow template output to use release name

helm template output command uses the chart name only when writing
templates to disk. This changes will also use the release name
to avoid colloiding the path when output nore than one release
of smae chart.

Signed-off-by: Martin Hickey <martin.hickey@ie.ibm.com>

* Update after review

Comment:
- https://github.com/helm/helm/pull/7503/files#r374130090

Signed-off-by: Martin Hickey <martin.hickey@ie.ibm.com>
pull/7531/head
Martin Hickey 5 years ago committed by GitHub
parent 1897d4d60a
commit 084ab20f67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -137,6 +137,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
f.BoolVar(&includeCrds, "include-crds", false, "include CRDs in the templated output") f.BoolVar(&includeCrds, "include-crds", false, "include CRDs in the templated output")
f.BoolVar(&client.IsUpgrade, "is-upgrade", false, "set .Release.IsUpgrade instead of .Release.IsInstall") f.BoolVar(&client.IsUpgrade, "is-upgrade", false, "set .Release.IsUpgrade instead of .Release.IsInstall")
f.StringArrayVarP(&extraAPIs, "api-versions", "a", []string{}, "Kubernetes api versions used for Capabilities.APIVersions") f.StringArrayVarP(&extraAPIs, "api-versions", "a", []string{}, "Kubernetes api versions used for Capabilities.APIVersions")
f.BoolVar(&client.UseReleaseName, "release-name", false, "use release name in the output-dir path.")
return cmd return cmd
} }

@ -89,6 +89,9 @@ type Install struct {
APIVersions chartutil.VersionSet APIVersions chartutil.VersionSet
// Used by helm template to render charts with .Release.IsUpgrade. Ignored if Dry-Run is false // Used by helm template to render charts with .Release.IsUpgrade. Ignored if Dry-Run is false
IsUpgrade bool IsUpgrade bool
// Used by helm template to add the release as part of OutputDir path
// OutputDir/<ReleaseName>
UseReleaseName bool
} }
// ChartPathOptions captures common options used for controlling chart paths // ChartPathOptions captures common options used for controlling chart paths
@ -217,7 +220,7 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release.
rel := i.createRelease(chrt, vals) rel := i.createRelease(chrt, vals)
var manifestDoc *bytes.Buffer var manifestDoc *bytes.Buffer
rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.OutputDir, i.SubNotes) rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName)
// Even for errors, attach this if available // Even for errors, attach this if available
if manifestDoc != nil { if manifestDoc != nil {
rel.Manifest = manifestDoc.String() rel.Manifest = manifestDoc.String()
@ -421,7 +424,7 @@ func (i *Install) replaceRelease(rel *release.Release) error {
} }
// renderResources renders the templates in a chart // renderResources renders the templates in a chart
func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, outputDir string, subNotes bool) ([]*release.Hook, *bytes.Buffer, string, error) { func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName string, outputDir string, subNotes, useReleaseName bool) ([]*release.Hook, *bytes.Buffer, string, error) {
hs := []*release.Hook{} hs := []*release.Hook{}
b := bytes.NewBuffer(nil) b := bytes.NewBuffer(nil)
@ -498,7 +501,11 @@ func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values
if outputDir == "" { if outputDir == "" {
fmt.Fprintf(b, "---\n# Source: %s\n%s\n", m.Name, m.Content) fmt.Fprintf(b, "---\n# Source: %s\n%s\n", m.Name, m.Content)
} else { } else {
err = writeToFile(outputDir, m.Name, m.Content, fileWritten[m.Name]) newDir := outputDir
if useReleaseName {
newDir = filepath.Join(outputDir, releaseName)
}
err = writeToFile(newDir, m.Name, m.Content, fileWritten[m.Name])
if err != nil { if err != nil {
return hs, b, "", err return hs, b, "", err
} }

@ -471,6 +471,46 @@ func TestInstallReleaseOutputDir(t *testing.T) {
is.True(os.IsNotExist(err)) is.True(os.IsNotExist(err))
} }
func TestInstallOutputDirWithReleaseName(t *testing.T) {
is := assert.New(t)
instAction := installAction(t)
vals := map[string]interface{}{}
dir, err := ioutil.TempDir("", "output-dir")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(dir)
instAction.OutputDir = dir
instAction.UseReleaseName = true
instAction.ReleaseName = "madra"
newDir := filepath.Join(dir, instAction.ReleaseName)
_, err = instAction.Run(buildChart(withSampleTemplates(), withMultipleManifestTemplate()), vals)
if err != nil {
t.Fatalf("Failed install: %s", err)
}
_, err = os.Stat(filepath.Join(newDir, "hello/templates/goodbye"))
is.NoError(err)
_, err = os.Stat(filepath.Join(newDir, "hello/templates/hello"))
is.NoError(err)
_, err = os.Stat(filepath.Join(newDir, "hello/templates/with-partials"))
is.NoError(err)
_, err = os.Stat(filepath.Join(newDir, "hello/templates/rbac"))
is.NoError(err)
test.AssertGoldenFile(t, filepath.Join(newDir, "hello/templates/rbac"), "rbac.txt")
_, err = os.Stat(filepath.Join(newDir, "hello/templates/empty"))
is.True(os.IsNotExist(err))
}
func TestNameAndChart(t *testing.T) { func TestNameAndChart(t *testing.T) {
is := assert.New(t) is := assert.New(t)
instAction := installAction(t) instAction := installAction(t)

@ -161,7 +161,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin
return nil, nil, err return nil, nil, err
} }
hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", u.SubNotes) hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

Loading…
Cancel
Save