diff --git a/pkg/manifest/hooks.go b/pkg/manifest/hooks.go index d1d3839c5..097f2bc7e 100644 --- a/pkg/manifest/hooks.go +++ b/pkg/manifest/hooks.go @@ -31,6 +31,12 @@ import ( util "k8s.io/helm/pkg/releaseutil" ) +// NOTESFILE_SUFFIX that we want to treat special. It goes through the templating engine +// but it's not a yaml file (resource) hence can't have hooks, etc. And the user actually +// wants to see this file after rendering in the status command. However, it must be a suffix +// since there can be filepath in front of it. +const notesFileSuffix = "NOTES.txt" + type result struct { hooks []*release.Hook generic []Manifest @@ -49,11 +55,17 @@ type manifestFile struct { // Any file that does not declare one of the hook types will be placed in the // 'generic' bucket. // -// Files that do not parse into the expected format are simply placed into a map and -// returned. -func Partition(files map[string]string, apis chartutil.VersionSet, sort SortOrder) ([]*release.Hook, []Manifest, error) { +// Files that do not parse into the expected format are simply placed into a +// slice and returned. +// +// NOTES files discovered in charts (parent and child) are returned in a map; +// keys of the map are the directories the notes are found in, values are the +// contents of the NOTES. +func Partition(files map[string]string, apis chartutil.VersionSet, sort SortOrder) ([]*release.Hook, []Manifest, map[string]string, error) { result := &result{} + notes := make(map[string]string) + for filePath, c := range files { // Skip partials. We could return these as a separate map, but there doesn't @@ -67,6 +79,18 @@ func Partition(files map[string]string, apis chartutil.VersionSet, sort SortOrde continue } + // NOTES.txt gets rendered like all the other files, but because it's + // not a hook nor a resource, pull it out of here into a separate file + // so that we can actually use the output of the rendered 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. + + if strings.HasSuffix(filePath, notesFileSuffix) { + notes[path.Dir(filePath)] = c + continue + } + manifestFile := &manifestFile{ entries: util.SplitManifests(c), path: filePath, @@ -74,11 +98,11 @@ func Partition(files map[string]string, apis chartutil.VersionSet, sort SortOrde } if err := manifestFile.sort(result); err != nil { - return result.hooks, result.generic, err + return result.hooks, result.generic, notes, err } } - return result.hooks, sortByKind(result.generic, sort), nil + return result.hooks, sortByKind(result.generic, sort), notes, nil } // sort takes a manifestFile object which may contain multiple resource definition diff --git a/pkg/manifest/hooks_test.go b/pkg/manifest/hooks_test.go index e0ba3420b..974b54ec2 100644 --- a/pkg/manifest/hooks_test.go +++ b/pkg/manifest/hooks_test.go @@ -140,7 +140,7 @@ metadata: manifests[o.path] = o.manifest } - hs, generic, err := Partition(manifests, chartutil.NewVersionSet("v1", "v1beta1"), InstallOrder) + hs, generic, _, err := Partition(manifests, chartutil.NewVersionSet("v1", "v1beta1"), InstallOrder) if err != nil { t.Fatalf("Unexpected error: %s", err) } diff --git a/pkg/tiller/release_modules.go b/pkg/tiller/release_modules.go index 98db9c637..e0f705a54 100644 --- a/pkg/tiller/release_modules.go +++ b/pkg/tiller/release_modules.go @@ -162,7 +162,7 @@ func (m *RemoteReleaseModule) Delete(r *release.Release, req *services.Uninstall // DeleteRelease is a helper that allows Rudder to delete a release without exposing most of Tiller inner functions func DeleteRelease(rel *release.Release, vs chartutil.VersionSet, kubeClient environment.KubeClient) (kept string, errs []error) { manifests := relutil.SplitManifests(rel.Manifest) - _, files, err := manifest.Partition(manifests, vs, manifest.UninstallOrder) + _, files, _, err := manifest.Partition(manifests, vs, manifest.UninstallOrder) if err != nil { // We could instead just delete everything in no particular order. // FIXME: One way to delete at this point would be to try a label-based diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index fcd58e2f8..f3c567b52 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -49,12 +49,6 @@ const ( // charts to add data. Effectively, that gives us 53 chars. // See https://github.com/kubernetes/helm/issues/1528 releaseNameMaxLen = 53 - - // NOTESFILE_SUFFIX that we want to treat special. It goes through the templating engine - // but it's not a yaml file (resource) hence can't have hooks, etc. And the user actually - // wants to see this file after rendering in the status command. However, it must be a suffix - // since there can be filepath in front of it. - notesFileSuffix = "NOTES.txt" ) var ( @@ -306,32 +300,10 @@ func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values return nil, nil, "", err } - // NOTES.txt gets rendered like all the other files, but because it's not a hook nor a resource, - // pull it out of here into a separate file so that we can actually use the output of the rendered - // 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.Metadata.Name, "templates", notesFileSuffix)) { - - // If buffer contains data, add newline before adding more - if notesBuffer.Len() > 0 { - notesBuffer.WriteString("\n") - } - notesBuffer.WriteString(v) - } - delete(files, k) - } - } - - notes := notesBuffer.String() - // Sort hooks, manifests, and partials. Only hooks and manifests are returned, // as partials are not used after renderer.Render. Empty manifests are also // removed here. - hooks, manifests, err := manifest.Partition(files, vs, manifest.InstallOrder) + hooks, manifests, notesMap, err := manifest.Partition(files, vs, manifest.InstallOrder) if err != nil { // By catching parse errors here, we can prevent bogus releases from going // to Kubernetes. @@ -349,6 +321,21 @@ func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values return nil, b, "", err } + // Partition gave us a map of all the notes in the parent and child charts, + // so now flatten that map into a single string. + var notesBuffer bytes.Buffer + for chartName, chartNotes := range notesMap { + if subNotes || chartName == path.Join(ch.Metadata.Name, "templates") { + // If buffer contains data, add newline before adding more + if notesBuffer.Len() > 0 { + notesBuffer.WriteString("\n") + } + notesBuffer.WriteString(chartNotes) + } + } + + notes := notesBuffer.String() + // Aggregate all valid manifests into one big doc. b := bytes.NewBuffer(nil) for _, m := range manifests {