Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: support runtime args #2085

Merged
merged 1 commit into from
Aug 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions daemon/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,6 @@ type Config struct {
OOMScoreAdjust int `json:"oom-score-adjust,omitempty"`

// runtimes config
// TODO(Ace-Tang): runtime args is not support, since containerd is not support,
// add a resolution later if it needed.
Runtimes map[string]types.Runtime `json:"add-runtime,omitempty"`

// Namespace is passed to containerd, Namespace is not a daemon flag,
Expand Down Expand Up @@ -141,11 +139,10 @@ func (cfg *Config) Validate() error {
if len(cfg.Runtimes) == 0 {
cfg.Runtimes = make(map[string]types.Runtime)
}
if _, exist := cfg.Runtimes[cfg.DefaultRuntime]; exist {
return fmt.Errorf("default runtime %s cannot be re-register", cfg.DefaultRuntime)
if _, exist := cfg.Runtimes[cfg.DefaultRuntime]; !exist {
// add default runtime
cfg.Runtimes[cfg.DefaultRuntime] = types.Runtime{Path: cfg.DefaultRuntime}
}
// add default runtime
cfg.Runtimes[cfg.DefaultRuntime] = types.Runtime{Path: cfg.DefaultRuntime}

return nil
}
Expand Down
5 changes: 5 additions & 0 deletions daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ func (d *Daemon) Run() error {
return err
}

// initializes runtimes real path.
if err := initialRuntime(d.config.HomeDir, d.config.Runtimes); err != nil {
return err
}

d.eventsService = events.NewEvents()

imageMgr, err := internal.GenImageMgr(d.config, d)
Expand Down
54 changes: 54 additions & 0 deletions daemon/daemon_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package daemon

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/alibaba/pouch/apis/types"
)

var (
runtimeDir = "runtimes"
runtimeDirPerm os.FileMode = 0700
runtimeScriptPerm os.FileMode = 0700
)

// initialRuntime initializes real runtime path. If runtime.args passed,
// we will make a executable script as a path, or runtime.path is record as path.
// NOTE: containerd not support runtime args directly, so we make executable
// script include runtime path and args as a runtime execute binary.
func initialRuntime(baseDir string, runtimes map[string]types.Runtime) error {
dir := filepath.Join(baseDir, runtimeDir)

// remove runtime scripts last generated, since runtime config may changed
// every time daemon start.
if err := os.RemoveAll(dir); err != nil {
return fmt.Errorf("failed to clean runtime scripts directory %s: %s", dir, err)
}

if err := os.MkdirAll(dir, runtimeDirPerm); err != nil {
return fmt.Errorf("failed to new runtime scripts directory %s: %s", dir, err)
}

// create script for runtime who has args
for name, r := range runtimes {
if len(r.RuntimeArgs) == 0 {
continue
}

script := filepath.Join(dir, name)
if r.Path == "" {
r.Path = name
}
data := fmt.Sprintf("#!/bin/sh\n%s %s $@\n", r.Path, strings.Join(r.RuntimeArgs, " "))

if err := ioutil.WriteFile(script, []byte(data), runtimeScriptPerm); err != nil {
return fmt.Errorf("failed to create runtime script %s: %s", script, err)
}
}

return nil
}
67 changes: 67 additions & 0 deletions daemon/daemon_utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package daemon

import (
"io/ioutil"
"os"
"path/filepath"
"testing"

"github.com/alibaba/pouch/apis/types"

"github.com/stretchr/testify/assert"
)

func TestInitialRuntime(t *testing.T) {
assert := assert.New(t)
tmpDir, err := ioutil.TempDir("", "runtime-path")
assert.NoError(err)
defer os.RemoveAll(tmpDir)

runtimeDir = "runtimes"

for _, tc := range []struct {
runtimes map[string]types.Runtime
rname string
rpath string
filedata string
}{
{
runtimes: map[string]types.Runtime{
"c": {
Path: "/foo/bar/c",
RuntimeArgs: []string{
"--foo=foo",
"--bar=bar",
},
},
},
rname: "c",
rpath: filepath.Join(tmpDir, runtimeDir, "c"),
filedata: "#!/bin/sh\n/foo/bar/c --foo=foo --bar=bar $@\n",
},
{
runtimes: map[string]types.Runtime{
"d": {
RuntimeArgs: []string{
"--foo=foo",
"--bar=bar",
},
},
},
rname: "d",
rpath: filepath.Join(tmpDir, runtimeDir, "d"),
filedata: "#!/bin/sh\nd --foo=foo --bar=bar $@\n",
},
} {
err = initialRuntime(tmpDir, tc.runtimes)
assert.NoError(err)
if tc.filedata != "" {
if _, err := os.Stat(tc.rpath); err != nil {
t.Fatalf("%s should exist", tc.rpath)
}
data, err := ioutil.ReadFile(tc.rpath)
assert.NoError(err)
assert.Equal(tc.filedata, string(data))
}
}
}
7 changes: 6 additions & 1 deletion daemon/mgr/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -638,12 +638,17 @@ func (mgr *ContainerManager) createContainerdContainer(ctx context.Context, c *C
return errors.Wrap(err, "failed to open io")
}

runtime, err := mgr.getRuntime(c.HostConfig.Runtime)
if err != nil {
return err
}

c.Lock()
ctrdContainer := &ctrd.Container{
ID: c.ID,
Image: c.Config.Image,
Labels: c.Config.Labels,
Runtime: c.HostConfig.Runtime,
Runtime: runtime,
Spec: sw.s,
IO: io,
RootFSProvided: c.RootFSProvided,
Expand Down
3 changes: 3 additions & 0 deletions daemon/mgr/container_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ var (
const (
// DefaultStopTimeout is the timeout (in seconds) for the syscall signal used to stop a container.
DefaultStopTimeout = 10

// RuntimeDir is specified name keeps runtime path script.
RuntimeDir = "runtimes"
)

// ContainerFilter defines a function to filter
Expand Down
24 changes: 24 additions & 0 deletions daemon/mgr/container_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package mgr

import (
"fmt"
"path/filepath"
"strconv"
"strings"

Expand Down Expand Up @@ -104,6 +105,29 @@ func (mgr *ContainerManager) generateName(id string) string {
return name
}

// getRuntime returns runtime real path.
// TODO(huamin): do we need validate runtime is executable ?
func (mgr *ContainerManager) getRuntime(runtime string) (string, error) {
r, exist := mgr.Config.Runtimes[runtime]
if !exist {
return "", fmt.Errorf("failed to find runtime %s in daemon config", runtime)
}

// it is ok to use runtime name as a path.
rPath := runtime
if len(r.RuntimeArgs) > 0 {
rPath = filepath.Join(mgr.Config.HomeDir, RuntimeDir, runtime)
}

// generally speaking, path is not be empty, but we not forbid empty path
// in config set, since name can be a path too.
if r.Path != "" {
rPath = r.Path
}

return rPath, nil
}

// BuildContainerEndpoint is used to build container's endpoint config.
func BuildContainerEndpoint(c *Container) *networktypes.Endpoint {
return &networktypes.Endpoint{
Expand Down