Containerd Server学习 Part 1


【编者的话】containerd v1.0.0的源码分析,以docker-containerd --config /var/run/docker/containerd/containerd.toml为入口,看大神们如何组织Go语言代码

containerd.io
github: containerd v1.0.0

准备:

go get -v github.com/containerd/containerd
cd $GOPATH/src/github.com/containerd/containerd
git checkout v1.0.0 -b v1.0.0

分析

命令行
* 位置:cmd/containerd/main.go
* 作用:定义containerd 命令行相关参数与配置文件
* 依赖:github.com/urfave/cli
package main

import (
"fmt"
"os"

"github.com/containerd/containerd/version"
"github.com/urfave/cli"
)

const usage = `
                __        _                     __
_________  ____  / /_____ _(_)___  ___  _________/ /
/ ___/ __ \/ __ \/ __/ __ ` + "`" + `/ / __ \/ _ \/ ___/ __  /
/ /__/ /_/ / / / / /_/ /_/ / / / / /  __/ /  / /_/ /
\___/\____/_/ /_/\__/\__,_/_/_/ /_/\___/_/   \__,_/

high performance container runtime
`

func main() {
app := cli.NewApp()
app.Name = "containerd"
app.Version = version.Version
app.Usage = usage
app.Flags = []cli.Flag{
    cli.StringFlag{
        Name:  "config,c",
        Usage: "path to the configuration file",
        Value: defaultConfigPath,
    },
}
app.Commands = []cli.Command{}
app.Action = func(context *cli.Context) error {
    return nil
}
if err := app.Run(os.Args); err != nil {
    fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
    os.Exit(1)
}
}


配置文件解析
* 位置:server/config.go
* 作用:解析配置文件相关参数
* 依赖:
github.com/BurntSushi/toml
github.com/pkg/errors
// LoadConfig loads the containerd server config from the provided path
func LoadConfig(path string, v *Config) error {
if v == nil {
    return errors.Wrapf(errdefs.ErrInvalidArgument, "argument v must not be nil")
}
md, err := toml.DecodeFile(path, v)
if err != nil {
    return err
}
v.md = md
return nil
}


添加参数
* 位置:cmd/containerd/main.go
* 作用:应用参数到相关配置
func applyFlags(context *cli.Context, config *server.Config) error {
// the order for config vs flag values is that flags will always override
// the config values if they are set
if err := setLevel(context, config); err != nil {
    return err
}
for _, v := range []struct {
    name string
    d    *string
}{
    {
        name: "root",
        d:    &config.Root,
    },
    {
        name: "state",
        d:    &config.State,
    },
    {
        name: "address",
        d:    &config.GRPC.Address,
    },
} {
    if s := context.GlobalString(v.name); s != "" {
        *v.d = s
    }
}
return nil
}


日志
* 位置:log/context.go
* 作用:应用日志
* 依赖: github.com/sirupsen/logrus
...
var ctx    = log.WithModule(gocontext.Background(), "containerd")
...
log.G(ctx).WithFields(logrus.Fields{
        "version":  version.Version,
        "revision": version.Revision,
    }).Info("starting containerd")
...

log/context.go

func WithModule(ctx context.Context, module string) context.Context {
parent := GetModulePath(ctx)
if parent != "" {
    if path.Base(parent) == module {
        return ctx
    }
    module = path.Join(parent, module)
}

ctx = WithLogger(ctx, GetLogger(ctx).WithField("module", module))
return context.WithValue(ctx, moduleKey{}, module)
}


整理:

* github.com/llitfkitfk/containerd/tree/part-1
* jianshu

0 个评论

要回复文章请先登录注册