diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go index 63f71125..f2628760 100644 --- a/libcontainer/configs/config.go +++ b/libcontainer/configs/config.go @@ -176,33 +176,34 @@ type Hooks struct { // but before the user supplied command is executed from init. Prestart []Hook - // PostStop commands are executed after the container init process exits. + // Poststop commands are executed after the container init process exits. Poststop []Hook } // HookState is the payload provided to a hook on execution. type HookState struct { - ID string `json:"id"` - Pid int `json:"pid"` + ID string `json:"id"` + Pid int `json:"pid"` + Root string `json:"root"` } type Hook interface { // Run executes the hook with the provided state. - Run(*HookState) error + Run(HookState) error } // NewFunctionHooks will call the provided function when the hook is run. -func NewFunctionHook(f func(*HookState) error) *FuncHook { - return &FuncHook{ +func NewFunctionHook(f func(HookState) error) FuncHook { + return FuncHook{ run: f, } } type FuncHook struct { - run func(*HookState) error + run func(HookState) error } -func (f *FuncHook) Run(s *HookState) error { +func (f FuncHook) Run(s HookState) error { return f.run(s) } @@ -214,8 +215,8 @@ type Command struct { } // NewCommandHooks will execute the provided command when the hook is run. -func NewCommandHook(cmd Command) *CommandHook { - return &CommandHook{ +func NewCommandHook(cmd Command) CommandHook { + return CommandHook{ Command: cmd, } } @@ -224,7 +225,7 @@ type CommandHook struct { Command } -func (c *Command) Run(s *HookState) error { +func (c Command) Run(s HookState) error { b, err := json.Marshal(s) if err != nil { return err diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 7472473b..574773bf 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -250,10 +250,11 @@ func (c *linuxContainer) Destroy() error { c.initProcess = nil if c.config.Hooks != nil { s := configs.HookState{ - ID: c.id, + ID: c.id, + Root: c.config.Rootfs, } for _, hook := range c.config.Hooks.Poststop { - if err := hook.Run(&s); err != nil { + if err := hook.Run(s); err != nil { return err } } diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go index 6131c156..bbd1037f 100644 --- a/libcontainer/integration/exec_test.go +++ b/libcontainer/integration/exec_test.go @@ -933,7 +933,7 @@ func TestOomScoreAdj(t *testing.T) { } } -func TestPrestartHook(t *testing.T) { +func TestHook(t *testing.T) { if testing.Short() { return } @@ -948,18 +948,22 @@ func TestPrestartHook(t *testing.T) { config := newTemplateConfig(rootfs) config.Hooks = &configs.Hooks{ Prestart: []configs.Hook{ - configs.NewFunctionHook(func(s *configs.HookState) error { - f, err := os.Create(filepath.Join(rootfs, "test")) + configs.NewFunctionHook(func(s configs.HookState) error { + f, err := os.Create(filepath.Join(s.Root, "test")) if err != nil { return err } return f.Close() }), }, + Poststop: []configs.Hook{ + configs.NewFunctionHook(func(s configs.HookState) error { + return os.RemoveAll(filepath.Join(s.Root, "test")) + }), + }, } container, err := factory.Create("test", config) ok(t, err) - defer container.Destroy() var stdout bytes.Buffer pconfig := libcontainer.Process{ @@ -978,6 +982,15 @@ func TestPrestartHook(t *testing.T) { // Check that the ls output has the expected file touched by the prestart hook if !strings.Contains(outputLs, "/test") { - t.Fatal("ls output doesn't have the expected file: ", outputLs) + container.Destroy() + t.Fatalf("ls output doesn't have the expected file: %s", outputLs) + } + + if err := container.Destroy(); err != nil { + t.Fatalf("container destory %s", err) + } + fi, err := os.Stat(filepath.Join(rootfs, "test")) + if err == nil || !os.IsNotExist(err) { + t.Fatalf("expected file to not exist, got %s", fi.Name()) } } diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go index 9b5b562f..f191c16e 100644 --- a/libcontainer/process_linux.go +++ b/libcontainer/process_linux.go @@ -203,11 +203,12 @@ func (p *initProcess) start() (err error) { }() if p.config.Config.Hooks != nil { s := configs.HookState{ - ID: p.container.id, - Pid: p.pid(), + ID: p.container.id, + Pid: p.pid(), + Root: p.config.Config.Rootfs, } for _, hook := range p.config.Config.Hooks.Prestart { - if err := hook.Run(&s); err != nil { + if err := hook.Run(s); err != nil { return newSystemError(err) } }