This article will describe installing gerrit which is web base code review tool. Gerrit server hostname is ubuntu-16.04.hiroom2.com.
Table of Contents
1 gerrit server configuration
Here will describe configuration for running gerrit server on Ubuntu 16.04.
1.1 Install gerrit package
Install gerrit package with apt.
$ sudo apt install -y openjdk-8-jdk $ sudo su -c 'echo "deb mirror://mirrorlist.gerritforge.com/deb gerrit contrib" \ > /etc/apt/sources.list.d/gerritforge.list' $ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1871F775 $ sudo apt-get update -y $ sudo apt-get install -y gerrit $ sudo systemctl enable gerrit $ sudo systemctl start gerrit
Now you can access to gerrit with below URL.
http://<server>:8080
1.2 Change TCP port
The gerrit default port is 8080. This port can be changed with following.
The domain name in canonicalWebUrl will be used for page transition. You can use IP address instead of the domain name. But these must be accessible from other machine. The domain name is set to hostname by default.
$ diff -uprN /etc/gerrit/gerrit.config{.org,} --- /etc/gerrit/gerrit.config.org 2016-07-25 19:59:41.598934505 +0900 +++ /etc/gerrit/gerrit.config 2016-07-25 19:59:55.114798625 +0900 @@ -1,6 +1,6 @@ [gerrit] basePath = git - canonicalWebUrl = http://ubuntu-16.04-gerrit.hiroom2.com:8080/ + canonicalWebUrl = http://ubuntu-16.04-gerrit.hiroom2.com:8081/ [database] type = h2 database = db/ReviewDB @@ -13,7 +13,7 @@ [sshd] listenAddress = *:29418 [httpd] - listenUrl = http://*:8080/ + listenUrl = http://*:8081/ [cache] directory = cache [receive]
Restart gerrit.
$ sudo systemctl restart gerrit
Now you can access to gerrit with below URL.
http://<server>:8081
1.3 Use Apache2
Apache2's proxy_http will provides access via <server>/gerrit instead of <server>:<port>. Apache2's auth_digest will provides authentication for accessing gerrit URL.
Make gerrit to use Apache2.
$ diff -uprN /etc/gerrit/gerrit.config{.org,} --- /etc/gerrit/gerrit.config.org 2016-07-25 20:02:36.845106678 +0900 +++ /etc/gerrit/gerrit.config 2016-07-25 20:03:24.788584852 +0900 @@ -1,6 +1,6 @@ [gerrit] basePath = git - canonicalWebUrl = http://ubuntu-16.04-gerrit.hiroom2.com:8081/ + canonicalWebUrl = http://ubuntu-16.04-gerrit.hiroom2.com/gerrit [database] type = h2 database = db/ReviewDB @@ -13,7 +13,7 @@ [sshd] listenAddress = *:29418 [httpd] - listenUrl = http://*:8081/ + listenUrl = proxy-http://127.0.0.1:8081/gerrit [cache] directory = cache [receive]
Restart gerrit.
$ sudo systemctl restart gerrit
Install apache2 package with apt.
$ sudo apt install -y apache2
Create Apache2 configuration.
- Use proxy_http for rewrite <server>:<port> to <server>/gerrit.
- Use auth_digest for authentication gerrit server URL.
- Use nocanon for accessing URL which has a slash like path/to/src.c.
$ sudo su -c 'cat << EOF > /etc/apache2/mods-enabled/gerrit.conf ProxyPass /gerrit http://localhost:8081/gerrit nocanon ProxyPassReverse /gerrit http://localhost:8081/gerrit nocanon ProxyRequests Off <Proxy http://localhost:8081/gerrit> Order deny,allow Allow from all </Proxy> <Location /gerrit> AuthType Digest AuthName "gerrit" AuthUserFile /etc/apache2/.htdigest Require valid-user </Location> EOF '
Create digest authentication password file.
$ sudo htdigest -c /etc/apache2/.htdigest "gerrit" hiroom2 Adding password for hiroom2 in realm gerrit. New password: Re-type new password:
gerrit will use %2F instead of slash. Make AllowEncodedSlashes On in VirtualHost directive.
$ diff -uprN /etc/apache2/sites-available/000-default.conf{.org,} --- /etc/apache2/sites-available/000-default.conf.org 2016-07-25 20:21:33.160757290 +0900 +++ /etc/apache2/sites-available/000-default.conf 2016-07-25 20:21:52.892879066 +0900 @@ -26,6 +26,8 @@ # following line enables the CGI configuration for this host only # after it has been globally disabled with "a2disconf". #Include conf-available/serve-cgi-bin.conf + + AllowEncodedSlashes On </VirtualHost> # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
Enable proxy_http and auth_digest with a2enmod. Restart Apache2.
$ sudo a2enmod proxy_http auth_digest $ sudo systemctl restart apache2
2 Add admin user who can use HTTP authentication
Add admin user with following.
- Create SSH public key on gerrit client.
- Change gerrit authentication to HTTP.
- Access to gerrit server and create user.
- Change gerrit authentication to DEVELOPMENT_BECOME_ANY_ACCOUNT.
- Add user to Administrators group with Administrator user.
- Change gerrit authentication to HTTP.
- Register email via SSH.
- This user can add user belonging Administrators group without DEVELOPMENT_BECOME_ANY_ACCOUNT.
Create SSH public key on gerrit client. If you have SSH public key already, please use it.
$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/hiroom2/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/hiroom2/.ssh/id_rsa. Your public key has been saved in /home/hiroom2/.ssh/id_rsa.pub. <snip> $ cat .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ<snip>ooooWgJfN/LHp hiroom2@ubuntu-16
Change gerrit authentication to HTTP.
$ diff -uprN /etc/gerrit/gerrit.config{.org,} --- /etc/gerrit/gerrit.config.org 2016-07-28 00:24:10.609299708 +0900 +++ /etc/gerrit/gerrit.config 2016-07-28 00:24:24.629195859 +0900 @@ -7,7 +7,7 @@ [index] type = LUCENE [auth] - type = DEVELOPMENT_BECOME_ANY_ACCOUNT + type = HTTP [sendemail] smtpServer = localhost [sshd]
Restart gerrit.
$ sudo systemctl restart gerrit
Access to gerrit server with below URL.
http://<server>/gerrit
The dialog for digest authentication is displayed. Input username and password which are created with htdigest.
Register Fullname and SSH public key. You must use Fullname which is different from username. Unfortunatelly, email might cannot be registered via HTTP. email will be registered via SSH later.
Change gerrit authentication to DEVELOPMENT_BECOME_ANY_ACCOUNT.
$ diff -uprN /etc/gerrit/gerrit.config{.org,} --- /etc/gerrit/gerrit.config.org 2016-07-28 00:37:43.171990767 +0900 +++ /etc/gerrit/gerrit.config 2016-07-28 00:39:11.763461918 +0900 @@ -7,7 +7,7 @@ [index] type = LUCENE [auth] - type = HTTP + type = DEVELOPMENT_BECOME_ANY_ACCOUNT [sendemail] smtpServer = localhost [sshd]
Restart gerrit.
$ sudo systemctl restart gerrit
Reload browser and select "Switch Account" at the upper right.
Select Administrator.
Select "List Groups" of "People" at the upper.
Add user to Administrators group.
Change gerrit authentication to HTTP.
$ diff -uprN /etc/gerrit/gerrit.config{.org,} --- /etc/gerrit/gerrit.config.org 2016-07-28 00:39:38.915300824 +0900 +++ /etc/gerrit/gerrit.config 2016-07-28 00:40:21.187050856 +0900 @@ -7,7 +7,7 @@ [index] type = LUCENE [auth] - type = DEVELOPMENT_BECOME_ANY_ACCOUNT + type = HTTP [sendemail] smtpServer = localhost [sshd]
Restart gerrit.
$ sudo systemctl restart gerrit
Register email via SSH.
$ # ssh -p 29418 <server> gerrit set-account --add-email <mail> <user> $ # ssh -p 29418 <server> gerrit set-account --preferred-email <mail> <user> $ ssh -p 29418 ubuntu-16.04-gerrit.hiroom2.com gerrit set-account \ --add-email "hiroom2@ubuntu-16.04-client.hiroom2.com" hiroom2 $ ssh -p 29418 ubuntu-16.04-gerrit.hiroom2.com gerrit set-account \ --preferred-email "hiroom2@ubuntu-16.04-client.hiroom2.com" hiroom2
This user can add the other user to Administrators group without switching HTTP and DEVELOPMENT_BECOME_ANY_ACCOUNT.
In case of HTTP user like commiter and reviewer is as below.
- Add username and password to digest authentication password file.
- Access to gerrit via HTTP with username and password and create user.
- Update user's email via SSH
In case of Non-HTTP user like Jenkins is as below.
- Create user via SSH.
3 gerrit client configuration
Here will describe configuration for using gerrit server from client on Ubuntu 16.04.
3.1 no matching key exchange method found. Their offer: diffie-hellman-group1-sha1
While gerrit will use diffie-hellman-group1-sha1, OpenSSH 7 client does not support old encryption including diffie-hellman-group1-sha1 by default. This will cause SSH connection error.
$ # OpenSSH 7 client $ ssh -p 29418 ubuntu-16.04-gerrit.hiroom2.com gerrit Unable to negotiate with 192.168.11.86 port 29418: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1
For avoiding this issue, use the following alias in .bashrc.
alias ssh='ssh -oKexAlgorithms=+diffie-hellman-group1-sha1'
You can also use the following configuration in .ssh/config.
$ cat .ssh/config Host ubuntu-16.04-gerrit.hiroom2.com KexAlgorithms +diffie-hellman-group1-sha1
3.2 Install git-review package
Install git-review package which is a tool for sending a patch to gerrit server.
$ sudo apt-get install -y git-review
4 Create new project
Create new project with the following SSH command. If you do not import existing repository to the project, you must use –empty-commit option.
ssh -p 29418 <server> gerrit create-project --empty-commit <name> \ --description "'<desc>'"
Create new project which names new-project.
$ ssh -p 29418 ubuntu-16.04-gerrit.hiroom2.com gerrit create-project \ --empty-commit new-project.git --description "'Create project from SSH command'"
git clone via HTTP.
$ git clone http://ubuntu-16.04-gerrit.hiroom2.com/gerrit/new-project.git $ cd new-project
Create .gitreview which is configuration file for git-review. Please change host and project to your environment.
$ cat <<EOF > .gitreview [gerrit] host=ubuntu-16.04-gerrit.hiroom2.com port=29418 project=new-project defaultbranch=master EOF
Commit patch.
$ echo hello > hello.txt $ git add hello.txt $ git commit -m "Hello, World"
git log before git-review is as below.
$ git log commit e2b5070e2cdc576a2e669366f85797ebfdc29b49 Author: hiroom2 gerrit <hiroom2@ubuntu-16> Date: Thu Jul 28 05:29:51 2016 +0900 Hello, World commit bc9d23cb95c8d94ae8e3544bac512c4210c7c443 Author: hiroom2 gerrit <hiroom2@ubuntu-16.04-gerrit.hiroom2.com> Date: Thu Jul 28 05:25:49 2016 +0900 Initial empty repository
git-reviewを実行します。
$ git review # or git review -R Creating a git remote called "gerrit" that maps to: ssh://hiroom2@ubuntu-16.04-gerrit.hiroom2.com:29418/new-project Your change was committed before the commit hook was installed. Amending the commit to add a gerrit change id. remote: Processing changes: new: 1, refs: 1, done remote: remote: New Changes: remote: http://ubuntu-16.04-gerrit.hiroom2.com/gerrit/1 Hello, World remote: To ssh://hiroom2@ubuntu-16.04-gerrit.hiroom2.com:29418/new-project * [new branch] HEAD -> refs/publish/master
git log after git-review is as below. "Change-ID:xxx" has been appended. The "Change-ID:xxx" is ID for managing the patch on gerrit server.
$ git log commit 2fc75bd27f6bb323ad19a39b74c68b5faafac848 Author: hiroom2 gerrit <hiroom2@ubuntu-16> Date: Thu Jul 28 05:29:51 2016 +0900 Hello, World Change-Id: I965523a134ac6bfaae91491bc7d53d153a93e3d2 commit bc9d23cb95c8d94ae8e3544bac512c4210c7c443 Author: hiroom2 gerrit <hiroom2@ubuntu-16.04-gerrit.hiroom2.com> Date: Thu Jul 28 05:25:49 2016 +0900 Initial empty repository
This "Change-Id:xxx" is appended by .git/hooks/commit-msg which was downloaded when running git-review. If you have the other .git/hooks/commit-msg, git-review won't download .git/hooks/commit-msg for gerrit and "Change-Id:xxx" will not appended. In this case, you need to download .git/hooks/commit-msg for gerrit via following URL.
$ # wget http://<server>/gerrit/tools/hooks/commit-msg $ wget http://ubuntu-16.04-gerrit.hiroom2.com/gerrit/tools/hooks/commit-msg $ mv commit-msg .git/hooks/commit-msg_gerrit
Rename existing .git/hooks/commit-msg to .git/hooks/commit-msg_xxx. Add the following .git/hooks/commit-msg which will call .git/hooks/commig_msg-xxx.
$ cat .git/hooks/commit-msg #!/bin/sh for script in `ls ${0}_*`; do echo "Running ${script}" ${script} $@ ret=$? if [ ${ret} -ne 0 ]; then echo "${script} is FAILED." exit ${ret} fi done
Select "Open" of "All" at the upper. The patch by git-review is displayed.
Select patch and detail page is displayed. You can check patch on this page. Select "Abandon" if there is a problem, select "Code-Review+2" if there is no problem. This article will select "Code-Review+2".
"Submit" will be enabled when value of "Code-Review" is +2. "Submit" will push the patch to repository.
5 Import existing repository to gerrit
Create project without –empty-commit option.
$ ssh -p 29418 ubuntu-16.04-gerrit.hiroom2.com gerrit create-project \ existing-project.git --description "'Create existing project from SSH command'"
Create bare repository of existing repository.
$ git clone --bare <path-to-repo>/existing-project.git $ cd existing-project.git
Push bare repository to gerrit server via SSH.
$ git push ssh://ubuntu-16.04-gerrit.hiroom2.com:29418/existing-project.git *:*
After this, you can git clone via HTTP. The hash value is the same with existing repository.
$ git clone http://ubuntu-16.04-gerrit.hiroom2.com/gerrit/existing-project.git
6 Jenkins
Add Verified score in addition to Code-Review score and make Jenkins verified automatically. Adding Verified score will provides build and test result before code review. Submit can be done when Code-Review score is over than +2 and Verified score is over than + 1. This article will use existing-project which was used before.
6.1 Add Verified score
Code-Review score is defined by Code-Review label in project configuration. Define Verified label in All-Projects's project configuration. All-Project is the base project for creating project.
Select "Open" of "All" menu and select All-Project.
Select "Edit Project Config".
Project configuration is displayed.
Change project configuration with as below.
diff --git a/project.config b/project.config index 2584f6b..919288d 100644 --- a/project.config +++ b/project.config @@ -28,6 +28,9 @@ label-Code-Review = -2..+2 group Administrators label-Code-Review = -2..+2 group Project Owners label-Code-Review = -1..+1 group Registered Users + label-Verified = -1..+1 group Administrators + label-Verified = -1..+1 group Project Owners + label-Verified = -1..+1 group Registered Users submit = group Administrators submit = group Project Owners editTopicName = +force group Administrators @@ -40,6 +43,8 @@ push = group Project Owners label-Code-Review = -2..+2 group Administrators label-Code-Review = -2..+2 group Project Owners + label-Verified = -1..+1 group Administrators + label-Verified = -1..+1 group Project Owners submit = group Administrators submit = group Project Owners [access "refs/tags/*"] @@ -57,3 +62,8 @@ value = 0 No score value = +1 Looks good to me, but someone else must approve value = +2 Looks good to me, approved +[label "Verified"] + function = MaxWithBlock + value = -1 Fails + value = 0 No score + value = +1 Verified
Select "Publish Edit", "Publish", "Code-Review+2", "Submit". Change is applied.
6.2 Add jenkins user to gerrit
Create Jenkins's SSH public key on Jenkins server.
$ sudo su - jenkins $ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/var/lib/jenkins/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /var/lib/jenkins/.ssh/id_rsa. Your public key has been saved in /var/lib/jenkins/.ssh/id_rsa.pub. <snip>
Add jenkins user to gerrit with admin user. Register Jenkins's SSH public key.
$ cat id_rsa.pub | ssh -p 29418 ubuntu-16.04-gerrit.hiroom2.com gerrit \ create-account --ssh-key - --group "'Administrators'" \ --full-name "'jenkins gerrit'" \ --email "'jenkins@ubuntu-16.04-jenkins.hiroom2.com'" jenkins
6.3 Jenkins's Gerrit Trigger Plugin
Gerrit Trigger Plugin run test on Jenkins via git-review and update Verified score to gerrit. Install Gerrit Trigger Plugin in Jenkins's Plugin Manager.
Open Gerit Trigger Plugin configuration.
Manage Jenkins -> Gerrit Trigger
Input gerrit server.
Set gerrit server hostname to "Hostname", gerrit server URL to "Frontend URL" and jenkins to "Username".
http://<server>/gerrit # Frontend URL
You can check connection with "Test Connection". Save this configuration.
Click status of appended gerrit server. It will be blue from red.
Create new project with "New Item".
This article will use "Freestyle project".
Select "git" at "Source Code Management".
- Set gerrit project repository URL to "Repository URL".
- Click "Advanced" and set $GERRIT_REFSPEC to "Refspec".
- Click "Add Branch" and $GERRIT_MASTER to "Branch Specifier".
Check "Gerrit event" at "Build Triggers".
- Set gerrit server to "Choose a Server". This gerrit server was appended in Gerrit Trigger Plugin configuration.
- Append "Patchset Created" and "Draft Published" to "Trigger on".
- Set "Plain" to "Type" and gerrit project name to Pattern in "Gerrit Project".
- Set "Path" to "Type" and "**" to "Pattern" in "Gerrit Project's Branches".
6.4 Excecution result
Clone existing-project from gerrit server.
$ git clone http://ubuntu-16.04-gerrit.hiroom2.com/gerrit/existing-project.git $ cd existing-project
Append .gitreview for existing-project.
$ cat <<EOF > .gitreview [gerrit] host=ubuntu-16.04-gerrit.hiroom2.com port=29418 project=existing-project defaultbranch=master EOF
Create new file and commit it.
$ echo hello > hello.txt $ git add hello.txt $ git commit -m "Hello, World"
Send patchset to gerrit server with git-review.
$ git review -R Creating a git remote called "gerrit" that maps to: ssh://hiroom2@ubuntu-16.04-gerrit.hiroom2.com:29418/existing-project Your change was committed before the commit hook was installed. Amending the commit to add a gerrit change id. remote: Processing changes: new: 1, refs: 1, done remote: remote: New Changes: remote: http://ubuntu-16.04-gerrit.hiroom2.com/gerrit/2 Hello, World remote: To ssh://hiroom2@ubuntu-16.04-gerrit.hiroom2.com:29418/existing-project * [new branch] HEAD -> refs/publish/master
Build history has a new build which was triggered by gerrit.
Verified score is updated by Jenkins on gerrit server. After Code-Review score is +2, it can submit.