diff options
Diffstat (limited to 'pkg/hooks/1.0.0/when.go')
-rw-r--r-- | pkg/hooks/1.0.0/when.go | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/pkg/hooks/1.0.0/when.go b/pkg/hooks/1.0.0/when.go new file mode 100644 index 000000000..3d2a5fd72 --- /dev/null +++ b/pkg/hooks/1.0.0/when.go @@ -0,0 +1,92 @@ +package hook + +import ( + "regexp" + + rspec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/pkg/errors" +) + +// When holds hook-injection conditions. +type When struct { + Always *bool `json:"always,omitempty"` + Annotations map[string]string `json:"annotation,omitempty"` + Commands []string `json:"commands,omitempty"` + HasBindMounts *bool `json:"hasBindMounts,omitempty"` + + // Or enables any-of matching. + // + // Deprecated: this property is for is backwards-compatibility with + // 0.1.0 hooks. It will be removed when we drop support for them. + Or bool `json:"-"` +} + +// Match returns true if the given conditions match the configuration. +func (when *When) Match(config *rspec.Spec, annotations map[string]string, hasBindMounts bool) (match bool, err error) { + matches := 0 + + if when.Always != nil { + if *when.Always { + if when.Or { + return true, nil + } + matches++ + } else if !when.Or { + return false, nil + } + } + + if when.HasBindMounts != nil { + if *when.HasBindMounts && hasBindMounts { + if when.Or { + return true, nil + } + matches++ + } else if !when.Or { + return false, nil + } + } + + for keyPattern, valuePattern := range when.Annotations { + match := false + for key, value := range annotations { + match, err = regexp.MatchString(keyPattern, key) + if err != nil { + return false, errors.Wrap(err, "annotation key") + } + if match { + match, err = regexp.MatchString(valuePattern, value) + if err != nil { + return false, errors.Wrap(err, "annotation value") + } + if match { + break + } + } + } + if match { + if when.Or { + return true, nil + } + matches++ + } else if !when.Or { + return false, nil + } + } + + if config.Process != nil { + command := config.Process.Args[0] + for _, cmdPattern := range when.Commands { + match, err := regexp.MatchString(cmdPattern, command) + if err != nil { + return false, errors.Wrap(err, "command") + } + if match { + return true, nil + } + } + return false, nil + } + + return matches > 0, nil +} |