前面分析了使用cobra创建client,下面选取一条命令分析下client端如何执行
命令的处理都在cli目录之下,以 image 的 pull 为例
/cli/command/commands/commands.go AddCommands函数增加命令注册
pull命令在 image.NewImageCommand(dockerCli) 里面
/cli/command/image/cmd.go 里定义了增加 pull命令 NewPullCommand(dockerCli),
/cli/command/image/pull.go 定义了pull命令
unc NewPullCommand(dockerCli *command.DockerCli) *cobra.Command {
    var opts pullOptions
    cmd := &cobra.Command{
        Use:   "pull [OPTIONS] NAME[:TAG|@DIGEST]",
        Short: "Pull an image or a repository from a registry",
        Args:  cli.ExactArgs(1),
        RunE: func(cmd *cobra.Command, args []string) error {
            opts.remote = args[0]
            return runPull(dockerCli, opts)  //pull命令的执行
        },
    }
    flags := cmd.Flags()
    flags.BoolVarP(&opts.all, "all-tags", "a", false, "Download all tagged images in the repository")
    command.AddTrustVerificationFlags(flags)
    return cmd
}
pull命令的运行也在改文件内,省略一些异常处理之后
func runPull(dockerCli *command.DockerCli, opts pullOptions) error {
    distributionRef, err := reference.ParseNormalizedNamed(opts.remote)  // 根据命令字符串获取domain的一些信息
    // Resolve the Repository name from fqn to RepositoryInfo
    repoInfo, err := registry.ParseRepositoryInfo(distributionRef)  //registry/config.go  调用newRepositoryInfo创建repsitory仓库的一些信息
    ctx := context.Background()   //上下文
    authConfig := command.ResolveAuthConfig(ctx, dockerCli, repoInfo.Index) // registry.go  创建鉴权的数据
    requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(dockerCli, repoInfo.Index, "pull") // registry.go  鉴权的函数
    // Check if reference has a digest
    _, isCanonical := distributionRef.(reference.Canonical)
    if command.IsTrusted() && !isCanonical {
        err = trustedPull(ctx, dockerCli, repoInfo, distributionRef, authConfig, requestPrivilege)  // trust.go  先获取Repository信息,在Repository获取所有Target信息,遍历target最终还是调用imagePullPrivileged
    } else {
        err = imagePullPrivileged(ctx, dockerCli, authConfig, reference.FamiliarString(distributionRef), requestPrivilege, opts.all)  //trust.go  该函数pull image 并且将结果回显
    }
}
创建repoinfo
//config := newServiceConfig(ServiceOptions{})
func newRepositoryInfo(config *serviceConfig, name reference.Named) (*RepositoryInfo, error) {
    index, err := newIndexInfo(config, reference.Domain(name))
    if err != nil {
        return nil, err
    }
    official := !strings.ContainsRune(reference.FamiliarName(name), ‘/‘)
    return &RepositoryInfo{
        Name:     reference.TrimNamed(name),
        Index:    index,
        Official: official,
    }, nil
}
// imagePullPrivileged pulls the image and displays it to the output
func imagePullPrivileged(ctx context.Context, cli *command.DockerCli, authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc, all bool) error {
    encodedAuth, err := command.EncodeAuthToBase64(authConfig)
    options := types.ImagePullOptions{
        RegistryAuth:  encodedAuth,
        PrivilegeFunc: requestPrivilege,
        All:           all,
    }
    responseBody, err := cli.Client().ImagePull(ctx, ref, options)  // client/image_pull.go  关键一句 cli.tryImageCreate(ctx, query, options.RegistryAuth)
    defer responseBody.Close()   // 执行完之后关闭
    return jsonmessage.DisplayJSONMessagesToStream(responseBody, cli.Out(), nil) //  显示json信息
}
func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
    headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
    return cli.post(ctx, "/images/create", query, nil, headers)
}
原文:http://www.cnblogs.com/arwen-spy/p/6562116.html