diff options
Diffstat (limited to 'pkg/hooks')
-rw-r--r-- | pkg/hooks/0.1.0/hook.go | 2 | ||||
-rw-r--r-- | pkg/hooks/1.0.0/when_test.go | 2 | ||||
-rw-r--r-- | pkg/hooks/docs/oci-hooks.5.md | 2 | ||||
-rw-r--r-- | pkg/hooks/exec/exec.go | 5 | ||||
-rw-r--r-- | pkg/hooks/exec/runtimeconfigfilter.go | 12 | ||||
-rw-r--r-- | pkg/hooks/hooks.go | 24 | ||||
-rw-r--r-- | pkg/hooks/monitor.go | 49 | ||||
-rw-r--r-- | pkg/hooks/monitor_test.go | 25 | ||||
-rw-r--r-- | pkg/hooks/read.go | 11 |
9 files changed, 52 insertions, 80 deletions
diff --git a/pkg/hooks/0.1.0/hook.go b/pkg/hooks/0.1.0/hook.go index ba68b0f10..88a387647 100644 --- a/pkg/hooks/0.1.0/hook.go +++ b/pkg/hooks/0.1.0/hook.go @@ -6,7 +6,7 @@ import ( "errors" "strings" - hooks "github.com/containers/libpod/pkg/hooks" + "github.com/containers/libpod/pkg/hooks" current "github.com/containers/libpod/pkg/hooks/1.0.0" rspec "github.com/opencontainers/runtime-spec/specs-go" ) diff --git a/pkg/hooks/1.0.0/when_test.go b/pkg/hooks/1.0.0/when_test.go index 7187b297b..a749063ff 100644 --- a/pkg/hooks/1.0.0/when_test.go +++ b/pkg/hooks/1.0.0/when_test.go @@ -30,7 +30,7 @@ func TestAlways(t *testing.T) { for _, always := range []bool{true, false} { for _, or := range []bool{true, false} { for _, process := range []*rspec.Process{processStruct, nil} { - t.Run(fmt.Sprintf("always %t, or %t, has process %t", always, or, (process != nil)), func(t *testing.T) { + t.Run(fmt.Sprintf("always %t, or %t, has process %t", always, or, process != nil), func(t *testing.T) { config.Process = process when := When{Always: &always, Or: or} match, err := when.Match(config, map[string]string{}, false) diff --git a/pkg/hooks/docs/oci-hooks.5.md b/pkg/hooks/docs/oci-hooks.5.md index c876dd2f8..fc0442283 100644 --- a/pkg/hooks/docs/oci-hooks.5.md +++ b/pkg/hooks/docs/oci-hooks.5.md @@ -90,7 +90,7 @@ $ cat /etc/containers/oci/hooks.d/oci-systemd-hook.json "path": "/usr/libexec/oci/hooks.d/oci-systemd-hook" } "when": { - "args": [".*/init$" , ".*/systemd$"], + "commands": [".*/init$" , ".*/systemd$"], }, "stages": ["prestart", "poststop"] } diff --git a/pkg/hooks/exec/exec.go b/pkg/hooks/exec/exec.go index 0dd091561..4038e3d94 100644 --- a/pkg/hooks/exec/exec.go +++ b/pkg/hooks/exec/exec.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "fmt" + "github.com/sirupsen/logrus" "io" osexec "os/exec" "time" @@ -54,7 +55,9 @@ func Run(ctx context.Context, hook *rspec.Hook, state []byte, stdout io.Writer, case err = <-exit: return err, err case <-ctx.Done(): - cmd.Process.Kill() + if err := cmd.Process.Kill(); err != nil { + logrus.Errorf("failed to kill pid %v", cmd.Process) + } timer := time.NewTimer(postKillTimeout) defer timer.Stop() select { diff --git a/pkg/hooks/exec/runtimeconfigfilter.go b/pkg/hooks/exec/runtimeconfigfilter.go index c6971f680..10b8fedc2 100644 --- a/pkg/hooks/exec/runtimeconfigfilter.go +++ b/pkg/hooks/exec/runtimeconfigfilter.go @@ -27,7 +27,11 @@ var spewConfig = spew.ConfigState{ // reads back a possibly-altered form from their standard output). func RuntimeConfigFilter(ctx context.Context, hooks []spec.Hook, config *spec.Spec, postKillTimeout time.Duration) (hookErr, err error) { data, err := json.Marshal(config) + if err != nil { + return nil, err + } for i, hook := range hooks { + hook := hook var stdout bytes.Buffer hookErr, err = Run(ctx, &hook, data, &stdout, nil, postKillTimeout) if err != nil { @@ -43,11 +47,11 @@ func RuntimeConfigFilter(ctx context.Context, hooks []spec.Hook, config *spec.Sp } if !reflect.DeepEqual(config, &newConfig) { - old := spewConfig.Sdump(config) - new := spewConfig.Sdump(&newConfig) + oldConfig := spewConfig.Sdump(config) + newConfig := spewConfig.Sdump(&newConfig) diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ - A: difflib.SplitLines(old), - B: difflib.SplitLines(new), + A: difflib.SplitLines(oldConfig), + B: difflib.SplitLines(newConfig), FromFile: "Old", FromDate: "", ToFile: "New", diff --git a/pkg/hooks/hooks.go b/pkg/hooks/hooks.go index 5ed028b95..b962ffa5c 100644 --- a/pkg/hooks/hooks.go +++ b/pkg/hooks/hooks.go @@ -4,7 +4,6 @@ package hooks import ( "context" "fmt" - "path/filepath" "sort" "strings" "sync" @@ -138,26 +137,3 @@ func (m *Manager) Hooks(config *rspec.Spec, annotations map[string]string, hasBi return extensionStageHooks, nil } - -// remove remove a hook by name. -func (m *Manager) remove(hook string) (ok bool) { - m.lock.Lock() - defer m.lock.Unlock() - _, ok = m.hooks[hook] - if ok { - delete(m.hooks, hook) - } - return ok -} - -// add adds a hook by path -func (m *Manager) add(path string) (err error) { - m.lock.Lock() - defer m.lock.Unlock() - hook, err := Read(path, m.extensionStages) - if err != nil { - return err - } - m.hooks[filepath.Base(path)] = hook - return nil -} diff --git a/pkg/hooks/monitor.go b/pkg/hooks/monitor.go index febe3483f..c50b321f2 100644 --- a/pkg/hooks/monitor.go +++ b/pkg/hooks/monitor.go @@ -2,9 +2,8 @@ package hooks import ( "context" - "os" - "path/filepath" + current "github.com/containers/libpod/pkg/hooks/1.0.0" "github.com/fsnotify/fsnotify" "github.com/sirupsen/logrus" ) @@ -49,47 +48,11 @@ func (m *Manager) Monitor(ctx context.Context, sync chan<- error) { for { select { case event := <-watcher.Events: - filename := filepath.Base(event.Name) - if len(m.directories) <= 1 { - if event.Op&fsnotify.Remove == fsnotify.Remove { - ok := m.remove(filename) - if ok { - logrus.Debugf("removed hook %s", event.Name) - } - } else if event.Op&fsnotify.Create == fsnotify.Create || event.Op&fsnotify.Write == fsnotify.Write { - err = m.add(event.Name) - if err == nil { - logrus.Debugf("added hook %s", event.Name) - } else if err != ErrNoJSONSuffix { - logrus.Errorf("failed to add hook %s: %v", event.Name, err) - } - } - } else if event.Op&fsnotify.Create == fsnotify.Create || event.Op&fsnotify.Write == fsnotify.Write || event.Op&fsnotify.Remove == fsnotify.Remove { - err = nil - found := false - for i := len(m.directories) - 1; i >= 0; i-- { - path := filepath.Join(m.directories[i], filename) - err = m.add(path) - if err == nil { - found = true - logrus.Debugf("(re)added hook %s (triggered activity on %s)", path, event.Name) - break - } else if err == ErrNoJSONSuffix { - found = true - break // this is not going to change for fallback directories - } else if os.IsNotExist(err) { - continue // move on to the next fallback directory - } else { - found = true - logrus.Errorf("failed to (re)add hook %s (triggered by activity on %s): %v", path, event.Name, err) - break - } - } - if (found || event.Op&fsnotify.Remove == fsnotify.Remove) && err != nil { - ok := m.remove(filename) - if ok { - logrus.Debugf("removed hook %s (triggered by activity on %s)", filename, event.Name) - } + m.hooks = make(map[string]*current.Hook) + for _, dir := range m.directories { + err = ReadDir(dir, m.extensionStages, m.hooks) + if err != nil { + logrus.Errorf("failed loading hooks for %s: %v", event.Name, err) } } case <-ctx.Done(): diff --git a/pkg/hooks/monitor_test.go b/pkg/hooks/monitor_test.go index 31d7f9e39..dc67eaf83 100644 --- a/pkg/hooks/monitor_test.go +++ b/pkg/hooks/monitor_test.go @@ -226,7 +226,28 @@ func TestMonitorTwoDirGood(t *testing.T) { assert.Equal(t, primaryInjected, config.Hooks) // masked by primary }) - t.Run("bad-primary-addition", func(t *testing.T) { + primaryPath2 := filepath.Join(primaryDir, "0a.json") //0a because it will be before a.json alphabetically + + t.Run("bad-primary-new-addition", func(t *testing.T) { + err = ioutil.WriteFile(primaryPath2, []byte("{\"version\": \"-1\"}"), 0644) + if err != nil { + t.Fatal(err) + } + + time.Sleep(100 * time.Millisecond) // wait for monitor to notice + + config := &rspec.Spec{} + fmt.Println("expected: ", config.Hooks) + expected := primaryInjected // 0a.json is bad, a.json is still good + _, err = manager.Hooks(config, map[string]string{}, false) + fmt.Println("actual: ", config.Hooks) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, expected, config.Hooks) + }) + + t.Run("bad-primary-same-addition", func(t *testing.T) { err = ioutil.WriteFile(primaryPath, []byte("{\"version\": \"-1\"}"), 0644) if err != nil { t.Fatal(err) @@ -235,7 +256,7 @@ func TestMonitorTwoDirGood(t *testing.T) { time.Sleep(100 * time.Millisecond) // wait for monitor to notice config := &rspec.Spec{} - expected := config.Hooks + expected := fallbackInjected _, err = manager.Hooks(config, map[string]string{}, false) if err != nil { t.Fatal(err) diff --git a/pkg/hooks/read.go b/pkg/hooks/read.go index d3995a0be..560ff1899 100644 --- a/pkg/hooks/read.go +++ b/pkg/hooks/read.go @@ -67,7 +67,7 @@ func ReadDir(path string, extensionStages []string, hooks map[string]*current.Ho if err != nil { return err } - + res := err for _, file := range files { filePath := filepath.Join(path, file.Name()) hook, err := Read(filePath, extensionStages) @@ -80,12 +80,17 @@ func ReadDir(path string, extensionStages []string, hooks map[string]*current.Ho continue } } - return err + if res == nil { + res = err + } else { + res = errors.Wrapf(res, "%v", err) + } + continue } hooks[file.Name()] = hook logrus.Debugf("added hook %s", filePath) } - return nil + return res } func init() { |