pull/31096/merge
Bhargav Ravuri 2 days ago committed by GitHub
commit 207e7bf890
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -27,6 +27,7 @@ import (
"path"
"path/filepath"
"slices"
"sort"
"strings"
"sync"
"text/template"
@ -177,7 +178,9 @@ func splitAndDeannotate(postrendered string) (map[string]string, error) {
// 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 common.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrenderer.PostRenderer, interactWithRemote, enableDNS, hideSecret bool) ([]*release.Hook, *bytes.Buffer, string, error) {
func (cfg *Configuration) renderResources(ch *chart.Chart, values common.Values, releaseName, outputDir string,
renderSubchartNotes, useReleaseName, includeCrds bool, pr postrenderer.PostRenderer, interactWithRemote, enableDNS,
hideSecret, isDryRun bool) ([]*release.Hook, *bytes.Buffer, string, error) {
var hs []*release.Hook
b := bytes.NewBuffer(nil)
@ -225,20 +228,71 @@ func (cfg *Configuration) renderResources(ch *chart.Chart, values common.Values,
// text file. We have to spin through this map because the file contains path information, so we
// look for terminating NOTES.txt. We also remove it from the files so that we don't have to skip
// it in the sortHooks.
var notesBuffer bytes.Buffer
for k, v := range files {
if strings.HasSuffix(k, notesFileSuffix) {
if subNotes || (k == path.Join(ch.Name(), "templates", notesFileSuffix)) {
// If buffer contains data, add newline before adding more
if notesBuffer.Len() > 0 {
notesBuffer.WriteString("\n")
}
notesBuffer.WriteString(v)
//
// If --render-subchart-notes flag is enabled, the NOTES.txt files from the subcharts are also included by rendering
// engine.
notesFilePathToContent := make(map[string]string)
notesFilePaths := make([]string, 0)
for filePath, fileContent := range files {
// Filter the notes filepath(s), i.e., filepaths that end with "NOTES.txt", from all files. Note: Depending on
// the --render-subchart-notes flag, there may be more than one notes file.
if strings.HasSuffix(filePath, notesFileSuffix) {
// If --render-subchart-notes flag is enabled, add all the notes files, i.e., notes from the root chart, and
// subcharts, if any.
//
// If not enabled, select just the root chart's notes file, which will be in the format:
// <chart-name>/templates/NOTES.txt
if renderSubchartNotes || (filePath == path.Join(ch.Name(), "templates", notesFileSuffix)) {
// Store the notes file's (path -> content) pairs. In a dry run, the notes file names will be useful as
// the source details in the output.
//
// Since the filepaths are of already existing files, they will be unique. No checks needed.
notesFilePathToContent[filePath] = fileContent
// Store the list of notes filepaths. The list will be used for ordering and will be sorted in the next
// steps.
notesFilePaths = append(notesFilePaths, filePath)
}
delete(files, k)
// Remove the notes files from the manifest files list. Rendered notes will be returned separately.
delete(files, filePath)
}
}
notes := notesBuffer.String()
// Sort the notes filepaths based on depth first, and then in alphabetical order. Since the notes file's names are
// the same for all charts, the ordering is based on the chart names and notes filepaths.
//
// For example, for a chart and its subcharts in the hierarchy as follows:
//
// foo
// └── charts
// ├── bar
// │ └── charts
// │ └── qux
// └── baz
//
// The notes files must be sorted as follows:
// 1. foo/templates/NOTES.txt
// 2. foo/charts/bar/templates/NOTES.txt
// 3. foo/charts/baz/templates/NOTES.txt
// 4. foo/charts/bar/charts/qux/templates/NOTES.txt
sort.Slice(notesFilePaths, func(notesI, notesJ int) bool {
// Count the number of occurrences of the string "/charts/" for depth.
depth := func(s string) int {
return strings.Count(s, "/charts/")
}
// When the depth of both charts is not the same, the smaller depth one goes first. In the above example, foo
// goes before bar and baz, and bar goes before qux.
depthI := depth(notesFilePaths[notesI])
depthJ := depth(notesFilePaths[notesJ])
if depthI != depthJ {
return depthI < depthJ
}
// When both charts have the same depth, like bar and baz in the above example, use alphabetical order.
return notesFilePaths[notesI] < notesFilePaths[notesJ]
})
if pr != nil {
// We need to send files to the post-renderer before sorting and splitting
@ -251,19 +305,19 @@ func (cfg *Configuration) renderResources(ch *chart.Chart, values common.Values,
// Merge files as stream of documents for sending to post renderer
merged, err := annotateAndMerge(files)
if err != nil {
return hs, b, notes, fmt.Errorf("error merging manifests: %w", err)
return hs, b, "", fmt.Errorf("error merging manifests: %w", err)
}
// Run the post renderer
postRendered, err := pr.Run(bytes.NewBufferString(merged))
if err != nil {
return hs, b, notes, fmt.Errorf("error while running post render on files: %w", err)
return hs, b, "", fmt.Errorf("error while running post render on files: %w", err)
}
// Use the file list and contents received from the post renderer
files, err = splitAndDeannotate(postRendered.String())
if err != nil {
return hs, b, notes, fmt.Errorf("error while parsing post rendered output: %w", err)
return hs, b, "", fmt.Errorf("error while parsing post rendered output: %w", err)
}
}
@ -327,7 +381,62 @@ func (cfg *Configuration) renderResources(ch *chart.Chart, values common.Values,
}
}
return hs, b, notes, nil
// The rendered notes are returned as a string, which can be used in the output of the calling command. If
// --render-subchart-notes is enabled, the notes from the subcharts are also included in the output in an ordered
// manner, separated by empty lines.
//
// foo NOTES HERE
//
// bar NOTES HERE
//
// baz NOTES HERE
//
// qux NOTES HERE
//
// In a dry run, the notes are prefixed with the source file name and separator instead of an empty line as follows.
// For helm install/upgrade commands, dry run can be enabled by using the `--dry-run` flag. The helm template
// command is considered a dry run by default. However, to include notes in the helm template, the `--notes` flag
// must be enabled.
//
// ---
// # Source: foo/templates/NOTES.txt
// foo NOTES HERE
//
// If --render-subchart-notes is enabled on dry run with any of those commands, the notes from the subcharts are
// also included in the output.
//
// ---
// # Source: foo/templates/NOTES.txt
// foo NOTES HERE
// ---
// # Source: foo/charts/bar/templates/NOTES.txt
// bar NOTES HERE
// ---
// # Source: foo/charts/baz/templates/NOTES.txt
// baz NOTES HERE
// ---
// # Source: foo/charts/bar/charts/qux/templates/NOTES.txt
// qux NOTES HERE
//
// Note: The order of the notes files above is based on depth first, and then in alphabetical order.
var renderedNotes bytes.Buffer
for _, noteFilePath := range notesFilePaths {
// When dry run is enabled, add the notes file name and separator to the notes and write to the buffer.
if isDryRun {
fmt.Fprintf(&renderedNotes, "---\n# Source: %s\n%s", noteFilePath, notesFilePathToContent[noteFilePath])
continue
}
// When dry run is disabled, write rendered notes to the buffer. If the buffer contains data, add a newline to
// separate from the next note.
if renderedNotes.Len() > 0 {
renderedNotes.WriteString("\n")
}
renderedNotes.WriteString(notesFilePathToContent[noteFilePath])
}
return hs, b, renderedNotes.String(), nil
}
// RESTClientGetter gets the rest client

@ -788,7 +788,7 @@ func TestRenderResources_PostRenderer_Success(t *testing.T) {
hooks, buf, notes, err := cfg.renderResources(
ch, values, "test-release", "", false, false, false,
mockPR, false, false, false,
mockPR, false, false, false, false,
)
assert.NoError(t, err)
@ -831,7 +831,7 @@ func TestRenderResources_PostRenderer_Error(t *testing.T) {
_, _, _, err := cfg.renderResources(
ch, values, "test-release", "", false, false, false,
mockPR, false, false, false,
mockPR, false, false, false, false,
)
assert.Error(t, err)
@ -859,7 +859,7 @@ func TestRenderResources_PostRenderer_MergeError(t *testing.T) {
_, _, _, err := cfg.renderResources(
ch, values, "test-release", "", false, false, false,
mockPR, false, false, false,
mockPR, false, false, false, false,
)
assert.Error(t, err)
@ -881,7 +881,7 @@ func TestRenderResources_PostRenderer_SplitError(t *testing.T) {
_, _, _, err := cfg.renderResources(
ch, values, "test-release", "", false, false, false,
mockPR, false, false, false,
mockPR, false, false, false, false,
)
assert.Error(t, err)
@ -902,7 +902,7 @@ func TestRenderResources_PostRenderer_Integration(t *testing.T) {
hooks, buf, notes, err := cfg.renderResources(
ch, values, "test-release", "", false, false, false,
mockPR, false, false, false,
mockPR, false, false, false, false,
)
assert.NoError(t, err)
@ -938,7 +938,7 @@ func TestRenderResources_NoPostRenderer(t *testing.T) {
hooks, buf, notes, err := cfg.renderResources(
ch, values, "test-release", "", false, false, false,
nil, false, false, false,
nil, false, false, false, false,
)
assert.NoError(t, err)

@ -353,7 +353,9 @@ func (i *Install) RunWithContext(ctx context.Context, ch ci.Charter, vals map[st
rel := i.createRelease(chrt, vals, i.Labels)
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, interactWithRemote, i.EnableDNS, i.HideSecret)
rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName,
i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, interactWithRemote, i.EnableDNS,
i.HideSecret, i.isDryRun())
// Even for errors, attach this if available
if manifestDoc != nil {
rel.Manifest = manifestDoc.String()

@ -295,7 +295,8 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chartv2.Chart, vals map[str
interactWithRemote = true
}
hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, interactWithRemote, u.EnableDNS, u.HideSecret)
hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false,
u.PostRenderer, interactWithRemote, u.EnableDNS, u.HideSecret, u.isDryRun())
if err != nil {
return nil, nil, false, err
}

@ -173,7 +173,7 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
},
}
addInstallFlags(cmd, cmd.Flags(), client, valueOpts)
addInstallFlags(cmd, cmd.Flags(), client, valueOpts, false)
// hide-secret is not available in all places the install flags are used so
// it is added separately
f := cmd.Flags()
@ -184,7 +184,8 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
return cmd
}
func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Install, valueOpts *values.Options) {
func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Install, valueOpts *values.Options,
isTemplateCommand bool) {
f.BoolVar(&client.CreateNamespace, "create-namespace", false, "create the release namespace if not present")
// --dry-run options with expected outcome:
// - Not set means no dry run and server is contacted.
@ -211,12 +212,21 @@ func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Instal
f.BoolVar(&client.RollbackOnFailure, "rollback-on-failure", false, "if set, Helm will rollback (uninstall) the installation upon failure. The --wait flag will be default to \"watcher\" if --rollback-on-failure is set")
f.MarkDeprecated("atomic", "use --rollback-on-failure instead")
f.BoolVar(&client.SkipCRDs, "skip-crds", false, "if set, no CRDs will be installed. By default, CRDs are installed if not already present")
f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent")
f.BoolVar(&client.SkipSchemaValidation, "skip-schema-validation", false, "if set, disables JSON schema validation")
f.StringToStringVarP(&client.Labels, "labels", "l", nil, "Labels that would be added to release metadata. Should be divided by comma.")
f.BoolVar(&client.EnableDNS, "enable-dns", false, "enable DNS lookups when rendering templates")
f.BoolVar(&client.HideNotes, "hide-notes", false, "if set, do not show notes in install output. Does not affect presence in chart metadata")
f.BoolVar(&client.TakeOwnership, "take-ownership", false, "if set, install will ignore the check for helm annotations and take ownership of the existing resources")
// Set the --render-subchart-notes flag description based on the command. The template command requires some
// additional information than the install/upgrade commands.
renderSubchartNotesFlagDesc := "if set, render subchart notes along with the parent"
if isTemplateCommand {
renderSubchartNotesFlagDesc = fmt.Sprintf("%s. Note: This will only work if --notes flag is enabled.",
renderSubchartNotesFlagDesc)
}
f.BoolVar(&client.SubNotes, "render-subchart-notes", false, renderSubchartNotesFlagDesc)
addValueOptionsFlags(f, valueOpts)
addChartPathOptionsFlags(f, &client.ChartPathOptions)
AddWaitFlag(cmd, &client.WaitStrategy)

@ -20,10 +20,13 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"helm.sh/helm/v4/pkg/repo/v1/repotest"
"github.com/stretchr/testify/assert"
)
func TestInstall(t *testing.T) {
@ -274,11 +277,141 @@ func TestInstall(t *testing.T) {
wantError: true,
golden: "output/install-hide-secret.txt",
},
{
// Running `helm install` on a chart that doesn't have notes or subcharts should print the install command's
// output without notes.
name: "helm install on chart without notes or subcharts",
cmd: fmt.Sprintf("install luffy '%s' --namespace default", emptyChart),
golden: "output/install-without-notes-or-subcharts.txt",
},
{
// Running `helm install --dry-run` on a chart that doesn't have notes or subcharts should print the install
// command's dry-run output without notes.
name: "helm install --dry-run on chart without notes or subcharts",
cmd: fmt.Sprintf("install luffy '%s' --namespace default --dry-run", emptyChart),
golden: "output/install-without-notes-or-subcharts-with-flag-dry-run-enabled.txt",
},
{
// Running `helm install --render-subchart-notes` on a chart that doesn't have notes or subcharts should
// print the install command's output without any notes.
name: "helm install --render-subchart-notes on chart without notes or subcharts",
cmd: fmt.Sprintf("install luffy '%s' --namespace default --render-subchart-notes", emptyChart),
golden: "output/install-without-notes-or-subcharts.txt",
},
{
// Running `helm install --dry-run --render-subchart-notes` on a chart that doesn't have notes or subcharts
// should print the install command's dry-run output without any notes.
name: "helm install --dry-run --render-subchart-notes on chart without notes or subcharts",
cmd: fmt.Sprintf("install luffy '%s' --namespace default --dry-run --render-subchart-notes", emptyChart),
golden: "output/install-without-notes-or-subcharts-with-flag-dry-run-enabled.txt",
},
{
// Running `helm install` on a chart that has notes but no subcharts should print the install command's
// output with (current chart's) notes.
name: "helm install on chart with notes without subcharts",
cmd: fmt.Sprintf("install luffy '%s' --namespace default", chartWithNotes),
golden: "output/install-with-notes.txt",
},
{
// Running `helm install --dry-run` on a chart that has notes but no subcharts should print the install
// command's dry-run output with (current chart's) notes. Note: The notes in dry-run output include the
// source filename and separator "---".
name: "helm install --dry-run on chart with notes without subcharts",
cmd: fmt.Sprintf("install luffy '%s' --namespace default --dry-run", chartWithNotes),
golden: "output/install-with-notes-with-flag-dry-run-enabled.txt",
},
{
// Running `helm install --render-subchart-notes` on a chart that has notes but no subcharts should print
// the install command's output with (current chart's) notes, i.e., no subchart's notes as no subchart.
name: "helm install --render-subchart-notes on chart with notes without subcharts",
cmd: fmt.Sprintf("install luffy '%s' --namespace default --render-subchart-notes", chartWithNotes),
golden: "output/install-with-notes.txt",
},
{
// Running `helm install --dry-run --render-subchart-notes` on a chart that has notes but no subcharts
// should print the install command's dry-run output (current chart's) notes, i.e., no subchart's notes as
// no subchart. Note: The notes in dry-run output include the source filename and separator "---".
name: "helm install --dry-run --render-subchart-notes on chart with notes without subcharts",
cmd: fmt.Sprintf("install luffy '%s' --namespace default --dry-run --render-subchart-notes",
chartWithNotes),
golden: "output/install-with-notes-with-flag-dry-run-enabled.txt",
},
{
// Running `helm install` on a chart that has notes and 2 levels of subcharts should print install command's
// output with just root chart's notes, i.e., without subchart's notes.
name: "helm install on chart with notes and subcharts",
cmd: fmt.Sprintf("install luffy '%s' --namespace default", chartWithNotesAnd2LevelsOfSubCharts),
golden: "output/install-with-notes-and-subcharts.txt",
},
{
// Running `helm install --dry-run` on a chart that has notes and 2 levels of subcharts should print the
// install command's dry-run output with just the root chart's notes, i.e., without the subchart's notes.
// sNote: The notes in dry-run output include the source filename and separator "---".
name: "helm install --dry-run on chart with notes and subcharts",
cmd: fmt.Sprintf("install luffy '%s' --namespace default --dry-run",
chartWithNotesAnd2LevelsOfSubCharts),
golden: "output/install-with-notes-and-subcharts-with-flag-dry-run-enabled.txt",
},
{
// Running `helm install --render-subchart-notes` on a chart that has notes and 2 levels of subcharts should
// print the install command's output with both the root chart and the subcharts' notes.
name: "helm install --render-subchart-notes on chart with notes and subcharts",
cmd: fmt.Sprintf("install luffy '%s' --namespace default --render-subchart-notes",
chartWithNotesAnd2LevelsOfSubCharts),
golden: "output/install-with-notes-and-subcharts-with-flag-render-subchart-notes-enabled.txt",
},
{
// Running `helm install --dry-run --render-subchart-notes` on a chart that has notes and 2 levels of
// subcharts should print the install command's dry-run output with both the root chart and the subcharts'
// notes. Note: The notes in dry-run output include the source filename and separator "---".
name: "helm install --dry-run --render-subchart-notes on chart with notes and subcharts",
cmd: fmt.Sprintf("install luffy '%s' --namespace default --dry-run --render-subchart-notes",
chartWithNotesAnd2LevelsOfSubCharts),
golden: "output/" +
"install-with-notes-and-subcharts-with-both-flags-dry-run-and-render-subchart-notes-enabled.txt",
},
}
runTestCmd(t, tests)
}
// TestInstallHelpOutput tests the `helm install --help` command's output text. This is required because the
// --render-subchart-notes flag's description is different for the template command from that of install/upgrade
// commands.
func TestInstallHelpOutput(t *testing.T) {
const (
outputFilePath = "testdata/output/install-help.txt"
testNamespace = "test-namespace"
repositoryCache = "test-repository-cache-dir"
repositoryConfig = "test-repository-config.yaml"
registryConfig = "test-registry-config.json"
contentCache = "test-content-cache"
gnupgHome = "test-gpg"
commandText = "install --help"
)
// Reset the envs and the configs at the end of this test so that the updates wouldnt affect other tests.
defer resetEnv()()
// Read the expected output file.
expectedOutput, err := os.ReadFile(outputFilePath)
assert.NoError(t, err, "unexpected error while reading expected output's file %q", outputFilePath)
// Set the configs that might otherwise change based on the local environment if not explicitly set. Note: These
// configs are not related to the current test.
settings.RepositoryCache = repositoryCache
settings.RepositoryConfig = repositoryConfig
settings.RegistryConfig = registryConfig
settings.ContentCache = contentCache
settings.SetNamespace(testNamespace)
t.Setenv("GNUPGHOME", gnupgHome)
// Run the `helm install --help` command and compare the help text.
_, actualOutput, err := executeActionCommandC(storageFixture(), commandText)
assert.NoError(t, err, "unexpected error running command %q", commandText)
assert.Equal(t, string(expectedOutput), actualOutput, "mismatch of output")
}
func TestInstallOutputCompletion(t *testing.T) {
outputFlagCompletionTest(t, "install")
}

@ -58,6 +58,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
var kubeVersion string
var extraAPIs []string
var showFiles []string
var renderNotes bool
cmd := &cobra.Command{
Use: "template [NAME] [CHART]",
@ -136,6 +137,38 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
}
// If --notes flag is enabled, add the rendered notes file (templates/NOTES.txt) content to the output.
// Since the template command is considered a dry run, the rendered notes include the source file name
// and the separator as follows:
//
// ---
// # Source: foo/templates/NOTES.txt
// foo NOTES HERE
//
// If --render-subchart-notes flag is also enabled, the rendered notes will include notes from subcharts
// as follows:
//
// ---
// # Source: foo/templates/NOTES.txt
// foo NOTES HERE
// ---
// # Source: foo/charts/bar/templates/NOTES.txt
// bar NOTES HERE
// ---
// # Source: foo/charts/baz/templates/NOTES.txt
// baz NOTES HERE
// ---
// # Source: foo/charts/bar/charts/qux/templates/NOTES.txt
// qux NOTES HERE
//
// Note: The order of the notes files above is based on depth first, and then in alphabetical order.
//
// If just --render-subchart-notes flag is enabled and --notes flag is not, skip adding any notes to
// output.
if renderNotes {
fmt.Fprint(&manifests, rel.Info.Notes)
}
// if we have a list of files to render, then check that each of the
// provided files exists in the chart.
if len(showFiles) > 0 {
@ -193,7 +226,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
f := cmd.Flags()
addInstallFlags(cmd, f, client, valueOpts)
addInstallFlags(cmd, f, client, valueOpts, true)
f.StringArrayVarP(&showFiles, "show-only", "s", []string{}, "only show manifests rendered from the given templates")
f.StringVar(&client.OutputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout")
f.BoolVar(&validate, "validate", false, "validate your manifests against the Kubernetes cluster you are currently pointing at. This is the same validation performed on an install")
@ -203,6 +236,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
f.StringVar(&kubeVersion, "kube-version", "", "Kubernetes version used for Capabilities.KubeVersion")
f.StringSliceVarP(&extraAPIs, "api-versions", "a", []string{}, "Kubernetes api versions used for Capabilities.APIVersions (multiple can be specified)")
f.BoolVar(&client.UseReleaseName, "release-name", false, "use release name in the output-dir path.")
f.BoolVar(&renderNotes, "notes", false, "if set, render the current chart's notes file")
bindPostRenderFlag(cmd, &client.PostRenderer, settings)
return cmd

@ -18,11 +18,19 @@ package cmd
import (
"fmt"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
var chartPath = "testdata/testcharts/subchart"
var (
emptyChart = "testdata/testcharts/empty"
chartPath = "testdata/testcharts/subchart"
chartWithNotes = "testdata/testcharts/chart-with-notes"
chartWithNotesAnd2LevelsOfSubCharts = "testdata/testcharts/chart-with-notes-and-2-levels-of-subcharts"
)
func TestTemplateCmd(t *testing.T) {
deletevalchart := "testdata/testcharts/issue-9027"
@ -166,10 +174,135 @@ func TestTemplateCmd(t *testing.T) {
cmd: fmt.Sprintf("template '%s' -f %s/extra_values.yaml", chartPath, chartPath),
golden: "output/template-subchart-cm-set-file.txt",
},
{
// Running `helm template` on a chart that doesn't have notes or subcharts should print the template
// command's output without notes.
name: "helm template on chart without notes or subcharts",
cmd: fmt.Sprintf("template luffy '%s' --namespace default", emptyChart),
golden: "output/template-without-notes-or-subcharts.txt",
},
{
// Running `helm template --notes` on a chart that doesn't have notes or subcharts should print template
// command's output without notes.
name: "helm template --notes on chart without notes or subcharts",
cmd: fmt.Sprintf("template luffy '%s' --namespace default --notes", emptyChart),
golden: "output/template-without-notes-or-subcharts.txt",
},
{
// Running `helm template --render-subchart-notes` on a chart that doesn't have notes or subcharts should
// print the template command's output without notes.
name: "helm template --render-subchart-notes on chart without notes or subcharts",
cmd: fmt.Sprintf("template luffy '%s' --namespace default --render-subchart-notes", emptyChart),
golden: "output/template-without-notes-or-subcharts.txt",
},
{
// Running `helm template --notes --render-subchart-notes` on a chart that doesn't have notes or subcharts
// should print the template command's output without notes.
name: "helm template --notes --render-subchart-notes on chart without notes or subcharts",
cmd: fmt.Sprintf("template luffy '%s' --namespace default --notes --render-subchart-notes", emptyChart),
golden: "output/template-without-notes-or-subcharts.txt",
},
{
// Running `helm template` on a chart that has notes but no subcharts should print the template command's
// output without notes, since --notes flag is not enabled.
name: "helm template on chart with notes without subcharts",
cmd: fmt.Sprintf("template luffy '%s' --namespace default", chartWithNotes),
golden: "output/template-with-notes.txt",
},
{
// Running `helm template --notes` on a chart that has notes but no subcharts should print the template
// command's output with (current chart's) notes.
name: "helm template --notes on chart with notes without subcharts",
cmd: fmt.Sprintf("template luffy '%s' --namespace default --notes", chartWithNotes),
golden: "output/template-with-notes-with-flag-notes-enabled.txt",
},
{
// Running `helm template --render-subchart-notes` on a chart that has notes but no subcharts should print
// the template command's output without notes, since --notes flag is not enabled.
name: "helm template --render-subchart-notes on chart with notes without subcharts",
cmd: fmt.Sprintf("template luffy '%s' --namespace default --render-subchart-notes", chartWithNotes),
golden: "output/template-with-notes.txt",
},
{
// Running `helm template --notes --render-subchart-notes` on a chart that has notes but no subcharts should
// print the template command's output (current chart's) notes, i.e., no subchart's notes as no subcharts.
name: "helm template --notes --render-subchart-notes on chart with notes without subcharts",
cmd: fmt.Sprintf("template luffy '%s' --namespace default --notes --render-subchart-notes",
chartWithNotes),
golden: "output/template-with-notes-with-flag-notes-enabled.txt",
},
{
// Running `helm template` on a chart that has notes and 2 levels of subcharts should print template
// command's output without notes, since --notes flag is not enabled.
name: "helm template on chart with notes and subcharts",
cmd: fmt.Sprintf("template luffy '%s' --namespace default", chartWithNotesAnd2LevelsOfSubCharts),
golden: "output/template-with-notes-and-subcharts.txt",
},
{
// Running `helm template --notes` on a chart that has notes and 2 levels of subcharts should print template
// command's output with just root chart's notes, i.e., no subchart's notes as no --render-subchart-notes.
name: "helm template --notes on chart with notes and subcharts",
cmd: fmt.Sprintf("template luffy '%s' --namespace default --notes", chartWithNotesAnd2LevelsOfSubCharts),
golden: "output/template-with-notes-and-subcharts-with-flag-notes-enabled.txt",
},
{
// Running `helm template --render-subchart-notes` on a chart that has notes and 2 levels of subcharts
// should print the template command's output without notes, since --notes flag is not enabled.
name: "helm template --render-subchart-notes on chart with notes and subcharts",
cmd: fmt.Sprintf("template luffy '%s' --namespace default --render-subchart-notes",
chartWithNotesAnd2LevelsOfSubCharts),
golden: "output/template-with-notes-and-subcharts.txt",
},
{
// Running `helm template --notes --render-subchart-notes` on a chart that has notes and 2 levels of
// subcharts should print the template command's output with both the root chart and the subchart's notes.
name: "helm template --notes --render-subchart-notes on chart with notes and subcharts",
cmd: fmt.Sprintf("template luffy '%s' --namespace default --notes --render-subchart-notes",
chartWithNotesAnd2LevelsOfSubCharts),
golden: "output/" +
"template-with-notes-and-subcharts-with-both-flags-notes-and-render-subchart-notes-enabled.txt",
},
}
runTestCmd(t, tests)
}
// TestTemplateHelpOutput tests the `helm template --help` command's output text. This is required because the
// --render-subchart-notes flag's description is different for the template command from that of install/upgrade
// commands.
func TestTemplateHelpOutput(t *testing.T) {
const (
outputFilePath = "testdata/output/template-help.txt"
testNamespace = "test-namespace"
repositoryCache = "test-repository-cache-dir"
repositoryConfig = "test-repository-config.yaml"
registryConfig = "test-registry-config.json"
contentCache = "test-content-cache"
gnupgHome = "test-gpg"
commandText = "template --help"
)
// Reset the envs and the configs at the end of this test so that the updates wouldnt affect other tests.
defer resetEnv()()
// Read the expected output file.
expectedOutput, err := os.ReadFile(outputFilePath)
assert.NoError(t, err, "unexpected error while reading expected output's file %q", outputFilePath)
// Set the configs that might otherwise change based on the local environment if not explicitly set. Note: These
// configs are not related to the current test.
settings.RepositoryCache = repositoryCache
settings.RepositoryConfig = repositoryConfig
settings.RegistryConfig = registryConfig
settings.ContentCache = contentCache
settings.SetNamespace(testNamespace)
t.Setenv("GNUPGHOME", gnupgHome)
// Run the `helm template --help` command and compare the help text.
_, actualOutput, err := executeActionCommandC(storageFixture(), commandText)
assert.NoError(t, err, "unexpected error running command %q", commandText)
assert.Equal(t, string(expectedOutput), actualOutput, "mismatch of output")
}
func TestTemplateVersionCompletion(t *testing.T) {
repoFile := "testdata/helmhome/helm/repositories.yaml"
repoCache := "testdata/helmhome/helm/repository"

@ -0,0 +1,159 @@
This command installs a chart archive.
The install argument must be a chart reference, a path to a packaged chart,
a path to an unpacked chart directory or a URL.
To override values in a chart, use either the '--values' flag and pass in a file
or use the '--set' flag and pass configuration from the command line, to force
a string value use '--set-string'. You can use '--set-file' to set individual
values from a file when the value itself is too long for the command line
or is dynamically generated. You can also use '--set-json' to set json values
(scalars/objects/arrays) from the command line. Additionally, you can use '--set-json' and passing json object as a string.
$ helm install -f myvalues.yaml myredis ./redis
or
$ helm install --set name=prod myredis ./redis
or
$ helm install --set-string long_int=1234567890 myredis ./redis
or
$ helm install --set-file my_script=dothings.sh myredis ./redis
or
$ helm install --set-json 'master.sidecars=[{"name":"sidecar","image":"myImage","imagePullPolicy":"Always","ports":[{"name":"portname","containerPort":1234}]}]' myredis ./redis
or
$ helm install --set-json '{"master":{"sidecars":[{"name":"sidecar","image":"myImage","imagePullPolicy":"Always","ports":[{"name":"portname","containerPort":1234}]}]}}' myredis ./redis
You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
contained a key called 'Test', the value set in override.yaml would take precedence:
$ helm install -f myvalues.yaml -f override.yaml myredis ./redis
You can specify the '--set' flag multiple times. The priority will be given to the
last (right-most) set specified. For example, if both 'bar' and 'newbar' values are
set for a key called 'foo', the 'newbar' value would take precedence:
$ helm install --set foo=bar --set foo=newbar myredis ./redis
Similarly, in the following example 'foo' is set to '["four"]':
$ helm install --set-json='foo=["one", "two", "three"]' --set-json='foo=["four"]' myredis ./redis
And in the following example, 'foo' is set to '{"key1":"value1","key2":"bar"}':
$ helm install --set-json='foo={"key1":"value1","key2":"value2"}' --set-json='foo.key2="bar"' myredis ./redis
To check the generated manifests of a release without installing the chart,
the --debug and --dry-run flags can be combined.
The --dry-run flag will output all generated chart manifests, including Secrets
which can contain sensitive values. To hide Kubernetes Secrets use the
--hide-secret flag. Please carefully consider how and when these flags are used.
If --verify is set, the chart MUST have a provenance file, and the provenance
file MUST pass all verification steps.
There are six different ways you can express the chart you want to install:
1. By chart reference: helm install mymaria example/mariadb
2. By path to a packaged chart: helm install mynginx ./nginx-1.2.3.tgz
3. By path to an unpacked chart directory: helm install mynginx ./nginx
4. By absolute URL: helm install mynginx https://example.com/charts/nginx-1.2.3.tgz
5. By chart reference and repo url: helm install --repo https://example.com/charts/ mynginx nginx
6. By OCI registries: helm install mynginx --version 1.2.3 oci://example.com/charts/nginx
CHART REFERENCES
A chart reference is a convenient way of referencing a chart in a chart repository.
When you use a chart reference with a repo prefix ('example/mariadb'), Helm will look in the local
configuration for a chart repository named 'example', and will then look for a
chart in that repository whose name is 'mariadb'. It will install the latest stable version of that chart
until you specify '--devel' flag to also include development version (alpha, beta, and release candidate releases), or
supply a version number with the '--version' flag.
To see the list of chart repositories, use 'helm repo list'. To search for
charts in a repository, use 'helm search'.
Usage:
helm install [NAME] [CHART] [flags]
Flags:
--ca-file string verify certificates of HTTPS-enabled servers using this CA bundle
--cert-file string identify HTTPS client using this SSL certificate file
--create-namespace create the release namespace if not present
--dependency-update update dependencies if they are missing before installing the chart
--description string add a custom description
--devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored
--disable-openapi-validation if set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema
--dry-run string[="client"] simulate an install. If --dry-run is set with no option being specified or as '--dry-run=client', it will not attempt cluster connections. Setting '--dry-run=server' allows attempting cluster connections.
--enable-dns enable DNS lookups when rendering templates
--force-conflicts if set server-side apply will force changes against conflicts
--force-replace force resource updates by replacement
-g, --generate-name generate the name (and omit the NAME parameter)
-h, --help help for install
--hide-notes if set, do not show notes in install output. Does not affect presence in chart metadata
--hide-secret hide Kubernetes Secrets when also using the --dry-run flag
--insecure-skip-tls-verify skip tls certificate checks for the chart download
--key-file string identify HTTPS client using this SSL key file
--keyring string location of public keys used for verification (default "test-gpg/pubring.gpg")
-l, --labels stringToString Labels that would be added to release metadata. Should be divided by comma. (default [])
--name-template string specify template used to name the release
--no-hooks prevent hooks from running during install
-o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table)
--pass-credentials pass credentials to all domains
--password string chart repository password where to locate the requested chart
--plain-http use insecure HTTP connections for the chart download
--post-renderer postRendererString the name of a postrenderer type plugin to be used for post rendering. If it exists, the plugin will be used
--post-renderer-args postRendererArgsSlice an argument to the post-renderer (can specify multiple) (default [])
--render-subchart-notes if set, render subchart notes along with the parent
--replace reuse the given name, only if that name is a deleted release which remains in the history. This is unsafe in production
--repo string chart repository url where to locate the requested chart
--rollback-on-failure if set, Helm will rollback (uninstall) the installation upon failure. The --wait flag will be default to "watcher" if --rollback-on-failure is set
--server-side object updates run in the server instead of the client (default true)
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-json stringArray set JSON values on the command line (can specify multiple or separate values with commas: key1=jsonval1,key2=jsonval2 or using json format: {"key1": jsonval1, "key2": "jsonval2"})
--set-literal stringArray set a literal STRING value on the command line
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--skip-crds if set, no CRDs will be installed. By default, CRDs are installed if not already present
--skip-schema-validation if set, disables JSON schema validation
--take-ownership if set, install will ignore the check for helm annotations and take ownership of the existing resources
--timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s)
--username string chart repository username where to locate the requested chart
-f, --values strings specify values in a YAML file or a URL (can specify multiple)
--verify verify the package before using it
--version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used
--wait WaitStrategy[=watcher] if specified, will wait until all resources are in the expected state before marking the operation as successful. It will wait for as long as --timeout. Valid inputs are 'watcher' and 'legacy' (default hookOnly)
--wait-for-jobs if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout
Global Flags:
--burst-limit int client-side default throttling limit (default 100)
--color string use colored output (never, auto, always) (default "auto")
--colour string use colored output (never, auto, always) (default "auto")
--content-cache string path to the directory containing cached content (e.g. charts) (default "test-content-cache")
--debug enable verbose output
--kube-apiserver string the address and the port for the Kubernetes API server
--kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--kube-as-user string username to impersonate for the operation
--kube-ca-file string the certificate authority file for the Kubernetes API server connection
--kube-context string name of the kubeconfig context to use
--kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used
--kube-token string bearer token used for authentication
--kubeconfig string path to the kubeconfig file
-n, --namespace string namespace scope for this request (default "test-namespace")
--qps float32 queries per second used when communicating with the Kubernetes API, not including bursting
--registry-config string path to the registry config file (default "test-registry-config.json")
--repository-cache string path to the directory containing cached repository indexes (default "test-repository-cache-dir")
--repository-config string path to the file containing repository names and URLs (default "test-repository-config.yaml")

@ -0,0 +1,153 @@
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: pending-install
REVISION: 1
DESCRIPTION: Dry run complete
HOOKS:
---
# Source: foo/templates/tests/test-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "luffy-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World
---
# Source: foo/templates/tests/test-nothing.yaml
apiVersion: v1
kind: Pod
metadata:
name: "luffy-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "luffy-testconfig"
command:
- echo
- "$message"
restartPolicy: Never
MANIFEST:
---
# Source: foo/templates/rbac/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: foo-sa
---
# Source: foo/templates/rbac/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: foo-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
---
# Source: foo/templates/rbac/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: foo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: foo-role
subjects:
- kind: ServiceAccount
name: foo-sa
namespace: default
---
# Source: foo/charts/bar/charts/qux/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: qux
labels:
helm.sh/chart: "qux-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: usopp
selector:
app.kubernetes.io/name: qux
---
# Source: foo/charts/bar/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: bar
labels:
helm.sh/chart: "bar-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: zoro
selector:
app.kubernetes.io/name: bar
---
# Source: foo/charts/baz/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: baz
labels:
helm.sh/chart: "baz-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: nami
selector:
app.kubernetes.io/name: baz
---
# Source: foo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: foo
labels:
helm.sh/chart: "foo-0.1.0"
app.kubernetes.io/instance: "luffy"
kube-version/major: "1"
kube-version/minor: "20"
kube-version/version: "v1.20.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: luffy
selector:
app.kubernetes.io/name: foo
NOTES:
---
# Source: foo/templates/NOTES.txt
Sample notes for foo
---
# Source: foo/charts/bar/templates/NOTES.txt
Sample notes for bar
---
# Source: foo/charts/baz/templates/NOTES.txt
Sample notes for baz
---
# Source: foo/charts/bar/charts/qux/templates/NOTES.txt
Sample notes for qux

@ -0,0 +1,144 @@
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: pending-install
REVISION: 1
DESCRIPTION: Dry run complete
HOOKS:
---
# Source: foo/templates/tests/test-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "luffy-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World
---
# Source: foo/templates/tests/test-nothing.yaml
apiVersion: v1
kind: Pod
metadata:
name: "luffy-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "luffy-testconfig"
command:
- echo
- "$message"
restartPolicy: Never
MANIFEST:
---
# Source: foo/templates/rbac/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: foo-sa
---
# Source: foo/templates/rbac/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: foo-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
---
# Source: foo/templates/rbac/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: foo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: foo-role
subjects:
- kind: ServiceAccount
name: foo-sa
namespace: default
---
# Source: foo/charts/bar/charts/qux/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: qux
labels:
helm.sh/chart: "qux-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: usopp
selector:
app.kubernetes.io/name: qux
---
# Source: foo/charts/bar/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: bar
labels:
helm.sh/chart: "bar-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: zoro
selector:
app.kubernetes.io/name: bar
---
# Source: foo/charts/baz/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: baz
labels:
helm.sh/chart: "baz-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: nami
selector:
app.kubernetes.io/name: baz
---
# Source: foo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: foo
labels:
helm.sh/chart: "foo-0.1.0"
app.kubernetes.io/instance: "luffy"
kube-version/major: "1"
kube-version/minor: "20"
kube-version/version: "v1.20.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: luffy
selector:
app.kubernetes.io/name: foo
NOTES:
---
# Source: foo/templates/NOTES.txt
Sample notes for foo

@ -0,0 +1,14 @@
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
NOTES:
Sample notes for foo
Sample notes for bar
Sample notes for baz
Sample notes for qux

@ -0,0 +1,8 @@
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
NOTES:
Sample notes for foo

@ -0,0 +1,93 @@
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: pending-install
REVISION: 1
DESCRIPTION: Dry run complete
HOOKS:
---
# Source: foo/templates/tests/test-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "luffy-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World
---
# Source: foo/templates/tests/test-nothing.yaml
apiVersion: v1
kind: Pod
metadata:
name: "luffy-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "luffy-testconfig"
command:
- echo
- "$message"
restartPolicy: Never
MANIFEST:
---
# Source: foo/templates/rbac/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: foo-sa
---
# Source: foo/templates/rbac/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: foo-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
---
# Source: foo/templates/rbac/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: foo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: foo-role
subjects:
- kind: ServiceAccount
name: foo-sa
namespace: default
---
# Source: foo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: foo
labels:
helm.sh/chart: "foo-0.1.0"
app.kubernetes.io/instance: "luffy"
kube-version/major: "1"
kube-version/minor: "20"
kube-version/version: "v1.20.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: sanji
selector:
app.kubernetes.io/name: foo
NOTES:
---
# Source: foo/templates/NOTES.txt
Sample notes for foo

@ -0,0 +1,8 @@
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
NOTES:
Sample notes for foo

@ -0,0 +1,13 @@
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: pending-install
REVISION: 1
DESCRIPTION: Dry run complete
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: empty/templates/empty.yaml
# This file is intentionally blank

@ -0,0 +1,7 @@
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None

@ -0,0 +1,87 @@
Render chart templates locally and display the output.
Any values that would normally be looked up or retrieved in-cluster will be
faked locally. Additionally, none of the server-side testing of chart validity
(e.g. whether an API is supported) is done.
Usage:
helm template [NAME] [CHART] [flags]
Flags:
-a, --api-versions strings Kubernetes api versions used for Capabilities.APIVersions (multiple can be specified)
--ca-file string verify certificates of HTTPS-enabled servers using this CA bundle
--cert-file string identify HTTPS client using this SSL certificate file
--create-namespace create the release namespace if not present
--dependency-update update dependencies if they are missing before installing the chart
--description string add a custom description
--devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored
--disable-openapi-validation if set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema
--dry-run string[="client"] simulate an install. If --dry-run is set with no option being specified or as '--dry-run=client', it will not attempt cluster connections. Setting '--dry-run=server' allows attempting cluster connections.
--enable-dns enable DNS lookups when rendering templates
--force-conflicts if set server-side apply will force changes against conflicts
--force-replace force resource updates by replacement
-g, --generate-name generate the name (and omit the NAME parameter)
-h, --help help for template
--hide-notes if set, do not show notes in install output. Does not affect presence in chart metadata
--include-crds include CRDs in the templated output
--insecure-skip-tls-verify skip tls certificate checks for the chart download
--is-upgrade set .Release.IsUpgrade instead of .Release.IsInstall
--key-file string identify HTTPS client using this SSL key file
--keyring string location of public keys used for verification (default "test-gpg/pubring.gpg")
--kube-version string Kubernetes version used for Capabilities.KubeVersion
-l, --labels stringToString Labels that would be added to release metadata. Should be divided by comma. (default [])
--name-template string specify template used to name the release
--no-hooks prevent hooks from running during install
--notes if set, render the current chart's notes file
--output-dir string writes the executed templates to files in output-dir instead of stdout
--pass-credentials pass credentials to all domains
--password string chart repository password where to locate the requested chart
--plain-http use insecure HTTP connections for the chart download
--post-renderer postRendererString the name of a postrenderer type plugin to be used for post rendering. If it exists, the plugin will be used
--post-renderer-args postRendererArgsSlice an argument to the post-renderer (can specify multiple) (default [])
--release-name use release name in the output-dir path.
--render-subchart-notes if set, render subchart notes along with the parent. Note: This will only work if --notes flag is enabled.
--replace reuse the given name, only if that name is a deleted release which remains in the history. This is unsafe in production
--repo string chart repository url where to locate the requested chart
--rollback-on-failure if set, Helm will rollback (uninstall) the installation upon failure. The --wait flag will be default to "watcher" if --rollback-on-failure is set
--server-side object updates run in the server instead of the client (default true)
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-json stringArray set JSON values on the command line (can specify multiple or separate values with commas: key1=jsonval1,key2=jsonval2 or using json format: {"key1": jsonval1, "key2": "jsonval2"})
--set-literal stringArray set a literal STRING value on the command line
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
-s, --show-only stringArray only show manifests rendered from the given templates
--skip-crds if set, no CRDs will be installed. By default, CRDs are installed if not already present
--skip-schema-validation if set, disables JSON schema validation
--skip-tests skip tests from templated output
--take-ownership if set, install will ignore the check for helm annotations and take ownership of the existing resources
--timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s)
--username string chart repository username where to locate the requested chart
--validate validate your manifests against the Kubernetes cluster you are currently pointing at. This is the same validation performed on an install
-f, --values strings specify values in a YAML file or a URL (can specify multiple)
--verify verify the package before using it
--version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used
--wait WaitStrategy[=watcher] if specified, will wait until all resources are in the expected state before marking the operation as successful. It will wait for as long as --timeout. Valid inputs are 'watcher' and 'legacy' (default hookOnly)
--wait-for-jobs if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout
Global Flags:
--burst-limit int client-side default throttling limit (default 100)
--color string use colored output (never, auto, always) (default "auto")
--colour string use colored output (never, auto, always) (default "auto")
--content-cache string path to the directory containing cached content (e.g. charts) (default "test-content-cache")
--debug enable verbose output
--kube-apiserver string the address and the port for the Kubernetes API server
--kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--kube-as-user string username to impersonate for the operation
--kube-ca-file string the certificate authority file for the Kubernetes API server connection
--kube-context string name of the kubeconfig context to use
--kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used
--kube-token string bearer token used for authentication
--kubeconfig string path to the kubeconfig file
-n, --namespace string namespace scope for this request (default "test-namespace")
--qps float32 queries per second used when communicating with the Kubernetes API, not including bursting
--registry-config string path to the registry config file (default "test-registry-config.json")
--repository-cache string path to the directory containing cached repository indexes (default "test-repository-cache-dir")
--repository-config string path to the file containing repository names and URLs (default "test-repository-config.yaml")

@ -0,0 +1,143 @@
---
# Source: foo/templates/rbac/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: foo-sa
---
# Source: foo/templates/rbac/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: foo-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
---
# Source: foo/templates/rbac/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: foo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: foo-role
subjects:
- kind: ServiceAccount
name: foo-sa
namespace: default
---
# Source: foo/charts/bar/charts/qux/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: qux
labels:
helm.sh/chart: "qux-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: usopp
selector:
app.kubernetes.io/name: qux
---
# Source: foo/charts/bar/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: bar
labels:
helm.sh/chart: "bar-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: zoro
selector:
app.kubernetes.io/name: bar
---
# Source: foo/charts/baz/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: baz
labels:
helm.sh/chart: "baz-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: nami
selector:
app.kubernetes.io/name: baz
---
# Source: foo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: foo
labels:
helm.sh/chart: "foo-0.1.0"
app.kubernetes.io/instance: "luffy"
kube-version/major: "1"
kube-version/minor: "20"
kube-version/version: "v1.20.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: luffy
selector:
app.kubernetes.io/name: foo
---
# Source: foo/templates/tests/test-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "luffy-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World
---
# Source: foo/templates/tests/test-nothing.yaml
apiVersion: v1
kind: Pod
metadata:
name: "luffy-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "luffy-testconfig"
command:
- echo
- "$message"
restartPolicy: Never
---
# Source: foo/templates/NOTES.txt
Sample notes for foo
---
# Source: foo/charts/bar/templates/NOTES.txt
Sample notes for bar
---
# Source: foo/charts/baz/templates/NOTES.txt
Sample notes for baz
---
# Source: foo/charts/bar/charts/qux/templates/NOTES.txt
Sample notes for qux

@ -0,0 +1,134 @@
---
# Source: foo/templates/rbac/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: foo-sa
---
# Source: foo/templates/rbac/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: foo-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
---
# Source: foo/templates/rbac/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: foo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: foo-role
subjects:
- kind: ServiceAccount
name: foo-sa
namespace: default
---
# Source: foo/charts/bar/charts/qux/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: qux
labels:
helm.sh/chart: "qux-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: usopp
selector:
app.kubernetes.io/name: qux
---
# Source: foo/charts/bar/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: bar
labels:
helm.sh/chart: "bar-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: zoro
selector:
app.kubernetes.io/name: bar
---
# Source: foo/charts/baz/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: baz
labels:
helm.sh/chart: "baz-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: nami
selector:
app.kubernetes.io/name: baz
---
# Source: foo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: foo
labels:
helm.sh/chart: "foo-0.1.0"
app.kubernetes.io/instance: "luffy"
kube-version/major: "1"
kube-version/minor: "20"
kube-version/version: "v1.20.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: luffy
selector:
app.kubernetes.io/name: foo
---
# Source: foo/templates/tests/test-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "luffy-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World
---
# Source: foo/templates/tests/test-nothing.yaml
apiVersion: v1
kind: Pod
metadata:
name: "luffy-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "luffy-testconfig"
command:
- echo
- "$message"
restartPolicy: Never
---
# Source: foo/templates/NOTES.txt
Sample notes for foo

@ -0,0 +1,131 @@
---
# Source: foo/templates/rbac/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: foo-sa
---
# Source: foo/templates/rbac/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: foo-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
---
# Source: foo/templates/rbac/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: foo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: foo-role
subjects:
- kind: ServiceAccount
name: foo-sa
namespace: default
---
# Source: foo/charts/bar/charts/qux/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: qux
labels:
helm.sh/chart: "qux-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: usopp
selector:
app.kubernetes.io/name: qux
---
# Source: foo/charts/bar/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: bar
labels:
helm.sh/chart: "bar-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: zoro
selector:
app.kubernetes.io/name: bar
---
# Source: foo/charts/baz/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: baz
labels:
helm.sh/chart: "baz-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: nami
selector:
app.kubernetes.io/name: baz
---
# Source: foo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: foo
labels:
helm.sh/chart: "foo-0.1.0"
app.kubernetes.io/instance: "luffy"
kube-version/major: "1"
kube-version/minor: "20"
kube-version/version: "v1.20.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: luffy
selector:
app.kubernetes.io/name: foo
---
# Source: foo/templates/tests/test-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "luffy-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World
---
# Source: foo/templates/tests/test-nothing.yaml
apiVersion: v1
kind: Pod
metadata:
name: "luffy-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "luffy-testconfig"
command:
- echo
- "$message"
restartPolicy: Never

@ -0,0 +1,83 @@
---
# Source: foo/templates/rbac/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: foo-sa
---
# Source: foo/templates/rbac/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: foo-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
---
# Source: foo/templates/rbac/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: foo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: foo-role
subjects:
- kind: ServiceAccount
name: foo-sa
namespace: default
---
# Source: foo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: foo
labels:
helm.sh/chart: "foo-0.1.0"
app.kubernetes.io/instance: "luffy"
kube-version/major: "1"
kube-version/minor: "20"
kube-version/version: "v1.20.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: sanji
selector:
app.kubernetes.io/name: foo
---
# Source: foo/templates/tests/test-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "luffy-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World
---
# Source: foo/templates/tests/test-nothing.yaml
apiVersion: v1
kind: Pod
metadata:
name: "luffy-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "luffy-testconfig"
command:
- echo
- "$message"
restartPolicy: Never
---
# Source: foo/templates/NOTES.txt
Sample notes for foo

@ -0,0 +1,80 @@
---
# Source: foo/templates/rbac/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: foo-sa
---
# Source: foo/templates/rbac/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: foo-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
---
# Source: foo/templates/rbac/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: foo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: foo-role
subjects:
- kind: ServiceAccount
name: foo-sa
namespace: default
---
# Source: foo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: foo
labels:
helm.sh/chart: "foo-0.1.0"
app.kubernetes.io/instance: "luffy"
kube-version/major: "1"
kube-version/minor: "20"
kube-version/version: "v1.20.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: sanji
selector:
app.kubernetes.io/name: foo
---
# Source: foo/templates/tests/test-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "luffy-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World
---
# Source: foo/templates/tests/test-nothing.yaml
apiVersion: v1
kind: Pod
metadata:
name: "luffy-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "luffy-testconfig"
command:
- echo
- "$message"
restartPolicy: Never

@ -0,0 +1,3 @@
---
# Source: empty/templates/empty.yaml
# This file is intentionally blank

@ -0,0 +1,113 @@
This command upgrades a release to a new version of a chart.
The upgrade arguments must be a release and chart. The chart
argument can be either: a chart reference('example/mariadb'), a path to a chart directory,
a packaged chart, or a fully qualified URL. For chart references, the latest
version will be specified unless the '--version' flag is set.
To override values in a chart, use either the '--values' flag and pass in a file
or use the '--set' flag and pass configuration from the command line, to force string
values, use '--set-string'. You can use '--set-file' to set individual
values from a file when the value itself is too long for the command line
or is dynamically generated. You can also use '--set-json' to set json values
(scalars/objects/arrays) from the command line. Additionally, you can use '--set-json' and passing json object as a string.
You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
contained a key called 'Test', the value set in override.yaml would take precedence:
$ helm upgrade -f myvalues.yaml -f override.yaml redis ./redis
You can specify the '--set' flag multiple times. The priority will be given to the
last (right-most) set specified. For example, if both 'bar' and 'newbar' values are
set for a key called 'foo', the 'newbar' value would take precedence:
$ helm upgrade --set foo=bar --set foo=newbar redis ./redis
You can update the values for an existing release with this command as well via the
'--reuse-values' flag. The 'RELEASE' and 'CHART' arguments should be set to the original
parameters, and existing values will be merged with any values set via '--values'/'-f'
or '--set' flags. Priority is given to new values.
$ helm upgrade --reuse-values --set foo=bar --set foo=newbar redis ./redis
The --dry-run flag will output all generated chart manifests, including Secrets
which can contain sensitive values. To hide Kubernetes Secrets use the
--hide-secret flag. Please carefully consider how and when these flags are used.
Usage:
helm upgrade [RELEASE] [CHART] [flags]
Flags:
--ca-file string verify certificates of HTTPS-enabled servers using this CA bundle
--cert-file string identify HTTPS client using this SSL certificate file
--cleanup-on-fail allow deletion of new resources created in this upgrade when upgrade fails
--create-namespace if --install is set, create the release namespace if not present
--dependency-update update dependencies if they are missing before installing the chart
--description string add a custom description
--devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored
--disable-openapi-validation if set, the upgrade process will not validate rendered templates against the Kubernetes OpenAPI Schema
--dry-run string[="client"] simulate an install. If --dry-run is set with no option being specified or as '--dry-run=client', it will not attempt cluster connections. Setting '--dry-run=server' allows attempting cluster connections.
--enable-dns enable DNS lookups when rendering templates
--force-conflicts if set server-side apply will force changes against conflicts
--force-replace force resource updates by replacement
-h, --help help for upgrade
--hide-notes if set, do not show notes in upgrade output. Does not affect presence in chart metadata
--hide-secret hide Kubernetes Secrets when also using the --dry-run flag
--history-max int limit the maximum number of revisions saved per release. Use 0 for no limit (default 10)
--insecure-skip-tls-verify skip tls certificate checks for the chart download
-i, --install if a release by this name doesn't already exist, run an install
--key-file string identify HTTPS client using this SSL key file
--keyring string location of public keys used for verification (default "test-gpg/pubring.gpg")
-l, --labels stringToString Labels that would be added to release metadata. Should be separated by comma. Original release labels will be merged with upgrade labels. You can unset label using null. (default [])
--no-hooks disable pre/post upgrade hooks
-o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table)
--pass-credentials pass credentials to all domains
--password string chart repository password where to locate the requested chart
--plain-http use insecure HTTP connections for the chart download
--post-renderer postRendererString the name of a postrenderer type plugin to be used for post rendering. If it exists, the plugin will be used
--post-renderer-args postRendererArgsSlice an argument to the post-renderer (can specify multiple) (default [])
--render-subchart-notes if set, render subchart notes along with the parent
--repo string chart repository url where to locate the requested chart
--reset-then-reuse-values when upgrading, reset the values to the ones built into the chart, apply the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' or '--reuse-values' is specified, this is ignored
--reset-values when upgrading, reset the values to the ones built into the chart
--reuse-values when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored
--rollback-on-failure if set, Helm will rollback the upgrade to previous success release upon failure. The --wait flag will be defaulted to "watcher" if --rollback-on-failure is set
--server-side string must be "true", "false" or "auto". Object updates run in the server instead of the client ("auto" defaults the value from the previous chart release's method) (default "auto")
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-json stringArray set JSON values on the command line (can specify multiple or separate values with commas: key1=jsonval1,key2=jsonval2 or using json format: {"key1": jsonval1, "key2": "jsonval2"})
--set-literal stringArray set a literal STRING value on the command line
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--skip-crds if set, no CRDs will be installed when an upgrade is performed with install flag enabled. By default, CRDs are installed if not already present, when an upgrade is performed with install flag enabled
--skip-schema-validation if set, disables JSON schema validation
--take-ownership if set, upgrade will ignore the check for helm annotations and take ownership of the existing resources
--timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s)
--username string chart repository username where to locate the requested chart
-f, --values strings specify values in a YAML file or a URL (can specify multiple)
--verify verify the package before using it
--version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used
--wait WaitStrategy[=watcher] if specified, will wait until all resources are in the expected state before marking the operation as successful. It will wait for as long as --timeout. Valid inputs are 'watcher' and 'legacy' (default hookOnly)
--wait-for-jobs if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout
Global Flags:
--burst-limit int client-side default throttling limit (default 100)
--color string use colored output (never, auto, always) (default "auto")
--colour string use colored output (never, auto, always) (default "auto")
--content-cache string path to the directory containing cached content (e.g. charts) (default "test-content-cache")
--debug enable verbose output
--kube-apiserver string the address and the port for the Kubernetes API server
--kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--kube-as-user string username to impersonate for the operation
--kube-ca-file string the certificate authority file for the Kubernetes API server connection
--kube-context string name of the kubeconfig context to use
--kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used
--kube-token string bearer token used for authentication
--kubeconfig string path to the kubeconfig file
-n, --namespace string namespace scope for this request (default "test-namespace")
--qps float32 queries per second used when communicating with the Kubernetes API, not including bursting
--registry-config string path to the registry config file (default "test-registry-config.json")
--repository-cache string path to the directory containing cached repository indexes (default "test-repository-cache-dir")
--repository-config string path to the file containing repository names and URLs (default "test-repository-config.yaml")

@ -0,0 +1,154 @@
Release "luffy" has been upgraded. Happy Helming!
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: pending-upgrade
REVISION: 2
DESCRIPTION: Dry run complete
HOOKS:
---
# Source: foo/templates/tests/test-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "luffy-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World
---
# Source: foo/templates/tests/test-nothing.yaml
apiVersion: v1
kind: Pod
metadata:
name: "luffy-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "luffy-testconfig"
command:
- echo
- "$message"
restartPolicy: Never
MANIFEST:
---
# Source: foo/templates/rbac/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: foo-sa
---
# Source: foo/templates/rbac/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: foo-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
---
# Source: foo/templates/rbac/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: foo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: foo-role
subjects:
- kind: ServiceAccount
name: foo-sa
namespace: default
---
# Source: foo/charts/bar/charts/qux/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: qux
labels:
helm.sh/chart: "qux-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: usopp
selector:
app.kubernetes.io/name: qux
---
# Source: foo/charts/bar/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: bar
labels:
helm.sh/chart: "bar-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: zoro
selector:
app.kubernetes.io/name: bar
---
# Source: foo/charts/baz/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: baz
labels:
helm.sh/chart: "baz-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: nami
selector:
app.kubernetes.io/name: baz
---
# Source: foo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: foo
labels:
helm.sh/chart: "foo-0.1.0"
app.kubernetes.io/instance: "luffy"
kube-version/major: "1"
kube-version/minor: "20"
kube-version/version: "v1.20.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: luffy
selector:
app.kubernetes.io/name: foo
NOTES:
---
# Source: foo/templates/NOTES.txt
Sample notes for foo
---
# Source: foo/charts/bar/templates/NOTES.txt
Sample notes for bar
---
# Source: foo/charts/baz/templates/NOTES.txt
Sample notes for baz
---
# Source: foo/charts/bar/charts/qux/templates/NOTES.txt
Sample notes for qux

@ -0,0 +1,145 @@
Release "luffy" has been upgraded. Happy Helming!
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: pending-upgrade
REVISION: 2
DESCRIPTION: Dry run complete
HOOKS:
---
# Source: foo/templates/tests/test-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "luffy-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World
---
# Source: foo/templates/tests/test-nothing.yaml
apiVersion: v1
kind: Pod
metadata:
name: "luffy-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "luffy-testconfig"
command:
- echo
- "$message"
restartPolicy: Never
MANIFEST:
---
# Source: foo/templates/rbac/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: foo-sa
---
# Source: foo/templates/rbac/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: foo-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
---
# Source: foo/templates/rbac/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: foo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: foo-role
subjects:
- kind: ServiceAccount
name: foo-sa
namespace: default
---
# Source: foo/charts/bar/charts/qux/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: qux
labels:
helm.sh/chart: "qux-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: usopp
selector:
app.kubernetes.io/name: qux
---
# Source: foo/charts/bar/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: bar
labels:
helm.sh/chart: "bar-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: zoro
selector:
app.kubernetes.io/name: bar
---
# Source: foo/charts/baz/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: baz
labels:
helm.sh/chart: "baz-0.1.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: nami
selector:
app.kubernetes.io/name: baz
---
# Source: foo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: foo
labels:
helm.sh/chart: "foo-0.1.0"
app.kubernetes.io/instance: "luffy"
kube-version/major: "1"
kube-version/minor: "20"
kube-version/version: "v1.20.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: luffy
selector:
app.kubernetes.io/name: foo
NOTES:
---
# Source: foo/templates/NOTES.txt
Sample notes for foo

@ -0,0 +1,15 @@
Release "luffy" has been upgraded. Happy Helming!
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 2
DESCRIPTION: Upgrade complete
NOTES:
Sample notes for foo
Sample notes for bar
Sample notes for baz
Sample notes for qux

@ -0,0 +1,9 @@
Release "luffy" has been upgraded. Happy Helming!
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 2
DESCRIPTION: Upgrade complete
NOTES:
Sample notes for foo

@ -0,0 +1,94 @@
Release "luffy" has been upgraded. Happy Helming!
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: pending-upgrade
REVISION: 2
DESCRIPTION: Dry run complete
HOOKS:
---
# Source: foo/templates/tests/test-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "luffy-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World
---
# Source: foo/templates/tests/test-nothing.yaml
apiVersion: v1
kind: Pod
metadata:
name: "luffy-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "luffy-testconfig"
command:
- echo
- "$message"
restartPolicy: Never
MANIFEST:
---
# Source: foo/templates/rbac/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: foo-sa
---
# Source: foo/templates/rbac/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: foo-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
---
# Source: foo/templates/rbac/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: foo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: foo-role
subjects:
- kind: ServiceAccount
name: foo-sa
namespace: default
---
# Source: foo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: foo
labels:
helm.sh/chart: "foo-0.1.0"
app.kubernetes.io/instance: "luffy"
kube-version/major: "1"
kube-version/minor: "20"
kube-version/version: "v1.20.0"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: sanji
selector:
app.kubernetes.io/name: foo
NOTES:
---
# Source: foo/templates/NOTES.txt
Sample notes for foo

@ -0,0 +1,9 @@
Release "luffy" has been upgraded. Happy Helming!
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 2
DESCRIPTION: Upgrade complete
NOTES:
Sample notes for foo

@ -0,0 +1,14 @@
Release "luffy" has been upgraded. Happy Helming!
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: pending-upgrade
REVISION: 2
DESCRIPTION: Dry run complete
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: empty/templates/empty.yaml
# This file is intentionally blank

@ -0,0 +1,8 @@
Release "luffy" has been upgraded. Happy Helming!
NAME: luffy
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 2
DESCRIPTION: Upgrade complete
TEST SUITE: None

@ -0,0 +1,20 @@
apiVersion: v1
description: A Helm chart 'foo' for Kubernetes
name: foo
version: 0.1.0
dependencies:
- name: bar
repository: http://localhost:8080
version: 0.1.0
condition: bar.enabled
tags:
- strawhats
- bar
- name: baz
repository: http://localhost:8080
version: 0.1.0
condition: baz.enabled
tags:
- strawhats
- baz

@ -0,0 +1,4 @@
apiVersion: v1
description: A Helm chart 'bar' for Kubernetes
name: bar
version: 0.1.0

@ -0,0 +1,4 @@
apiVersion: v1
description: A Helm chart 'qux' for Kubernetes
name: qux
version: 0.1.0

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.externalPort }}
targetPort: {{ .Values.service.internalPort }}
protocol: TCP
name: {{ .Values.service.name }}
selector:
app.kubernetes.io/name: {{ .Chart.Name }}

@ -0,0 +1,5 @@
service:
name: usopp
type: ClusterIP
externalPort: 80
internalPort: 80

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.externalPort }}
targetPort: {{ .Values.service.internalPort }}
protocol: TCP
name: {{ .Values.service.name }}
selector:
app.kubernetes.io/name: {{ .Chart.Name }}

@ -0,0 +1,5 @@
service:
name: zoro
type: ClusterIP
externalPort: 80
internalPort: 80

@ -0,0 +1,4 @@
apiVersion: v1
description: A Helm chart 'baz' for Kubernetes
name: baz
version: 0.1.0

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.externalPort }}
targetPort: {{ .Values.service.internalPort }}
protocol: TCP
name: {{ .Values.service.name }}
selector:
app.kubernetes.io/name: {{ .Chart.Name }}

