Skip to content

Commit

Permalink
Add CreateRuntime Hook
Browse files Browse the repository at this point in the history
Signed-off-by: Renaud Gaubert <[email protected]>
  • Loading branch information
Renaud Gaubert committed Feb 21, 2020
1 parent c4adba7 commit 9a5f50b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 15 deletions.
39 changes: 39 additions & 0 deletions libcontainer/configs/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,37 @@ type Config struct {
type Hooks struct {
// Prestart commands are executed after the container namespaces are created,
// but before the user supplied command is executed from init.
// Note: This hook is now deprecated
Prestart []Hook

// CreateRuntime commands MUST be called as part of the create operation after
// the runtime environment has been created but before the pivot_root has been executed.
// CreateRuntime is called immediately after the deprecated Prestart hook.
CreateRuntime []Hook

// Poststart commands are executed after the container init process starts.
Poststart []Hook

// Poststop commands are executed after the container init process exits.
Poststop []Hook
}

type HookName int

const (
Prestart HookName = iota
CreateRuntime
Poststart
Poststop
)

var HookToName = map[HookName]string{
Prestart: "Prestart",
CreateRuntime: "CreateRuntime",
Poststart: "Poststart",
Poststop: "Poststop",
}

type Capabilities struct {
// Bounding is the set of capabilities checked by the kernel.
Bounding []string
Expand All @@ -227,6 +249,23 @@ type Capabilities struct {
Ambient []string
}

func (hooks *Hooks) RunHooks(name HookName, spec *specs.State) error {
hooksMap := map[HookName][]Hook{
Prestart: hooks.Prestart,
CreateRuntime: hooks.CreateRuntime,
Poststart: hooks.Poststart,
Poststop: hooks.Poststop,
}

for i, hook := range hooksMap[name] {
if err := hook.Run(spec); err != nil {
return fmt.Errorf("%s hook #%d: %v", HookToName[name], i, err)
}
}

return nil
}

func (hooks *Hooks) UnmarshalJSON(b []byte) error {
var state struct {
Prestart []CommandHook
Expand Down
10 changes: 6 additions & 4 deletions libcontainer/container_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -1681,10 +1681,12 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
return nil
}
s.Pid = int(notify.GetPid())
for i, hook := range c.config.Hooks.Prestart {
if err := hook.Run(s); err != nil {
return newSystemErrorWithCausef(err, "running prestart hook %d", i)
}

if err := c.config.Hooks.RunHooks(configs.Prestart, s); err != nil {
return err
}
if err := c.config.Hooks.RunHooks(configs.CreateRuntime, s); err != nil {
return err
}
}
case notify.GetScript() == "post-restore":
Expand Down
28 changes: 17 additions & 11 deletions libcontainer/process_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,9 @@ func (p *initProcess) start() error {
if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil {
return newSystemErrorWithCause(err, "setting rlimits for ready process")
}
// call prestart hooks
// call prestart and CreateRuntime hooks
if !p.config.Config.Namespaces.Contains(configs.NEWNS) {
// Setup cgroup before prestart hook, so that the prestart hook could apply cgroup permissions.
// Setup cgroup before the hook, so that the prestart and CreateRuntime hook could apply cgroup permissions.
if err := p.manager.Set(p.config.Config); err != nil {
return newSystemErrorWithCause(err, "setting cgroup config for ready process")
}
Expand All @@ -397,10 +397,13 @@ func (p *initProcess) start() error {
// initProcessStartTime hasn't been set yet.
s.Pid = p.cmd.Process.Pid
s.Status = "creating"
for i, hook := range p.config.Config.Hooks.Prestart {
if err := hook.Run(s); err != nil {
return newSystemErrorWithCausef(err, "running prestart hook %d", i)
}
hooks := p.config.Config.Hooks

if err := hooks.RunHooks(configs.Prestart, s); err != nil {
return err
}
if err := hooks.RunHooks(configs.CreateRuntime, s); err != nil {
return err
}
}
}
Expand All @@ -427,10 +430,13 @@ func (p *initProcess) start() error {
// initProcessStartTime hasn't been set yet.
s.Pid = p.cmd.Process.Pid
s.Status = "creating"
for i, hook := range p.config.Config.Hooks.Prestart {
if err := hook.Run(s); err != nil {
return newSystemErrorWithCausef(err, "running prestart hook %d", i)
}
hooks := p.config.Config.Hooks

if err := hooks.RunHooks(configs.Prestart, s); err != nil {
return err
}
if err := hooks.RunHooks(configs.CreateRuntime, s); err != nil {
return err
}
}
// Sync with child.
Expand All @@ -449,7 +455,7 @@ func (p *initProcess) start() error {
return newSystemErrorWithCause(ierr, "container init")
}
if p.config.Config.Namespaces.Contains(configs.NEWNS) && !sentResume {
return newSystemError(fmt.Errorf("could not synchronise after executing prestart hooks with container process"))
return newSystemError(fmt.Errorf("could not synchronise after executing prestart and CreateRuntime hooks with container process"))
}
if err := unix.Shutdown(int(p.messageSockPair.parent.Fd()), unix.SHUT_WR); err != nil {
return newSystemErrorWithCause(err, "shutting down init pipe")
Expand Down

0 comments on commit 9a5f50b

Please sign in to comment.