入門系列之在Ubuntu 16.04使用Buildbot創建持續集成系統

歡迎你們前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~node

本文由angel_鬱發表於雲+社區專欄python

介紹

Buildbot是一個基於Python的持續集成系統,用於自動化軟件構建,測試和發佈過程。git

在本教程中,咱們將演示如何設置持續集成系統以自動測試對存儲庫的新更改。咱們將使用一個簡單的Node.js應用程序來演示測試過程和必要的配置。爲了將咱們的測試環境與Buildbot主機隔離,咱們將建立一個Docker鏡像做爲Buildbot worker運行。而後,咱們將配置Buildbot主服務器以觀察GitHub存儲庫的更改,每次檢測到新的更改時自動進行測試。github

準備

要學習本教程,您須要:web

  • 一個具備至少1 GB的RAM的Ubuntu16.04服務器,幷包括一個可使用sudo命令的非root 用戶。

另外,在開始本教程以前須要完成如下內容:sql

在GitHub中使用fork示例存儲庫

在咱們開始配置Buildbot以前,咱們將看一下咱們將用於本教程的示例存儲庫。

在您的Web瀏覽器中,訪問咱們將用於演示的GitHub上hello hapi應用程序。這個應用程序是一個簡單的「hello world」程序,帶有一些單元和集成測試,用hapi編寫的一個Node.js Web框架。

因爲此示例用於演示各類持續集成系統,您可能會注意到一些文件用於爲其餘系統定義管道。對於Buildbot,咱們將在服務器上而不是在存儲庫中定義構建步驟。

稍後,咱們將在咱們的存儲庫中爲Buildbot設置webhook,以便更改將自動觸發新測試。如今,咱們須要建立本身的存儲庫分支。

單擊屏幕右上角的Fork按鈕:

imgGitHub fork 按鈕

若是您是GitHub組織的成員,可能會詢問您在哪裏使用fork存儲庫:

img哪裏使用fork存儲庫

選擇賬戶或組織後,存儲庫的副本將添加到您的賬戶中:

img存儲庫的副本將添加到您的賬戶

您將在Buildbot配置中使用fork的URL。如今咱們有了一個存儲庫URL,咱們能夠開始配置Buildbot了。

爲Buildbot設置Docker

咱們將從設置Docker開始,以便Buildbot使用它來執行構建。首先,咱們須要配置Docker和Buildbot之間的訪問。以後,咱們須要建立一個Docker鏡像以用於咱們的容器。

爲Buildbot配置Docker訪問

咱們須要容許Buildbot和Docker在幾個不一樣的級別進行通訊。

首先,咱們須要確保Buildbot進程能夠訪問Docker守護程序。咱們能夠經過將作到這一點buildbot用戶的docker組:

$ sudo usermod -aG docker buildbot

下次從新啓動Buildbot主服務器時,這個新組將可用於Buildbot,咱們稍後會這樣作。

咱們還須要確保Buildbot知道如何與Docker通訊。因爲Buildbot是用Python編寫的,它利用docker-py Python包而不是直接發出Docker命令。

您能夠輸入如下命令安裝docker-py

$ sudo -H pip install docker-py

最後,咱們須要打開從容器到主機系統和外部世界的網絡訪問。咱們能夠經過在防火牆中容許docker0的接口例外來實現此目的。

經過輸入如下內容容許從docker0界面訪問流量:

$ sudo ufw allow in on docker0

Buildbot和Docker如今應該可以有效地相互通訊。

建立一個Docker鏡像以用做Buildbot Worker

接下來,咱們將建立一個Docker容器,用做Buildbot worker來運行咱們的測試。Buildbot能夠動態啓動Docker容器以用做worker,但首先須要使用包含的一些Buildbot worker組件構建容器。

幸運的是,Buildbot項目提供了一個基本的Buildbot worker映像,該鏡像已經配置了全部特定於Buildbot的需求。咱們只須要將此鏡像用做基礎並安裝咱們項目所需的其餘依賴項。

