Skip to content

Commit

Permalink
feature: add runtime config
Browse files Browse the repository at this point in the history
1. support add-runtime in daemon
2. fix parse daemon flags twice, which make flags be set for twice
3. add runtime info in pouch info
4. fix slice-type flags merge not take effect, move merge flags
operation in runDaemon, since(*cobra.Command).Execute() will do flags
parse.

Signed-off-by: Ace-Tang <[email protected]>
  • Loading branch information
Ace-Tang committed Jun 8, 2018
1 parent 77d19ed commit 9c2cfd0
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 29 deletions.
6 changes: 3 additions & 3 deletions cli/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ func prettyPrintInfo(cli *Cli, info *types.SystemInfo) error {
fmt.Fprintln(os.Stdout, "Logging Driver:", info.LoggingDriver)
fmt.Fprintln(os.Stdout, "Volume Drivers:", info.VolumeDrivers)
fmt.Fprintln(os.Stdout, "Cgroup Driver:", info.CgroupDriver)
fmt.Fprintln(os.Stdout, "Default Runtime:", info.DefaultRuntime)
if len(info.Runtimes) > 0 {
fmt.Fprintln(os.Stdout, "Runtimes:")
fmt.Fprintf(os.Stdout, "Runtimes:")
for name := range info.Runtimes {
fmt.Fprintf(os.Stdout, "%s", name)
fmt.Fprintf(os.Stdout, " %s", name)
}
fmt.Fprint(os.Stdout, "\n")
fmt.Fprintln(os.Stdout, "Default Runtime:", info.DefaultRuntime)
}
fmt.Fprintln(os.Stdout, "runc:", info.RuncCommit)
fmt.Fprintln(os.Stdout, "containerd:", info.ContainerdCommit)
Expand Down
59 changes: 59 additions & 0 deletions config/opt/runtime.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package opt

import (
"fmt"
"strings"

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

// Runtime defines runtimes information
type Runtime struct {
values *map[string]types.Runtime
}

// NewRuntime initials a Runtime struct
func NewRuntime(rts *map[string]types.Runtime) *Runtime {
if rts == nil {
rts = &map[string]types.Runtime{}
}

if *rts == nil {
*rts = map[string]types.Runtime{}
}

rt := &Runtime{values: rts}
return rt
}

// Set implement Runtime as pflag.Value interface
func (r *Runtime) Set(val string) error {
splits := strings.Split(val, "=")
if len(splits) != 2 || splits[0] == "" || splits[1] == "" {
return fmt.Errorf("invalid runtime %s, correct format must be runtime=path", val)
}

name := splits[0]
path := splits[1]
if _, exist := (*r.values)[name]; exist {
return fmt.Errorf("runtime %s already registers to daemon", name)
}

(*r.values)[name] = types.Runtime{Path: path}
return nil
}

// String implement Runtime as pflag.Value interface
func (r *Runtime) String() string {
var str []string
for k := range *r.values {
str = append(str, fmt.Sprintf("%s", k))
}

return fmt.Sprintf("%v", str)
}

// Type implement Runtime as pflag.Value interface
func (r *Runtime) Type() string {
return "value"
}
25 changes: 25 additions & 0 deletions config/opt/runtime_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package opt

import (
"testing"

"github.com/alibaba/pouch/apis/types"
"github.com/stretchr/testify/assert"
)

func TestNewRuntime(t *testing.T) {
assert := assert.New(t)

for _, r := range []*map[string]types.Runtime{
nil,
{},
{
"a": {},
"b": {Path: "foo"},
},
} {
runtime := NewRuntime(r)
// just test no panic here
assert.NoError(runtime.Set("foo=bar"))
}
}
47 changes: 42 additions & 5 deletions daemon/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ type Config struct {

// oom_score_adj for the daemon
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"`
}

// Validate validates the user input config.
Expand All @@ -128,6 +133,16 @@ func (cfg *Config) Validate() error {

// TODO: add config validation

// validates runtimes config
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)
}
// add default runtime
cfg.Runtimes[cfg.DefaultRuntime] = types.Runtime{Path: cfg.DefaultRuntime}

return nil
}

Expand All @@ -141,17 +156,16 @@ func (cfg *Config) MergeConfigurations(flagSet *pflag.FlagSet) error {
return fmt.Errorf("failed to read contents from config file %s: %s", cfg.ConfigFile, err)
}

