github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/cmd/dockerd/docker.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"runtime"
     7  
     8  	"github.com/docker/docker/cli"
     9  	"github.com/docker/docker/daemon/config"
    10  	"github.com/docker/docker/dockerversion"
    11  	"github.com/docker/docker/pkg/reexec"
    12  	"github.com/docker/docker/pkg/term"
    13  	"github.com/moby/buildkit/util/apicaps"
    14  	"github.com/sirupsen/logrus"
    15  	"github.com/spf13/cobra"
    16  )
    17  
    18  func newDaemonCommand() *cobra.Command {
    19  	// 1、初始化配置数据结构daemonOptions
    20  	opts := newDaemonOptions(config.New())
    21  
    22  	cmd := &cobra.Command{
    23  		Use:           "dockerd [OPTIONS]",
    24  		Short:         "A self-sufficient runtime for containers.",
    25  		SilenceUsage:  true,
    26  		SilenceErrors: true,
    27  		Args:          cli.NoArgs,
    28  		RunE: func(cmd *cobra.Command, args []string) error {
    29  			opts.flags = cmd.Flags()
    30  			// 4、关键函数
    31  			return runDaemon(opts)
    32  		},
    33  		DisableFlagsInUseLine: true,
    34  		Version:               fmt.Sprintf("%s, build %s", dockerversion.Version, dockerversion.GitCommit),
    35  	}
    36  	// 2、主要是为生成命令行帮助文档、使用文档等注册了一些函数一些模版语言
    37  	cli.SetupRootCommand(cmd)
    38  
    39  	// 3、参数解析
    40  	flags := cmd.Flags()
    41  	flags.BoolP("version", "v", false, "Print version information and quit")
    42  	flags.StringVar(&opts.configFile, "config-file", defaultDaemonConfigFile, "Daemon configuration file")
    43  	opts.InstallFlags(flags)
    44  	installConfigFlags(opts.daemonConfig, flags)
    45  	installServiceFlags(flags)
    46  
    47  	return cmd
    48  }
    49  
    50  func init() {
    51  	if dockerversion.ProductName != "" {
    52  		apicaps.ExportedProduct = dockerversion.ProductName
    53  	}
    54  }
    55  
    56  func main() {
    57  	// 1、第一次执行registeredInitializers map中应该是没有注册过任何东西,所以肯定返回false
    58  	// “docker 源码分析”一书中解释,reexec存在的作用是:协调execdirver与创建容器时dockerinit这两者的关系;这一说法有待验证
    59  	if reexec.Init() {
    60  		return
    61  	}
    62  
    63  	// Set terminal emulation based on platform as required.
    64  	_, stdout, stderr := term.StdStreams()
    65  
    66  	// 2、日志初始化
    67  	// @jhowardmsft - maybe there is a historic reason why on non-Windows, stderr is used
    68  	// here. However, on Windows it makes no sense and there is no need.
    69  	if runtime.GOOS == "windows" {
    70  		logrus.SetOutput(stdout)
    71  	} else {
    72  		logrus.SetOutput(stderr)
    73  	}
    74  
    75  	// 3、创建cobra command对象
    76  	cmd := newDaemonCommand()
    77  	cmd.SetOutput(stdout)
    78  	if err := cmd.Execute(); err != nil {
    79  		fmt.Fprintf(stderr, "%s\n", err)
    80  		os.Exit(1)
    81  	}
    82  }