summaryrefslogtreecommitdiff
path: root/pkg/hooks/hooks.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/hooks/hooks.go')
-rw-r--r--pkg/hooks/hooks.go41
1 files changed, 27 insertions, 14 deletions
diff --git a/pkg/hooks/hooks.go b/pkg/hooks/hooks.go
index 337d6e3e2..6413829ee 100644
--- a/pkg/hooks/hooks.go
+++ b/pkg/hooks/hooks.go
@@ -27,10 +27,11 @@ const (
// Manager provides an opaque interface for managing CRI-O hooks.
type Manager struct {
- hooks map[string]*current.Hook
- language language.Tag
- directories []string
- lock sync.Mutex
+ hooks map[string]*current.Hook
+ directories []string
+ extensionStages []string
+ language language.Tag
+ lock sync.Mutex
}
type namedHook struct {
@@ -44,15 +45,16 @@ type namedHooks []*namedHook
// increasing preference (hook configurations in later directories
// override configurations with the same filename from earlier
// directories).
-func New(ctx context.Context, directories []string, lang language.Tag) (manager *Manager, err error) {
+func New(ctx context.Context, directories []string, extensionStages []string, lang language.Tag) (manager *Manager, err error) {
manager = &Manager{
- hooks: map[string]*current.Hook{},
- directories: directories,
- language: lang,
+ hooks: map[string]*current.Hook{},
+ directories: directories,
+ extensionStages: extensionStages,
+ language: lang,
}
for _, dir := range directories {
- err = ReadDir(dir, manager.hooks)
+ err = ReadDir(dir, manager.extensionStages, manager.hooks)
if err != nil {
return nil, err
}
@@ -80,14 +82,18 @@ func (m *Manager) namedHooks() (hooks []*namedHook) {
}
// Hooks injects OCI runtime hooks for a given container configuration.
-func (m *Manager) Hooks(config *rspec.Spec, annotations map[string]string, hasBindMounts bool) (err error) {
+func (m *Manager) Hooks(config *rspec.Spec, annotations map[string]string, hasBindMounts bool) (extensionStages map[string][]rspec.Hook, err error) {
hooks := m.namedHooks()
collator := collate.New(m.language, collate.IgnoreCase, collate.IgnoreWidth)
collator.Sort(namedHooks(hooks))
+ validStages := map[string]bool{} // beyond the OCI stages
+ for _, stage := range m.extensionStages {
+ validStages[stage] = true
+ }
for _, namedHook := range hooks {
match, err := namedHook.hook.When.Match(config, annotations, hasBindMounts)
if err != nil {
- return errors.Wrapf(err, "matching hook %q", namedHook.name)
+ return extensionStages, errors.Wrapf(err, "matching hook %q", namedHook.name)
}
if match {
if config.Hooks == nil {
@@ -102,12 +108,19 @@ func (m *Manager) Hooks(config *rspec.Spec, annotations map[string]string, hasBi
case "poststop":
config.Hooks.Poststop = append(config.Hooks.Poststop, namedHook.hook.Hook)
default:
- return fmt.Errorf("hook %q: unknown stage %q", namedHook.name, stage)
+ if !validStages[stage] {
+ return extensionStages, fmt.Errorf("hook %q: unknown stage %q", namedHook.name, stage)
+ }
+ if extensionStages == nil {
+ extensionStages = map[string][]rspec.Hook{}
+ }
+ extensionStages[stage] = append(extensionStages[stage], namedHook.hook.Hook)
}
}
}
}
- return nil
+
+ return extensionStages, nil
}
// remove remove a hook by name.
@@ -125,7 +138,7 @@ func (m *Manager) remove(hook string) (ok bool) {
func (m *Manager) add(path string) (err error) {
m.lock.Lock()
defer m.lock.Unlock()
- hook, err := Read(path)
+ hook, err := Read(path, m.extensionStages)
if err != nil {
return err
}