@ -0,0 +1,5 @@
service:
name: nami
type: ClusterIP
externalPort: 80
internalPort: 80

@ -0,0 +1,8 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ .Chart.Name }}-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]

@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ .Chart.Name }}-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ .Chart.Name }}-role
subjects:
- kind: ServiceAccount
name: {{ .Chart.Name }}-sa
namespace: default

@ -0,0 +1,4 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Chart.Name }}-sa

@ -0,0 +1,22 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
app.kubernetes.io/instance: "{{ .Release.Name }}"
kube-version/major: "{{ .Capabilities.KubeVersion.Major }}"
kube-version/minor: "{{ .Capabilities.KubeVersion.Minor }}"
kube-version/version: "v{{ .Capabilities.KubeVersion.Major }}.{{ .Capabilities.KubeVersion.Minor }}.0"
{{- if .Capabilities.APIVersions.Has "helm.k8s.io/test" }}
kube-api-version/test: v1
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.externalPort }}
targetPort: {{ .Values.service.internalPort }}
protocol: TCP
name: {{ .Values.service.name }}
selector:
app.kubernetes.io/name: {{ .Chart.Name }}

@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ .Release.Name }}-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World

@ -0,0 +1,17 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "{{ .Release.Name }}-testconfig"
command:
- echo
- "$message"
restartPolicy: Never

