Ubuntu + Gerrit + Apache 搭建代码审核服务器

我们公司采用Gerrit作为代码审核服务器并结合JIRA、Jenkins等开源工具,组成了一个完整项目管理平台。某天,我兴致来了,也想在自己的服务器上搭建一个Gerrit。于是,便有了以下内容...

一、Gerrit介绍

Gerrit的目的是提供一个轻量级的框架来review每一个commit,review通过之后,commit会被合入代码库。

Gerrit是一个中间区域,可以看到提交至Gerrit上的代码相对于服务器代码仓库中代码的差异,从而便于检查代码的改动。Gerrit也是整个代码review的推动者。

任何拥有多个成员的团队都应该有一个中央代码仓库。 Git在理论上可以在没有这样的中心位置的情况下工作,但实际上通常有一个中央仓库库作为项目实际内容的权威副本。 开发者从该中央仓库fetch和push

Gerrit被部署在上图的中央仓库的位置,并增加一个新的概念:a store of pending changes(未决的修改)。每个人仍然可以从中央仓库fetch,但是push操作则有所变化,push操作会直接push到中央仓库,而是push到了pending changes location,以供review。只有在commit通过了review之后,才会被submit到中央仓库。如下图所示。

Gerrit具有强大的访问控制模型。用户可以被授予访问权限,绕过review,直接推送到中央仓库。Gerrit甚至可以在没有代码review的情况下使用,只用于托管仓库和访问控制。

二、应用场景

在安装gerrit之前,我使用node在服务器上部署了一个站点,也就是本博客,其占用了80端口。

在安装gerrit之后,我的服务器又将多出一个站点,用户该如何访问?我又该如何部署呢?这时候,我们就需要了解一下反向代理端口转发了。

1. 正向代理与反向代理

如下所示为正向代理和反向代理的示意图。一般来说,我们会把正向代理是与客户端划为一体,把反向代理和服务器划为一体。

此时,重新思考一下我们的应用场景:博客是一个web服务器,gerrit是一个web服务器,apache作为反向代理,这样就可以满足我们的需求了。

那么反向代理到底是如何做到的呢?答案就是端口转发

我们知道在浏览器输入网址后,它会在解析后的IP地址之后加上一个默认的端口号80。所以,我们访问chuquan.me时就不需要输入完整的地址chuquan.me:80了。正因为如此,绝大多数服务器软件(包括apache)的默认监听端口也是80

在安装了apache之后,80端口被apache占用了。因此,gerrit和博客都不能使用80端口了。这时候,我们需要给这两个站点配置使用其他的端口号,如:gerrit的HTTP协议使用8081端口,博客使用8082端口。它们与apache之间使用端口转发来实现反向代理

三、开发环境

  • Ubuntu 14.04.5 LTS
  • Java 1.8.0_151
  • Git 1.9.1
  • Apache/2.4.7

四、安装Gerrit

1. 新建专用用户

新建一个用户来专门管理Gerrit相关内容。在root用户下新建一个gerrit用户。

1
2
$ adduser gerrit
$ su gerrit

2. 下载Gerrit安装包

Gerrit下载地址:https://www.gerritcodereview.com/releases/2.14.md

我安装的Gerrit版本是2.14.6。在Linux环境下使用wget进行下载,最终得到一个war包,位于/home/gerrit/目录下。

1
$ wget https://gerrit-releases.storage.googleapis.com/gerrit-2.14.6.war

3. 安装Gerrit

/home/gerrit/目录下,进行安装:

