mirror of
https://github.com/containers/podman.git
synced 2025-10-29 17:06:22 +08:00
If a .json file existed when we called ioutil.ReadDir but that file has been removed by the time we get around to calling Read on it, silently ignore the file. Iterating through all the files in the directory shouldn't take particularly long, so this is an unlikely corner case. And when it happens, silently ignoring the file gives the same outcome as you'd have gotten if the parallel remove had happened slightly earlier before the ioutil.ReadDir call. Signed-off-by: W. Trevor King <wking@tremily.us> Closes: #686 Approved by: mheon
88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
// Package hooks implements CRI-O's hook handling.
|
|
package hooks
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/pkg/errors"
|
|
current "github.com/projectatomic/libpod/pkg/hooks/1.0.0"
|
|
)
|
|
|
|
type reader func(content []byte) (*current.Hook, error)
|
|
|
|
var (
|
|
// ErrNoJSONSuffix represents hook-add attempts where the filename
|
|
// does not end in '.json'.
|
|
ErrNoJSONSuffix = errors.New("hook filename does not end in '.json'")
|
|
|
|
// Readers registers per-version hook readers.
|
|
Readers = map[string]reader{}
|
|
)
|
|
|
|
// Read reads a hook JSON file, verifies it, and returns the hook configuration.
|
|
func Read(path string) (*current.Hook, error) {
|
|
if !strings.HasSuffix(path, ".json") {
|
|
return nil, ErrNoJSONSuffix
|
|
}
|
|
content, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
hook, err := read(content)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "parsing hook %q", path)
|
|
}
|
|
err = hook.Validate()
|
|
return hook, err
|
|
}
|
|
|
|
func read(content []byte) (hook *current.Hook, err error) {
|
|
var ver version
|
|
if err := json.Unmarshal(content, &ver); err != nil {
|
|
return nil, errors.Wrap(err, "version check")
|
|
}
|
|
reader, ok := Readers[ver.Version]
|
|
if !ok {
|
|
return nil, fmt.Errorf("unrecognized hook version: %q", ver.Version)
|
|
}
|
|
|
|
hook, err = reader(content)
|
|
if err != nil {
|
|
return hook, errors.Wrap(err, ver.Version)
|
|
}
|
|
return hook, err
|
|
}
|
|
|
|
// ReadDir reads hook JSON files from a directory into the given map,
|
|
// clobbering any previous entries with the same filenames.
|
|
func ReadDir(path string, hooks map[string]*current.Hook) error {
|
|
files, err := ioutil.ReadDir(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, file := range files {
|
|
hook, err := Read(filepath.Join(path, file.Name()))
|
|
if err != nil {
|
|
if err == ErrNoJSONSuffix {
|
|
continue
|
|
}
|
|
if os.IsNotExist(err) {
|
|
continue
|
|
}
|
|
return err
|
|
}
|
|
hooks[file.Name()] = hook
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func init() {
|
|
Readers[current.Version] = current.Read
|
|
}
|