CI/CD

Drone CI源码解析之runner定制与实现

2021-07-30  本文已影响0人  王司技术谈

Drone CI提供了多种runtime,可以利用docker方式运行,也可以通过传统ssh方式运行,也可以采用k8s作为runtime。Drone CI实现了一个可拓展的runner架构,方便实现各种runner,要实现自己的runner非常简单,只需要拓展实现四个方法。下边会先介绍下runner架构和流程,然后重点介绍下核心需要拓展的四个方法。

Poller是一个守护进程不停的通过p.Client.Request调用api从server获取下一个需要执行的build stage, 然后通过p.Dispatch调用runner的Run方法,, 将server获取的stage数据结构编译成适合本地runner使用的数据结构,然后调用Execer的Exec方法完成实际的运行,具体核心代码如下:

poller := &poller.Poller{
   Dispatch: runner.Run,
}

func (p *Poller) poll(ctx context.Context, thread int) error {
    stage, err := p.Client.Request(ctx, p.Filter)
    return p.Dispatch(
        logger.WithContext(noContext, log), stage)
}

func (s *Runner) run(ctx context.Context, stage *drone.Stage, data *client.Context) error {
    spec := s.Compiler.Compile(ctx, args)
    err = s.Exec(ctxlogger, spec, state)
}

Exec 方法会调用engine的 Setup、Run、Destroy方法来完成build stage的整个运行生命周期,这三个方法就是drone runner架构的核心扩展点,如果你要定制自己的runner需要实现这三个方法, 和方法名一样Setup代表初始化,Run是实际执行,Destroy是收尾清理工作。

Engine interface {
    // Setup the pipeline environment.
    Setup(context.Context, Spec) error

    // Destroy the pipeline environment.
    Destroy(context.Context, Spec) error

    // Run runs the pipeline step.
    Run(context.Context, Spec, Step, io.Writer) (*State, error)
}
    
func (e *Execer) Exec(ctx context.Context, spec Spec, state *pipeline.State) error {
       e.engine.Setup(noContext, spec)
       e.engine.Run(ctx, spec, copy, wc)
       defer func() {
        err := e.engine.Destroy(noContext, spec)
    }
}

另一个核心扩展点就是Compiler 的Compile方法,将用户定义的.drone.yml格式的数据转化为engine.Run能方便使用的数据结构,如docker runner是将stage转化为docker api使用的标准结构。

总结下要实现自己的runner只需要实现Engine的三个方法和Compiler的Compile方法。

本人使用earthly作为runtime实现了自己的一个runner drone-runner-earthly,感兴趣的朋友可以围观。

上一篇 下一篇

猜你喜欢

热点阅读