Turn hook pointers into values.

Signed-off-by: David Calavera <david.calavera@gmail.com>
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
David Calavera 2015-09-11 13:28:25 -04:00 committed by Michael Crosby
parent dd969cbacd
commit 0f28592b35
4 changed files with 37 additions and 21 deletions

View File

@ -176,33 +176,34 @@ type Hooks struct {
// but before the user supplied command is executed from init. // but before the user supplied command is executed from init.
Prestart []Hook Prestart []Hook
// PostStop commands are executed after the container init process exits. // Poststop commands are executed after the container init process exits.
Poststop []Hook Poststop []Hook
} }
// 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 struct {
ID string `json:"id"` ID string `json:"id"`
Pid int `json:"pid"` Pid int `json:"pid"`
Root string `json:"root"`
} }
type Hook interface { type Hook interface {
// Run executes the hook with the provided state. // 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. // NewFunctionHooks will call the provided function when the hook is run.
func NewFunctionHook(f func(*HookState) error) *FuncHook { func NewFunctionHook(f func(HookState) error) FuncHook {
return &FuncHook{ return FuncHook{
run: f, run: f,
} }
} }
type FuncHook struct { 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) return f.run(s)
} }
@ -214,8 +215,8 @@ type Command struct {
} }
// NewCommandHooks will execute the provided command when the hook is run. // NewCommandHooks will execute the provided command when the hook is run.
func NewCommandHook(cmd Command) *CommandHook { func NewCommandHook(cmd Command) CommandHook {
return &CommandHook{ return CommandHook{
Command: cmd, Command: cmd,
} }
} }
@ -224,7 +225,7 @@ type CommandHook struct {
Command Command
} }
func (c *Command) Run(s *HookState) error { func (c Command) Run(s HookState) error {
b, err := json.Marshal(s) b, err := json.Marshal(s)
if err != nil { if err != nil {
return err return err

View File

@ -250,10 +250,11 @@ func (c *linuxContainer) Destroy() error {
c.initProcess = nil c.initProcess = nil
if c.config.Hooks != nil { if c.config.Hooks != nil {
s := configs.HookState{ s := configs.HookState{
ID: c.id, ID: c.id,
Root: c.config.Rootfs,
} }
for _, hook := range c.config.Hooks.Poststop { for _, hook := range c.config.Hooks.Poststop {
if err := hook.Run(&s); err != nil { if err := hook.Run(s); err != nil {
return err return err
} }
} }

View File

@ -933,7 +933,7 @@ func TestOomScoreAdj(t *testing.T) {
} }
} }
func TestPrestartHook(t *testing.T) { func TestHook(t *testing.T) {
if testing.Short() { if testing.Short() {
return return
} }
@ -948,18 +948,22 @@ func TestPrestartHook(t *testing.T) {
config := newTemplateConfig(rootfs) config := newTemplateConfig(rootfs)
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 {
f, err := os.Create(filepath.Join(rootfs, "test")) f, err := os.Create(filepath.Join(s.Root, "test"))
if err != nil { if err != nil {
return err return err
} }
return f.Close() 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) container, err := factory.Create("test", config)
ok(t, err) ok(t, err)
defer container.Destroy()
var stdout bytes.Buffer var stdout bytes.Buffer
pconfig := libcontainer.Process{ 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 // Check that the ls output has the expected file touched by the prestart hook
if !strings.Contains(outputLs, "/test") { 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())
} }
} }

View File

@ -203,11 +203,12 @@ func (p *initProcess) start() (err error) {
}() }()
if p.config.Config.Hooks != nil { if p.config.Config.Hooks != nil {
s := configs.HookState{ s := configs.HookState{
ID: p.container.id, ID: p.container.id,
Pid: p.pid(), Pid: p.pid(),
Root: p.config.Config.Rootfs,
} }
for _, hook := range p.config.Config.Hooks.Prestart { 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) return newSystemError(err)
} }
} }