You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
helm/cmd/tiller/hooks.go

110 lines
2.7 KiB

package main
import (
"fmt"
"log"
"strings"
"github.com/ghodss/yaml"
"k8s.io/helm/pkg/proto/hapi/release"
)
// hookAnno is the label name for a hook
const hookAnno = "helm.sh/hook"
const (
preInstall = "pre-install"
postInstall = "post-install"
preDelete = "pre-delete"
postDelete = "post-delete"
preUpgrade = "pre-upgrade"
postUpgrade = "post-upgrade"
)
var events = map[string]release.Hook_Event{
preInstall: release.Hook_PRE_INSTALL,
postInstall: release.Hook_POST_INSTALL,
preDelete: release.Hook_PRE_DELETE,
postDelete: release.Hook_POST_DELETE,
preUpgrade: release.Hook_PRE_UPGRADE,
postUpgrade: release.Hook_POST_UPGRADE,
}
type simpleHead struct {
Kind string `json:"kind,omitempty"`
Metadata *struct {
Name string `json:"name"`
Annotations map[string]string `json:"annotations"`
} `json:"metadata,omitempty"`
}
// sortHooks takes a map of filename/YAML contents and sorts them into hook types.
//
// 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
// 'generic' bucket.
//
// To determine hook type, this looks for a YAML structure like this:
//
// kind: SomeKind
// 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
// returned.
func sortHooks(files map[string]string) ([]*release.Hook, map[string]string, error) {
hs := []*release.Hook{}
generic := map[string]string{}
for n, c := range files {
var sh simpleHead
err := yaml.Unmarshal([]byte(c), &sh)
if err != nil {
e := fmt.Errorf("YAML parse error on %s: %s", n, err)
return hs, generic, e
}
if sh.Metadata == nil || sh.Metadata.Annotations == nil || len(sh.Metadata.Annotations) == 0 {
generic[n] = c
continue
}
hookTypes, ok := sh.Metadata.Annotations[hookAnno]
if !ok {
generic[n] = c
continue
}
h := &release.Hook{
Name: sh.Metadata.Name,
Kind: sh.Kind,
Path: n,
Manifest: c,
Events: []release.Hook_Event{},
}
isHook := false
for _, hookType := range strings.Split(hookTypes, ",") {
hookType = strings.ToLower(strings.TrimSpace(hookType))
e, ok := events[hookType]
if ok {
isHook = true
h.Events = append(h.Events, e)
}
}
if !isHook {
log.Printf("info: skipping unknown hook: %q", hookTypes)
continue
}
hs = append(hs, h)
}
return hs, generic, nil
}