Add runtimeArgs to pass to shim

This allows you to pass options like:

```bash
containerd --debug --runtime-args "--debug" --runtime-args
"--systemd-cgroup"
```

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2016-03-24 13:30:27 -07:00
parent 5f0f162c62
commit 6e4d5b385c
7 changed files with 65 additions and 49 deletions

View file

@ -91,10 +91,10 @@ func (p *process) start() error {
return err return err
} }
logPath := filepath.Join(cwd, "log.json") logPath := filepath.Join(cwd, "log.json")
args := []string{ args := append([]string{
"--log", logPath, "--log", logPath,
"--log-format", "json", "--log-format", "json",
} }, p.state.RuntimeArgs...)
if p.state.Exec { if p.state.Exec {
args = append(args, "exec", args = append(args, "exec",
"--process", filepath.Join(cwd, "process.json"), "--process", filepath.Join(cwd, "process.json"),

View file

@ -50,6 +50,11 @@ var daemonFlags = []cli.Flag{
Value: "runc", Value: "runc",
Usage: "name of the OCI compliant runtime to use when executing containers", Usage: "name of the OCI compliant runtime to use when executing containers",
}, },
cli.StringSliceFlag{
Name: "runtime-args",
Value: &cli.StringSlice{},
Usage: "specify additional runtime args",
},
} }
func main() { func main() {
@ -71,6 +76,7 @@ func main() {
context.String("state-dir"), context.String("state-dir"),
10, 10,
context.String("runtime"), context.String("runtime"),
context.StringSlice("runtime-args"),
); err != nil { ); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -80,7 +86,7 @@ func main() {
} }
} }
func daemon(address, stateDir string, concurrency int, runtimeName string) error { func daemon(address, stateDir string, concurrency int, runtimeName string, runtimeArgs []string) error {
// setup a standard reaper so that we don't leave any zombies if we are still alive // setup a standard reaper so that we don't leave any zombies if we are still alive
// this is just good practice because we are spawning new processes // this is just good practice because we are spawning new processes
s := make(chan os.Signal, 2048) s := make(chan os.Signal, 2048)
@ -88,7 +94,7 @@ func daemon(address, stateDir string, concurrency int, runtimeName string) error
if err := osutils.SetSubreaper(1); err != nil { if err := osutils.SetSubreaper(1); err != nil {
logrus.WithField("error", err).Error("containerd: set subpreaper") logrus.WithField("error", err).Error("containerd: set subpreaper")
} }
sv, err := supervisor.New(stateDir, runtimeName) sv, err := supervisor.New(stateDir, runtimeName, runtimeArgs)
if err != nil { if err != nil {
return err return err
} }

View file

@ -83,14 +83,15 @@ func NewStdio(stdin, stdout, stderr string) Stdio {
} }
// New returns a new container // New returns a new container
func New(root, id, bundle, runtimeName string, labels []string) (Container, error) { func New(root, id, bundle, runtimeName string, runtimeArgs, labels []string) (Container, error) {
c := &container{ c := &container{
root: root, root: root,
id: id, id: id,
bundle: bundle, bundle: bundle,
labels: labels, labels: labels,
processes: make(map[string]*process), processes: make(map[string]*process),
runtime: runtimeName, runtime: runtimeName,
runtimeArgs: runtimeArgs,
} }
if err := os.Mkdir(filepath.Join(root, id), 0755); err != nil { if err := os.Mkdir(filepath.Join(root, id), 0755); err != nil {
return nil, err return nil, err
@ -101,9 +102,10 @@ func New(root, id, bundle, runtimeName string, labels []string) (Container, erro
} }
defer f.Close() defer f.Close()
if err := json.NewEncoder(f).Encode(state{ if err := json.NewEncoder(f).Encode(state{
Bundle: bundle, Bundle: bundle,
Labels: labels, Labels: labels,
Runtime: runtimeName, Runtime: runtimeName,
RuntimeArgs: runtimeArgs,
}); err != nil { }); err != nil {
return nil, err return nil, err
} }
@ -121,12 +123,13 @@ func Load(root, id string) (Container, error) {
return nil, err return nil, err
} }
c := &container{ c := &container{
root: root, root: root,
id: id, id: id,
bundle: s.Bundle, bundle: s.Bundle,
labels: s.Labels, labels: s.Labels,
runtime: s.Runtime, runtime: s.Runtime,
processes: make(map[string]*process), runtimeArgs: s.RuntimeArgs,
processes: make(map[string]*process),
} }
dirs, err := ioutil.ReadDir(filepath.Join(root, id)) dirs, err := ioutil.ReadDir(filepath.Join(root, id))
if err != nil { if err != nil {
@ -166,13 +169,14 @@ func readProcessState(dir string) (*ProcessState, error) {
type container struct { type container struct {
// path to store runtime state information // path to store runtime state information
root string root string
id string id string
bundle string bundle string
runtime string runtime string
processes map[string]*process runtimeArgs []string
labels []string processes map[string]*process
oomFds []int labels []string
oomFds []int
} }
func (c *container) ID() string { func (c *container) ID() string {

View file

@ -35,8 +35,9 @@ func populateProcessStateForEncoding(config *processConfig, uid int, gid int) Pr
RootUID: uid, RootUID: uid,
RootGID: gid, RootGID: gid,
}, },
Stdin: config.stdio.Stdin, Stdin: config.stdio.Stdin,
Stdout: config.stdio.Stdout, Stdout: config.stdio.Stdout,
Stderr: config.stdio.Stderr, Stderr: config.stdio.Stderr,
RuntimeArgs: config.c.runtimeArgs,
} }
} }

View file

@ -53,20 +53,22 @@ const (
) )
type state struct { type state struct {
Bundle string `json:"bundle"` Bundle string `json:"bundle"`
Labels []string `json:"labels"` Labels []string `json:"labels"`
Stdin string `json:"stdin"` Stdin string `json:"stdin"`
Stdout string `json:"stdout"` Stdout string `json:"stdout"`
Stderr string `json:"stderr"` Stderr string `json:"stderr"`
Runtime string `json:"runtime"` Runtime string `json:"runtime"`
RuntimeArgs []string `json:"runtimeArgs"`
} }
type ProcessState struct { type ProcessState struct {
specs.ProcessSpec specs.ProcessSpec
Exec bool `json:"exec"` Exec bool `json:"exec"`
Stdin string `json:"containerdStdin"` Stdin string `json:"containerdStdin"`
Stdout string `json:"containerdStdout"` Stdout string `json:"containerdStdout"`
Stderr string `json:"containerdStderr"` Stderr string `json:"containerdStderr"`
RuntimeArgs []string `json:"runtimeArgs"`
PlatformProcessState PlatformProcessState
} }

View file

@ -20,7 +20,7 @@ type StartTask struct {
func (s *Supervisor) start(t *StartTask) error { func (s *Supervisor) start(t *StartTask) error {
start := time.Now() start := time.Now()
container, err := runtime.New(s.stateDir, t.ID, t.BundlePath, s.runtime, t.Labels) container, err := runtime.New(s.stateDir, t.ID, t.BundlePath, s.runtime, s.runtimeArgs, t.Labels)
if err != nil { if err != nil {
return err return err
} }

View file

@ -18,7 +18,7 @@ const (
) )
// New returns an initialized Process supervisor. // New returns an initialized Process supervisor.
func New(stateDir string, runtimeName string) (*Supervisor, error) { func New(stateDir string, runtimeName string, runtimeArgs []string) (*Supervisor, error) {
startTasks := make(chan *startTask, 10) startTasks := make(chan *startTask, 10)
if err := os.MkdirAll(stateDir, 0755); err != nil { if err := os.MkdirAll(stateDir, 0755); err != nil {
return nil, err return nil, err
@ -40,6 +40,7 @@ func New(stateDir string, runtimeName string) (*Supervisor, error) {
tasks: make(chan Task, defaultBufferSize), tasks: make(chan Task, defaultBufferSize),
monitor: monitor, monitor: monitor,
runtime: runtimeName, runtime: runtimeName,
runtimeArgs: runtimeArgs,
} }
if err := setupEventLog(s); err != nil { if err := setupEventLog(s); err != nil {
return nil, err return nil, err
@ -105,9 +106,10 @@ type Supervisor struct {
// stateDir is the directory on the system to store container runtime state information. // stateDir is the directory on the system to store container runtime state information.
stateDir string stateDir string
// name of the OCI compatible runtime used to execute containers // name of the OCI compatible runtime used to execute containers
runtime string runtime string
containers map[string]*containerInfo runtimeArgs []string
startTasks chan *startTask containers map[string]*containerInfo
startTasks chan *startTask
// we need a lock around the subscribers map only because additions and deletions from // we need a lock around the subscribers map only because additions and deletions from
// the map are via the API so we cannot really control the concurrency // the map are via the API so we cannot really control the concurrency
subscriberLock sync.RWMutex subscriberLock sync.RWMutex
@ -196,10 +198,11 @@ func (s *Supervisor) notifySubscribers(e Event) {
// state of the Supervisor // state of the Supervisor
func (s *Supervisor) Start() error { func (s *Supervisor) Start() error {
logrus.WithFields(logrus.Fields{ logrus.WithFields(logrus.Fields{
"stateDir": s.stateDir, "stateDir": s.stateDir,
"runtime": s.runtime, "runtime": s.runtime,
"memory": s.machine.Memory, "runtimeArgs": s.runtimeArgs,
"cpus": s.machine.Cpus, "memory": s.machine.Memory,
"cpus": s.machine.Cpus,
}).Debug("containerd: supervisor running") }).Debug("containerd: supervisor running")
go func() { go func() {
for i := range s.tasks { for i := range s.tasks {