Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
hook: Move OCI hooks handling to the CLI
Browse files Browse the repository at this point in the history
The CLI being the implementation of the OCI specification, and the
hooks being OCI specific, it makes sense to move the handling of any
OCI hooks to the CLI level. This changes allows the Kata API to
become OCI agnostic.

Signed-off-by: Sebastien Boeuf <[email protected]>
  • Loading branch information
Sebastien Boeuf committed Aug 17, 2018
1 parent 3333f8b commit a4b81e8
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 504 deletions.
6 changes: 6 additions & 0 deletions cli/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,12 @@ func createSandbox(ctx context.Context, ociSpec oci.CompatOCISpec, runtimeConfig
return vc.Process{}, err
}

if err := enterNetNS(sandbox.GetNetNs(), func() error {
return preStartHooks(ociSpec, containerID, bundlePath)
}); err != nil {
return vc.Process{}, err
}

if err := sandbox.SetupNetwork(); err != nil {
return vc.Process{}, err
}
Expand Down
5 changes: 5 additions & 0 deletions cli/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"os"

vc "github.com/kata-containers/runtime/virtcontainers"
vcAnnot "github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
opentracing "github.com/opentracing/opentracing-go"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -107,6 +108,10 @@ func delete(ctx context.Context, containerID string, force bool) error {

switch containerType {
case vc.PodSandbox:
if err := postStopHooks(ociSpec, sandboxID, status.Annotations[vcAnnot.BundlePathKey]); err != nil {
return err
}

if err := deleteSandbox(ctx, sandboxID); err != nil {
return err
}
Expand Down
139 changes: 139 additions & 0 deletions cli/hook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// Copyright (c) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//

package main

import (
"bytes"
"encoding/json"
"fmt"
"os"
"os/exec"
"syscall"
"time"

"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
)

// Logger returns a logrus logger appropriate for logging hook messages
func hookLogger() *logrus.Entry {
return kataLog.WithField("subsystem", "hook")
}

func runHook(hook specs.Hook, cid, bundlePath string) error {
state := specs.State{
Pid: os.Getpid(),
Bundle: bundlePath,
ID: cid,
}

stateJSON, err := json.Marshal(state)
if err != nil {
return err
}

var stdout, stderr bytes.Buffer
cmd := &exec.Cmd{
Path: hook.Path,
Args: hook.Args,
Env: hook.Env,
Stdin: bytes.NewReader(stateJSON),
Stdout: &stdout,
Stderr: &stderr,
}

if err := cmd.Start(); err != nil {
return err
}

if hook.Timeout == nil {
if err := cmd.Wait(); err != nil {
return fmt.Errorf("%s: stdout: %s, stderr: %s", err, stdout.String(), stderr.String())
}
} else {
done := make(chan error, 1)
go func() {
done <- cmd.Wait()
close(done)
}()

select {
case err := <-done:
if err != nil {
return fmt.Errorf("%s: stdout: %s, stderr: %s", err, stdout.String(), stderr.String())
}
case <-time.After(time.Duration(*hook.Timeout) * time.Second):
if err := syscall.Kill(cmd.Process.Pid, syscall.SIGKILL); err != nil {
return err
}

return fmt.Errorf("Hook timeout")
}
}

return nil
}

func preStartHooks(spec oci.CompatOCISpec, cid, bundlePath string) error {
// If no hook available, nothing needs to be done.
if spec.Hooks == nil {
return nil
}

for _, hook := range spec.Hooks.Prestart {
if err := runHook(hook, cid, bundlePath); err != nil {
hookLogger().WithFields(logrus.Fields{
"hook-type": "pre-start",
"error": err,
}).Error("hook error")

return err
}
}

return nil
}

func postStartHooks(spec oci.CompatOCISpec, cid, bundlePath string) error {
// If no hook available, nothing needs to be done.
if spec.Hooks == nil {
return nil
}

for _, hook := range spec.Hooks.Poststart {
if err := runHook(hook, cid, bundlePath); err != nil {
hookLogger().WithFields(logrus.Fields{
"hook-type": "post-start",
"error": err,
}).Error("hook error")

return err
}
}

return nil
}

func postStopHooks(spec oci.CompatOCISpec, cid, bundlePath string) error {
// If no hook available, nothing needs to be done.
if spec.Hooks == nil {
return nil
}

for _, hook := range spec.Hooks.Poststop {
if err := runHook(hook, cid, bundlePath); err != nil {
hookLogger().WithFields(logrus.Fields{
"hook-type": "post-stop",
"error": err,
}).Error("hook error")

return err
}
}

return nil
}
28 changes: 28 additions & 0 deletions cli/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import (
"net"
"os"
"path/filepath"
goruntime "runtime"
"strings"
"syscall"

"github.com/containernetworking/plugins/pkg/ns"
vc "github.com/kata-containers/runtime/virtcontainers"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
"github.com/opencontainers/runc/libcontainer/utils"
Expand Down Expand Up @@ -415,3 +417,29 @@ func delContainerIDMapping(ctx context.Context, containerID string) error {

return os.RemoveAll(path)
}

// enterNetNS is free from any call to a go routine, and it calls
// into runtime.LockOSThread(), meaning it won't be executed in a
// different thread than the one expected by the caller.
func enterNetNS(netNSPath string, cb func() error) error {
goruntime.LockOSThread()
defer goruntime.UnlockOSThread()

currentNS, err := ns.GetCurrentNS()
if err != nil {
return err
}
defer currentNS.Close()

targetNS, err := ns.GetNS(netNSPath)
if err != nil {
return err
}

if err := targetNS.Set(); err != nil {
return err
}
defer currentNS.Set()

return cb()
}
19 changes: 18 additions & 1 deletion cli/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"fmt"

vc "github.com/kata-containers/runtime/virtcontainers"
vcAnnot "github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
opentracing "github.com/opentracing/opentracing-go"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -78,7 +79,23 @@ func start(ctx context.Context, containerID string) (vc.VCSandbox, error) {
}

if containerType.IsSandbox() {
return vci.StartSandbox(sandboxID)
s, err := vci.StartSandbox(sandboxID)
if err != nil {
return nil, err
}

ociSpec, err := oci.GetOCIConfig(status)
if err != nil {
return nil, err
}

if err := enterNetNS(s.GetNetNs(), func() error {
return postStartHooks(ociSpec, sandboxID, status.Annotations[vcAnnot.BundlePathKey])
}); err != nil {
return nil, err
}

return s, nil
}

c, err := vci.StartContainer(sandboxID, containerID)
Expand Down
10 changes: 0 additions & 10 deletions virtcontainers/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,6 @@ func startSandbox(s *Sandbox) (*Sandbox, error) {
return nil, err
}

// Execute poststart hooks.
if err := s.config.Hooks.postStartHooks(s); err != nil {
return nil, err
}

return s, nil
}

Expand Down Expand Up @@ -235,11 +230,6 @@ func StopSandbox(sandboxID string) (VCSandbox, error) {
return nil, err
}

// Execute poststop hooks.
if err := s.config.Hooks.postStopHooks(s); err != nil {
return nil, err
}

return s, nil
}

Expand Down
16 changes: 2 additions & 14 deletions virtcontainers/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,24 +141,12 @@ func newTestSandboxConfigHyperstartAgentDefaultNetwork() SandboxConfig {
SockTtyName: testHyperstartTtySocket,
}

hooks := Hooks{
PreStartHooks: []Hook{
{
Path: getMockHookBinPath(),
Args: []string{testKeyHook, testContainerIDHook, testControllerIDHook},
},
},
PostStartHooks: []Hook{},
PostStopHooks: []Hook{},
}

netConfig := NetworkConfig{
NumInterfaces: len(hooks.PreStartHooks),
NumInterfaces: 1,
}

sandboxConfig := SandboxConfig{
ID: testSandboxID,
Hooks: hooks,
ID: testSandboxID,

HypervisorType: MockHypervisor,
HypervisorConfig: hypervisorConfig,
Expand Down
Loading

0 comments on commit a4b81e8

Please sign in to comment.