summaryrefslogtreecommitdiff
path: root/pkg/hooks/1.0.0/when.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/hooks/1.0.0/when.go')
-rw-r--r--pkg/hooks/1.0.0/when.go92
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
+}