github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/hooks/read.go (about) 1 // Package hooks implements CRI-O's hook handling. 2 package hooks 3 4 import ( 5 "encoding/json" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "strings" 10 11 old "github.com/containers/podman/v2/pkg/hooks/0.1.0" 12 current "github.com/containers/podman/v2/pkg/hooks/1.0.0" 13 "github.com/pkg/errors" 14 "github.com/sirupsen/logrus" 15 ) 16 17 type reader func(content []byte) (*current.Hook, error) 18 19 var ( 20 // ErrNoJSONSuffix represents hook-add attempts where the filename 21 // does not end in '.json'. 22 ErrNoJSONSuffix = errors.New("hook filename does not end in '.json'") 23 24 // Readers registers per-version hook readers. 25 Readers = map[string]reader{} 26 ) 27 28 // Read reads a hook JSON file, verifies it, and returns the hook configuration. 29 func Read(path string, extensionStages []string) (*current.Hook, error) { 30 if !strings.HasSuffix(path, ".json") { 31 return nil, ErrNoJSONSuffix 32 } 33 content, err := ioutil.ReadFile(path) 34 if err != nil { 35 return nil, err 36 } 37 hook, err := read(content) 38 if err != nil { 39 return nil, errors.Wrapf(err, "parsing hook %q", path) 40 } 41 err = hook.Validate(extensionStages) 42 return hook, err 43 } 44 45 func read(content []byte) (hook *current.Hook, err error) { 46 var ver version 47 if err := json.Unmarshal(content, &ver); err != nil { 48 return nil, errors.Wrap(err, "version check") 49 } 50 reader, ok := Readers[ver.Version] 51 if !ok { 52 return nil, errors.Errorf("unrecognized hook version: %q", ver.Version) 53 } 54 55 hook, err = reader(content) 56 if err != nil { 57 return hook, errors.Wrap(err, ver.Version) 58 } 59 return hook, err 60 } 61 62 // ReadDir reads hook JSON files from a directory into the given map, 63 // clobbering any previous entries with the same filenames. 64 func ReadDir(path string, extensionStages []string, hooks map[string]*current.Hook) error { 65 logrus.Debugf("reading hooks from %s", path) 66 files, err := ioutil.ReadDir(path) 67 if err != nil { 68 return err 69 } 70 res := err 71 for _, file := range files { 72 filePath := filepath.Join(path, file.Name()) 73 hook, err := Read(filePath, extensionStages) 74 if err != nil { 75 if err == ErrNoJSONSuffix { 76 continue 77 } 78 if os.IsNotExist(err) { 79 if err2, ok := err.(*os.PathError); ok && err2.Path == filePath { 80 continue 81 } 82 } 83 if res == nil { 84 res = err 85 } else { 86 res = errors.Wrapf(res, "%v", err) 87 } 88 continue 89 } 90 hooks[file.Name()] = hook 91 logrus.Debugf("added hook %s", filePath) 92 } 93 return res 94 } 95 96 func init() { 97 Readers[current.Version] = current.Read 98 Readers[old.Version] = old.Read 99 Readers[""] = old.Read 100 }