@ -0,0 +1,5 @@
service:
name: luffy
type: ClusterIP
externalPort: 80
internalPort: 80

@ -0,0 +1,4 @@
apiVersion: v1
description: A Helm chart 'foo' for Kubernetes
name: foo
version: 0.1.0

@ -0,0 +1 @@
Sample notes for {{ .Chart.Name }}

@ -0,0 +1,8 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ .Chart.Name }}-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]

@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ .Chart.Name }}-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ .Chart.Name }}-role
subjects:
- kind: ServiceAccount
name: {{ .Chart.Name }}-sa
namespace: default

@ -0,0 +1,4 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Chart.Name }}-sa

@ -0,0 +1,22 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}
labels:
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
app.kubernetes.io/instance: "{{ .Release.Name }}"
kube-version/major: "{{ .Capabilities.KubeVersion.Major }}"
kube-version/minor: "{{ .Capabilities.KubeVersion.Minor }}"
kube-version/version: "v{{ .Capabilities.KubeVersion.Major }}.{{ .Capabilities.KubeVersion.Minor }}.0"
{{- if .Capabilities.APIVersions.Has "helm.k8s.io/test" }}
kube-api-version/test: v1
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.externalPort }}
targetPort: {{ .Values.service.internalPort }}
protocol: TCP
name: {{ .Values.service.name }}
selector:
app.kubernetes.io/name: {{ .Chart.Name }}

