Commit 6bfb08a7 authored by Michelle Noorali's avatar Michelle Noorali

ref(tiller): refactor sortManifests()

parent 83c69a8e
...@@ -51,102 +51,149 @@ type manifest struct { ...@@ -51,102 +51,149 @@ type manifest struct {
head *util.SimpleHead head *util.SimpleHead
} }
// sortManifests takes a map of filename/YAML contents and sorts them into hook types. type result struct {
hooks []*release.Hook
generic []manifest
}
type manifestFile struct {
entries map[string]string
path string
apis chartutil.VersionSet
}
// sortManifests takes a map of filename/YAML contents, splits the file
// by manifest entries, and sorts the entries into hook types.
// //
// The resulting hooks struct will be populated with all of the generated hooks. // The resulting hooks struct will be populated with all of the generated hooks.
// 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.
// //
// To determine hook type, this looks for a YAML structure like this:
//
// kind: SomeKind
// apiVersion: v1
// metadata:
// annotations:
// helm.sh/hook: pre-install
//
// Where HOOK_NAME is one of the known hooks.
//
// If a file declares more than one hook, it will be copied into all of the applicable
// hook buckets. (Note: label keys are not unique within the labels section).
//
// 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 map and
// returned. // returned.
func sortManifests(files map[string]string, apis chartutil.VersionSet, sort SortOrder) ([]*release.Hook, []manifest, error) { func sortManifests(files map[string]string, apis chartutil.VersionSet, sort SortOrder) ([]*release.Hook, []manifest, error) {
hs := []*release.Hook{} result := &result{}
generic := []manifest{}
for filePath, c := range files {
for n, 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
// seem to be any need for that at this time. // seem to be any need for that at this time.
if strings.HasPrefix(path.Base(n), "_") { if strings.HasPrefix(path.Base(filePath), "_") {
continue continue
} }
// Skip empty files, and log this. // Skip empty files and log this.
if len(strings.TrimSpace(c)) == 0 { if len(strings.TrimSpace(c)) == 0 {
log.Printf("info: manifest %q is empty. Skipping.", n) log.Printf("info: manifest %q is empty. Skipping.", filePath)
continue continue
} }
entries := util.SplitManifests(c) manifestFile := &manifestFile{
for _, m := range entries { entries: util.SplitManifests(c),
var sh util.SimpleHead path: filePath,
err := yaml.Unmarshal([]byte(m), &sh) apis: apis,
}
if err != nil { if err := manifestFile.sort(result); err != nil {
e := fmt.Errorf("YAML parse error on %s: %s", n, err) return result.hooks, result.generic, err
return hs, generic, e }
} }
if sh.Version != "" && !apis.Has(sh.Version) { return result.hooks, sortByKind(result.generic, sort), nil
return hs, generic, fmt.Errorf("apiVersion %q in %s is not available", sh.Version, n) }
}
if sh.Metadata == nil || sh.Metadata.Annotations == nil || len(sh.Metadata.Annotations) == 0 { // sort takes a manifestFile object which may contain multiple resource definition
generic = append(generic, manifest{name: n, content: m, head: &sh}) // entries and sorts each entry by hook types, and saves the resulting hooks and
continue // generic manifests (or non-hooks) to the result struct.
} //
// To determine hook type, it looks for a YAML structure like this:
//
// kind: SomeKind
// apiVersion: v1
// metadata:
// annotations:
// helm.sh/hook: pre-install
//
func (file *manifestFile) sort(result *result) error {
for _, m := range file.entries {
var entry util.SimpleHead
err := yaml.Unmarshal([]byte(m), &entry)
if err != nil {
e := fmt.Errorf("YAML parse error on %s: %s", file.path, err)
return e
}
hookTypes, ok := sh.Metadata.Annotations[hooks.HookAnno] if entry.Version != "" && !file.apis.Has(entry.Version) {
if !ok { return fmt.Errorf("apiVersion %q in %s is not available", entry.Version, file.path)
generic = append(generic, manifest{name: n, content: m, head: &sh}) }
continue
}
hws, _ := sh.Metadata.Annotations[hooks.HookWeightAnno] if !hasAnyAnnotation(entry) {
hw, err := strconv.Atoi(hws) result.generic = append(result.generic, manifest{
if err != nil { name: file.path,
hw = 0 content: m,
} head: &entry,
fmt.Println("NAME: " + sh.Metadata.Name) })
continue
h := &release.Hook{ }
Name: sh.Metadata.Name,
Kind: sh.Kind,
Path: n, //TODO: fix by putting back into big loop
Manifest: m,
Events: []release.Hook_Event{},
Weight: int32(hw),
}
isHook := false hookTypes, ok := entry.Metadata.Annotations[hooks.HookAnno]
for _, hookType := range strings.Split(hookTypes, ",") { if !ok {
hookType = strings.ToLower(strings.TrimSpace(hookType)) result.generic = append(result.generic, manifest{
e, ok := events[hookType] name: file.path,
if ok { content: m,
isHook = true head: &entry,
h.Events = append(h.Events, e) })
} continue
} }
hw := calculateHookWeight(entry)
if !isHook { h := &release.Hook{
log.Printf("info: skipping unknown hook: %q", hookTypes) Name: entry.Metadata.Name,
continue Kind: entry.Kind,
Path: file.path,
Manifest: m,
Events: []release.Hook_Event{},
Weight: hw,
}
isKnownHook := false
for _, hookType := range strings.Split(hookTypes, ",") {
hookType = strings.ToLower(strings.TrimSpace(hookType))
e, ok := events[hookType]
if ok {
isKnownHook = true
h.Events = append(h.Events, e)
} }
hs = append(hs, h)
} }
if !isKnownHook {
log.Printf("info: skipping unknown hook: %q", hookTypes)
continue
}
result.hooks = append(result.hooks, h)
}
return nil
}
func hasAnyAnnotation(entry util.SimpleHead) bool {
if entry.Metadata == nil ||
entry.Metadata.Annotations == nil ||
len(entry.Metadata.Annotations) == 0 {
return false
}
return true
}
func calculateHookWeight(entry util.SimpleHead) int32 {
hws, _ := entry.Metadata.Annotations[hooks.HookWeightAnno]
hw, err := strconv.Atoi(hws)
if err != nil {
hw = 0
} }
return hs, sortByKind(generic, sort), nil return int32(hw)
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment