转载

buildbot

大师Martin Fowler对持续集成(Continuous Integration)是这样定义的:持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。 buildbot 图片来源于:百度百科

在BuildBot中,可以通过三种方式触发构建:

  • 监测到代码库的变化 ,从而触发构建
  • 通过配置, 定时 触发构建
  • 通过配置,允许 强制 触发构建

BuildBot有如下优点:

  • 跨平台:可以运行在各种平台上,实现不同平台上的测试
  • 可以处理各种语言编写的程序,例如C、Java、Python
  • 环境要求低并且配置简单:仅依赖Python和网络库Twisted
  • 结果的交付方式多,例如Email、webpage、IRC或者其他协议工具
  • 通过子类继承并重写父类从而灵活的配置
  • 很好的实现了 分布式 部署和集成工作

使用BuildBot的公司:

  • https://github.com/buildbot/buildbot/wiki/SuccessStories

BuildBot整体架构: buildbot BuildBot是由一个 buildmaster 和一个或者多个 worker ,通过星型拓扑结构连接而成的。

各个组件的作用:

  • Repository :代码仓库,用于代码管理和版本控制,目前流行的有SVN、Git等
  • BuildMaster:监测代码库上的变化,这些变化可能会引发构建
  • Worker:根据BuildMaster下发的Command,执行构建,同时将执行状态和结果返回给BuildMaster
  • Notifiers:在构建的时候,会产生各种各样的状态消息,它们会被发送到Notifiers

Worker连接:

Worker通常运行在各种不同的平台上。它们通过TCP协议连接到BuildMaster上。这些TCP连接都是由Worker发起的。BuildMaster下发的Command以及Worker返回的Result都通过这些TCP连接进行传输。BuildMaster是集群的管理者,因此所有Command都是由BuildMaster下发给Worker的。

BuildMaster只提供用于执行构建的指令,并不会提供源代码。因此,Worker需要去代码仓库获取源代码。

buildbot

BuildMaster架构:

(BuildMaster的各个组件均在master.cfg中配置)

  • ChangeSource:

    当监测到VCS上面发生变化时,ChangeSource会创建一个Change对象,提交给各个Scheduler。

    ChangeSource既可以通过监听钩子脚本产生的消息,也可以通过定期轮询的方式,监测VCS上的变化

  • Scheduler:

    决定何时执行构建。Scheduler会收集Change,构造BuildRequest,当Worker可用时,将BuildRequest交付给Builder

  • Builder:

    用于精确地控制如何执行构建(其中包含一系列的BuildStep)

  • Status plugin:

    通过HTTP、mail、IRC之类的协议,交付与构建结果有关的信息

buildbot

(本文假定读者已经安装了Python3,本文在Python 3.7.2下测试通过)

1,安装:

 
  
pip install 'buildbot[bundle]'
pip install buildbot-worker

2,创建,并启动master:

 
  

x

mkdir -p ~/tmp
buildbot create-master ~/tmp/master
mv ~/tmp/master/master.cfg.sample ~/tmp/master/master.cfg
buildbot upgrade-master ~/tmp/master
buildbot start ~/tmp/master
# 日志在:~/tmp/master/twistd.log

3,创建,并启动worker:

 
  
xxxxxxxxxx
mkdir -p ~/tmp
buildbot-worker create-worker ~/tmp/worker localhost example-worker pass
buildbot-worker start ~/tmp/worker
# 日志在:~/tmp/worker/twistd.log

其中:

  • localhost:运行buildmaster的服务器的地址。本例中是localhost

  • example-worker/pass:在buildmaster的配置文件中,有一个 workers列表 ,它是buildmaster所能识别的worker的集合。该列表中的元素是Worker对象,每个Worker对象都有唯一的名字 和 密码。在worker上配置的worker名称和密码,必须与buildmaster中配置的相同。比如:

     
        
    xxxxxxxxxx
    # master.cfg
    ####### WORKERS
    # The 'workers' list defines the set of recognized workers. Each element is
    # a Worker object, specifying a unique worker name and password.  The same
    # worker name and password must be configured on the worker.
    c['workers'] = [worker.Worker("example-worker", "pass")]

4,webstatus page:

接下来,访问: http://localhost:8010 ,可以看到类似下面的web页面: buildbot 点击左侧的“Builds”,打开子菜单。然后通过“Builders”,可以看到刚刚启动的worker,已经连接到master上了。 buildbot

