github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/hooks/monitor.go (about) 1 package hooks 2 3 import ( 4 "context" 5 6 current "github.com/hanks177/podman/v4/pkg/hooks/1.0.0" 7 "github.com/fsnotify/fsnotify" 8 "github.com/sirupsen/logrus" 9 ) 10 11 // Monitor dynamically monitors hook directories for additions, 12 // updates, and removals. 13 // 14 // This function writes two empty structs to the sync channel: the 15 // first is written after the watchers are established and the second 16 // when this function exits. The expected usage is: 17 // 18 // ctx, cancel := context.WithCancel(context.Background()) 19 // sync := make(chan error, 2) 20 // go m.Monitor(ctx, sync) 21 // err := <-sync // block until writers are established 22 // if err != nil { 23 // return err // failed to establish watchers 24 // } 25 // // do stuff 26 // cancel() 27 // err = <-sync // block until monitor finishes 28 func (m *Manager) Monitor(ctx context.Context, sync chan<- error) { 29 watcher, err := fsnotify.NewWatcher() 30 if err != nil { 31 sync <- err 32 return 33 } 34 defer watcher.Close() 35 36 for _, dir := range m.directories { 37 err = watcher.Add(dir) 38 if err != nil { 39 logrus.Errorf("Failed to watch %q for hooks", dir) 40 sync <- err 41 return 42 } 43 logrus.Debugf("monitoring %q for hooks", dir) 44 } 45 46 sync <- nil 47 48 for { 49 select { 50 case event := <-watcher.Events: 51 m.hooks = make(map[string]*current.Hook) 52 for _, dir := range m.directories { 53 err = ReadDir(dir, m.extensionStages, m.hooks) 54 if err != nil { 55 logrus.Errorf("Failed loading hooks for %s: %v", event.Name, err) 56 } 57 } 58 case <-ctx.Done(): 59 err = ctx.Err() 60 logrus.Debugf("hook monitoring canceled: %v", err) 61 sync <- err 62 close(sync) 63 return 64 } 65 } 66 }