Implement hook timeouts
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
4d431183be
commit
6f84d902ca
|
@ -3,7 +3,9 @@ package configs
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
@ -274,10 +276,11 @@ func (f FuncHook) Run(s HookState) error {
|
|||
}
|
||||
|
||||
type Command struct {
|
||||
Path string `json:"path"`
|
||||
Args []string `json:"args"`
|
||||
Env []string `json:"env"`
|
||||
Dir string `json:"dir"`
|
||||
Path string `json:"path"`
|
||||
Args []string `json:"args"`
|
||||
Env []string `json:"env"`
|
||||
Dir string `json:"dir"`
|
||||
Timeout *time.Duration `json:"timeout"`
|
||||
}
|
||||
|
||||
// NewCommandHooks will execute the provided command when the hook is run.
|
||||
|
@ -302,5 +305,19 @@ func (c Command) Run(s HookState) error {
|
|||
Env: c.Env,
|
||||
Stdin: bytes.NewReader(b),
|
||||
}
|
||||
return cmd.Run()
|
||||
errC := make(chan error, 1)
|
||||
go func() {
|
||||
errC <- cmd.Run()
|
||||
}()
|
||||
if c.Timeout != nil {
|
||||
select {
|
||||
case err := <-errC:
|
||||
return err
|
||||
case <-time.After(*c.Timeout):
|
||||
cmd.Process.Kill()
|
||||
cmd.Wait()
|
||||
return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
|
||||
}
|
||||
}
|
||||
return <-errC
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
|
@ -719,27 +720,28 @@ func setupSeccomp(config *specs.Seccomp) (*configs.Seccomp, error) {
|
|||
func createHooks(rspec *specs.Spec, config *configs.Config) {
|
||||
config.Hooks = &configs.Hooks{}
|
||||
for _, h := range rspec.Hooks.Prestart {
|
||||
cmd := configs.Command{
|
||||
Path: h.Path,
|
||||
Args: h.Args,
|
||||
Env: h.Env,
|
||||
}
|
||||
cmd := createCommandHook(h)
|
||||
config.Hooks.Prestart = append(config.Hooks.Prestart, configs.NewCommandHook(cmd))
|
||||
}
|
||||
for _, h := range rspec.Hooks.Poststart {
|
||||
cmd := configs.Command{
|
||||
Path: h.Path,
|
||||
Args: h.Args,
|
||||
Env: h.Env,
|
||||
}
|
||||
cmd := createCommandHook(h)
|
||||
config.Hooks.Poststart = append(config.Hooks.Poststart, configs.NewCommandHook(cmd))
|
||||
}
|
||||
for _, h := range rspec.Hooks.Poststop {
|
||||
cmd := configs.Command{
|
||||
Path: h.Path,
|
||||
Args: h.Args,
|
||||
Env: h.Env,
|
||||
}
|
||||
cmd := createCommandHook(h)
|
||||
config.Hooks.Poststop = append(config.Hooks.Poststop, configs.NewCommandHook(cmd))
|
||||
}
|
||||
}
|
||||
|
||||
func createCommandHook(h specs.Hook) configs.Command {
|
||||
cmd := configs.Command{
|
||||
Path: h.Path,
|
||||
Args: h.Args,
|
||||
Env: h.Env,
|
||||
}
|
||||
if h.Timeout != nil {
|
||||
d := time.Duration(*h.Timeout) * time.Second
|
||||
cmd.Timeout = &d
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue