公司之前一直用gitlab来存放项目代码 ,目前因为业务需要(代码bug太多)需要引入gerrit来进行code review。

最初用的是centos 7.4,但是安装完成后,GerritResource中没有ALL_Project.git和All_Users.git生成,日志中一直在报错,反复装了几次后发现,在centos7上的兼容性不是太完美,所以采购了centos6.8 服务器进行安装,还是比较顺利的完成了安装。

另外本文采用LDAP认证,LDAP的配置本文不做讲解,参考其他文章。

已经在用: gitlab-ce-9.3.3-ce.0.el7.x86_64 最新部署: centos 6.8 x64 gerrit 2.15.6 nginx 1.10.2 mysql 5.6

1、建立专有帐户 $ useradd gerrit -m -s /bin/bash $ passwd gerrit ##本文密码与用户同名 $ su - gerrit

2、配置 Java 环境

[root@ao-internal02 ~]# java -version
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
[root@ao-internal02 ~]# 

3、从官网下载gerrit https://www.gerritcodereview.com/ 当前最新版本为 2.15.6。

4、安装 MySQL

5、创建数据库、用户、授权 这里选择 MySQL 作为 Gerrit 的数据库,其它选项全部采用默认配置。对于这种选择,需要连上 MySQL,为 Gerrit 创建相应的数据库,用户,并为用户授权:

$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 35
Server version: 5.7.20-0ubuntu0.16.04.1 (Ubuntu)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SELECT USER();
+----------------+
| USER()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

mysql> create database reviewdb;
Query OK, 1 row affected (0.01 sec)

mysql> CREATE USER 'gerrit'@'localhost' IDENTIFIED BY 'gerrit';
Query OK, 0 rows affected (0.01 sec)

mysql> grant all privileges on reviewdb.* to gerrit@localhost identified by 'gerrit';
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| reviewdb           |
| sys                |
+--------------------+
8 rows in set (0.01 sec)

6、安装gerrit 把包传到gerrit的家目录,修改相关的权限 。通过如下命令安装 Gerrit:

[gerrit@ao-internal02 ~]$ java -jar  gerrit-2.15.6.war  init -d review_site
Using secure store: com.google.gerrit.server.securestore.DefaultSecureStore

*** Gerrit Code Review 2.15.6
*** 


*** Git Repositories
*** 

Location of Git repositories   [GerritResource]: 
**git 代码仓库的位置, 默认会在之前敲的init -d 目录下新建一个GerritResource文件夹,这个选项用于配置 Gerrit 的 Git 仓库的保存地址。上面的配置将创建 /home/gerrit/review_site/GerritResource 目录用于保存 Gerrit 的 Git 仓库。
*** SQL Database
*** 

Database server type           [mysql]:  ##这里使用Mysql数据,默认是H2不太会用。
Server hostname                [localhost]: 10.81.232.115   ##数据库地址
Server port                    [(mysql default)]: 3306    ##数据库端口
Database name                  [reviewdb]:      ##数据库名称 
Database username              [gerrit]:      ##数据库用户
Change gerrit's password       [y/N]?]   ##数据库用户的密码

*** Index
*** 

Type                           [lucene/?]:    ##默认

*** User Authentication
*** 

Authentication method          [http/?]:     ##使用哪种认证方式,这里使用ldap
Get username from custom HTTP header [y/N]?  ##默认
SSO logout URL                 :   ##默认
Enable signed push support     [y/N]?   ##默认

*** Review Labels
*** 

Install Verified label         [y/N]?   ##默认

*** Email Delivery
*** 

SMTP server hostname           [smtp.exmail.qq.com]: 
SMTP server port               [465]: 
SMTP encryption                [tls/?]: 
SMTP username                  [dr@baidu.com]: 
Change dr@baidu.com's password [y/N]? 

*** Container Process
*** 

