-
Notifications
You must be signed in to change notification settings - Fork 2.9k
hooks: Add package support for extension stages #758
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
bb12fe5 to
48b5291
Compare
|
@wking gofmt errors |
|
Otherwise looks fine |
|
LGTM |
48b5291 to
9876ab6
Compare
We aren't consuming this yet, but these pkg/hooks changes lay the groundwork for future libpod changes to support post-exit hooks [1,2]. [1]: containers#730 [2]: opencontainers/runc#1797 Signed-off-by: W. Trevor King <[email protected]>
|
Pushed a fix for the gofmt errors. |
| }, | ||
| Stages: []string{"prestart", "b"}, | ||
| } | ||
| err := hook.Validate([]string{"a", "b", "c"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Do on one line
if err := ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Do on one line
if err := ...
Is there a way to do this automatically (e.g. with gofmt)? I usually use separate lines, and there are already many instances of the separate-line approach in the hooks package:
$ git describe --tags
v0.5.2-3-g07253fc
$ git grep -B1 'if err != nil' pkg/hooks
pkg/hooks/0.1.0/hook_test.go- hook, err := read([]byte("{\"hook\": \"/a/b/c\", \"stages\": [\"prestart\"], \"cmds\": [\"sh\"]}"))
pkg/hooks/0.1.0/hook_test.go: if err != nil {
--
pkg/hooks/0.1.0/hook_test.go- hook, err := read([]byte("{\"hook\": \"/a/b/c\", \"arguments\": [\"d\", \"e\"], \"stages\": [\"prestart\"], \
"cmds\": [\"sh\"]}"))
pkg/hooks/0.1.0/hook_test.go: if err != nil {
--
...
--
pkg/hooks/1.0.0/hook_test.go- err := hook.Validate()
pkg/hooks/1.0.0/hook_test.go: if err != nil {
--
...
--
pkg/hooks/hooks.go- err = ReadDir(dir, manager.hooks)
pkg/hooks/hooks.go: if err != nil {
--
...
--
pkg/hooks/hooks_test.go- err = ioutil.WriteFile(jsonPath, []byte(fmt.Sprintf("{\"version\": \"1.0.0\", \"hook\": {\"path\": \"%s\", \"timeout\": %d}, \"when\": {\"always\": true}, \"stages\": [\"prestart\"%s]}", path, i+1, extraStages)), 0644)
pkg/hooks/hooks_test.go: if err != nil {
--
...
--
--
pkg/hooks/hooks_test.go- err = manager.Hooks(config, map[string]string{}, false)
pkg/hooks/hooks_test.go: if err != nil {
--
...
--
pkg/hooks/monitor.go-// err := <-sync // block until writers are established
pkg/hooks/monitor.go:// if err != nil {
--
...
--
pkg/hooks/monitor_test.go- err = <-sync
pkg/hooks/monitor_test.go: if err != nil {
--
...It looks like I've only gone with the one-line approach twice:
$ git grep 'if .*:=' pkg/hooks
pkg/hooks/1.0.0/hook.go: if _, err := os.Stat(hook.Hook.Path); err != nil {
pkg/hooks/read.go: if err := json.Unmarshal(content, &ver); err != nil {I can go whichever way you like for any lines you like. Changing this one line manually is easy, but I'm not sure how you feel about the other cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't know of any gofmt call to do it. But when I look at the go code in hooks directory I see all instances where err is created by itself to use the single line.
grep "err.*:=" -r pkg/hooks/
pkg/hooks/hooks.go: raw, err := ioutil.ReadFile(hookPath)
pkg/hooks/hooks.go: if err := json.Unmarshal(raw, &hook); err != nil {
pkg/hooks/hooks.go: if _, err := os.Stat(hook.Hook); err != nil {
pkg/hooks/hooks.go: if _, err := os.Stat(hooksPath); err != nil {
pkg/hooks/hooks.go: files, err := ioutil.ReadDir(hooksPath)
pkg/hooks/hooks.go: hook, err := readHook(filepath.Join(hooksPath, file.Name()))
pkg/hooks/hooks.go: if err := readHooks(hooksPath, hooksMap); err != nil {
pkg/hooks/hooks.go: if err := readHooks(OverrideHooksDir, hooksMap); err != nil {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But when I look at the go code in hooks directory I see all instances where err is created by itself to use the single line.
grep "err.*:=" -r pkg/hooks/ ... pkg/hooks/hooks.go: if err := json.Unmarshal(raw, &hook); err != nil { ...
It looks like you're looking at a version from before 68eb128 (#686), which moved the Unmarshal call from pkg/hooks/hooks.go into other places:
$ git show 68eb128fb0a | grep '^diff\|json\.Unmarshal' | grep -B1 Unmarshal
diff --git a/pkg/hooks/0.1.0/hook.go b/pkg/hooks/0.1.0/hook.go
+ if err = json.Unmarshal(content, &raw); err != nil {
--
diff --git a/pkg/hooks/1.0.0/hook.go b/pkg/hooks/1.0.0/hook.go
+ if err = json.Unmarshal(content, &hook); err != nil {
--
diff --git a/pkg/hooks/hooks.go b/pkg/hooks/hooks.go
- if err := json.Unmarshal(raw, &hook); err != nil {
--
diff --git a/pkg/hooks/read.go b/pkg/hooks/read.go
+ if err := json.Unmarshal(content, &ver); err != nil {My grep above is still what I get with the current master (69a6cb2). And 68eb128 added a bunch of examples with the two-line approach. Most of those additions were *_test.go files, but there were some others which show up in my earlier grep.
Anyhow, I'm fine translating any of these to the one-line approach but identifying them is hard. Do you also want me to adjust master entries like this to:
if _, err := Read(filepath.Join("does", "not", "exist.json")); err == nil {
t.Fatal("unexpected success")
} else {
assert.Regexp(t, "^open does/not/exist.json: no such file or directory$", err.Error())
if !os.IsNotExist(err) {
t.Fatal("opaque wrapping for not-exist errors")
}
}I'm not sure where you see the tighter-scoping benefit of the one-line approach balancing out the readability drop from the more compact approach. For that TestUnknownPath example, the above if/else would be the entire test function, so gains from tighter scoping would be very small.
Or should I just be adjusting entries already being touched by this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is an example of a line touched in this PR that could be one-lined if you like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I guess I was looking at an older pool. I guess we can allow this in and then I will open a PR to fix the non single like ones.
|
One Nit. |
The initial PR comment here is pretty brief, but I went into a bit more detail here. There's also more discussion on |
|
📌 Commit 9876ab6 has been approved by |
|
☀️ Test successful - status-papr |
| * **`hasBindMounts`** (OPTIONAL, boolean) If `hasBindMounts` is true and the caller requested host-to-container bind mounts (beyond those that CRI-O or libpod use by default), this condition matches. | ||
| * **`stages`** (REQUIRED, array of strings) Stages when the hook MUST be injected. | ||
| Entries MUST be chosen from the 1.0.1 OCI Runtime Specification [hook stages][spec-hooks]. | ||
| Entries MUST be chosen from the 1.0.1 OCI Runtime Specification [hook stages][spec-hooks] or from extention stages supported by the package consumer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Being strict here helps catch typos like pre-start (where the user likely intended prestart). But it's going to make sharing a single /usr/share/containers/oci/hooks.d difficult. Do we expect all tools consuming that directory to always agree on the set of extension stages? Do we expect tools to add additional directories for extension stages not yet adopted across the whole consumer community? Do we want to provide a way for tools to allow unrecognized extension stages?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm content to say that all users of a single hooks.d should share the same extension stages - simplest solution for now. We can make further changes later if this proves inadequate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm content to say that all users of a single hooks.d should share the same extension stages - simplest solution for now.
So what directory should I change to when I add postexit support for #730? Does the extensionStages config need to be per-directory to avoid breaking users who don't need postexit but have existing content in /usr/share/containers/oci/hooks.d?
We aren't consuming this yet, but these pkg/hooks changes lay the groundwork for future libpod changes to support post-exit hooks (#730, opencontainers/runc#1797, cri-o/cri-o#1366).