在咱們的例子中,咱們將使用示例應用程序是Node.js應用程序,所以咱們須要確保Node.js在鏡像上可用。

要定義咱們的鏡像,請建立並打開Dockerfile在主目錄中調用的文件:

$ nano ~/Dockerfile

在這個文件中,咱們使用了基於Buildbot worker的鏡像FROM buildbot/buildbot-worker:master。以後,咱們能夠切換到root用戶安裝Node.js,而後切換回buildbot用戶運行實際命令:

〜/ Dockerfile

FROM buildbot/buildbot-worker:master

USER root
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
RUN apt-get install -y nodejs
USER buildbot

完成後保存並關閉文件。

一旦咱們擁有了Dockerfile,咱們就能夠從中構建咱們的鏡像。咱們將調用鏡像npm-worker來明確咱們安裝的額外依賴項:

$ docker build -t npm-worker - < ~/Dockerfile

Docker將根據咱們在其中列出的命令開始構建您的鏡像Dockerfile。它將下拉基本鏡像及其依賴層,安裝Node.js,而後將生成的環境保存到一個名爲npm-worker的鏡像中。

配置Buildbot主服務器

如今咱們有了Docker鏡像,咱們能夠配置Buildbot主機來使用它。

由於咱們正在定義一個全新的構建過程,而且由於到目前爲止咱們對主配置的定製不多,因此咱們將從頭開始配置。爲避免丟失當前信息,咱們將原始文件移動到備份文件:

$ sudo mv /home/buildbot/master/master.cfg /home/buildbot/master/master.cfg.bak

顯示備份文件的配置,以便咱們能夠複製一些重要值以在新配置中使用:

$ sudo cat /home/buildbot/master/master.cfg.bak

咱們要轉移到新配置的重要部分是用戶憑據和權限。在輸出中查找c['www']['authz']c['www']['auth']開頭的配置部分:

. . .
c['www']['authz'] = util.Authz(
        allowRules = [
                util.AnyEndpointMatcher(role="admins")
        ],
        roleMatchers = [
                util.RolesFromUsername(roles=['admins'], usernames=['Sammy'])
        ]
)
c['www']['auth'] = util.UserPasswordAuth({'Sammy': 'Password'})
. . .

將這些行復制並保存在某處,以便之後能夠引用它們。咱們將這些詳細信息添加到咱們的新Buildbot主配置中,以保留咱們的用戶和身份驗證設置。

如今,建立一個新master.cfg文件,咱們能夠在其中從新定義Buildbot實例的行爲:

$ sudo nano /home/buildbot/master/master.cfg

咱們將在此文件中定義新的Buildbot主配置。

設置基本項目配置

Buildbot配置文件其實是一個Python模塊,它以犧牲一些複雜性爲代價提供了極大的靈活性。

咱們將從一些基本配置開始。將如下行粘貼到您的文件中:

/home/buildbot/master/master.cfg

# -*- python -*-
# ex: set filetype=python:
from buildbot.plugins import *


c = BuildmasterConfig = {}

# Basic config
c['buildbotNetUsageData'] = None
c['title'] = "Hello Hapi"
c['titleURL'] = "https://github.com/your_github_name/hello_hapi"
c['buildbotURL'] = "https://buildmaster_domain_name/"
c['protocols'] = {'pb': {'port': 9989}}

該文件的頂部包含一些註釋,許多文本編輯器可以解釋這些註釋以正確應用語法高亮顯示。而後,咱們從buildbot.plugins包中導入全部內容,以便咱們可使用工具來構建配置。

Buildbot配置所有由名爲BuildmasterConfig的字典定義,所以咱們將此變量設置爲空字典以啓動。

咱們建立一個名爲c的速記變量,設置爲同一個字,以減小整個文件中所需的輸入量。

