[manifest] teach the hook partitioner how to handle notes, too

Signed-off-by: Mike Lundy <mike@fluffypenguin.org>
pull/5040/head
Mike Lundy 7 years ago
parent edb007b1ba
commit 495a7d1a5d
No known key found for this signature in database
GPG Key ID: 9CC064ECB96D9325

@ -31,6 +31,12 @@ import (
util "k8s.io/helm/pkg/releaseutil" 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 { type result struct {
hooks []*release.Hook hooks []*release.Hook
generic []Manifest 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 // Any file that does not declare one of the hook types will be placed in the
// 'generic' bucket. // 'generic' bucket.
// //
// Files that do not parse into the expected format are simply placed into a map and // Files that do not parse into the expected format are simply placed into a
// returned. // slice and returned.
func Partition(files map[string]string, apis chartutil.VersionSet, sort SortOrder) ([]*release.Hook, []Manifest, error) { //
// 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{} result := &result{}
notes := make(map[string]string)
for filePath, c := range files { for filePath, c := range files {
// Skip partials. We could return these as a separate map, but there doesn't // 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 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{ manifestFile := &manifestFile{
entries: util.SplitManifests(c), entries: util.SplitManifests(c),
path: filePath, path: filePath,
@ -74,11 +98,11 @@ func Partition(files map[string]string, apis chartutil.VersionSet, sort SortOrde
} }
if err := manifestFile.sort(result); err != nil { 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 // sort takes a manifestFile object which may contain multiple resource definition

@ -140,7 +140,7 @@ metadata:
manifests[o.path] = o.manifest 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 { if err != nil {
t.Fatalf("Unexpected error: %s", err) t.Fatalf("Unexpected error: %s", err)
} }

@ -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 // 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) { func DeleteRelease(rel *release.Release, vs chartutil.VersionSet, kubeClient environment.KubeClient) (kept string, errs []error) {
manifests := relutil.SplitManifests(rel.Manifest) manifests := relutil.SplitManifests(rel.Manifest)
_, files, err := manifest.Partition(manifests, vs, manifest.UninstallOrder) _, files, _, err := manifest.Partition(manifests, vs, manifest.UninstallOrder)
if err != nil { if err != nil {
// We could instead just delete everything in no particular order. // 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 // FIXME: One way to delete at this point would be to try a label-based

@ -49,12 +49,6 @@ const (
// charts to add data. Effectively, that gives us 53 chars. // charts to add data. Effectively, that gives us 53 chars.
// See https://github.com/kubernetes/helm/issues/1528 // See https://github.com/kubernetes/helm/issues/1528
releaseNameMaxLen = 53 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 ( var (
@ -306,32 +300,10 @@ func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values
return nil, nil, "", err 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, // Sort hooks, manifests, and partials. Only hooks and manifests are returned,
// as partials are not used after renderer.Render. Empty manifests are also // as partials are not used after renderer.Render. Empty manifests are also
// removed here. // removed here.
hooks, manifests, err := manifest.Partition(files, vs, manifest.InstallOrder) hooks, manifests, notesMap, err := manifest.Partition(files, vs, manifest.InstallOrder)
if err != nil { if err != nil {
// By catching parse errors here, we can prevent bogus releases from going // By catching parse errors here, we can prevent bogus releases from going
// to Kubernetes. // to Kubernetes.
@ -349,6 +321,21 @@ func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values
return nil, b, "", err 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. // Aggregate all valid manifests into one big doc.
b := bytes.NewBuffer(nil) b := bytes.NewBuffer(nil)
for _, m := range manifests { for _, m := range manifests {

Loading…
Cancel
Save