天天看點

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

作者:Java技術識堂

近年來,由于開源項目、社群的活躍熱度大增,進而引來持續內建(CI)系統的誕生,也越發的聽到更多的人在說協同開發、靈活開發、疊代開發、持續內建和單元測試這些拉風的術語。國内公司能有完整的 CI 體系流程的應該也不多。反之一些開源項目都有完整的 CI體系,比如openstack。

為了實作代碼托管->代碼稽核->代碼釋出的一套自動化流程,我特意在IDC伺服器上部署了Gitlab+Gerrit+Jenkins對接環境,以下記錄了操作過程:

整體的架構圖如下:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

----------------------------------------------------------------------------------------------------------------------------------------

1)Gitlab上進行代碼托管

在gitlab上建立的項目設定成Private,普通使用者對這個項目就隻有pull權限,不能直接進行push,Git自帶code review功能。

強制Review :在 Gitlab 上建立的項目,指定相關使用者隻有Reporter權限,這樣使用者沒有權限使用git push功能,隻能git review到Gerrit 系統上,Jenkins在監聽Gerrit上的項目事件會觸發建構任務來測試代碼, Jenkins 把測試結果通過 ssh gerrit 給這個項目打上 Verified (資訊校驗)成功或失敗标記,成功通知其它人員 Review(代碼稽核) 。

Gitlab保護Master 分支:在 Gitlab 上建立的項目可以把 Master 分支保護起來,普通使用者可以自己建立分支并送出代碼到自己的分支上,沒有權限直接送出到Master分支,使用者最後送出申請把自己的分支 Merge 到 Master ,管理者收到 Merge 請求後, Review 後選擇是否合并。

可以将gitlab和gerrit部署在兩台機器上,這樣gitlab既可以托管gerrit代碼,也可以作為gerrit的備份。

因為gitlab和gerrit做了同步,gerrit上的代碼會同步到gitlab上。

這樣即使gerrit部署機出現故障,它裡面的代碼也不會丢失,可以去gitlab上拿。

2)Gerrit稽核代碼

Gerrit是一款被Android開源項目廣泛采用的code review(代碼稽核)系統。普通使用者将gitlab裡的項目clone到本地,修改代碼後,雖不能直接push到代碼中心 ,但是可以通過git review送出到gerrit上進行稽核。gerrit相關稽核員看到review資訊後,判斷是否通過,通過即commit送出。然後,gerrit代碼會和gitlab完成同步。