下面的配置中須要注意的一些事項:

  • buildbotNetUsageData設置爲None。若是要向開發人員報告使用狀況數據,請將其更改成字符串"basic"

  • titletitleURL反映項目的名稱和GitHub的倉庫。使用指向您本身的fork的連接。

  • buildbotURL設置爲Buildbot主服務器的SSL安全域名。記得從https://開始並以尾部斜槓/結束。

  • 與咱們的上一個配置不一樣,該protocol定義並不會和本地主機綁定。咱們須要經過Docker橋接網絡docker0容許來自Docker容器的鏈接。

配置Docker Worker

接下來,咱們須要定義咱們的Docker worker。Buildbot將根據須要使用Docker來配置工做人員。爲此,它須要知道如何鏈接到Docker以及使用哪一個映象。

將如下內容粘貼到文件的底部:

/home/buildbot/master/master.cfg

. . .

# Workers
c['workers'] = []
c['workers'].append(worker.DockerLatentWorker("npm-docker-worker", None,
                        docker_host='unix://var/run/docker.sock',
                        image='npm-worker',
                        masterFQDN='buildmaster_domain_name'))

c['workers'] =[]行演示了咱們在完成配置時將使用的基本約定。咱們將配置字典中的鍵設置爲空列表。而後,咱們將元素附加到列表以實現實際配置。這使咱們能夠在之後添加其餘元素。

爲了定義咱們的worker,咱們建立一個worker.DockerLatentWorker實例並將其追加到worker列表中。咱們將此工做者命名爲npm-docker-worker,以便稍後在配置中引用它。而後咱們將docker_host設置爲Docker的套接字位置,並提供咱們建立的Docker鏡像的名稱(在咱們的例子中爲npm-worker)。咱們將masterFQDN設置爲Buildbot master的域名,以確保容器能夠到達主服務器,而無論服務器的內部主機名設置如何。

配置調度程序

接下來,咱們將定義一個調度程序。Buildbot使用調度程序根據從變動源或更改掛鉤收到的更改來決定什麼時候以及如何運行構建(稍後咱們將配置更改掛鉤)。

將如下配置粘貼到文件的底部:

/home/buildbot/master/master.cfg

. . .

# Schedulers
c['schedulers'] = []
c['schedulers'].append(schedulers.SingleBranchScheduler(
                name="hello_hapi",
                change_filter=util.ChangeFilter(project='your_github_name/hello_hapi', branch='master'),
                treeStableTimer=3,
                builderNames=["npm"]))

咱們使用相同的方法將配置附加到空列表中。在這種狀況下,咱們附加一個schedulers.SingleBranchScheduler實例。這容許咱們在存儲庫中觀察單個分支,並簡化了配置。

咱們將調度程序命名爲「hello_hapi」以正確識別它。而後咱們定義一個更改過濾器。來自不一樣來源的許多不一樣變動集能夠交給調度程序。更改過濾器定義一組標準,用於肯定此特定調度程序是否應處理相關更改。在咱們的例子中,咱們根據項目名稱進行過濾,這將由GitHub webhook和咱們但願觀看的分支報告。

接下來,咱們將treeStableTimer設置爲3秒,該treeStableTimer肯定等待其餘更改的時間量。這有助於防止Buildbot爲與密切相關的更改排隊許多小型構建。最後,咱們定義當更改符合咱們的條件時應該使用的構建器的名稱(咱們將暫時定義此爲構建器)。

爲Node.js項目配置構建工廠

接下來,咱們將配置一個用於處理Node.js項目的構建工廠。構建工廠負責定義構建或在咱們的案例測試中應該採起的步驟。它經過定義util.BuildFactory實例而後添加應執行的順序步驟來完成此操做。

將如下內容粘貼到文件的底部:

/home/buildbot/master/master.cfg

. . .

