Repository: helm/helm (go)

Issue:
Render only manifests in given directory
<!-- If you need help or think you have found a bug, please help us with your issue by entering the following information (otherwise you can delete this text): -->
It would be nice if the `-s/--show-only` flag of `helm template` could understand `*` or directories. Currently it just returns `Error: could not find template ... in chart`.

Output of `helm version`:
```
version.BuildInfo{Version:"v3.1.2", GitCommit:"d878d4d45863e42fd5cff6743294a11d28a9abce", GitTreeState:"clean", GoVersion:"go1.13.8"}
```

Output of `kubectl version`:
```
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.4", GitCommit:"8d8aa39598534325ad77120c120a22b3a990b5ea", GitTreeState:"clean", BuildDate:"2020-03-12T21:03:42Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2020-01-14T00:09:19Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}
```

Cloud Provider/Platform (AKS, GKE, Minikube etc.):  `kind`




Pull request:
Improve --show-only flag
Allows `--show-only` to handle directories and globs.

Fixes #7809 

Patch:
diff --git a/cmd/helm/template.go b/cmd/helm/template.go
index bd14cde1d..a4438b50c 100644
--- a/cmd/helm/template.go
+++ b/cmd/helm/template.go
@@ -22,6 +22,7 @@ import (
 	"io"
 	"path/filepath"
 	"regexp"
+	"sort"
 	"strings"
 
 	"github.com/spf13/cobra"
@@ -86,12 +87,21 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 				// 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 {
+					// This is necessary to ensure consistent manifest ordering when using --show-only
+					// with globs or directory names.
 					splitManifests := releaseutil.SplitManifests(manifests.String())
+					manifestsKeys := make([]string, 0, len(splitManifests))
+					for k := range splitManifests {
+						manifestsKeys = append(manifestsKeys, k)
+					}
+					sort.Sort(releaseutil.BySplitManifestsOrder(manifestsKeys))
+
 					manifestNameRegex := regexp.MustCompile("# Source: [^/]+/(.+)")
 					var manifestsToRender []string
 					for _, f := range showFiles {
 						missing := true
-						for _, manifest := range splitManifests {
+						for _, manifestKey := range manifestsKeys {
+							manifest := splitManifests[manifestKey]
 							submatch := manifestNameRegex.FindStringSubmatch(manifest)
 							if len(submatch) == 0 {
 								continue
@@ -104,10 +114,11 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 
 							// if the filepath provided matches a manifest path in the
 							// chart, render that manifest
-							if f == manifestPath {
-								manifestsToRender = append(manifestsToRender, manifest)
-								missing = false
+							if matched, _ := filepath.Match(f, manifestPath); !matched {
+								continue
 							}
+							manifestsToRender = append(manifestsToRender, manifest)
+							missing = false
 						}
 						if missing {
 							return fmt.Errorf("could not find template %s in chart", f)
diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go
index af8ff68e3..48eac0b0f 100644
--- a/cmd/helm/upgrade.go
+++ b/cmd/helm/upgrade.go
@@ -112,6 +112,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 					instClient.Atomic = client.Atomic
 					instClient.PostRenderer = client.PostRenderer
 					instClient.DisableOpenAPIValidation = client.DisableOpenAPIValidation
+					instClient.SubNotes = client.SubNotes
 
 					rel, err := runInstall(args, instClient, valueOpts, out)
 					if err != nil {
diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go
index 24eb1e277..b088f20ce 100644
--- a/pkg/chartutil/create.go
+++ b/pkg/chartutil/create.go
@@ -53,6 +53,8 @@ const (
 	ServiceName = TemplatesDir + sep + "service.yaml"
 	// ServiceAccountName is the name of the example serviceaccount file.
 	ServiceAccountName = TemplatesDir + sep + "serviceaccount.yaml"
+	// HorizontalPodAutoscalerName is the name of the example hpa file.
+	HorizontalPodAutoscalerName = TemplatesDir + sep + "hpa.yaml"
 	// NotesName is the name of the example NOTES.txt file.
 	NotesName = TemplatesDir + sep + "NOTES.txt"
 	// HelpersName is the name of the example helpers file.
@@ -149,6 +151,13 @@ resources: {}
   #   cpu: 100m
   #   memory: 128Mi
 
+autoscaling:
+  enabled: false
+  minReplicas: 1
+  maxReplicas: 100
+  targetCPUUtilizationPercentage: 80
+  # targetMemoryUtilizationPercentage: 80
+
 nodeSelector: {}
 
 tolerations: []
@@ -231,7 +240,9 @@ metadata:
   labels:
     {{- include "<CHARTNAME>.labels" . | nindent 4 }}
 spec:
+{{- if not .Values.autoscaling.enabled }}
   replicas: {{ .Values.replicaCount }}
+{{- end }}
   selector:
     matchLabels:
       {{- include "<CHARTNAME>.selectorLabels" . | nindent 6 }}
@@ -312,6 +323,36 @@ metadata:
 {{- end -}}
 `
 
+const defaultHorizontalPodAutoscaler = `{{- if .Values.autoscaling.enabled }}
+apiVersion: autoscaling/v2beta1
+kind: HorizontalPodAutoscaler
+metadata:
+  name: {{ include "<CHARTNAME>.fullname" . }}
+  labels:
+    {{- include "<CHARTNAME>.labels" . | nindent 4 }}
+spec:
+  scaleTargetRef:
+    apiVersion: apps/v1
+    kind: Deployment
+    name: {{ include "<CHARTNAME>.fullname" . }}
+  minReplicas: {{ .Values.autoscaling.minReplicas }}
+  maxReplicas: {{ .Values.autoscaling.maxReplicas }}
+  metrics:
+  {{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
+    - type: Resource
+      resource:
+        name: cpu
+        targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
+  {{- end }}
+  {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
+    - type: Resource
+      resource:
+        name: memory
+        targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
+  {{- end }}
+{{- end }}
+`
+
 const defaultNotes = `1. Get the application URL by running these commands:
 {{- if .Values.ingress.enabled }}
 {{- range $host := .Values.ingress.hosts }}
@@ -526,6 +567,11 @@ func Create(name, dir string) (string, error) {
 			path:    filepath.Join(cdir, ServiceAccountName),
 			content: transform(defaultServiceAccount, name),
 		},
+		{
+			// hpa.yaml
+			path:    filepath.Join(cdir, HorizontalPodAutoscalerName),
+			content: transform(defaultHorizontalPodAutoscaler, name),
+		},
 		{
 			// NOTES.txt
 			path:    filepath.Join(cdir, NotesName),


Test patch:
diff --git a/cmd/helm/create_test.go b/cmd/helm/create_test.go
index 0a9b7b9a5..bbb8d394a 100644
--- a/cmd/helm/create_test.go
+++ b/cmd/helm/create_test.go
@@ -106,7 +106,7 @@ func TestCreateStarterCmd(t *testing.T) {
 		t.Errorf("Wrong API version: %q", c.Metadata.APIVersion)
 	}
 
-	expectedNumberOfTemplates := 8
+	expectedNumberOfTemplates := 9
 	if l := len(c.Templates); l != expectedNumberOfTemplates {
 		t.Errorf("Expected %d templates, got %d", expectedNumberOfTemplates, l)
 	}
@@ -174,7 +174,7 @@ func TestCreateStarterAbsoluteCmd(t *testing.T) {
 		t.Errorf("Wrong API version: %q", c.Metadata.APIVersion)
 	}
 
-	expectedNumberOfTemplates := 8
+	expectedNumberOfTemplates := 9
 	if l := len(c.Templates); l != expectedNumberOfTemplates {
 		t.Errorf("Expected %d templates, got %d", expectedNumberOfTemplates, l)
 	}
diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go
index 3fd139fad..87ee79e5a 100644
--- a/cmd/helm/template_test.go
+++ b/cmd/helm/template_test.go
@@ -94,6 +94,13 @@ func TestTemplateCmd(t *testing.T) {
 			cmd:    fmt.Sprintf("template '%s' --show-only templates/service.yaml --show-only charts/subcharta/templates/service.yaml", chartPath),
 			golden: "output/template-show-only-multiple.txt",
 		},
+		{
+			name:   "template with show-only glob",
+			cmd:    fmt.Sprintf("template '%s' --show-only templates/subdir/role*", chartPath),
+			golden: "output/template-show-only-glob.txt",
+			// Repeat to ensure manifest ordering regressions are caught
+			repeat: 10,
+		},
 		{
 			name:   "sorted output of manifests (order of filenames, then order of objects within each YAML file)",
 			cmd:    fmt.Sprintf("template '%s'", "testdata/testcharts/object-order"),
diff --git a/cmd/helm/testdata/output/template-name-template.txt b/cmd/helm/testdata/output/template-name-template.txt
index acba50360..0130a2a92 100644
--- a/cmd/helm/testdata/output/template-name-template.txt
+++ b/cmd/helm/testdata/output/template-name-template.txt
@@ -1,4 +1,33 @@
 ---
+# Source: subchart1/templates/subdir/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: subchart1-sa
+---
+# Source: subchart1/templates/subdir/role.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: subchart1-role
+rules:
+- resources: ["*"]
+  verbs: ["get","list","watch"]
+---
+# Source: subchart1/templates/subdir/rolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: subchart1-binding
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: subchart1-role
+subjects:
+- kind: ServiceAccount
+  name: subchart1-sa
+  namespace: default
+---
 # Source: subchart1/charts/subcharta/templates/service.yaml
 apiVersion: v1
 kind: Service
diff --git a/cmd/helm/testdata/output/template-set.txt b/cmd/helm/testdata/output/template-set.txt
index b0924b5b6..ddaa8886b 100644
--- a/cmd/helm/testdata/output/template-set.txt
+++ b/cmd/helm/testdata/output/template-set.txt
@@ -1,4 +1,33 @@
 ---
+# Source: subchart1/templates/subdir/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: subchart1-sa
+---
+# Source: subchart1/templates/subdir/role.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: subchart1-role
+rules:
+- resources: ["*"]
+  verbs: ["get","list","watch"]
+---
+# Source: subchart1/templates/subdir/rolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: subchart1-binding
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: subchart1-role
+subjects:
+- kind: ServiceAccount
+  name: subchart1-sa
+  namespace: default
+---
 # Source: subchart1/charts/subcharta/templates/service.yaml
 apiVersion: v1
 kind: Service
diff --git a/cmd/helm/testdata/output/template-show-only-glob.txt b/cmd/helm/testdata/output/template-show-only-glob.txt
new file mode 100644
index 000000000..0970e6cd3
--- /dev/null
+++ b/cmd/helm/testdata/output/template-show-only-glob.txt
@@ -0,0 +1,23 @@
+---
+# Source: subchart1/templates/subdir/role.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: subchart1-role
+rules:
+- resources: ["*"]
+  verbs: ["get","list","watch"]
+---
+# Source: subchart1/templates/subdir/rolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: subchart1-binding
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: subchart1-role
+subjects:
+- kind: ServiceAccount
+  name: subchart1-sa
+  namespace: default
diff --git a/cmd/helm/testdata/output/template-values-files.txt b/cmd/helm/testdata/output/template-values-files.txt
index b0924b5b6..ddaa8886b 100644
--- a/cmd/helm/testdata/output/template-values-files.txt
+++ b/cmd/helm/testdata/output/template-values-files.txt
@@ -1,4 +1,33 @@
 ---
+# Source: subchart1/templates/subdir/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: subchart1-sa
+---
+# Source: subchart1/templates/subdir/role.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: subchart1-role
+rules:
+- resources: ["*"]
+  verbs: ["get","list","watch"]
+---
+# Source: subchart1/templates/subdir/rolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: subchart1-binding
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: subchart1-role
+subjects:
+- kind: ServiceAccount
+  name: subchart1-sa
+  namespace: default
+---
 # Source: subchart1/charts/subcharta/templates/service.yaml
 apiVersion: v1
 kind: Service
diff --git a/cmd/helm/testdata/output/template-with-api-version.txt b/cmd/helm/testdata/output/template-with-api-version.txt
index da3559082..7a2a4d5bf 100644
--- a/cmd/helm/testdata/output/template-with-api-version.txt
+++ b/cmd/helm/testdata/output/template-with-api-version.txt
@@ -1,4 +1,33 @@
 ---
+# Source: subchart1/templates/subdir/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: subchart1-sa
+---
+# Source: subchart1/templates/subdir/role.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: subchart1-role
+rules:
+- resources: ["*"]
+  verbs: ["get","list","watch"]
+---
+# Source: subchart1/templates/subdir/rolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: subchart1-binding
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: subchart1-role
+subjects:
+- kind: ServiceAccount
+  name: subchart1-sa
+  namespace: default
+---
 # Source: subchart1/charts/subcharta/templates/service.yaml
 apiVersion: v1
 kind: Service
diff --git a/cmd/helm/testdata/output/template-with-crds.txt b/cmd/helm/testdata/output/template-with-crds.txt
index 9fa1c7e6d..b04a4d5d2 100644
--- a/cmd/helm/testdata/output/template-with-crds.txt
+++ b/cmd/helm/testdata/output/template-with-crds.txt
@@ -15,6 +15,35 @@ spec:
     singular: authconfig
 
 ---
+# Source: subchart1/templates/subdir/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: subchart1-sa
+---
+# Source: subchart1/templates/subdir/role.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: subchart1-role
+rules:
+- resources: ["*"]
+  verbs: ["get","list","watch"]
+---
+# Source: subchart1/templates/subdir/rolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: subchart1-binding
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: subchart1-role
+subjects:
+- kind: ServiceAccount
+  name: subchart1-sa
+  namespace: default
+---
 # Source: subchart1/charts/subcharta/templates/service.yaml
 apiVersion: v1
 kind: Service
diff --git a/cmd/helm/testdata/output/template.txt b/cmd/helm/testdata/output/template.txt
index 080be618c..8301c2231 100644
--- a/cmd/helm/testdata/output/template.txt
+++ b/cmd/helm/testdata/output/template.txt
@@ -1,4 +1,33 @@
 ---
+# Source: subchart1/templates/subdir/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: subchart1-sa
+---
+# Source: subchart1/templates/subdir/role.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: subchart1-role
+rules:
+- resources: ["*"]
+  verbs: ["get","list","watch"]
+---
+# Source: subchart1/templates/subdir/rolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: subchart1-binding
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: subchart1-role
+subjects:
+- kind: ServiceAccount
+  name: subchart1-sa
+  namespace: default
+---
 # Source: subchart1/charts/subcharta/templates/service.yaml
 apiVersion: v1
 kind: Service
diff --git a/cmd/helm/testdata/testcharts/chart-with-subchart-notes/Chart.yaml b/cmd/helm/testdata/testcharts/chart-with-subchart-notes/Chart.yaml
new file mode 100644
index 000000000..90545a6a3
--- /dev/null
+++ b/cmd/helm/testdata/testcharts/chart-with-subchart-notes/Chart.yaml
@@ -0,0 +1,7 @@
+apiVersion: v2
+description: Chart with subchart notes
+name: chart-with-subchart-notes
+version: 0.0.1
+dependencies:
+  - name: subchart-with-notes
+    version: 0.0.1
diff --git a/cmd/helm/testdata/testcharts/chart-with-subchart-notes/charts/subchart-with-notes/Chart.yaml b/cmd/helm/testdata/testcharts/chart-with-subchart-notes/charts/subchart-with-notes/Chart.yaml
new file mode 100644
index 000000000..f0fead9ee
--- /dev/null
+++ b/cmd/helm/testdata/testcharts/chart-with-subchart-notes/charts/subchart-with-notes/Chart.yaml
@@ -0,0 +1,4 @@
+apiVersion: v2
+description: Subchart with notes
+name: subchart-with-notes
+version: 0.0.1
diff --git a/cmd/helm/testdata/testcharts/chart-with-subchart-notes/charts/subchart-with-notes/templates/NOTES.txt b/cmd/helm/testdata/testcharts/chart-with-subchart-notes/charts/subchart-with-notes/templates/NOTES.txt
new file mode 100644
index 000000000..1f61a294e
--- /dev/null
+++ b/cmd/helm/testdata/testcharts/chart-with-subchart-notes/charts/subchart-with-notes/templates/NOTES.txt
@@ -0,0 +1,1 @@
+SUBCHART NOTES
diff --git a/cmd/helm/testdata/testcharts/chart-with-subchart-notes/templates/NOTES.txt b/cmd/helm/testdata/testcharts/chart-with-subchart-notes/templates/NOTES.txt
new file mode 100644
index 000000000..9e166d370
--- /dev/null
+++ b/cmd/helm/testdata/testcharts/chart-with-subchart-notes/templates/NOTES.txt
@@ -0,0 +1,1 @@
+PARENT NOTES
diff --git a/cmd/helm/upgrade_test.go b/cmd/helm/upgrade_test.go
index 3cecbe6d3..4956c0247 100644
--- a/cmd/helm/upgrade_test.go
+++ b/cmd/helm/upgrade_test.go
@@ -196,6 +196,38 @@ func TestUpgradeWithStringValue(t *testing.T) {
 
 }
 
+func TestUpgradeInstallWithSubchartNotes(t *testing.T) {
+
+	releaseName := "wacky-bunny-v1"
+	relMock, ch, _ := prepareMockRelease(releaseName, t)
+
+	defer resetEnv()()
+
+	store := storageFixture()
+
+	store.Create(relMock(releaseName, 1, ch))
+
+	cmd := fmt.Sprintf("upgrade %s -i --render-subchart-notes '%s'", releaseName, "testdata/testcharts/chart-with-subchart-notes")
+	_, _, err := executeActionCommandC(store, cmd)
+	if err != nil {
+		t.Errorf("unexpected error, got '%v'", err)
+	}
+
+	upgradedRel, err := store.Get(releaseName, 2)
+	if err != nil {
+		t.Errorf("unexpected error, got '%v'", err)
+	}
+
+	if !strings.Contains(upgradedRel.Info.Notes, "PARENT NOTES") {
+		t.Errorf("The parent notes are not set correctly. NOTES: %s", upgradedRel.Info.Notes)
+	}
+
+	if !strings.Contains(upgradedRel.Info.Notes, "SUBCHART NOTES") {
+		t.Errorf("The subchart notes are not set correctly. NOTES: %s", upgradedRel.Info.Notes)
+	}
+
+}
+
 func TestUpgradeWithValuesFile(t *testing.T) {
 
 	releaseName := "funny-bunny-v4"
diff --git a/pkg/chart/chart_test.go b/pkg/chart/chart_test.go
index ef623fff6..4f19bf87d 100644
--- a/pkg/chart/chart_test.go
+++ b/pkg/chart/chart_test.go
@@ -78,3 +78,21 @@ func TestSaveChartNoRawData(t *testing.T) {
 
 	is.Equal([]*File(nil), res.Raw)
 }
+
+func TestMetadata(t *testing.T) {
+	chrt := Chart{
+		Metadata: &Metadata{
+			Name:       "foo.yaml",
+			AppVersion: "1.0.0",
+			APIVersion: "v2",
+			Version:    "1.0.0",
+			Type:       "application",
+		},
+	}
+
+	is := assert.New(t)
+
+	is.Equal("foo.yaml", chrt.Name())
+	is.Equal("1.0.0", chrt.AppVersion())
+	is.Equal(nil, chrt.Validate())
+}
diff --git a/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/role.yaml b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/role.yaml
new file mode 100644
index 000000000..91b954e5f
--- /dev/null
+++ b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/role.yaml
@@ -0,0 +1,7 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: {{ .Chart.Name }}-role
+rules:
+- resources: ["*"]
+  verbs: ["get","list","watch"]
diff --git a/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/rolebinding.yaml b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/rolebinding.yaml
new file mode 100644
index 000000000..5d193f1a6
--- /dev/null
+++ b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/rolebinding.yaml
@@ -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
diff --git a/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/serviceaccount.yaml b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/serviceaccount.yaml
new file mode 100644
index 000000000..7126c7d89
--- /dev/null
+++ b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/subdir/serviceaccount.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ .Chart.Name }}-sa