mirror of
https://github.com/containers/podman.git
synced 2025-10-18 11:42:55 +08:00

The process property is optional [1], which this package already handled appropriately, although I've added a new test here to guard against regressions. The process.args entry is required when process is set [2], and it's also required to contain at least one entry [3]. The previous implementation here assumed that would always be satisfied, and panicked on empty process.args. With this commit, we avoid the panic and instead return an error message explaining why the input was invalid. [1]: https://github.com/opencontainers/runtime-spec/blame/v1.0.1/config.md#L145 [2]: https://github.com/opencontainers/runtime-spec/blame/v1.0.1/config.md#L157 [3]: https://github.com/opencontainers/runtime-spec/blame/v1.0.1/config.md#L158 Reported-by: Brent Baude <bbaude@redhat.com> Signed-off-by: W. Trevor King <wking@tremily.us> Closes: #829 Approved by: mheon
96 lines
2.1 KiB
Go
96 lines
2.1 KiB
Go
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 {
|
|
if len(config.Process.Args) == 0 {
|
|
return false, errors.New("process.args must have at least one entry")
|
|
}
|
|
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
|
|
}
|