grrit的精髓在于不允許直接将本地修改同步到遠端倉庫。客戶機必須先push到遠端倉庫的refs/for/*分支上,等待稽核。

gerrit上也可以對比代碼稽核送出前後的内容狀态。

3)jenkins代碼釋出

當使用者git review後,代碼通過jenkins自動測試(verified)、人工review 後,代碼隻是merge到了Gerrit的項目中,并沒有merge到 Gitlab的項目中,是以需要當 Gerrit 項目倉庫有變化時自動同步到Gitlab的項目倉庫中。Gerrit 自帶一個 Replication 功能,同時我們在安裝 Gerrit 時候預設安裝了這個 Plugin,通過添加replication.config 給 Gerrit即可(下文有介紹)

----------------------------------------------------------------------------------------------------------------------------------------

一、基礎環境搭建(參考下面三篇文檔)

CI持續內建系統環境---部署gerrit環境完整記錄

CI持續內建系統環境---部署Gitlab環境完整記錄

CI持續內建系統環境---部署Jenkins完整記錄

二、Gitlab+Gerrit+Jenkins的對接

1)Gitlab配置

gitlab上的管理者賬号是gerrit,郵箱是[email protected]

建立了一個普通賬号wangshibo,郵箱是[email protected]

[root@115]# su - gerrit

[gerrit@115 ~]$ ssh-keygen -t rsa -C [email protected] //産生公私鑰

[gerrit@115 ~]$ cat ~/.ssh/id_rsa.pub

将上面gerrit賬号的公鑰内容更新到Gitlab上。

使用gerrit賬号登陸Gitlab,點選頁面右上角的Profile Settings - 點選左側的SSH Keys小鑰匙圖示 - 點選Add SSH Key。

在Key對應的輸入框中輸入上段落$cat .ssh/id_rsa.pub顯示的公鑰全文,點選Title,應該會自動填充為[email protected]。如下:

在Gitlab上建立wangshibo使用者

然後在機器上生成wangshibo公鑰(先提前在機器上建立wangshibo使用者,跟上面一樣操作),然後将公鑰内容更新到Gitlab上(用wangshibo賬号登陸Gitlab)

用gerrit登陸Gitlab,建立group組為dev-group,然後建立新項目test-project1(在dev-group組下,即項目的Namespace為dev-group,将wangshibo使用者添加到dev-group組内,權限為Reporter),具體如下截圖:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

建立的項目設定成Private即私有的,這樣普通使用者這它就隻有pull權限,沒有push權限。

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

在test-project1工程裡建立檔案,建立過程此處省略......

檔案建立後,如下:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

在linux系統上登入wangshibo賬号下,克隆工程test-project1.git,測試權限

[root@115]# su - wangshibo

[wangshibo@115 ~]$ git clone [email protected]:dev-group/test-project1.git

Initialized empty Git repository in /home/wangshibo/test-project1/.git/

remote: Counting objects: 15, done.

remote: Compressing objects: 100% (9/9), done.

remote: Total 15 (delta 0), reused 0 (delta 0)

Receiving objects: 100% (15/15), done.

[wangshibo@115 ~]$ cd ~/test-project1/

[wangshibo@115 ~]$ git config --global user.name 'wangshibo'

[wangshibo@115 ~]$ git config --global user.email '[email protected]'

[wangshibo@115 ~]$ touch testfile

[wangshibo@115 ~]$ git add testfile

[wangshibo@115 ~]$ git commit -m 'wangshibo add testfile'

[wangshibo@115 ~]$git push

GitLab: You are not allowed to push code to this project.

fatal: The remote end hung up unexpectedly
           

上面有報錯,因為普通使用者沒有直接push的權限。需要先review到gerrit上進行稽核并commit後,才能更新到代碼中心倉庫裡。

2)Gerrit配置

在linux伺服器上切換到gerrit賬号下生成公私鑰

[gerrit@115]$ ssh-keygen -t rsa -C [email protected]

将id_rsa.pub公鑰内容更新到gerrit上(管理者gerrit賬号登陸)的SSH Public Keys裡

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

同樣的,将gerrit的其他兩個普通賬号wangshibo和jenkins也在linux伺服器上生産公私鑰,郵箱分别是[email protected][email protected]

并将兩者的公鑰id_rsa.pub内容分别更新到各自登陸的gerrit的SSH Public Keys裡

3)Jenkins配置

Jenkins系統已經建立了管理者賬戶jenkins并安裝了Gerrit Trigger插件和Git plugin插件

在“系統管理”->“插件管理"->”可選插件"->搜尋上面兩個插件進行安裝

使用jenkins賬号登陸jenkins,進行Jenkins系統的SMTP設定 (根據具體情況配置)

“首頁面->系統管理->系統設定”,具體設定如下:

首先管理者郵件位址設定成[email protected]

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

設定SMTP的伺服器位址,點選“進階”

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

[email protected]的密碼要确認填對,然後測試郵件發送功能,如果如下出現successfully,就成功了!點選“儲存”

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

接下來設定Gerrit Trigger

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

Add New Server : Check4Gerrit

勾選 Gerrit Server With Default Configurations

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

具體設定如下:

設定好之後,點選“Test Connection”,如果測試連接配接出現如下的Success,即表示連接配接成功!

點選左下方的Save儲存。

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

-----------------------------------------------------------------------------------------

如果上一步在點選“Test Connection”測試的時候,出現下面報錯:

解決辦法:

管理者登入gerrit

Projects->List->All-Projects

Projects->Access

Global Capabilities->Stream Events 點選 Non-Interactive Users

添加 [email protected] 使用者到 ‘Non-Interactive Users’ 組

-----------------------------------------------------------------------------------------

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

4)Gerrit 和 Jenkins 整合

讓Gerrit支援Jenkins

如果安裝Gerrit時沒有或者沒有選擇添加Verified标簽功能[‘lable Verified’],需要自己添加。

如下是手動添加Verified标簽功能的設定(由于我在安裝Gerrit的時候已經選擇安裝Verified标簽功能了,是以下面橙色字型安裝操作可省略)

[如果在安裝gerrit的時候沒有選擇安裝這個标簽功能,就需要在此處手動安裝下。具體可以登陸gerrit,ProjectS->list->All-Projects->Access->Edit->Add Permission 看裡面是否有Verfied的選項]

# su - gerrit

$ git init cfg; cd cfg

$ git config --global user.name 'gerrit'

$ git config --global user.email '[email protected]'

$ git remote add origin ssh://[email protected]:29418/All-Projects

$ git pull origin refs/meta/config

$ vim project.config

[label "Verified"]

    function = MaxWithBlock

    value = -1 Fails

    value = 0 No score

    value = +1 Verified

$ git commit -a -m 'Updated permissions'

$ git push origin HEAD:refs/meta/config

$ rm -rf cfg
           

用gerrit管理者賬号登入Gerrit

現在送出的Review請求隻有Code Rivew稽核,我們要求的是需要Jenkins的Verified和Code Review雙重保障,在 Projects 的 Access 欄裡,針對 Reference: refs/heads/ 項添加 Verified 功能,如下如下:

Projects -> List -> All-Projects

Projects -> Access -> Edit -> 找到 Reference: refs/heads/* 項 -> Add Permission -> Label Verified -> Group Name 裡輸入 Non-Interactive Users -> 回車 或者 點選Add 按鈕 -> 在最下面點選 Save Changes 儲存更改。

(注意:提前把jenkins使用者添加到Non-Interactive Users組内)

權限修改結果如下:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

截圖如下:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

添加Verified後的權限如下

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

Gitlab上設定test-project1工程

前面我們在Gitlab上搭建了一個 test-project1 的工程,普通使用者是沒有辦法去 push 的,隻能使用 git review 指令送出. 而 git review 指令需要 .gitreview 檔案存在于項目目錄裡。

用 gerrit使用者添加.gitreview 檔案

[root@115]# su - gerrit

[gerrit@115]$ git clone [email protected]:dev-group/test-project1.git

[gerrit@115]$ cd test-project1

[gerrit@115]$ vim .gitreview
           

1

2

3

4

[gerrit]

host=103.10.86.30

port=29418

project= test -project1.git

添加.gitreview到版本庫

[gerrit@115]$git add .gitreview

[gerrit@115]$git config --global user.name 'gerrit'

[gerrit@115]$git config --global user.email '[email protected]'

[gerrit@115]$git commit .gitreview -m 'add .gitreview file by gerrit.'

[gerrit@115]$git push origin master
           

用gerrit使用者添加.testr.conf 檔案

Python 代碼我使用了 testr,需要先安裝 testr 指令

[root@115]# easy_install pip

[root@115]# pip install testrepository
           

在 test-project1 這個項目中添加 .testr.conf 檔案

[root@115]#su - gerrit

[gerrit@115]$cd test-project1

[gerrit@115]$vim .testr.conf
           

1

2

3

4

5

6

7

[DEFAULT]

test_command=OS_STDOUT_CAPTURE=1

OS_STDERR_CAPTURE=1

OS_TEST_TIMEOUT=60

${PYTHON:-python} -m subunit.run discover -t ./ ./ $LISTOPT $IDOPTION

test_id_option=--load-list $IDFILE

test_list_option=-list

送出到版本庫中

[gerrit@115]$git add .testr.conf

[gerrit@115]$git commit .testr.conf -m 'add .testr.conf file by gerrit'

[gerrit@115]$git push origin master
           

Gerrit上設定 test-project1工程

在Gerrit上建立 test-project1 項目

要知道review是在gerrit上,而gerrit上現在是沒有項目的,想讓gitlab上的項目能在gerrit上review的話,必須在gerrit上建立相同的項目,并有相同的倉庫檔案.

用gerrit使用者在 Gerrit 上建立 test-project1 項目

[root@115]# su - gerrit

[gerrit@115]$ ssh-gerrit gerrit create-project test-project1 (gerrit環境部署篇裡已經設定好的别名,友善連接配接gerrit)

登陸gerrit界面,發現test-project1工程已經建立了。(這種方式建立的項目是空的)

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

clone --bare Gitlab上的倉庫到 Gerrit (gerrit上的項目最好是從gitlab上git clone --bare過來,并且項目不要為空)

因為gerrit使用者無通路gitlab的權限。是以要先看是否gerrit使用者下已經存在了id_rsa密鑰,如果沒有則建立,然後把公鑰加入到gitlab的管理者賬戶上(因為後面Gerrit系統還會有個複制git庫到 Gitlab的功能需要管理者權限)(這個測試環境,gitlab和gerrit的管理者我用的都是gerrit,是以秘鑰也是共用)

[gerrit@115]$ cd /home/gerrit/gerrit_site/git/ //即登陸到gerrit安裝目錄的git下

[gerrit@115 git]$ rm -fr test-project1.git

[gerrit@115 git]$ git clone --bare [email protected]:dev-group/test-project1.git //建立并将遠端gitlab上的這個項目内容釋出到gerrit上

[gerrit@115 git]$ ls

All-Projects.git test-project1.git

[gerrit@115 git]$ cd test-project1.git/

[gerrit@115 git]$ ls                                 //即test-project1工程和gerrit裡預設的All-Projects.git工程結構是一樣的了

branches config description HEAD hooks info objects packed-refs refs
           

同步 Gerrit的test-project1 項目到 Gitlab 上的 test-project1 項目目錄中

當使用者git review後,代碼通過 jenkins 測試、人工 review 後,代碼隻是 merge 到了 Gerrit 的 test-project1 項目中,并沒有 merge 到 Gitlab 的 test-project1 項目中,是以需要當 Gerrit test-project1 項目倉庫有變化時自動同步到 Gitlab 的 test-project1 項目倉庫中。

Gerrit 自帶一個 Replication 功能,同時我們在安裝 Gerrit 時候預設安裝了這個 Plugin。

現在隻需要添加一個 replication.config 給 Gerrit

[gerrit@115]$ cd /home/gerrit/gerrit_site/etc/

[gerrit@115]$ vim replication.config
           

1

2

3

4

5

6

7

[remote "test-project1" ]

projects = test -project1

url = [email protected]:dev-group /test-project1 .git

push = +refs /heads/ *:refs /heads/ *

push = +refs /tags/ *:refs /tags/ *

push = +refs /changes/ *:refs /changes/ *

threads = 3

設定gerrit使用者的 ~/.ssh/config

[gerrit@115]$ vim /home/gerrit/.ssh/config

1

2

3

Host 103.10.86.30:

IdentityFile ~/. ssh /id_rsa

PreferredAuthentications publickey

在gerrit使用者的~/.ssh/known_hosts 中,給103.10.86.30 添加 rsa 密鑰

[gerrit@115]$ sh -c "ssh-keyscan -t rsa 103.10.86.30 >> /home/gerrit/.ssh/known_hosts"

[gerrit@115]$ sh -c "ssh-keygen -H -f /home/gerrit/.ssh/known_hosts"

----------------------------------------------特别注意----------------------------------------------

上面設定的~/.ssh/config檔案的權限已定要設定成600

不然會報錯:“Bad owner or permissions on .ssh/config“

----------------------------------------------------------------------------------------------------

重新啟動 Gerrit 服務

[gerrit@115]$/home/gerrit/gerrit_site/bin/gerrit.sh restart

Gerrit 的複制功能配置完畢

在 gerrit 文檔中有一個 ${name} 變量用來複制 Gerrit 的所有項目,這裡并不需要。如果有多個項目需要複制,則在 replication.config 中添加多個 [remote ….] 字段即可。務必按照上面步驟配置複制功能。

在 Jenkins 上對 test-project1 項目建立建構任務

Jenkins上首先安裝git插件:Git Plugin

登陸jenkins,“系統管理”->“管理插件”->“可選插件”->選擇Git Pluin插件進行安裝

Jenkins上建立項目

添加 test-project1工程

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

下面添加url:http://103.10.86.30:8080/p/test-project1.git

添加分支:origin/$GERRIT_BRANCH

如下:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

建構Excute Shell,添加如下腳本

cd $WORKSPACE

[ ! -e .testrepository ] && testr init

testr run

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

測試

linux系統上用wangshibo賬号送出一個更改

用wangshibo登入

删除目錄 test-project1

克隆 test-project1 工程

進入 test-project1 目錄

添加檔案、送出

git review 增加 review 到Gerrit

[root@115]# su - wangshibo




[wangshibo@115]$ rm -rf test-project1/

[wangshibo@115]$ git clone [email protected]:dev-group/test-project1.git

[wangshibo@115]$ cd test-project1/

[wangshibo@115]$ touch testfile

[wangshibo@115]$ git add testfile

[wangshibo@115]$ git commit -m "wangshibo add this testfile"
           
[wangshibo@115]$ git review                         //送出review代碼稽核請求

The authenticity of host '[103.10.86.30]:29418 ([103.10.86.30]:29418)' can't be established.

RSA key fingerprint is 83:ff:31:e8:68:66:6d:49:29:08:91:aa:ef:36:77:3e.

Are you sure you want to continue connecting (yes/no)? yes

Creating a git remote called "gerrit" that maps to:

ssh://[email protected]:29418/test-project1.git

Your change was committed before the commit hook was installed

Amending the commit to add a gerrit change id

remote: Resolving deltas: 100% (1/1)

remote: Processing changes: new: 1, refs: 1, done

To ssh://[email protected]:29418/test-project1.git

* [new branch] HEAD -> refs/publish/master
           

----------------------------------------小提示----------------------------------------

安裝git-review

[root@115]# git clone git://github.com/facebook/git-review.git

[root@115]# cd git-review

[root@115]# python setup.py install

[root@115]# pip install git-review==1.21

[root@115]# yum install readline-devel
           

--------------------------------------------------------------------------------------

代碼稽核處理

用gerrit管理者賬号登入 Gerrit ,點選"All“->”Open“-> 打開送出的review

打開後就能看見jenkins使用者已經Verified【原因下面會提到】。

然後點選Review進行稽核

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

由于上面已經配置了gerrit跟jenkins的對接工作,是以當git review指令一執行,jenkins上的test-project1工程的測試任務就會自動觸發

如下:如果任務自動執行成功了,就說明jenkins測試通過,然後jenkins會利用ssh連接配接gerrit并給送出的subject打上verified資訊校驗結果,然後稽核人員再進行review。

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

是以用gerrit管理者登陸後發現,jenkins已經通過了Verified。然後進入subject,先檢視代碼/檔案變更,然後點選Reply,寫一點review後的意見之類的,然後評分(+2通過,-2拒絕,+1投贊成票,-1投反對票),然後點選post。

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

注意:

等到jenkins上Verified通過後,即看到下圖右下角出現“Verified +1 jenkins"後

才能點選"Code-Review+2",如下:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

然後點選“Submit",送出稽核過的代碼

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

再次檢視,review請求已被稽核處理,并且已經Merged合并了!

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

最後登入 Gitlab檢視 test-project1 工程,可以看到新增加檔案操作已經同步過來了

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

注意:在稽核人員進行review和submit操作前,要先等到jenkins測試并通過ssh方式連上gerrit給相應送出稽核的subjects帶上Verified通過後才能進行。(gitlab+gerrit+jenkins環境配置後,送出到gerrit上稽核的subjects的review人員中會預設第一個是jenkins,jenkins有結果并verified後,其他人員才能veriew和submit。也就是說當開發人員使用git review上報gerrit進行code review後,jenkins會自動觸發測試任務,通過後會在gerrit的subject稽核界面顯示verified結果,當顯示的結果是“verified +1 jenkins“後就可以進行Review和submit了,最後同步到gitlab中心倉庫。)

檢視同步日志:

可以在gerrit伺服器上檢視replication日志:

[gerrit@115 logs]$ pwd

/home/gerrit/gerrit_site/logs

[gerrit@115 logs]$ cat replication_log
           

.........................

[2016-07-14 15:30:13,043] [237da7bf] Replication to [email protected]:dev-group/test-project1.git completed in 1288 ms

[2016-07-14 15:32:29,358] [] scheduling replication test-project1:refs/heads/master => [email protected]:dev-group/test-project1.git

[2016-07-14 15:32:29,360] [] scheduled test-project1:refs/heads/master => [03b983c0] push [email protected]:dev-group/test-project1.git to run after 15s

[2016-07-14 15:32:44,360] [03b983c0] Replication to [email protected]:dev-group/test-project1.git started...

[2016-07-14 15:32:44,363] [03b983c0] Push to [email protected]:dev-group/test-project1.git references: [RemoteRefUpdate[remoteName=refs/heads/master, NOT_ATTEMPTED, (null)...dda55b52b5e5f78e2332ea2ffcb7317120347baa, srcRef=refs/heads/master, forceUpdate, message=null]]

[2016-07-14 15:32:48,019] [03b983c0] Replication to [email protected]:dev-group/test-project1.git completed in 3658 ms

----------------------------------------------------------------------------------------------------

關于jenkins上的結果:

如上,在伺服器上wangshibo賬号下

git review指令一執行,即代碼稽核隻要一提出,Jenkins 就會自動擷取送出資訊并判斷是否verified

如下,當jenkins上之前建立的工程test-project1執行成功後,那麼jenkins對送出到gerrit上的review請求

就會自動執行Verified(如上)

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

----------------------------------------------注意----------------------------------------------

有個發現:

jenkins上測試并傳回給gerrit上送出的subject打上Verified資訊核實通過的标簽後,會将代碼拿到自己本地相應工程的workspace目錄下

這裡的jenkins代碼路徑是:/usr/local/tomcat7/webapps/jenkins/workspace/test-project1

不過值得注意的是,jenkins拿過來的代碼隻是每次git review修改前的代碼狀态

可以把這個當做每次代碼修改送出前的備份狀态

即:代碼修改後,在gerrit裡面稽核,commit後同步到gitlab,修改前的代碼狀态存放在jenkins裡面

-----------------------------------------------------------------------------------------------

手動安裝gerrit插件

[gerrit@115r ~]$ pwd

/home/gerrit

[gerrit@115r ~]$ ls

gerrit-2.11.3.war gerrit_site
           

進行插件安裝,下面安裝了四個插件

[gerrit@115r ~]$ java -jar gerrit-2.11.3.war init -d gerrit_site --batch --install-plugin replication

Initialized /home/gerrit/gerrit_site

[gerrit@115r ~]$ java -jar gerrit-2.11.3.war init -d gerrit_site --batch --install-plugin reviewnotes

Initialized /home/gerrit/gerrit_site

[gerrit@115r ~]$ java -jar gerrit-2.11.3.war init -d gerrit_site --batch --install-plugin commit-message-length-validator

Initialized /home/gerrit/gerrit_site

[gerrit@115r ~]$ java -jar gerrit-2.11.3.war init -d gerrit_site --batch --install-plugin download-commands

Initialized /home/gerrit/gerrit_site
           

檢視plugins目錄,發現已經有插件了

[gerrit@115r ~]$ cd gerrit_site/plugins/

[gerrit@115r ~]$ ls

commit-message-length-validator.jar download-commands.jar replication.jar 
           

檢視安裝了哪些插件

[gerrit@115r ~]$ ssh-gerrit gerrit plugin ls

Name Version Status File

-------------------------------------------------------------------------------

commit-message-length-validator v2.11.3 ENABLED commit-message-length-validator.jar

download-commands v2.11.3 ENABLED download-commands.jar

replication v2.11.3 ENABLED replication.jar

reviewnotes v2.11.3 ENABLED reviewnotes.jar

或者登陸gerrit也可檢視

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

------------------------------------------------注意------------------------------------------------

gerrit手動同步代碼到gitlab中心倉庫上

[gerrit@115r ~]$ ssh-gerrit gerrit --help          //檢視幫助,發現gerrit COMMAND --help可查找指令幫忙

[gerrit@115r ~]$ ssh-gerrit replication start --help          //檢視replication同步指令的用法




replication start [PATTERN ...] [--] [--all] [--help (-h)] [--url PATTERN] [--wait]




PATTERN : project name pattern




-- : end of options

--all : push all known projects

--help (-h) : display this help text

--url PATTERN : pattern to match URL on

--wait : wait for replication to finish before exiting







[gerrit@115r ~]$ ssh-gerrit replication start --all                    //同步所有工程
           

-------------------------------------------------------------------------------------------------------

重載replication的同步服務

[gerrit@115r ~]$ ssh-gerrit gerrit plugin reload replication

如果報錯:fatal: remote plugin administration is disabled

解決辦法:

在/home/gerrit/gerrit_site/etc/gerrit.config檔案裡添加下面内容:

[plugins]

allowRemoteAdmin = true

然後重新開機gerrit服務即可:

[gerrit@115r ~]$ /home/gerrit/gerrit_site/bin/gerrit.sh restart

Stopping Gerrit Code Review: OK

Starting Gerrit Code Review: OK

----------------------------------------------------------------------

ssh-gerrit是别名

[gerrit@115r ~]$ cat ~/.bashrc

# .bashrc

# Source global definitions

if [ -f /etc/bashrc ]; then

. /etc/bashrc

fi

alias ssh-gerrit='ssh -p 29418 -i ~/.ssh/id_rsa 103.10.86.30 -l gerrit'

# User specific aliases and functions

-------------------------------------------------------------------------------------------

多個工程在Gitlab上可以放在不同的group下進行管理

如下面兩個工程(多個工程,就在後面追加配置就行)

dev-group /test-project1

app/xqsj_android

多個工程的replication

[gerrit@Zabbix-server etc]$ cat replication.config

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

[remote "test-project1" ]

projects = test -project1

url = [email protected]:dev-group /test-project1 .git

push = +refs /heads/ *:refs /heads/ *

push = +refs /tags/ *:refs /tags/ *

push = +refs /changes/ *:refs /changes/ *

threads = 3

[remote "xqsj_android" ]

projects = xqsj_android

url = [email protected]:app /xqsj_android .git

push = +refs /heads/ *:refs /heads/ *

push = +refs /tags/ *:refs /tags/ *

push = +refs /changes/ *:refs /changes/ *

threads = 3

然後在每個代碼庫裡添加.gitreview和.testr.conf 檔案,

注意.gitreview檔案裡的項目名稱

按照上面同步配置後,Gerrit裡面的代碼就會自動同步到Gitlab上,包括master分支和其他分支都會自動同步的。

如果,自動同步失效或者有問題的話,可以嘗試手動同步(下面有提到)

另外:為了減少錯誤,建議在配置的時候,gitlab和gerrit裡的賬号設定成一樣的,共用賬号/郵箱/公鑰

gerrit預設的兩個project:All-Project和All-Users絕不能删除!!

--------------------------------------------去掉jenkins測試的方式---------------------------------------------

如果gerrit不跟jenkins結合,不通過jenkins測試并傳回verified核實的方式,可以采用下面的代碼稽核流程(必須先對送出的稽核資訊進行verified核實,然後再進行代碼的review稽核,最後submit送出):

[去掉上面gerrit和jenkins對接設定,即關閉jenkins服務(關停對應的tomcat應用),gerrit的access授權項verified裡删除“Group Non-Interactive Users”(在這個組内踢出jenkins使用者),并删除gerrit上的jenkins使用者]

1)上傳代碼者(自己先verified核實,然後通知稽核者稽核)

修改代碼,驗證後送出到 Gerrit 上。

代碼送出後登陸 Gerrit,自己檢查代碼(重點看縮進格式跟原檔案是否一緻;去掉紅色空格部分;修改内容是否正确;命名是否有意義;注釋内容是否符合要求等)。

自己檢查沒問題後,點 “Reply”按鈕,在“Verified”中 +1,在“Code Review”中 +1,并點“Post“

在”Reviewer”欄中,點選”Add"添加稽核者 [如果不添加稽核者,上傳者自己也可以稽核并完成送出。注意:隻有Review是+2的時候,才能出現submit的送出按鈕]

如果代碼稽核沒有通過,請重複步驟1,2,3。

流程截圖:

代碼送出後,上傳者自行登陸gerrit,找到送出的subject,點選"Reply"

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

2)稽核者

收到郵件通知後登陸 Gerrit,稽核代碼。

如果稽核通過,點 “Reply”按鈕,在“Verified”中 +1,在“Code Review”中 +2,并點“Post”,最後點選“Submit“送出!

如果代碼稽核沒有通過,點 “Review”按鈕,在“Code Review”中 -2,寫好評論後,點“Post”。

流程截圖:

如上,subject的owner添加稽核者後,稽核者登陸gerrit進行review

點選“Reply"

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

這樣,就完成了一個代碼的稽核全部過程!

登陸gitlab,就會發現gerrit上稽核通過并送出後的代碼已經同步過來了!

注意:

如上的設定,在gerrit裡授權的時候:

Revified權限清單裡添加“Project Owners“(-1和+1)和稽核者組(-1和+1)

Review權限清單裡添加“Project Owners“和稽核者組(都要設定-2和+2)

附授權截圖:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

------------------------------------讓非管理者使用者也有gitweb通路權限--------------------------------------

發現在gerrit與gitweb內建後,預設情況下,隻有gerrit的管理者才有gitweb的通路權限,普通使用者點選gitweb連結顯示404錯誤。

最後發現使用gitweb需要有【refs/*】下所有的read權限和【refs/meta/config】的read權限!

預設情況下:

【refs/*】下的read權限授予對象是:Administrators和Anonymous Users(所有使用者都是匿名使用者,這個範圍很大,已預設包括所有使用者)

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

【refs/meta/config】的read權限授予對象是:Administrators和Project Owners

如想要比如上面的xqsh-app組内的使用者能正常通路gitweb,那麼就在【refs/meta/config】分支下授予這個組的Allow權限即可!!

截圖如下:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

使用普通使用者wangshibo(在xqsj-app組内)登陸gerrit,發現能打開xqsj_android項目的gitweb超連結通路了

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

---------------------------------------------------------------------------------------------------------

後續應開發人員的要求:Gitlab+gerrit+jenkins環境下,gerrit有幾個細節,都是需要設定好的:

1)項目A的開發人員對于除A以外的項目沒有通路權限;

2)每個開發人員應該有+2和submit,以及建立分支的權限;

3)給teamleader配置force push的權限;

設定方案:

第1個要求:

在gerrit裡面設定read權限,即"refs/*"下的"Read"權限。

先保持将All-Projects預設權限不變!

然後重新Edit項目A的權限去覆寫掉All-Projects繼承過來的這個權限(下面會提到)

如下截圖(前面的Exclusive一定要打勾,覆寫效果才能生效)

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

其實,開發人員是沒有必要開通gitlab賬号!隻要gerrit提前和gitlab做好同步對接工作,那麼直接設定好gerrit權限,開發人員可直接通過ssh方式登陸gerrit進行代碼操作(git clone代碼,然後修改,送出稽核,自動同步等)是以,隻需要給開發人員開通gerrit賬号即可!

<如下,通過ssh方式連接配接gerrit上的項目,進行git clone代碼或git pull操作等>

如下:

按照gerrit上的ssh連接配接方式clone項目代碼(前提是把本地伺服器的公鑰上傳到gerrit上)

可以複制下圖中的clone或clone with commit-msg hook位址在本地進行代碼clone

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

第2個要求:

a)在gerrit裡面設定,建立組比如xqsj-app,然後把這個組添加到gerrit界面相對應項目的”access“授權裡的“refs/heads/*”->Label Code-Review内,以及Submit内,這樣就保證每個開發人員有+2和submit權限

b)将上面建立的xqsh-app組添加到gerrit界面相對應項目的”access“授權裡的“refs/heads/*”->“Create Reference”内,這樣就能保證每個開發人員有建立分支的權限了。

第3個要求:

建立teamleader組,比如xqsj-app-teamleader,将這個組添加到A項目編輯的下面兩個權限裡,去覆寫從All-Projects繼承過來的權限!

“refs/heads/*”->"Push"

“refs/meta/config”->“Push”

這兩個地方地Push權限最好隻賦給Administrators管理者和teamleader組,這樣就保證了每個teamleader有force push的權限了。

(注意,勾上在後面的“force push”前的小框,如下截圖)

這樣,xqsj-app-teamleader組内的使用者通過ssh方式連接配接gerrit,git clone下載下傳代碼,修改後可直接git push了(不需要review稽核)

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

在這裡還講一下下面/refs/for/refs/*的兩個Push權限,這個All-Projects裡預設是賦予Registered Users注冊使用者的

那麼,在給項目新編輯權限去覆寫的時候,最好把權限賦予對象改成項目所在的組!

(如上面所說的,修改代碼push的中心倉庫的權限就隻關聯到上面兩個權限,跟這個無關)

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

如下:

将wangshibo使用者拉到xqsj-app-teamleader組内,上面已經設定了“Force Push”權限,是以wangshibo使用者連接配接gerrit

修改後的代碼可直接push了!然後同步到gitlab!

[wangshibo@115 ~]$ git clone ssh://[email protected]:29418/xqsj_android

Initialized empty Git repository in /home/wangshibo/www/xqsj_android/.git/

remote: Counting objects: 653, done

remote: Finding sources: 100% (653/653)

remote: Total 653 (delta 180), reused 653 (delta 180)

Receiving objects: 100% (653/653), 2.86 MiB, done.

Resolving deltas: 100% (180/180), done.

[wangshibo@Zabbix-server www]$ ls

xqsj_android

[wangshibo@115 ~]$ cd xqsj_android/

[wangshibo@115 ~]$ vim testfile                  //修改代碼

[wangshibo@115 ~]$ git add testfile

[wangshibo@115 ~]$ git commit -m "222"

[master 87a02b7] 222

1 files changed, 1 insertions(+), 0 deletions(-)

[wangshibo@115 ~]$ git push             //直接push即可!如果wangshibo不在teamleader組内,就不能直接push了,就隻能git review稽核了!

Counting objects: 5, done.

Delta compression using up to 32 threads.

Compressing objects: 100% (2/2), done.

Writing objects: 100% (3/3), 261 bytes, done.

Total 3 (delta 1), reused 0 (delta 0)

remote: Resolving deltas: 100% (1/1)

remote: Processing changes: refs: 1, done

To ssh://[email protected]:29418/xqsj_android

1840a0c..87a02b7 master -> master
           

這樣,一個項目的開發人員在修改代碼并送出gerrit後,就可以指定有相應權限的人員進行review和submit了。

另外注意:

修改gerrit上建立的group組名或增删等操作,可以直接在伺服器上的mysql裡面操作。

---------------------------------------------------特别注意-------------------------------------------------------

如果要想讓建立立的項目不繼承或不完全繼承All-Project項目權限,可以自己重新修改或添權重限,以便去覆寫掉不想繼承的權限!

這裡以我測試環境的一個項目xqsj_android做個例子說明:

首先在gerrit上建立一個組xqsj_android,将wangshibo普通使用者放到這個組内!

1)想要wangshibo登陸gerrit後,隻能通路它所在的項目xqsj_android

設定方法:

上面已講到,即将All-Projects的access裡的"refs/*"-"Read"權限隻給Administors(就隻保留管理者的這個read權限),這樣,project工程就隻有管理者權限才能通路到了!

<因為其他建立的項目預設都是繼承All-Projects權限的,設定上面的Read權限隻保留Administors後,其他的項目如果不Edit自己的權限去覆寫繼承過來的權限,那麼這些項目内的使用者登陸後,都通路不了這些項目的>

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

然後再在xqsj_android項目上建立Reference權限,去覆寫繼承過來的All-Project權限!

特别注意下面的“Exclusive”,這個一定要勾上!!勾上了才能生效,才能覆寫All-Project項目的權限。

截圖如下:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

如上截圖,發現“refs/*”的“Read”權限除給了管理者Administrators,也添加了xqsj_android組,由于wangshibo在這個組内,

是以wangshibo登陸gerrit後,有通路xqsj_android項目的權限。

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

注意:

All-Projects預設的權限最好都保持不變,不要動!

建立項目有的權限可以自行Edit編輯,然後去覆寫All-Projects繼承過來的權限(建立的Reference時,後面的Exclusive一定要在前面的小方框内打上勾,這樣覆寫才能生效!)

下面貼一下本人線上的gerrit項目修改後的權限:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

------------------------------------------------------------------------------------------------------

git clone下載下傳代碼,可以根據gitlab上的ssh方式克隆,也可以根據gerrit上的ssh方式克隆代碼。

具體采用哪種,根據自己的需要判斷。

注意:當稽核未通過打回時,我們再修改完成之後,執行:

git add 檔案名

git commit --amend ##注意會保留上次的 change-id ,不會生成新的評審任務編号,重用原有的任務編号,将該送出轉換為老評審任務的新更新檔集

git review

-------------------------------------------------------------------------------------------------------

如果想讓某個使用者隻有讀權限,沒有寫權限。即登陸gerrit後隻能檢視,不能進行下載下傳,上傳送出等操作

解決:

1)建立一個read的使用者組,然後将這個隻讀使用者拉到這個read組内

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

2)在相應項目的access授權裡添加這個使用者組,如下,隻需添加下面兩個地方的Read部分即可:

其中,“refs/meta/config”裡的Read授權,可以讓使用者檢視到gitlab

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

----------------------------------------------添加tag權限----------------------------------------------

如上,已經給teamleader使用者組内的使用者授權直接push了,但是後面發現teamleader裡的使用者隻能直接push推送代碼到gerrit裡,

而不能直接push推送tag标簽到gerrit裡!

這是因為上面的push權限是針對“refs/heads/*”和“refs/meta/config”設定的

而push tag需要針對“refs/tags/*”進行設定

是以,需要添加refs/tags/*部分的設定,并給與push權限,如下:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

--------------------------------------------------------------------------------------------------------------

gerrit完整遷移

将遠端gerrit上的代碼遷移到本地新的gerrit上

要求:

遠端gerrit裡的代碼分支和送出記錄都要遷移過來,【即Git倉庫遷移而不丢失log】(push的時候使用--mirrot鏡像方式即可)

流程:

1)将遠端gerrit的項目比如A進行git clone –bare克隆裸版本庫到本地

2)在本地新的gerrit上建立同名項目A(建立空倉庫)

3)然後将克隆過來的A項目内容git push --mirror到本地新gerrit上的項目A内

git push --mirror [email protected]/username/newproject.git (新gerrit上項目A的通路位址)

這種方式就能保證分支和送出記錄都能完整遷移過來了!!!

----------------------------------------------------------------------------------------------------------

後續對項目代碼進行操作,在登陸gerrit稽核後,檢視代碼(對比代碼送出前後的内容)時候出現了一個錯誤,具體如下:

其實代碼review通過并submit後,檢視代碼有兩種方式:

1)通過項目的gitweb檢視。當然,這種方法檢視也比較繁瑣,沒有下面的第(2)種方法檢視起來友善

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

2)通過submit送出後的界面(也就是merged合并後的界面),如下點選紅色方框内的稽核代碼進行檢視:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

但是點選上面紅色方框内的稽核代碼進行檢視,出現如下報錯:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

經過排查,發現造成這個報錯的原因是由于nginx的反代配置有誤造成的 ,如下:

proxy_pass http://103.10.86.30:8080/;

需要将上面的反向代理改為:

proxy_pass http://103.10.86.30:8080;

也就是說代理後的url後面不能加"/",這個細節在前期配置的時候沒有注意啊!!

gerrit.conf最後完整配置如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

[root@localhost vhosts] # pwd

/usr/local/nginx/conf/vhosts

[root@localhost vhosts] # cat gerrit.conf

server {

listen 80;

server_name localhost;

#charset koi8-r;

#access_log /var/log/nginx/log/host.access.log main;

location / {

auth_basic "Gerrit Code Review" ;

auth_basic_user_file /home/gerrit/gerrit_site/etc/passwords ;

proxy_pass http: //103 .10.86.30:8080;

proxy_set_header X-Forwarded-For $remote_addr;

proxy_set_header Host $host;

}

}

[root@localhost vhosts] # /usr/local/nginx/sbin/nginx -s reload

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

對比代碼在review前後的狀态:修改了哪些内容(右邊部分是review修改後的代碼狀态。點選右邊"Patch Set 1"後面的圖示,可以下載下傳或修改代碼)

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

-------------------------------------------------------------------------------------------------------------

以上部署環境中,有一個不安全的地方,就是使用者送出代碼後,自己對代碼都有review最終稽核權限,即"使用者自己review送出稽核-自己+1/+2稽核-自己submit",這樣設計不是很合理!

現在做下調整:

使用者自己review送出代碼後,自己隻有Code-Review +2的權限和Submit,Verfied +1的權限統一交由專門的稽核人員去處理,比如teamleader組。

這樣,代碼稽核的過程:

1)使用者自己review送出代碼稽核

2)teamleader組内人員收到稽核後,通過Verfied +1稽核

3) 使用者自己通過Code-Review +2稽核

4)使用者自己Submit送出,Merged合并處理。

具體的權限設定調整如下:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

----------------------------------------------------------------------------------------------------------------------------------

有一個問題:

如果給某個賬号開了push權限,他在代碼commit送出後,就可以直接git push上傳到gerrit裡面,可以不經過git review稽核送出的代碼。如下授權截圖:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

但是這樣直接git push的話,在gerrit界面的Merged處就追蹤不到這個賬号送出代碼的記錄了,也就是說,隻有經過review稽核送出的代碼記錄才能在gerrit界面的Merged下追蹤到!如下:

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

如上所說,那麼直接push送出代碼的記錄該怎麼追蹤到呢?

莫慌!

其實不管是push直接送出代碼的記錄,還是經過review稽核送出的代碼記錄,都可以在gitweb的log裡追蹤到的!

CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接
CI持續內建系統環境--Gitlab+Gerrit+Jenkins完整對接

雖然授權了push權限,但是也還是可以使用git review指令進行稽核的,這樣在gerrit界面的Merged裡也能追蹤到送出記錄了。

如果是直接git push的,那麼送出代碼的時候就會直接繞過review稽核了,這樣當然不會在gerrit的Merged裡留有記錄。

----------------------------------------------------------------------------------------------------------------------------------

到此!

gerrit環境部署及其中遇到的一些問題,權限設定等已經收錄完成,希望對有用到gerrit的朋友們有所幫助!!

繼續閱讀