var origin map[string]interface{}
if err = json.NewDecoder(bytes.NewReader(contents)).Decode(&origin); err != nil {
var fileFlags map[string]interface{}
if err = json.NewDecoder(bytes.NewReader(contents)).Decode(&fileFlags); err != nil {
return fmt.Errorf("failed to decode json: %s", err)
}

if len(origin) == 0 {
if len(fileFlags) == 0 {
return nil
}

fileFlags := make(map[string]interface{}, 0)
iterateConfig(origin, fileFlags)
transferTLSConfig(fileFlags)

// check if invalid or unknown flag exist in config file
if err = getUnknownFlags(flagSet, fileFlags); err != nil {
Expand Down Expand Up @@ -211,6 +225,29 @@ func (cfg *Config) delValue(flagSet *pflag.FlagSet, fileFlags map[string]interfa
return cfg
}

// transferTLSConfig fetch key value from tls config
// {
// "tlscert": "...",
// "tlscacert": "..."
// }
// add this transfer logic since no flag named TLS, but tlscert, tlscert...
// we should fetch them to do unknown flags and conflict flags check
func transferTLSConfig(config map[string]interface{}) {
v, exist := config["TLS"]
if !exist {
return
}

var tlscofig map[string]interface{}
iterateConfig(map[string]interface{}{
"TLS": v,
}, tlscofig)

for k, v := range tlscofig {
config[k] = v
}
}

// iterateConfig resolves key-value from config file iteratly.
func iterateConfig(origin map[string]interface{}, config map[string]interface{}) {
for k, v := range origin {
Expand Down
4 changes: 4 additions & 0 deletions daemon/mgr/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ func (mgr *ContainerManager) Create(ctx context.Context, name string, config *ty
config.HostConfig.Runtime = mgr.Config.DefaultRuntime
}

if _, exist := mgr.Config.Runtimes[config.HostConfig.Runtime]; !exist {
return nil, fmt.Errorf("unknown runtime %s", config.HostConfig.Runtime)
}

config.Image = primaryRef.String()
// create a snapshot with image.
if err := mgr.Client.CreateSnapshot(ctx, id, config.Image); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion daemon/mgr/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func (mgr *SystemManager) Info() (types.SystemInfo, error) {
PouchRootDir: mgr.config.HomeDir,
RegistryConfig: &mgr.config.RegistryService,
// RuncCommit: ,
// Runtimes: ,
Runtimes: mgr.config.Runtimes,
// SecurityOptions: ,
ServerVersion: version.Version,
ListenAddresses: mgr.config.Listen,
Expand Down
4 changes: 2 additions & 2 deletions hack/make.sh
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,10 @@ function target
# start pouch daemon
echo "start pouch daemon"
if stat /usr/bin/lxcfs ; then
$POUCHD --debug --enable-lxcfs=true \
$POUCHD --debug --enable-lxcfs=true --add-runtime runv=runv \
--lxcfs=/usr/bin/lxcfs > "$TMP/log" 2>&1 &
else
$POUCHD --debug > "$TMP/log" 2>&1 &
$POUCHD --debug --add-runtime runv=runv > "$TMP/log" 2>&1 &
fi

# wait until pouch daemon is ready
Expand Down
26 changes: 8 additions & 18 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"syscall"
"time"

"github.com/alibaba/pouch/config/opt"
"github.com/alibaba/pouch/daemon"
"github.com/alibaba/pouch/daemon/config"
"github.com/alibaba/pouch/lxcfs"
Expand Down Expand Up @@ -42,17 +43,11 @@ func main() {
Args: cobra.NoArgs,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
return runDaemon()
return runDaemon(cmd)
},
}

setupFlags(cmdServe)
parseFlags(cmdServe, os.Args[1:])
if err := loadDaemonFile(cfg, cmdServe.Flags()); err != nil {
logrus.Errorf("failed to load daemon file: %s", err)
os.Exit(1)
}

if err := cmdServe.Execute(); err != nil {
logrus.Error(err)
os.Exit(1)
Expand Down Expand Up @@ -116,21 +111,16 @@ func setupFlags(cmd *cobra.Command) {
flagSet.BoolVar(&cfg.EnableProfiler, "enable-profiler", false, "Set if pouchd setup profiler")
flagSet.StringVar(&cfg.Pidfile, "pidfile", "/var/run/pouch.pid", "Save daemon pid")
flagSet.IntVar(&cfg.OOMScoreAdjust, "oom-score-adj", -500, "Set the oom_score_adj for the daemon")
}
flagSet.Var(opt.NewRuntime(&cfg.Runtimes), "add-runtime", "register a OCI runtime to daemon")

// parse flags
func parseFlags(cmd *cobra.Command, flags []string) {
err := cmd.Flags().Parse(flags)
if err == nil || err == pflag.ErrHelp {
return
}

cmd.SetOutput(os.Stderr)
cmd.Usage()
}

// runDaemon prepares configs, setups essential details and runs pouchd daemon.
func runDaemon() error {
func runDaemon(cmd *cobra.Command) error {
if err := loadDaemonFile(cfg, cmd.Flags()); err != nil {
return fmt.Errorf("failed to load daemon file: %s", err)
}

//user specifies --version or -v, print version and return.
if printVersion {
fmt.Printf("pouchd version: %s, build: %s, build at: %s\n", version.Version, version.GitCommit, version.BuildTime)
Expand Down
15 changes: 15 additions & 0 deletions test/z_cli_daemon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,3 +451,18 @@ func (suite *PouchDaemonSuite) TestDaemonStartOverOneTimes(c *check.C) {
c.Assert(err, check.NotNil)

}

// TestDaemonWithMultiRuntimes tests start daemon with multiple runtimes
func (suite *PouchDaemonSuite) TestDaemonWithMultiRuntimes(c *check.C) {
dcfg1, err := StartDefaultDaemonDebug(
"--add-runtime", "foo=bar")
c.Assert(err, check.IsNil)
dcfg1.KillDaemon()

// should fail if runtime name equal
dcfg2, err := StartDefaultDaemonDebug(
"--add-runtime", "runa=runa",
"--add-runtime", "runa=runa")
c.Assert(err, check.NotNil)
dcfg2.KillDaemon()
}

0 comments on commit 9c2cfd0

Please sign in to comment.