@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ .Release.Name }}-testconfig"
annotations:
"helm.sh/hook": test
data:
message: Hello World

@ -0,0 +1,17 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: "alpine:latest"
envFrom:
- configMapRef:
name: "{{ .Release.Name }}-testconfig"
command:
- echo
- "$message"
restartPolicy: Never

@ -0,0 +1,5 @@
service:
name: sanji
type: ClusterIP
externalPort: 80
internalPort: 80

@ -29,6 +29,8 @@ import (
"helm.sh/helm/v4/pkg/chart/v2/loader"
chartutil "helm.sh/helm/v4/pkg/chart/v2/util"
release "helm.sh/helm/v4/pkg/release/v1"
"github.com/stretchr/testify/assert"
)
func TestUpgradeCmd(t *testing.T) {
@ -188,10 +190,152 @@ func TestUpgradeCmd(t *testing.T) {
golden: "output/upgrade-uninstalled-with-keep-history.txt",
rels: []*release.Release{relWithStatusMock("funny-bunny", 2, ch, release.StatusUninstalled)},
},
{
// Running `helm upgrade` on a chart that doesn't have notes or subcharts should print the upgrade command's
// output without notes.
name: "helm upgrade on chart without notes or subcharts",
cmd: fmt.Sprintf("upgrade luffy '%s' --namespace default", emptyChart),
golden: "output/upgrade-without-notes-or-subcharts.txt",
rels: []*release.Release{relMock("luffy", 1, ch)},
},
{
// Running `helm upgrade --dry-run` on a chart that doesn't have notes or subcharts should print upgrade
// command's dry-run output without notes.
name: "helm upgrade --dry-run on chart without notes or subcharts",
cmd: fmt.Sprintf("upgrade luffy '%s' --namespace default --dry-run", emptyChart),
golden: "output/upgrade-without-notes-or-subcharts-with-flag-dry-run-enabled.txt",
rels: []*release.Release{relMock("luffy", 1, ch)},
},
{
// Running `helm upgrade --render-subchart-notes` on a chart that doesn't have notes or subcharts should
// print the upgrade command's output without any notes.
name: "helm upgrade --render-subchart-notes on chart without notes or subcharts",
cmd: fmt.Sprintf("upgrade luffy '%s' --namespace default --render-subchart-notes", emptyChart),
golden: "output/upgrade-without-notes-or-subcharts.txt",
rels: []*release.Release{relMock("luffy", 1, ch)},
},
{
// Running `helm upgrade --dry-run --render-subchart-notes` on a chart that doesn't have notes or subcharts
// should print the upgrade command's dry-run output without any notes.
name: "helm upgrade --dry-run --render-subchart-notes on chart without notes or subcharts",
cmd: fmt.Sprintf("upgrade luffy '%s' --namespace default --dry-run --render-subchart-notes", emptyChart),
golden: "output/upgrade-without-notes-or-subcharts-with-flag-dry-run-enabled.txt",
rels: []*release.Release{relMock("luffy", 1, ch)},
},
{
// Running `helm upgrade` on a chart that has notes but no subcharts should print the upgrade command's
// output with (current chart's) notes.
name: "helm upgrade on chart with notes without subcharts",
cmd: fmt.Sprintf("upgrade luffy '%s' --namespace default", chartWithNotes),
golden: "output/upgrade-with-notes.txt",
rels: []*release.Release{relMock("luffy", 1, ch)},
},
{
// Running `helm upgrade --dry-run` on a chart that has notes but no subcharts should print the upgrade
// command's dry-run output with (current chart's) notes. Note: The notes in dry-run output include the
// source filename and separator "---".
name: "helm upgrade --dry-run on chart with notes without subcharts",
cmd: fmt.Sprintf("upgrade luffy '%s' --namespace default --dry-run", chartWithNotes),
golden: "output/upgrade-with-notes-with-flag-dry-run-enabled.txt",
rels: []*release.Release{relMock("luffy", 1, ch)},
},
{
// Running `helm upgrade --render-subchart-notes` on a chart that has notes but no subcharts should print
// the upgrade command's output with (current chart's) notes, i.e., no subchart's notes as no subchart.
name: "helm upgrade --render-subchart-notes on chart with notes without subcharts",
cmd: fmt.Sprintf("upgrade luffy '%s' --namespace default --render-subchart-notes", chartWithNotes),
golden: "output/upgrade-with-notes.txt",
rels: []*release.Release{relMock("luffy", 1, ch)},
},
{
// Running `helm upgrade --dry-run --render-subchart-notes` on a chart that has notes but no subcharts
// should print the upgrade command's dry-run output (current chart's) notes, i.e., no subchart's notes as
// no subchart. Note: The notes in dry-run output include the source filename and separator "---".
name: "helm upgrade --dry-run --render-subchart-notes on chart with notes without subcharts",
cmd: fmt.Sprintf("upgrade luffy '%s' --namespace default --dry-run --render-subchart-notes",
chartWithNotes),
golden: "output/upgrade-with-notes-with-flag-dry-run-enabled.txt",
rels: []*release.Release{relMock("luffy", 1, ch)},
},
{
// Running `helm upgrade` on a chart that has notes and 2 levels of subcharts should print upgrade command's
// output with just root chart's notes, i.e., without subchart's notes.
name: "helm upgrade on chart with notes and subcharts",
cmd: fmt.Sprintf("upgrade luffy '%s' --namespace default", chartWithNotesAnd2LevelsOfSubCharts),
golden: "output/upgrade-with-notes-and-subcharts.txt",
rels: []*release.Release{relMock("luffy", 1, ch)},
},
{
// Running `helm upgrade --dry-run` on a chart that has notes and 2 levels of subcharts should print the
// upgrade command's dry-run output with just the root chart's notes, i.e., without subcharts' notes. Note:
// The notes in dry-run output include the source filename and separator "---".
name: "helm upgrade --dry-run on chart with notes and subcharts",
cmd: fmt.Sprintf("upgrade luffy '%s' --namespace default --dry-run",
chartWithNotesAnd2LevelsOfSubCharts),
golden: "output/upgrade-with-notes-and-subcharts-with-flag-dry-run-enabled.txt",
rels: []*release.Release{relMock("luffy", 1, ch)},
},
{
// Running `helm upgrade --render-subchart-notes` on a chart that has notes and 2 levels of subcharts should
// print the upgrade command's output with both the root chart and the subcharts' notes.
name: "helm upgrade --render-subchart-notes on chart with notes and subcharts",
cmd: fmt.Sprintf("upgrade luffy '%s' --namespace default --render-subchart-notes",
chartWithNotesAnd2LevelsOfSubCharts),
golden: "output/upgrade-with-notes-and-subcharts-with-flag-render-subchart-notes-enabled.txt",
rels: []*release.Release{relMock("luffy", 1, ch)},
},
{
// Running `helm upgrade --dry-run --render-subchart-notes` on a chart that has notes and 2 levels of
// subcharts should print the upgrade command's dry-run output with both the root chart and the subcharts'
// notes. Note: The notes in dry-run output include the source filename and separator "---".
name: "helm upgrade --dry-run --render-subchart-notes on chart with notes and subcharts",
cmd: fmt.Sprintf("upgrade luffy '%s' --namespace default --dry-run --render-subchart-notes",
chartWithNotesAnd2LevelsOfSubCharts),
golden: "output/" +
"upgrade-with-notes-and-subcharts-with-both-flags-dry-run-and-render-subchart-notes-enabled.txt",
rels: []*release.Release{relMock("luffy", 1, ch)},
},
}
runTestCmd(t, tests)
}
// TestUpgradeHelpOutput tests the `helm upgrade --help` command's output text. This is required because the
// --render-subchart-notes flag's description is different for the template command from that of install/upgrade
// commands.
func TestUpgradeHelpOutput(t *testing.T) {
const (
outputFilePath = "testdata/output/upgrade-help.txt"
testNamespace = "test-namespace"
repositoryCache = "test-repository-cache-dir"
repositoryConfig = "test-repository-config.yaml"
registryConfig = "test-registry-config.json"
contentCache = "test-content-cache"
gnupgHome = "test-gpg"
commandText = "upgrade --help"
)
// Reset the envs and the configs at the end of this test so that the updates wouldnt affect other tests.
defer resetEnv()()
// Read the expected output file.
expectedOutput, err := os.ReadFile(outputFilePath)
assert.NoError(t, err, "unexpected error while reading expected output's file %q", outputFilePath)
// Set the configs that might otherwise change based on the local environment if not explicitly set. Note: These
// configs are not related to the current test.
settings.RepositoryCache = repositoryCache
settings.RepositoryConfig = repositoryConfig
settings.RegistryConfig = registryConfig
settings.ContentCache = contentCache
settings.SetNamespace(testNamespace)
t.Setenv("GNUPGHOME", gnupgHome)
// Run the `helm upgrade --help` command and compare the help text.
_, actualOutput, err := executeActionCommandC(storageFixture(), commandText)
assert.NoError(t, err, "unexpected error running command %q", commandText)
assert.Equal(t, string(expectedOutput), actualOutput, "mismatch of output")
}
func TestUpgradeWithValue(t *testing.T) {
releaseName := "funny-bunny-v2"
relMock, ch, chartPath := prepareMockRelease(t, releaseName)

Loading…
Cancel
Save