# Build Factories
npm_f = util.BuildFactory()
npm_f.addStep(steps.GitHub(repourl='git://github.com/your_github_name/hello_hapi.git', mode='full', method='clobber'))
npm_f.addStep(steps.ShellCommand(command=["npm", "install"]))
npm_f.addStep(steps.ShellCommand(command=["npm", "test"]))

首先,咱們定義一個名爲npm_f的構建工廠。咱們添加的第一步是steps.GitHub實例。在這裏,咱們設置應該下拉到構建器中的存儲庫。咱們設置mode「full」method「clobber」以在每次提取新代碼時徹底清理咱們的存儲庫。

咱們添加的第二個和第三個步驟是steps.ShellCommand對象,它們定義在構建期間在存儲庫中運行的shell命令。在咱們的例子中,咱們須要運行npm install以收集項目的依賴項。以後,咱們須要運行npm test以運行咱們的測試套件。在大多數狀況下,建議將命令定義爲一個list (["npm","install"]),以防止shell對命令中的元素應用不須要的擴展。

配置構建器

一旦咱們有一個添加了步驟的構建工廠,咱們就能夠設置一個構建器。構建器將咱們已定義的許多元素綁定在一塊兒,以肯定構建的執行方式。

將如下配置粘貼到文件的底部:

/home/buildbot/master/master.cfg

. . .

# Builders
c['builders'] = []
c['builders'].append(
        util.BuilderConfig(name="npm",
                workernames=["npm-docker-worker"],
                factory=npm_f))

咱們將一個util.BuilderConfig對象附加到builders列表中。請記住,咱們的構建工廠名爲npm_f,咱們的Docker工做者稱爲npm-docker-worker,咱們定義的調度程序將把任務傳遞給名爲npm的worker。。咱們的構建器定義了這些元素之間的關係,以便咱們的調度程序的更改將致使構建工廠步驟在Docker worker中執行。

配置數據庫和Web界面

最後,咱們能夠配置數據庫和Web界面設置。與以前的許多項目不一樣,這兩個設置被定義爲字典而不是列表。該db字典只指向/home/buildbot/master目錄中已有的state.sqlite文件。www詞典包含大量額外配置。

將如下內容粘貼到文件的底部。將您從原始Buildbot主配置中複製的身份驗證信息替換爲如下身份驗證塊:

/home/buildbot/master/master.cfg

. . .

# Database
c['db'] = { 'db_url': "sqlite:///state.sqlite",}

# Web Interface
c['www'] = dict(port=8010, plugins=dict(waterfall_view={}, console_view={}))

# Auth info copied from the original configuration
c['www']['authz'] = util.Authz(
        allowRules = [
                util.AnyEndpointMatcher(role="admins")
        ],
        roleMatchers = [
                util.RolesFromUsername(roles=['admins'], usernames=['Sammy'])
        ]
)
c['www']['auth'] = util.UserPasswordAuth({'Sammy': 'Password'})
# End of auth info copied from the original configuration

# GitHub webhook receiver
c['www']['change_hook_dialects'] = {
        'github': {
                'secret': 'your_secret_value',
                'strict': True,
        }
}

在定義數據庫設置以後,咱們建立一個www字典,該字典首先定義要偵聽的端口以及要包含在Web UI中的一些視圖。接下來,咱們添加從先前的Buildbot配置文件中提取的身份驗證要求。

最後,咱們在www字典中定義了一個名爲change_hook_dialects的字典。咱們使用它來定義一個GitHub更改掛鉤,它將偵聽來自GitHub的webhook消息。爲您的機密選擇一個安全密碼,GitHub將使用該密碼來驗證它將發送的消息。

完成後,保存並關閉文件。

從新啓動Buildbot Master以應用新配置

此時,咱們已經徹底從新配置了Buildbot主進程。咱們須要從新啓動Buildbot主進程來實現更改。

在咱們這樣作以前,檢查咱們的文件是否有重要的語法錯誤。因爲咱們從頭開始重建配置,所以咱們極可能會引入一些錯誤。