1
$ java -jar gerrit-2.14.6.war init -d review_site
上述命令会在当前目录下创建一个review_site目录。接下来就开始进行对话式安装,我们可以直接回车,表示采用默认安装选项。之后还可以通过配置文件进行详细配置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
*** Gerrit Code Review 2.14.6
***
*** Git Repositories
***
Location of Git repositories [git]:
*** SQL Database
***
Database server type [h2]:
*** User Authentication
***
Authentication method [OPENID/?]: http
Get username from custom HTTP header [y/N]?
SSO logout URL :
*** Email Delivery
***
SMTP server hostname [localhost]:
SMTP server port [(default)]:
SMTP encryption [NONE/?]:
SMTP username :
*** Container Process
***
Run as [gerrit]:
Java runtime [/usr/lib/jvm/java-7-openjdk-amd64/jre]:
Copy gerrit-2.13.4.war to /home/gerrit/review/bin/gerrit.war [Y/n]?
Copying gerrit-2.13.4.war to /home/gerrit/review/bin/gerrit.war
*** SSH Daemon
***
Listen on address [*]:
Listen on port [29418]:
*** HTTP Daemon
***
Behind reverse proxy [y/N]?
Proxy uses SSL (https://) [y/N]?
Subdirectory on proxy server [/]:
Listen on address [*]:
Listen on port [8080]:
*** Plugins
***
Installing plugins.
Install plugin download-commands version v2.11 [y/N]?
Install plugin reviewnotes version v2.11 [y/N]?
Install plugin singleusergroup version v2.11 [y/N]?
Install plugin replication version v2.11 [y/N]?
Install plugin commit-message-length-validator version v2.11 [y/N]?
Initializing plugins.
No plugins found with init steps.
Initialized /home/gerrit/review_site
...
安装完毕,Gerrit会自动启动,不过我们大概率会启动失败,因为默认的配置并不一定与你当前的环境相匹配。不过,没关系,我们可以根据系统环境对gerrit进行配置。

4. Gerrit配置

Gerrit安装完成后,会在review_site目录下生成多个目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ ll review_site
./
../
bin/
cache/
data/
db/
etc/
git/
index/
lib/
logs/
plugins/
static/
tmp/
其中etc/目录下存放着gerrit的配置文件gerrit.config,其中已有的内容是根据安装时的选择生成的。我们可以编辑gerrit.config来进行配置更改。其中115.28.168.118是服务器的公网IP地址。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[gerrit]
basePath = git
serverId = 084efaf9-3bf6-401c-a4b1-8778c998bde2
canonicalWebUrl = http://115.28.168.118 # 指定web访问Gerrit的网址或IP地址
[database]
type = h2
database = /home/gerrit/review_site/db/ReviewDB
[index]
type = LUCENE
[auth]
type = HTTP # 默认是OPENID,改成HTTP后,才能通过浏览器进行访问
[receive]
enableSignedPush = true
[sendemail]
smtpServer = localhost
[container]
user = gerrit
javaHome = /usr/lib/jvm/java-8-oracle/jre
[sshd]
listenAddress = *:29418
[httpd]
listenUrl = proxy-http://115.28.168.118:8081/ # HTTP代理地址及端口,这里我们配置成8081
[cache]
directory = cache

四、配置Apache

不同系统以及不同版本的Apache的配置文件可能会不一样,无外乎两种:httpd.confapache2.conf。本环境的配置文件是apache2.conf

1
2
$ cd /etc/apache2/
$ vim apache2.conf
在配置文件的末尾添加apache的端口转发配置。如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
...
# Blog相关配置
<VirtualHost *:80>
ServerName www.chuquan.me # 用于Apache过滤检测的域名
ServerAlias chuquan.me
ProxyPass / http://115.28.168.118:8082/ # Blog正向代理转发的端口
ProxyPassReverse / http://localhost:8082/ # Blog反向代理转发的端口
</VirtualHost>
# Gerrit相关配置
<VirtualHost *:80>
ServerName gerrit.chuquan.me # 用户Apache过滤检测的域名
ProxyRequests Off
ProxyVia Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
<Location /login/>
AuthType Basic
AuthName "Gerrit Code Review"
Require valid-user
AuthBasicProvider file
AuthUserFile /home/gerrit/review_site/etc/passwords
</Location>
AllowEncodedSlashes On
ProxyPass / http://115.28.168.118:8081/ # Gerrit正向代理转发的端口
ProxyPassReverse / http://115.28.168.118:8081/ # Gerrit反向代理转发端口,应该与ProxyPass一致
</VirtualHost>

五、服务重启

Apache和Gerrit配置(当然也包括blog的端口)完之后,我们需要重启服务,包括apache、gerrit,其重启命令分别如下:

1
$ /etc/init.d/apache2 restart 
1
2
$ cd /home/gerrit/
$ ./bin/gerrit.sh restart

1. Gerrit启动失败

在执行重启Gerrit的命令后,shell很可能会出现如下的信息:

1
Starting Gerrit Code Review: FAILED

我在安装过程中页出现了这个问题,于是,我通过在./bin/gerrit.sh脚本中的首行添加了一个-x选项,以打印脚本执行的相关信息。

1
2
#!/bin/sh -x
...
然后再执行该脚本,发现打印信息是一组循环信息。其中,当TIMEOUT的值递减至0时,启动失败。

经过调研发现:
> Gerrit启动慢是因为java程序启动慢,导致Gerrit启动非常慢,大概需要10分钟左右,而默认的超时时间(TIMEOUT)是90秒,导致一直提示“Starting Gerrit Code Review: FAILEDStarting Gerrit Code Review: FAILED”。对此有如下两种解决方案。

第一种解决方案是:修改java的java.security文件。首先,根据gerrit.config中配置javaHome = /user/lib/jvm/java-8-oracle/jre,找到并进入该目录,然后再进入lib/security/目录,修改java.security文件。将securerandom.source=file:/dev/random改为securerandom.source=file:/dev/urandom。由此,解决gerrit启动慢的问题。

第二种解决方案是:在gerrit.conf文件中的[container]字段下增加`startupTimeout = 900。

2. 反向代理异常

当我们配置结束并重启之后,在浏览器中访问很有可能会得到如下的页面:

这个页面在安装过程中,出现次数不下于10次。主要是两种情况,一种是Gerrit配置文件和Apache配置文件可能配置有误。另一种情况是配置没有生效,需要多试试重启。

3. 创建第一个Gerrit账户

当所有问题解决完之后,通过浏览器访问Gerrit,将不会出现上面的Error界面,而是会弹出输入对话框,需要你填写账户和密码。

这时候,我们需要为Gerrit创建一个账户,默认第一个创建的账户是管理员。

1
2
3
4
5
$ touch /home/gerrit/review_site/etc/passwords
$ htpasswd /home/gerrit/review_site/etc/passwords "admin"
New password:
Re-type new password:
Adding password for user root
重启服务后,再用浏览器打开,登录后就出现久违的界面了!

(完)