Run as                         [gerrit]: 
Java runtime                   [/usr/share/jdk1.8.0_151/jre]: 
Upgrade review_site/bin/gerrit.war [Y/n]? n

*** SSH Daemon
*** 

Listen on address              [*]: 
Listen on port                 [29418]: 

*** HTTP Daemon
*** 

Behind reverse proxy           [Y/n]? Y  ##是否使用反向代理 ,这是配置为是
Proxy uses SSL (https://)      [y/N]? 
Subdirectory on proxy server   [/]: 
Listen on address              [*]: 
Listen on port                 [8080]: 
Canonical URL                  [http://gerrit.baidu.com/]: 

*** Cache
*** 


*** Plugins
*** 

##以下这些插件要全部安装上,不然后续很麻烦。
##download-commands 尤其是这个插件,不安装的是没有clone地址的

Installing plugins.
Install plugin commit-message-length-validator version v2.15.6 [y/N]? 
Install plugin download-commands version v2.15.6 [y/N]? 
Install plugin hooks version v2.15.6 [y/N]? 
Install plugin replication version v2.15.6 [y/N]? 
Install plugin reviewnotes version v2.15.6 [y/N]? 
Install plugin singleusergroup version v2.15.6 [y/N]? 
Initializing plugins.
No plugins found with init steps.

*** Experimental features
*** 

Enable any experimental features [y/N]? 

Initialized /data/gerrit/review_site
[gerrit@ao-internal02 ~]$ 

##默认安装完后服务是会启动的。

##这里因为有调整,所以手工启动服务了。
[root@ao-internal02 bin]# ./gerrit.sh  start
Starting Gerrit Code Review: OK
[root@ao-internal02 bin]# 
[root@ao-internal02 bin]# netstat -antlop | grep 8082
tcp        0      0 0.0.0.0:8082            0.0.0.0:*               LISTEN      16538/GerritCodeRev  off (0.00/0/0)
[root@ao-internal02 bin]# 

监控日志输出:

[gerrit@ao-gerrit01 logs]$ pwd
/home/gerrit/review_site/logs
[gerrit@ao-gerrit01 logs]$ tail -f error_log

排错过程: 1、Gerrit 安装过程中,可能会报出如下的 Exception:

Exception in thread "main" com.google.gwtorm.server.OrmException: Cannot apply SQL
CREATE TABLE account_group_members_audit (
added_by INT DEFAULT 0 NOT NULL,
removed_by INT,
removed_on TIMESTAMP NULL DEFAULT NULL,
account_id INT DEFAULT 0 NOT NULL,
group_id INT DEFAULT 0 NOT NULL,
added_on TIMESTAMP NOT NULL
,PRIMARY KEY(account_id,group_id,added_on)
)
    at com.google.gwtorm.jdbc.JdbcExecutor.execute(JdbcExecutor.java:44)
    at com.google.gwtorm.jdbc.JdbcSchema.createRelations(JdbcSchema.java:134)
    at com.google.gwtorm.jdbc.JdbcSchema.updateSchema(JdbcSchema.java:104)
    at com.google.gerrit.server.schema.SchemaCreator.create(SchemaCreator.java:81)
    at com.google.gerrit.server.schema.SchemaUpdater.update(SchemaUpdater.java:108)
    at com.google.gerrit.pgm.init.BaseInit$SiteRun.upgradeSchema(BaseInit.java:386)
    at com.google.gerrit.pgm.init.BaseInit.run(BaseInit.java:143)
    at com.google.gerrit.pgm.util.AbstractProgram.main(AbstractProgram.java:61)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.google.gerrit.launcher.GerritLauncher.invokeProgram(GerritLauncher.java:204)
    at com.google.gerrit.launcher.GerritLauncher.mainImpl(GerritLauncher.java:108)
    at com.google.gerrit.launcher.GerritLauncher.main(GerritLauncher.java:63)
    at Main.main(Main.java:24)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Invalid default value for 'added_on'
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
    at com.mysql.jdbc.Util.getInstance(Util.java:408)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2497)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2455)
    at com.mysql.jdbc.StatementImpl.executeInternal(StatementImpl.java:839)
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:739)
    at com.google.gwtorm.jdbc.JdbcExecutor.execute(JdbcExecutor.java:42)
    ... 15 more