輸入如下命令檢查文件的語法:

$ sudo buildbot checkconfig /home/buildbot/master

該命令將報告它找到的任何問題。若是未找到任何錯誤,您將收到以下消息:

Config file is good!

若是報告了任何錯誤,請仔細閱讀錯誤消息,以便更好地瞭解錯誤。再次打開配置文件以嘗試解決任何問題。

若是再也不出現任何錯誤,請輸入如下命令從新啓動Buildbot主服務:

$ sudo systemctl restart buildbot-master

輸入如下命令檢查操做是否成功:

$ sudo systemctl status buildbot-master
● buildbot-master.service - BuildBot master service
   Loaded: loaded (/etc/systemd/system/buildbot-master.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2017-06-27 19:24:07 UTC; 2s ago
 Main PID: 8298 (buildbot)
    Tasks: 2
   Memory: 51.7M
      CPU: 1.782s
   CGroup: /system.slice/buildbot-master.service
           └─8298 /usr/bin/python /usr/local/bin/buildbot start --nodaemon

Jun 27 19:24:07 bb5 systemd[1]: Started BuildBot master service

若是服務可以成功從新啓動,則會將其標記爲活動狀態。

在示例存儲庫中建立GitHub Webhook

如今Buildbot配置了一個Web端點來接受GitHub webhook帖子,咱們能夠爲咱們的fork配置一個webhook。

在Web瀏覽器中,導航到示例項目存儲庫的fork:

https://github.com/your_github_user/hello_hapi

單擊「設置」選項卡以查看項目設置。在設置頁面的左側菜單中,單擊Webhooks(GitHub可能會提示您在此過程當中從新輸入密碼以確認您的身份):

img項目設置

單擊右側的「 添加webhook」按鈕以添加新的webhook。

下面的頁面將包含一個用於定義webhook的表單。在Payload URL字段中,添加項目的GitHub更改的URL。這是經過指定https://協議,而後是Buildbot master的域名,而後是/change_hook/github構建的。

將內容類型設置爲application/x-www-form-urlencoded。在「密碼」字段中,輸入您在Buildbot主配置文件中選擇的祕密密碼。您能夠選中「Just push」事件觸發器,勾選「Active」複選框:

img添加新的webhook

完成後,單擊「 添加webhook」按鈕。

您將返回到項目的webhooks索引,在該索引中將顯示您的新webhook。若是刷新幾回,則應在webhook旁邊顯示綠色複選標記圖標,表示郵件已成功傳輸:

imgwebhooks索引

若是您看到紅色的X,請再次單擊webhook,而後向下滾動到Recent Deliveries部分。若是您單擊failed delivery,能夠得到有關出現問題的更多信息。

測試Webhook

如今咱們已經有了webhook,咱們能夠測試以確保當咱們對存儲庫進行更改時,Buildbot會被警告,觸發Docker中的構建,而且可以成功執行測試套件。

在GitHub fork的主頁面中,單擊綠色「克隆或下載」按鈕左側的「 建立新文件 」按鈕:

img建立新文件

在隨後的屏幕上,建立dummy_file並填寫一些文本:

imgdummy_file

完成後,單擊頁面底部的「 提交新文件」按鈕。

接下來,訪問您的Buildbot Web界面,若是您還沒有經過身份驗證,請登陸。

根據您提交dummy_file到存儲庫後的時間長度,您可能會看到正在進行的構建,以下所示:

imgBuildbot 正在構建

若是構建已經完成,則它將位於「最近構建」部分中:

img構建完成

咱們定義的構建器名稱「npm」用於標記構建。在該示例中,咱們還能夠從先前的主配置中看到較早的樣本構建器運行。

不管進度如何,單擊構建器名稱和內部版本號連接以訪問構建詳細信息頁面。此視圖包含有關所執行的構建的信息。咱們添加到構建工廠的每一個步驟都將顯示在其本身的部分中:

img構建詳細信息

若是單擊某個步驟,將顯示該命令的輸出。若是出現問題,這能夠幫助調試:

img調試輸出

在上面的輸出中,咱們能夠驗證Buildbot是否在咱們的測試套件中成功運行了三個測試。

若是構建未成功完成,您可能但願檢查的其餘一些區域是構建詳細信息頁面上的其餘選項卡以及/home/buildbot/master/twistd.log文件。

調整Buildbot服務

在咱們完成以前,咱們應該對咱們的Buildbot服務進行一些調整。

目前,咱們爲再也不使用的工做人員定義了buildbot-worker服務(咱們的Docker工做程序在須要時自動啓動)。

咱們應該中止並禁用old worker。

要中止正在運行的服務並禁止它在引導時啓動,請輸入:

$ sudo systemctl stop buildbot-worker
$ sudo systemctl disable buildbot-worker
Removed symlink /etc/systemd/system/buildbot-master.service.wants/buildbot-worker.service.

上面的輸出結果代表工做人員下次啓動時不會啓動。要驗證服務是否再也不運行,請輸入:

$ sudo systemctl status buildbot-worker
● buildbot-worker.service - BuildBot worker service
   Loaded: loaded (/etc/systemd/system/buildbot-worker.service; disabled; vendor preset: enabled)
   Active: inactive (dead)

Jun 27 21:12:48 bb6 systemd[1]: Started BuildBot worker service.
Jun 27 21:55:51 bb6 systemd[1]: Stopping BuildBot worker service...
Jun 27 21:55:51 bb6 systemd[1]: Stopped BuildBot worker service.

咱們應該作的最後一件事是在Buildbot主服務和Docker守護進程之間創建一個soft依賴項。因爲Buildbot主服務沒法在沒有Docker的狀況下配置new workers,所以咱們應該定義此要求。

打開/ etc / systemd / system目錄中的buildbot-master.service文件以調整服務文件:

$ sudo nano /etc/systemd/system/buildbot-master.service

[Unit]部分中,將docker.service添加到network.target項以後的After指令中。添加另外一個名爲docker.serviceWants指令。Wants創建了一個軟依賴,而After指令創建了起始順序:

/etc/systemd/system/buildbot-master.service

[Unit]
Description=BuildBot master service
After=network.target docker.service
Wants=docker.service

[Service]
User=buildbot
Group=buildbot
WorkingDirectory=/home/buildbot/master
ExecStart=/usr/local/bin/buildbot start --nodaemon

[Install]
WantedBy=multi-user.target

完成後保存並關閉文件。

從新加載systemd守護程序和服務以當即應用配置:

$ sudo systemctl daemon-reload
$ sudo systemctl restart buildbot-master

如今應該在Docker可用以後啓動Buildbot主進程。

結論

在本教程中,咱們將Buildbot配置爲使用webhooks監聽對GitHub存儲庫的更改。收到更改後,Buildbot會根據自定義Docker鏡像啓動容器以測試新提交。Docker鏡像包含一個Buildbot工做器實例以及測試項目代碼所需的依賴項。這容許Buildbot在對存儲庫進行更改時根據須要動態啓動Buildbot worker。


參考文獻:《How To Set Up Continuous Integration with Buildbot on Ubuntu 16.04》

問答

騰訊雲服務器?

相關閱讀

教你從0到1搭建小程序音視頻

教你快速搭建一場發佈會直播方案

移形換影 - 短視頻色彩特效背後的故事

此文已由做者受權騰訊雲+社區發佈,原文連接:https://cloud.tencent.com/developer/article/1178239?fromSource=waitui

歡迎你們前往騰訊雲+社區或關注雲加社區微信公衆號(QcloudCommunity),第一時間獲取更多海量技術實踐乾貨哦~

海量技術實踐經驗,盡在雲加社區! https://cloud.tencent.com/developer?fromSource=waitui

相關文章
相關標籤/搜索