summaryrefslogtreecommitdiff
path: root/pkg/hooks/1.0.0
diff options
context:
space:
mode:
authorAditya R <arajan@redhat.com>2022-07-12 18:34:44 +0530
committerMatthew Heon <matthew.heon@pm.me>2022-07-26 13:48:10 -0400
commit73ecc5a4bdd620124650dbdb621df667beb8438f (patch)
tree9ca86f30eee328e5c7a5a9fe3163cfdb9b8c3053 /pkg/hooks/1.0.0
parentd151edeeaf4ce35586952ceef48a0c7c054c583b (diff)
downloadpodman-73ecc5a4bdd620124650dbdb621df667beb8438f.tar.gz
podman-73ecc5a4bdd620124650dbdb621df667beb8438f.tar.bz2
podman-73ecc5a4bdd620124650dbdb621df667beb8438f.zip
pkg,libpod: remove pkg/hooks and use hooks from c/common
PR https://github.com/containers/common/pull/1071 moved `pkg/hooks` to `c/common` hence remove that from podman and use `pkg/hooks` from `c/common` [NO NEW TESTS NEEDED] [NO TESTS NEEDED] Signed-off-by: Aditya R <arajan@redhat.com>
Diffstat (limited to 'pkg/hooks/1.0.0')
-rw-r--r--pkg/hooks/1.0.0/hook.go89
-rw-r--r--pkg/hooks/1.0.0/hook_test.go214
-rw-r--r--pkg/hooks/1.0.0/when.go96
-rw-r--r--pkg/hooks/1.0.0/when_test.go329
4 files changed, 0 insertions, 728 deletions
diff --git a/pkg/hooks/1.0.0/hook.go b/pkg/hooks/1.0.0/hook.go
deleted file mode 100644
index 71f940a64..000000000
--- a/pkg/hooks/1.0.0/hook.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Package hook is the 1.0.0 hook configuration structure.
-package hook
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "os"
- "regexp"
-
- rspec "github.com/opencontainers/runtime-spec/specs-go"
-)
-
-// Version is the hook configuration version defined in this package.
-const Version = "1.0.0"
-
-// Hook is the hook configuration structure.
-type Hook struct {
- Version string `json:"version"`
- Hook rspec.Hook `json:"hook"`
- When When `json:"when"`
- Stages []string `json:"stages"`
-}
-
-// Read reads hook JSON bytes, verifies them, and returns the hook configuration.
-func Read(content []byte) (hook *Hook, err error) {
- if err = json.Unmarshal(content, &hook); err != nil {
- return nil, err
- }
- return hook, nil
-}
-
-// Validate performs load-time hook validation.
-func (hook *Hook) Validate(extensionStages []string) (err error) {
- if hook == nil {
- return errors.New("nil hook")
- }
-
- if hook.Version != Version {
- return fmt.Errorf("unexpected hook version %q (expecting %v)", hook.Version, Version)
- }
-
- if hook.Hook.Path == "" {
- return errors.New("missing required property: hook.path")
- }
-
- if _, err := os.Stat(hook.Hook.Path); err != nil {
- return err
- }
-
- for key, value := range hook.When.Annotations {
- if _, err = regexp.Compile(key); err != nil {
- return fmt.Errorf("invalid annotation key %q: %w", key, err)
- }
- if _, err = regexp.Compile(value); err != nil {
- return fmt.Errorf("invalid annotation value %q: %w", value, err)
- }
- }
-
- for _, command := range hook.When.Commands {
- if _, err = regexp.Compile(command); err != nil {
- return fmt.Errorf("invalid command %q: %w", command, err)
- }
- }
-
- if hook.Stages == nil {
- return errors.New("missing required property: stages")
- }
-
- validStages := map[string]bool{
- "createContainer": true,
- "createRuntime": true,
- "prestart": true,
- "poststart": true,
- "poststop": true,
- "startContainer": true,
- }
- for _, stage := range extensionStages {
- validStages[stage] = true
- }
-
- for _, stage := range hook.Stages {
- if !validStages[stage] {
- return fmt.Errorf("unknown stage %q", stage)
- }
- }
-
- return nil
-}
diff --git a/pkg/hooks/1.0.0/hook_test.go b/pkg/hooks/1.0.0/hook_test.go
deleted file mode 100644
index bd6d6b654..000000000
--- a/pkg/hooks/1.0.0/hook_test.go
+++ /dev/null
@@ -1,214 +0,0 @@
-package hook
-
-import (
- "os"
- "path/filepath"
- "runtime"
- "testing"
-
- rspec "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/stretchr/testify/assert"
-)
-
-// path is the path to an example hook executable.
-var path string
-
-func TestGoodRead(t *testing.T) {
- hook, err := Read([]byte("{\"version\": \"1.0.0\", \"hook\": {\"path\": \"/a/b/c\"}, \"when\": {\"always\": true}, \"stages\": [\"prestart\"]}"))
- if err != nil {
- t.Fatal(err)
- }
- always := true
- assert.Equal(t, &Hook{
- Version: Version,
- Hook: rspec.Hook{
- Path: "/a/b/c",
- },
- When: When{
- Always: &always,
- },
- Stages: []string{"prestart"},
- }, hook)
-}
-
-func TestInvalidJSON(t *testing.T) {
- _, err := Read([]byte("{"))
- if err == nil {
- t.Fatal("unexpected success")
- }
- assert.Regexp(t, "^unexpected end of JSON input$", err.Error())
-}
-
-func TestGoodValidate(t *testing.T) {
- always := true
- hook := &Hook{
- Version: Version,
- Hook: rspec.Hook{
- Path: path,
- },
- When: When{
- Always: &always,
- },
- Stages: []string{"prestart"},
- }
- err := hook.Validate([]string{})
- if err != nil {
- t.Fatal(err)
- }
-}
-
-func TestNilValidation(t *testing.T) {
- var hook *Hook
- err := hook.Validate([]string{})
- if err == nil {
- t.Fatal("unexpected success")
- }
- assert.Regexp(t, "^nil hook$", err.Error())
-}
-
-func TestWrongVersion(t *testing.T) {
- hook := Hook{Version: "0.1.0"}
- err := hook.Validate([]string{})
- if err == nil {
- t.Fatal("unexpected success")
- }
- assert.Regexp(t, "^unexpected hook version \"0.1.0\" \\(expecting 1.0.0\\)$", err.Error())
-}
-
-func TestNoHookPath(t *testing.T) {
- hook := Hook{
- Version: "1.0.0",
- Hook: rspec.Hook{},
- }
- err := hook.Validate([]string{})
- if err == nil {
- t.Fatal("unexpected success")
- }
- assert.Regexp(t, "^missing required property: hook.path$", err.Error())
-}
-
-func TestUnknownHookPath(t *testing.T) {
- hook := Hook{
- Version: "1.0.0",
- Hook: rspec.Hook{
- Path: filepath.Join("does", "not", "exist"),
- },
- }
- err := hook.Validate([]string{})
- if err == nil {
- t.Fatal("unexpected success")
- }
- assert.Regexp(t, "^stat does/not/exist: no such file or directory$", err.Error())
- if !os.IsNotExist(err) {
- t.Fatal("opaque wrapping for not-exist errors")
- }
-}
-
-func TestNoStages(t *testing.T) {
- hook := Hook{
- Version: "1.0.0",
- Hook: rspec.Hook{
- Path: path,
- },
- }
- err := hook.Validate([]string{})
- if err == nil {
- t.Fatal("unexpected success")
- }
- assert.Regexp(t, "^missing required property: stages$", err.Error())
-}
-
-func TestInvalidStage(t *testing.T) {
- hook := Hook{
- Version: "1.0.0",
- Hook: rspec.Hook{
- Path: path,
- },
- Stages: []string{"does-not-exist"},
- }
- err := hook.Validate([]string{})
- if err == nil {
- t.Fatal("unexpected success")
- }
- assert.Regexp(t, "^unknown stage \"does-not-exist\"$", err.Error())
-}
-
-func TestExtensionStage(t *testing.T) {
- hook := Hook{
- Version: "1.0.0",
- Hook: rspec.Hook{
- Path: path,
- },
- Stages: []string{"prestart", "b"},
- }
- err := hook.Validate([]string{"a", "b", "c"})
- if err != nil {
- t.Fatal(err)
- }
-}
-
-func TestInvalidAnnotationKey(t *testing.T) {
- hook := Hook{
- Version: "1.0.0",
- Hook: rspec.Hook{
- Path: path,
- },
- When: When{
- Annotations: map[string]string{
- "[": "a",
- },
- },
- Stages: []string{"prestart"},
- }
- err := hook.Validate([]string{})
- if err == nil {
- t.Fatal("unexpected success")
- }
- assert.Regexp(t, "^invalid annotation key \"\\[\": error parsing regexp: .*", err.Error())
-}
-
-func TestInvalidAnnotationValue(t *testing.T) {
- hook := Hook{
- Version: "1.0.0",
- Hook: rspec.Hook{
- Path: path,
- },
- When: When{
- Annotations: map[string]string{
- "a": "[",
- },
- },
- Stages: []string{"prestart"},
- }
- err := hook.Validate([]string{})
- if err == nil {
- t.Fatal("unexpected success")
- }
- assert.Regexp(t, "^invalid annotation value \"\\[\": error parsing regexp: .*", err.Error())
-}
-
-func TestInvalidCommand(t *testing.T) {
- hook := Hook{
- Version: "1.0.0",
- Hook: rspec.Hook{
- Path: path,
- },
- When: When{
- Commands: []string{"["},
- },
- Stages: []string{"prestart"},
- }
- err := hook.Validate([]string{})
- if err == nil {
- t.Fatal("unexpected success")
- }
- assert.Regexp(t, "^invalid command \"\\[\": error parsing regexp: .*", err.Error())
-}
-
-func init() {
- if runtime.GOOS != "windows" {
- path = "/bin/sh"
- } else {
- panic("we need a reliable executable path on Windows")
- }
-}
diff --git a/pkg/hooks/1.0.0/when.go b/pkg/hooks/1.0.0/when.go
deleted file mode 100644
index a1351890f..000000000
--- a/pkg/hooks/1.0.0/when.go
+++ /dev/null
@@ -1,96 +0,0 @@
-package hook
-
-import (
- "errors"
- "fmt"
- "regexp"
-
- rspec "github.com/opencontainers/runtime-spec/specs-go"
-)
-
-// When holds hook-injection conditions.
-type When struct {
- Always *bool `json:"always,omitempty"`
- Annotations map[string]string `json:"annotations,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, fmt.Errorf("annotation key: %w", err)
- }
- if match {
- match, err = regexp.MatchString(valuePattern, value)
- if err != nil {
- return false, fmt.Errorf("annotation value: %w", err)
- }
- if match {
- break
- }
- }
- }
- if match {
- if when.Or {
- return true, nil
- }
- matches++
- } else if !when.Or {
- return false, nil
- }
- }
-
- if config.Process != nil && len(when.Commands) > 0 {
- 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, fmt.Errorf("command: %w", err)
- }
- if match {
- return true, nil
- }
- }
- return false, nil
- }
-
- return matches > 0, nil
-}
diff --git a/pkg/hooks/1.0.0/when_test.go b/pkg/hooks/1.0.0/when_test.go
deleted file mode 100644
index 94b0c3830..000000000
--- a/pkg/hooks/1.0.0/when_test.go
+++ /dev/null
@@ -1,329 +0,0 @@
-package hook
-
-import (
- "fmt"
- "testing"
-
- rspec "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/stretchr/testify/assert"
-)
-
-func TestNoMatch(t *testing.T) {
- config := &rspec.Spec{}
- for _, o := range []bool{true, false} {
- or := o
- t.Run(fmt.Sprintf("or %t", or), func(t *testing.T) {
- when := When{Or: or}
- match, err := when.Match(config, map[string]string{}, false)
- if err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, false, match)
- })
- }
-}
-
-func TestAlways(t *testing.T) {
- config := &rspec.Spec{}
- processStruct := &rspec.Process{
- Args: []string{"/bin/sh", "a", "b"},
- }
- for _, a := range []bool{true, false} {
- always := a
- for _, o := range []bool{true, false} {
- or := o
- for _, p := range []*rspec.Process{processStruct, nil} {
- process := p
- t.Run(fmt.Sprintf("always %t, or %t, has process %t", always, or, process != nil), func(t *testing.T) {
- config.Process = process
- when := When{Always: &always, Or: or}
- match, err := when.Match(config, map[string]string{}, false)
- if err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, always, match)
- })
- }
- }
- }
-}
-
-func TestHasBindMountsAnd(t *testing.T) {
- hasBindMounts := true
- when := When{HasBindMounts: &hasBindMounts}
- config := &rspec.Spec{}
- for _, b := range []bool{false, true} {
- containerHasBindMounts := b
- t.Run(fmt.Sprintf("%t", containerHasBindMounts), func(t *testing.T) {
- match, err := when.Match(config, map[string]string{}, containerHasBindMounts)
- if err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, containerHasBindMounts, match)
- })
- }
-}
-
-func TestHasBindMountsOr(t *testing.T) {
- hasBindMounts := true
- when := When{HasBindMounts: &hasBindMounts, Or: true}
- config := &rspec.Spec{}
- for _, b := range []bool{false, true} {
- containerHasBindMounts := b
- t.Run(fmt.Sprintf("%t", containerHasBindMounts), func(t *testing.T) {
- match, err := when.Match(config, map[string]string{}, containerHasBindMounts)
- if err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, containerHasBindMounts, match)
- })
- }
-}
-
-func TestAnnotations(t *testing.T) {
- when := When{
- Annotations: map[string]string{
- "^a$": "^b$",
- "^c$": "^d$",
- },
- }
- config := &rspec.Spec{}
- for _, tt := range []struct {
- name string
- annotations map[string]string
- or bool
- match bool
- }{
- {
- name: "matching both, and",
- annotations: map[string]string{
- "a": "b",
- "c": "d",
- "e": "f",
- },
- or: false,
- match: true,
- },
- {
- name: "matching one, and",
- annotations: map[string]string{
- "a": "b",
- },
- or: false,
- match: false,
- },
- {
- name: "matching one, or",
- annotations: map[string]string{
- "a": "b",
- },
- or: true,
- match: true,
- },
- {
- name: "key-only, or",
- annotations: map[string]string{
- "a": "bc",
- },
- or: true,
- match: false,
- },
- {
- name: "value-only, or",
- annotations: map[string]string{
- "ac": "b",
- },
- or: true,
- match: false,
- },
- } {
- test := tt
- t.Run(test.name, func(t *testing.T) {
- when.Or = test.or
- match, err := when.Match(config, test.annotations, false)
- if err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, test.match, match)
- })
- }
-}
-
-func TestCommands(t *testing.T) {
- when := When{
- Commands: []string{
- "^/bin/sh$",
- },
- }
- config := &rspec.Spec{}
- for _, tt := range []struct {
- name string
- process *rspec.Process
- match bool
- }{
- {
- name: "good",
- process: &rspec.Process{
- Args: []string{"/bin/sh", "a", "b"},
- },
- match: true,
- },
- {
- name: "extra characters",
- process: &rspec.Process{
- Args: []string{"/bin/shell", "a", "b"},
- },
- match: false,
- },
- {
- name: "process unset",
- match: false,
- },
- } {
- test := tt
- t.Run(test.name, func(t *testing.T) {
- config.Process = test.process
- match, err := when.Match(config, map[string]string{}, false)
- if err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, test.match, match)
- })
- }
-}
-
-func TestCommandsEmptyProcessArgs(t *testing.T) {
- when := When{
- Commands: []string{
- "^/bin/sh$",
- },
- }
- config := &rspec.Spec{
- Process: &rspec.Process{},
- }
- _, err := when.Match(config, map[string]string{}, false)
- if err == nil {
- t.Fatal("unexpected success")
- }
- assert.Regexp(t, "^process\\.args must have at least one entry$", err.Error())
-}
-
-func TestHasBindMountsAndCommands(t *testing.T) {
- hasBindMounts := true
- when := When{
- HasBindMounts: &hasBindMounts,
- Commands: []string{
- "^/bin/sh$",
- },
- }
- config := &rspec.Spec{Process: &rspec.Process{}}
- for _, tt := range []struct {
- name string
- command string
- hasBindMounts bool
- or bool
- match bool
- }{
- {
- name: "both, and",
- command: "/bin/sh",
- hasBindMounts: true,
- or: false,
- match: true,
- },
- {
- name: "both, or",
- command: "/bin/sh",
- hasBindMounts: true,
- or: true,
- match: true,
- },
- {
- name: "bind, and",
- command: "/bin/shell",
- hasBindMounts: true,
- or: false,
- match: false,
- },
- {
- name: "bind, or",
- command: "/bin/shell",
- hasBindMounts: true,
- or: true,
- match: true,
- },
- {
- name: "command, and",
- command: "/bin/sh",
- hasBindMounts: false,
- or: false,
- match: false,
- },
- {
- name: "command, or",
- command: "/bin/sh",
- hasBindMounts: false,
- or: true,
- match: true,
- },
- {
- name: "neither, and",
- command: "/bin/shell",
- hasBindMounts: false,
- or: false,
- match: false,
- },
- {
- name: "neither, or",
- command: "/bin/shell",
- hasBindMounts: false,
- or: true,
- match: false,
- },
- } {
- test := tt
- t.Run(test.name, func(t *testing.T) {
- config.Process.Args = []string{test.command}
- when.Or = test.or
- match, err := when.Match(config, map[string]string{}, test.hasBindMounts)
- if err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, test.match, match)
- })
- }
-}
-
-func TestInvalidRegexp(t *testing.T) {
- config := &rspec.Spec{Process: &rspec.Process{Args: []string{"/bin/sh"}}}
- for _, tt := range []struct {
- name string
- when When
- expected string
- }{
- {
- name: "invalid-annotation-key",
- when: When{Annotations: map[string]string{"[": "a"}},
- expected: "^annotation key: error parsing regexp: .*",
- },
- {
- name: "invalid-annotation-value",
- when: When{Annotations: map[string]string{"a": "["}},
- expected: "^annotation value: error parsing regexp: .*",
- },
- {
- name: "invalid-command",
- when: When{Commands: []string{"["}},
- expected: "^command: error parsing regexp: .*",
- },
- } {
- test := tt
- t.Run(test.name, func(t *testing.T) {
- _, err := test.when.Match(config, map[string]string{"a": "b"}, false)
- if err == nil {
- t.Fatal("unexpected success")
- }
- assert.Regexp(t, test.expected, err.Error())
- })
- }
-}