这个异常可通过如下方式解决:使用 MySQL root 用户登录,设置

set global explicit_defaults_for_timestamp=1;

像下面这样:

$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 76
Server version: 5.7.20-0ubuntu0.16.04.1 (Ubuntu)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> set global explicit_defaults_for_timestamp=1;
Query OK, 0 rows affected (0.00 sec)

mysql> exit;
Bye

如果数据库是主从,一定要在主库上创建库、用户、授权。否则会报错:

Enable any experimental features [y/N]? 

Exception in thread "main" com.google.gwtorm.server.OrmException: Cannot apply SQL
CREATE TABLE account_group_id(s SERIAL)
        at com.google.gwtorm.jdbc.JdbcExecutor.execute(JdbcExecutor.java:44)
        at com.google.gwtorm.jdbc.JdbcSchema.createSequences(JdbcSchema.java:122)
        at com.google.gwtorm.jdbc.JdbcSchema.updateSchema(JdbcSchema.java:103)
        at com.google.gerrit.server.schema.SchemaCreator.create(SchemaCreator.java:84)
        at com.google.gerrit.server.schema.SchemaUpdater.update(SchemaUpdater.java:111)
        at com.google.gerrit.pgm.init.BaseInit$SiteRun.upgradeSchema(BaseInit.java:389)
        at com.google.gerrit.pgm.init.BaseInit.run(BaseInit.java:146)
        at com.google.gerrit.pgm.util.AbstractProgram.main(AbstractProgram.java:61)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.google.gerrit.launcher.GerritLauncher.invokeProgram(GerritLauncher.java:223)
        at com.google.gerrit.launcher.GerritLauncher.mainImpl(GerritLauncher.java:119)
        at com.google.gerrit.launcher.GerritLauncher.main(GerritLauncher.java:63)
        at Main.main(Main.java:24)
Caused by: java.sql.SQLException: The MySQL server is running with the --read-only option so it cannot execute this statement
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2490)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2448)
        at com.mysql.jdbc.StatementImpl.executeInternal(StatementImpl.java:845)
        at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:745)
        at com.google.gwtorm.jdbc.JdbcExecutor.execute(JdbcExecutor.java:42)
        ... 15 more

解决办法: 在主库上建库、用户、授权。 最终配置文件:

[gerrit@ao-gerrit01 etc]$ more gerrit.config 
[gerrit]
        basePath = GerritResource
        serverId = 5ae3e303-92dc-4823-8284-e21a14034f75
        canonicalWebUrl = http://gerrit.baidu.com/
[database]
        type = mysql
        hostname = localhost
        database = reviewdb
        username = gerrit
[noteDb "changes"]
        disableReviewDb = true
        primaryStorage = note db
        read = true
        sequence = true
        write = true
[index]
        type = LUCENE
[auth]
        type = LDAP
        gitBasicAuthPolicy = LDAP
[ldap]
        server = ldap://101.11.23.191:389
        username = cn=Manager,dc=baidu,dc=com
        accountBase = dc=baidu,dc=com
        groupBase = dc=baidu,dc=com
[receive]
        enableSignedPush = false
[sendemail]
        enable = true
        smtpServer = smtp.exmail.qq.com
        smtpServerPort = 587
        smtpEncryption = TLS
        smtpUser = dr@baidu.com
        smtpPass = 123456
        from = dr@baidu.com
[container]
        user = gerrit
        javaHome = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre
[sshd]
        listenAddress = *:29418
[httpd]
        listenUrl = http://*:8080/
[cache]
        directory = cache
[gitweb]
    cgi = /var/www/git/gitweb.cgi
    type = gitweb
