sync up `HookState` with OCI spec `State`

`HookState` struct should follow definition of `State` in runtime-spec:

* modify json name of `version` to `ociVersion`.
* Remove redundant `Rootfs` field as rootfs can be retrived from
`bundlePath/config.json`.

Signed-off-by: Zhang Wei <zhangwei555@huawei.com>
This commit is contained in:
Zhang Wei 2016-12-19 23:38:56 +08:00
parent 9a1e53eafc
commit a344b2d6a8
7 changed files with 73 additions and 36 deletions

View File

@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/opencontainers/runtime-spec/specs-go"
) )
type Rlimit struct { type Rlimit struct {
@ -243,13 +244,7 @@ func (hooks Hooks) MarshalJSON() ([]byte, error) {
} }
// HookState is the payload provided to a hook on execution. // HookState is the payload provided to a hook on execution.
type HookState struct { type HookState specs.State
Version string `json:"ociVersion"`
ID string `json:"id"`
Pid int `json:"pid"`
Root string `json:"root"`
BundlePath string `json:"bundlePath"`
}
type Hook interface { type Hook interface {
// Run executes the hook with the provided state. // Run executes the hook with the provided state.

View File

@ -120,10 +120,10 @@ func TestMarshalHooksWithUnexpectedType(t *testing.T) {
func TestFuncHookRun(t *testing.T) { func TestFuncHookRun(t *testing.T) {
state := configs.HookState{ state := configs.HookState{
Version: "1", Version: "1",
ID: "1", ID: "1",
Pid: 1, Pid: 1,
Root: "root", BundlePath: "/bundle",
} }
fHook := configs.NewFunctionHook(func(s configs.HookState) error { fHook := configs.NewFunctionHook(func(s configs.HookState) error {
@ -138,10 +138,10 @@ func TestFuncHookRun(t *testing.T) {
func TestCommandHookRun(t *testing.T) { func TestCommandHookRun(t *testing.T) {
state := configs.HookState{ state := configs.HookState{
Version: "1", Version: "1",
ID: "1", ID: "1",
Pid: 1, Pid: 1,
Root: "root", BundlePath: "/bundle",
} }
timeout := time.Second timeout := time.Second
@ -161,10 +161,10 @@ func TestCommandHookRun(t *testing.T) {
func TestCommandHookRunTimeout(t *testing.T) { func TestCommandHookRunTimeout(t *testing.T) {
state := configs.HookState{ state := configs.HookState{
Version: "1", Version: "1",
ID: "1", ID: "1",
Pid: 1, Pid: 1,
Root: "root", BundlePath: "/bundle",
} }
timeout := (10 * time.Millisecond) timeout := (10 * time.Millisecond)

View File

@ -266,7 +266,6 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
Version: c.config.Version, Version: c.config.Version,
ID: c.id, ID: c.id,
Pid: parent.pid(), Pid: parent.pid(),
Root: c.config.Rootfs,
BundlePath: utils.SearchLabels(c.config.Labels, "bundle"), BundlePath: utils.SearchLabels(c.config.Labels, "bundle"),
} }
for i, hook := range c.config.Hooks.Poststart { for i, hook := range c.config.Hooks.Poststart {
@ -1038,10 +1037,10 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
case notify.GetScript() == "setup-namespaces": case notify.GetScript() == "setup-namespaces":
if c.config.Hooks != nil { if c.config.Hooks != nil {
s := configs.HookState{ s := configs.HookState{
Version: c.config.Version, Version: c.config.Version,
ID: c.id, ID: c.id,
Pid: int(notify.GetPid()), Pid: int(notify.GetPid()),
Root: c.config.Rootfs, BundlePath: utils.SearchLabels(c.config.Labels, "bundle"),
} }
for i, hook := range c.config.Hooks.Prestart { for i, hook := range c.config.Hooks.Prestart {
if err := hook.Run(s); err != nil { if err := hook.Run(s); err != nil {

View File

@ -2,6 +2,7 @@ package integration
import ( import (
"bytes" "bytes"
"encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -1048,17 +1049,32 @@ func TestHook(t *testing.T) {
if testing.Short() { if testing.Short() {
return return
} }
root, err := newTestRoot()
bundle, err := newTestBundle()
ok(t, err) ok(t, err)
defer os.RemoveAll(root) defer remove(bundle)
rootfs, err := newRootfs() rootfs, err := newRootfs()
ok(t, err) ok(t, err)
defer remove(rootfs) defer remove(rootfs)
config := newTemplateConfig(rootfs) config := newTemplateConfig(rootfs)
expectedBundlePath := "/path/to/bundle/path" expectedBundlePath := bundle
config.Labels = append(config.Labels, fmt.Sprintf("bundle=%s", expectedBundlePath)) config.Labels = append(config.Labels, fmt.Sprintf("bundle=%s", expectedBundlePath))
getRootfsFromBundle := func(bundle string) (string, error) {
f, err := os.Open(filepath.Join(bundle, "config.json"))
if err != nil {
return "", err
}
var config configs.Config
if err = json.NewDecoder(f).Decode(&config); err != nil {
return "", err
}
return config.Rootfs, nil
}
config.Hooks = &configs.Hooks{ config.Hooks = &configs.Hooks{
Prestart: []configs.Hook{ Prestart: []configs.Hook{
configs.NewFunctionHook(func(s configs.HookState) error { configs.NewFunctionHook(func(s configs.HookState) error {
@ -1066,7 +1082,11 @@ func TestHook(t *testing.T) {
t.Fatalf("Expected prestart hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath) t.Fatalf("Expected prestart hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath)
} }
f, err := os.Create(filepath.Join(s.Root, "test")) root, err := getRootfsFromBundle(s.BundlePath)
if err != nil {
return err
}
f, err := os.Create(filepath.Join(root, "test"))
if err != nil { if err != nil {
return err return err
} }
@ -1079,7 +1099,11 @@ func TestHook(t *testing.T) {
t.Fatalf("Expected poststart hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath) t.Fatalf("Expected poststart hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath)
} }
return ioutil.WriteFile(filepath.Join(s.Root, "test"), []byte("hello world"), 0755) root, err := getRootfsFromBundle(s.BundlePath)
if err != nil {
return err
}
return ioutil.WriteFile(filepath.Join(root, "test"), []byte("hello world"), 0755)
}), }),
}, },
Poststop: []configs.Hook{ Poststop: []configs.Hook{
@ -1088,10 +1112,20 @@ func TestHook(t *testing.T) {
t.Fatalf("Expected poststop hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath) t.Fatalf("Expected poststop hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath)
} }
return os.RemoveAll(filepath.Join(s.Root, "test")) root, err := getRootfsFromBundle(s.BundlePath)
if err != nil {
return err
}
return os.RemoveAll(filepath.Join(root, "test"))
}), }),
}, },
} }
// write config of json format into config.json under bundle
f, err := os.OpenFile(filepath.Join(bundle, "config.json"), os.O_CREATE|os.O_RDWR, 0644)
ok(t, err)
ok(t, json.NewEncoder(f).Encode(config))
container, err := factory.Create("test", config) container, err := factory.Create("test", config)
ok(t, err) ok(t, err)

View File

@ -76,6 +76,17 @@ func newTestRoot() (string, error) {
return dir, nil return dir, nil
} }
func newTestBundle() (string, error) {
dir, err := ioutil.TempDir("", "bundle")
if err != nil {
return "", err
}
if err := os.MkdirAll(dir, 0700); err != nil {
return "", err
}
return dir, nil
}
// newRootfs creates a new tmp directory and copies the busybox root filesystem // newRootfs creates a new tmp directory and copies the busybox root filesystem
func newRootfs() (string, error) { func newRootfs() (string, error) {
dir, err := ioutil.TempDir("", "") dir, err := ioutil.TempDir("", "")

View File

@ -339,10 +339,10 @@ func (p *initProcess) start() error {
if !p.config.Config.Namespaces.Contains(configs.NEWNS) { if !p.config.Config.Namespaces.Contains(configs.NEWNS) {
if p.config.Config.Hooks != nil { if p.config.Config.Hooks != nil {
s := configs.HookState{ s := configs.HookState{
Version: p.container.config.Version, Version: p.container.config.Version,
ID: p.container.id, ID: p.container.id,
Pid: p.pid(), Pid: p.pid(),
Root: p.config.Config.Rootfs, BundlePath: utils.SearchLabels(p.config.Config.Labels, "bundle"),
} }
for i, hook := range p.config.Config.Hooks.Prestart { for i, hook := range p.config.Config.Hooks.Prestart {
if err := hook.Run(s); err != nil { if err := hook.Run(s); err != nil {
@ -362,7 +362,6 @@ func (p *initProcess) start() error {
Version: p.container.config.Version, Version: p.container.config.Version,
ID: p.container.id, ID: p.container.id,
Pid: p.pid(), Pid: p.pid(),
Root: p.config.Config.Rootfs,
BundlePath: utils.SearchLabels(p.config.Config.Labels, "bundle"), BundlePath: utils.SearchLabels(p.config.Config.Labels, "bundle"),
} }
for i, hook := range p.config.Config.Hooks.Prestart { for i, hook := range p.config.Config.Hooks.Prestart {

View File

@ -60,7 +60,6 @@ func runPoststopHooks(c *linuxContainer) error {
s := configs.HookState{ s := configs.HookState{
Version: c.config.Version, Version: c.config.Version,
ID: c.id, ID: c.id,
Root: c.config.Rootfs,
BundlePath: utils.SearchLabels(c.config.Labels, "bundle"), BundlePath: utils.SearchLabels(c.config.Labels, "bundle"),
} }
for _, hook := range c.config.Hooks.Poststop { for _, hook := range c.config.Hooks.Poststop {