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,感兴趣的朋友可以围观。