Docker 源码(一)

416 阅读2分钟

docker.go

// main: 包名
package main

/**
 * fmt:             输出内容和获取输入内容
 * os:              提供了不依赖平台的操作系统函数接口,系统、文件
 * docker/cli:      Docker CE 和 Docker EE 产品中使用的 cli
 * spf13/cobra:     创建强大的现代 CLI 应用程序的库
 * sirupsen/logrus: Logrus 是 Go (golang) 的结构化记录器
 * reexec:          reexec模块是为了提供重新调用docker二进制文件的能力,类似fork的概念
 */
import (
   "fmt"
   "os"

   "github.com/docker/docker/cli"
   "github.com/docker/docker/daemon/config"
   "github.com/docker/docker/dockerversion"
   "github.com/docker/docker/pkg/jsonmessage"
   "github.com/docker/docker/pkg/reexec"
   "github.com/docker/docker/rootless"
   "github.com/moby/buildkit/util/apicaps"
   "github.com/moby/term"
   "github.com/sirupsen/logrus"
   "github.com/spf13/cobra"
)

// honorXDG:变量 是否为 rootless 模式启动 Docker
var (
   honorXDG bool
)

func newDaemonCommand() (*cobra.Command, error) {
   /**
    * 获取配置
    */
   opts := newDaemonOptions(config.New())


    /**
     * cobra.Command  命令行注册
     * Use:          命令总的用法
     * Short:        命令总的用法说明
     * SilenceUsage: true 命令执行遇见输入错误时,不显示错误
     * SilenceErrors:true 命令执行过程中遇到错误,不显示错误
     * Args:         表示期望的参数
     * RunE:         返回
     * DisableFlagsInUseLine:true 不会在命令帮助信息或者文档中显示命令支持的选项
     * Version:      定义版本
     */
   cmd := &cobra.Command{
      Use:           "dockerd [OPTIONS]",
      Short:         "A self-sufficient runtime for containers.",
      SilenceUsage:  true,
      SilenceErrors: true,
      Args:          cli.NoArgs,
      RunE: func(cmd *cobra.Command, args []string) error {
         opts.flags = cmd.Flags()

         // 读取配置,调用NewDaemon函数,创建Daemon,启动DaemonCli (注:具体请看 1.1)
         return runDaemon(opts)
      },
      DisableFlagsInUseLine: true,
      Version:               fmt.Sprintf("%s, build %s", dockerversion.Version, dockerversion.GitCommit),
   }

   // SetupRootCommand 设置默认用法、帮助和错误处理
   cli.SetupRootCommand(cmd)

   flags := cmd.Flags()

   flags.BoolP("version", "v", false, "Print version information and quit")

   // 获取默认配置
   defaultDaemonConfigFile, err := getDefaultDaemonConfigFile()
   if err != nil {
      return nil, err
   }
   
   flags.StringVar(&opts.configFile, "config-file", defaultDaemonConfigFile, "Daemon configuration file")
   configureCertsDir()
   
   // 通过传递地址,讲解析之后的参数,传递到options中
   opts.installFlags(flags)
   if err := installConfigFlags(opts.daemonConfig, flags); err != nil {
      return nil, err
   }
   installServiceFlags(flags)

   return cmd, nil
}

func init() {
   /**
    * dockerversion.ProductName 为空就赋值
    */
   if dockerversion.ProductName != "" {
      apicaps.ExportedProduct = dockerversion.ProductName
   }
   // When running with RootlessKit, $XDG_RUNTIME_DIR, $XDG_DATA_HOME, and $XDG_CONFIG_HOME needs to be
   // honored as the default dirs, because we are unlikely to have permissions to access the system-wide
   // directories.
   //
   // Note that even running with --rootless, when not running with RootlessKit, honorXDG needs to be kept false,
   // because the system-wide directories in the current mount namespace are expected to be accessible.
   // ("rootful" dockerd in rootless dockerd, #38702)
   /**
    * rootless.RunningWithRootlessKit(): 判断非root用户安装及启动docker(既: rootless模式运行)。
    */
   honorXDG = rootless.RunningWithRootlessKit()
}

func main() {
   /**
    * reexec.Init:命令是否存在,如果存在就执行并且返回true,异常就返回false,
    */
   if reexec.Init() {
      return
   }

   // initial log formatting; this setting is updated after the daemon configuration is loaded.
   
   /**
    * SetFormatter:设置日志的输出格式
    */
   logrus.SetFormatter(&logrus.TextFormatter{
      TimestampFormat: jsonmessage.RFC3339NanoFixed,
      FullTimestamp:   true,
   })

   // Set terminal emulation based on platform as required.
   /**
    * stdout: 获取终端标准输出
    * stderr: 获取终端标准错误
    */
   _, stdout, stderr := term.StdStreams()

   /**
    * 将 stdout,stderr 输出
    */
   initLogging(stdout, stderr)

   onError := func(err error) {
      fmt.Fprintf(stderr, "%s\n", err)
      os.Exit(1)
   }

   /**
    * newDaemonCommand: 返回 1. cobra.Command 2. 错误信息
    */
   cmd, err := newDaemonCommand()
   if err != nil {
      onError(err)
   }
   cmd.SetOut(stdout)
   if err := cmd.Execute(); err != nil {
      onError(err)
   }
}
package reexec

/**
 * make 初始化内置函数 map:键:string 值:func
 */
var registeredInitializers = make(map[string]func())

/**
 * Init:命令是否存在,如果存在就执行并返回true,异常就返回false
 */
func Init() bool {
   initializer, exists := registeredInitializers[os.Args[0]]
   if exists {
      initializer()

      return true
   }
   return false
}
/**
 * 输出
 */
func initLogging(_, stderr io.Writer) {
   logrus.SetOutput(stderr)
}