下面,开始详细地介绍buildmaster的各个组件。

Builder负责执行某个或一系列行为,这些行为可以是与构建软件相关的,也可以是任意命令。

需要使用一个worker列表来配置Builder,这些worker用于执行任务。Builder需要的基础信息还包括:它要做的事情的列表(这些事情会在被选择的worker上执行)。在Buildbot中,这个事情列表被表示为一个BuildFactory对象,它本质上是一个步骤序列,每个步骤定义了一个特定的操作或命令。

下面看一个例子:

 
  
xxxxxxxxxx
factory = util.BuildFactory()
# 检出源代码
factory.addStep(steps.Git(repourl='https://github.com/tim-chow/buildbot-test.git', mode='incremental'))
# 执行测试
factory.addStep(steps.ShellCommand(command=["python", "setup.py", "test"]))
c['builders'] = []
c['builders'].append(
    util.BuilderConfig(name="runtests",
      workernames=["worker-1"],
      factory=factory))

在这个例子中,创建了一个叫 runtests 的Builder,它能够在 worker-1 上运行。

最重要的是:Builder的名字不能相同,并且必须被添加到 c['builders'] (该值是一个BuilderConfig对象的列表)。

Scheduler在它等待的事件发生时,基于事件信息,决定是否以及何时执行构建。可以有多个Scheduler。

Scheduler主要包含两部分信息:

  • 监测哪些事件
  • 当监测的事件发生时,触发哪些Builder

下面看一个例子:

 
  
xxxxxxxxxx
# Configure the Schedulers, which decide how to react to incoming changes.  In this
# case, just kick off a 'runtests' build
c['schedulers'] = []
c['schedulers'].append(schedulers.SingleBranchScheduler(
                            name="all",
                            change_filter=util.ChangeFilter(branch='master'),
                            treeStableTimer=None,
                            builderNames=["runtests"]))
c['schedulers'].append(schedulers.ForceScheduler(
                            name="force",
                            builderNames=["runtests"]))

第一个Scheduler会接收代码仓库上的变化,但是 只关注 master分支上的变化。换句话说,它只对它感兴趣的变化作出反应。当检测到这样的变化时,它会运行 runteststreeStableTimer 是为了避免:在频繁提交时,产生大量的构建请求。

使用第二个Scheduler的时候,可以通过Web UI强制构建 runtests

与Builder类似,所有Scheduler都必须被添加到 c["schedulers"] 列表中。

ChangeSource的任务是监测代码库上的变化,并把它们提交给Scheduler。

ChangeSource可以通过多种方式,监测代码库上的变化。比如,周期性地轮询代码库;或者通过配置(比如,通过被commit触发的钩子脚本),使VCS把变更推送给ChangeSource。

下面看一个例子:

 
  
xxxxxxxxxx
c['change_source'] = []
c['change_source'].append(changes.GitPoller(
        'https://github.com/tim-chow/buildbot-test.git',
        workdir='integrate_buildbot_test', branch='master',
        pollInterval=120))

在这个例子中,创建了一个GitPoller类型的ChangeSource,它每隔120秒轮询一次代码库,获取master分支上的变化。

与Builder类似,所有ChangeSource都必须被添加到 c["change_source"] 列表中。

BuildMaster可以通过多种方式,将构建状态发送给用户。每个交付方法是一个Reporter Target对象。

下面看一个例子:

 
  
xxxxxxxxxx
c['services'] = []
m = reporters.MailNotifier(fromaddr="buildbot@localhost",
                           extraRecipients=["744475502@qq.com"],
                           sendToInterestedUsers=False,
                           builders=["runtests"])
c['services'].append(m)

在这个例子中,BuildMaster会将 runtests 的构建状态,以邮件的形式发送给 744475502@qq.com

如果想要获取,更多关于Reporter的细节,请查看: http://docs.buildbot.net/current/manual/configuration/reporters.html 。

与Builder类似,所有Reporter Target都必须被添加到 c["services"] 列表中。

master.cfg中的其它配置项

 
  
xxxxxxxxxx
c['protocols'] = {'pb': {'port': 9989}}

protocols 中包含 与 master和worker之间通信所使用的协议 有关的信息。

 
  
