深入理解Moby Buildkit系列 #8 - frontends模块

289 阅读2分钟

这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

想着上一次有关架构讨论的会议,袁小白因为自己没有帮上忙而闷闷不乐。 一心觉得龙飞也太厉害了,我什么时候能像龙飞一样就好了。 贾大智看起来好像只是会提问题,可看问题的角度,确实也值得学习。

这一次要看模块的源码了,可得上点心,争取多贡献自己的一份力量。 周六因为和朋友一起踏青,所以没能抽出时间看源码。 周日可要好好看看了。 心里想着,就起了个大早,泡上一杯自己喜欢的绿茶,津津有味的看了起来。

首先要将源码更新到最新: 版本信息(最早看的时候是三月份,目前从最新的和大家一起来梳理)

最早看的时候是三月份,目前从最新的和大家一起来梳理

frontends这个控件在龙飞讲的时序图里好像没看到,但根据贾大智的描述。 会出现在clientBuildctl build.jpg

  • 龙飞的时序图

frontends

获取用用户定义好的构建信息,就像龙飞说的./example | buildctl build命令。 用于转换成统一的后端标准构建操作集。 这里要强调的是Dockerfile是所支持前端的一种形式,那就意味着,大家可以自定义自己的前端语言,自己的Container building DSL

  • 贾大智的理解

那我们先顺藤摸瓜,从命令行buildctl build开始吧。

cmd

找到对应的buildctl的文件夹,并打开文件main.go,可以查看到以下代码结构: Screen Shot 2021-11-09 at 7.22.01 PM.png

看起来不算复杂,golang会在运行main函数前,执行init函数,且通过import可以看出,命令行工具用的是urfave/cli,版本v2有详细的使用说明

package main

import (
  "os"

  "github.com/urfave/cli/v2"
)

func main() {
  (&cli.App{}).Run(os.Args)
}

将系统参数传入cli.App实例,就可以运行了。

顺着这个思路再来看buildctl源码,在main函数中,有以下代码:

func main() {
   ...
   app := cli.NewApp()
   app.Name = "buildctl"
   app.Usage = "build utility"
   app.Version = version.Version

   defaultAddress := os.Getenv("BUILDKIT_HOST")
   if defaultAddress == "" {
      defaultAddress = appdefaults.Address
   }

   app.Flags = []cli.Flag{
      ...
      cli.IntFlag{
         Name:  "timeout",
         Usage: "timeout backend connection after value seconds",
         Value: 5,
      },
   }

   app.Commands = []cli.Command{
      diskUsageCommand,
      pruneCommand,
      buildCommand,
      debugCommand,
      dialStdioCommand,
   }

   ...

   handleErr(debugEnabled, app.Run(os.Args))

可以看出,和官方推荐的使用方法类似。

  • 先实例化命令行buildctl
  • 然后设置一些flag,也就是命令行参数,
  • 接着在app.Commands里注册对应的子命令,其中我们就发现了buildCommand,这里也就是我们要去一探究竟的地方了
  • 最后传入参数并运行app.Run(os.Args)

看来看源码也不怎么难吗,看到有个好的开头,袁小白品了口绿茶,味道刚刚好。

下一篇:深入理解Moby Buildkit系列 #9 - 失踪的frontends