[plugins]
        # allow install plugin
        allowRemoteAdmin = true
[gerrit@ao-gerrit01 etc]$ 

后续配置: 1、在/review_gerrit/bin/gerrit.sh中实际代码第一行加入 GERRIT_SITE=/home/gerrit/review_site

例如:

[root@ao-gerrit01 logs]# vim /review_gerrit/bin/gerrit.sh
GERRIT_SITE=/home/gerrit/review_site
#!/bin/sh
  GERRIT_SITE            =  /home/gerrit/review_site

2、全局使用gerrit: [root@ao-gerrit01 logs]# ln -s /home/gerrit/review_site/bin/gerrit.sh /usr/bin/gerrit 安装插件:

[gerrit@ao-gerrit01 ~]$ ssh -i .ssh/id_rsa -p 29418 gerritadmin@localhost gerrit plugin install -n replication.jar -  < gerrit-2.15.6/WEB-INF/plugins/replication.jar  
fatal: remote installation is disabled
[gerrit@ao-gerrit01 ~]$

3、# 安装复制插件

unzip gerrit-2.14.1.war
ssh -p 29418 gerrit_admin_user@localhost gerrit plugin install -n replication.jar - < ./WEB-INF/plugins/replication.jar

#如果安装时提示权限问题,要在gerrit.config 上添加 allowRemoteAdmin 参数,文件见下面

[plugins]
        # allow install plugin
        allowRemoteAdmin = true

重启一下服务

[gerrit@ao-gerrit01 ~]$ gerrit restart
Stopping Gerrit Code Review: OK
Starting Gerrit Code Review: WARNING: Could not adjust Gerrit's process for the kernel's out-of-memory killer.
         This may be caused by /usr/bin/gerrit not being run as root.
         Consider changing the OOM score adjustment manually for Gerrit's PID=6302 with e.g.:
         echo '-1000' | sudo tee /proc/6302/oom_score_adj
OK
[gerrit@ao-gerrit01 ~]$

安装replication

[gerrit@ao-gerrit01 ~]$ ssh -i .ssh/id_rsa -p 29418 gerritadmin@localhost gerrit plugin install -n replication.jar -  < gerrit-2.15.6/WEB-INF/plugins/replication.jar 
[gerrit@ao-gerrit01 ~]$ 
查看
[gerrit@ao-gerrit01 etc]$ ssh -i .ssh/id_rsa -p 29418 gerritadmin@localhost gerrit plugin ls
Warning: Identity file .ssh/id_rsa not accessible: No such file or directory.
Name                           Version    Status   File
-------------------------------------------------------------------------------
replication                    v2.15.6    ENABLED  replication.jar
[gerrit@ao-gerrit01 etc]$ 

4、Gerrit部署成功后创建项目看不到clone地址 在gerrit部署成功后使用admin账号登录,完成管理员注册流程,然后尝试创建第一个项目。创建项目test,权限继承ALL project,然后进入test,但是看不到clone地址。如下图:

解决办法: 安装插件download-commands 5、添加key的时候报504 解决办法: 确保gerrit.config中,邮箱配置是正确的。另外你的gerrit所在的机器是可以发送邮件的。我这里用的是postfix。配置完后,通过以下命令能收到邮件,即为正常 echo testmail| mail -s "testmail" dragon@baidu.com

6、代码同步到gerrit后,开发者diff不了,一点就报错,很忧伤 。如下图:

解决办法 : nginx配置文件的配置问题: 将 proxy_pass http://gerrit_server/; 修改为 proxy_pass http://gerrit_server;

 重启nginx服务

7、

配置/home/gerrit/review_site/etc/replication.config,没有的话新建:

URL这里目前只能写多个了,尝试使用了namespace无效。 就是仓库没办法使用变量,当有新增的话 维护起来比较麻烦, 目前还没有更好的解决办法,哪位大佬给予指导。