xxxxxxxxxx
c['title'] = "My Test BuildBot"
c['titleURL'] = "http://timd.cn/python-buildbot/"

title 字符串会出现在home页面的顶部(链接到 titleURL )。

 
  
xxxxxxxxxx
c['buildbotURL'] = "http://192.168.10.102:8013/"

buildbotURL 用于指出web服务的地址。它应该使用 www 中设置的端口。

 
  
xxxxxxxxxx
c['www'] = dict(port=8010,
                plugins=dict(waterfall_view={}, console_view={}, grid_view={}))

激活web UI的最小化配置。其中:

  • port :用于指定接收请求的TCP端口
  • plugins :用于指定要加载的UI插件以及它们的配置。这些插件是独立安装的
  • 如果想要了解,更多关于web服务的配置,请移步: http://docs.buildbot.net/current/manual/configuration/www.html
 
  
xxxxxxxxxx
c['db'] = {
    # This specifies what database buildbot uses to store its state.  You can leave
    # this at its default for all but the largest installations.
    'db_url' : "sqlite:///state.sqlite",
}

db_url 用于指定 用来保存BuildBot的状态的数据库 的url。

默认情况下,访问Web UI是无需认证的。为了安全起见,应该配置认证插件。每个认证插件是一个类。

比如:

 
  
xxxxxxxxxx
c['www'] = {
    # ...
    'auth': util.UserPasswordAuth({"timchow": "password"}),
}

如果想要了解,BuildBot支持哪些认证插件,以及如何自定义认证插件,请移步: http://docs.buildbot.net/current/manual/configuration/www.html#authentication-plugins 。

接下来学习 授权框架

授权框架只对HTTP生效。它根据规则,控制用户对Rest API的访问。

授权框架的执行流程如下图所示:

buildbot

授权框架是基于角色的:

  • 角色:授予用户的一个标签

    • 一个用户可以拥有多个角色,一个角色可以被授予给多个用户
  • Endpoint Matchers:负责创建用于匹配Rest端点的规则。对于某个Rest端点而言,如果某条规则匹配它,那么在用户拥有规则中指定的角色的情况下,才能访问它

    • 在下面的例子中,对于强制构建这个Rest端点而言,第一条规则匹配它,因此,在用户拥有admins角色的情况下,才能访问它

       
            
      xxxxxxxxxx
      allowRules=[
        util.AnyControlEndpointMatcher(role="admins"),
      ]
    • 默认的策略是:对于一个Rest端点,如果没有任何规则匹配它,那么允许任何用户访问它

    • 默认情况下,第一个匹配Rest端点的规则,会阻止接下来的匹配。如果想要继续检查其它规则,那么需要将Matcher的 defaultDeny 参数设置为False

  • Role Matchers:负责创建用于匹配授权用户的规则。对于某个用户而言,如果某条规则匹配它,那么它将被授予规则中指定的角色

    • 在下面的例子中,对于用户root而言,第一条规则匹配它,因此,它被授予admins角色;对于用户Charlie而言,没有任何规则匹配它,因此,它不会被授予任何角色

       
            
      xxxxxxxxxx
      roleMatchers=[
          RolesFromUsername(roles=["admins"], usernames=["root"]),
          RolesFromUsername(roles=["developers", "integrators"], usernames=["Alice", "Bob"])
      ]

综上,如果用户A想要访问端点B,那么首先用Role Matchers中的规则匹配用户A,最终得到用户A拥有的所有角色;然后用Endpoint Matchers中的规则匹配端点B,如果某条规则匹配端点B,并且用户A拥有该规则所指定的角色,则用户A可以访问端点B…

配置授权规则的方式,如下所示:

 
  
xxxxxxxxxx
authz = util.Authz(
  allowRules=[
    util.AnyControlEndpointMatcher(role="admins"),
  ],
  roleMatchers=[
    util.RolesFromEmails(admins=["my@email.com"])
  ]
c['www']['authz'] = authz
  • http://docs.buildbot.net/current/tutorial/fiveminutes.html
  • http://baike.baidu.com/link?url=coVt2VV3swKAAnyjHnCkt_UtuAaEgxtfD2YAPAYkjQlGy6kTcSHgGc3zYCIEDr2e53rugvitlK55QdA5hmTuEK
原文  http://timd.cn/buildbot/
正文到此结束
Loading...