We use Gerrit for our code review system for Git. It supersedes the CodeReview MediaWiki extension we have used for Subversion.
Gerrit is installed on cobalt in the prefix /var/lib/gerrit2. A mostly-cold replica runs at gerrit2001.
It is a Java daemon which listens for HTTP connections (port 8080) and SSH connections (port 29418). Apache proxies the relevant URLs on port 80 and 443 through to Gerrit. The SSH port provides a restricted shell for Git checkouts and administrative commands.
It uses the m2 DB cluster, database name "reviewdb", for most storage. Git repositories are stored at `/srv/gerrit/git/`
It uses the LDAP instance shared with Wikimedia Cloud Services and various other things, for authentication. Accounts under ou=people,dc=wikimedia,dc=org and groups under ou=groups,dc=wikimedia,dc=org are exposed to Gerrit. The Gerrit account name is the "cn" field in LDAP. In order to log in to Gerrit, a user needs to already have a Wikimedia developer account. See Help:Getting Started for the process of getting a developer account.
To find out what version of Gerrit is running, you can use either of the following two commands:
java -jar /var/lib/gerrit2/review_site/bin/gerrit.war version ssh -p 29418 gerrit.wikimedia.org gerrit version
It is 2.14.8-22-g07c8aa9910 at the time of writing.
Database installation is handled by Gerrit installation process, you simply need a user named 'gerrit2' with appropriate privileges. Make sure to set the charset of the database to utf8.
Replace <PASSWORD> below and apply:
CREATE USER 'gerrit2'@'localhost' IDENTIFIED BY <PASSWORD>; CREATE DATABASE reviewdb; ALTER DATABASE reviewdb charset=utf8; GRANT ALL ON reviewdb.* TO 'gerrit2'@'localhost'; FLUSH PRIVILEGES;
- Install OpenJDK 8 and git (
gitpackages on Debian)
- Install Bazel
Update our repository
- Clone gerrit and submodules and add upstream as a remote
git clone https://gerrit.wikimedia.org/r/operations/software/gerrit cd gerrit git remote add upstream https://gerrit.googlesource.com/gerrit git submodule update --init --recursive
- Checkout the
stable-Xbranch that tracks the current upstream release. As of 2018-08-01
git checkout -b stable-2.15 origin/stable-2.15
- Fetch upstream and fast-forward our branch to the latest tag and push the
stable-Xbranch directly to gerrit
git fetch --tags upstream/2.15 git merge --ff-only v2.15.3 git push origin stable-2.15
wmf/stable-Xand merge the latest tag, push the resulting SINGLE merge commit up for review
git checkout -b wmf/stable-2.15 origin/wmf/stable-2.15 git submodule update --init --recursive for plugin in "delete-project" "gitiles" "go-import" "its-phabricator" "lfs" "motd" "reviewers" "reviewers-by-blame" "webhooks" "zuul"; do pushd ./plugins/"$plugin" git checkout stable-2.15 popd done git merge v2.15.3 git push origin HEAD:refs/for/wmf/stable-2.15/v2.15.3
- Checkout the
wmf/stable-Xas of 2018-08-01
git checkout -b wmf/stable-2.15 origin/wmf/stable-2.15
- Build the
bazel build release
- Copy the resulting
bazel-bin/release.warto somewhere safe
- Checkout the
deploy/wmf/stable-Xbranch that aligns with the build branch
- Copy in the
release.waryou saved as
- Unzip the war file to a temporary location
- Copy all the files in
./pluginsin the deploy branch
- Commit the changes, upload to Gerrit, etc
./upload_artifacts.py --version=2.15.2 gerrit.war plugins/foo.jar ...for the core application and all updated plugins (cf: Archiva, specifically setting up your
- Note: Alternatively, you can upload them by using the web UI, but that gets repetitive over a bunch of plugins so I wrote the tool above
- SSH to the deployment master
- Navigate to `/srv/deployment/gerrit/gerrit`
- Fetch & checkout the appropriate `deploy/wmf/stable-X` branch
- `scap deploy`
- If you're only deploying plugins, you're done, otherwise SSH to the Gerrit master and issue `service gerrit restart`
Upgrading the database
When upgrading between major versions (or minor versions that have schema changes--for now), follow these steps:
- Back up the database (reviewdb on m2) just in case
- Note: This is going away soon
- Stop puppet
- Stop the gerrit daemon
- Start gerrit using the "init" flag. `cd /var/lib/gerrit2/review_site/ && sudo java -jar bin/gerrit.war init --batch --no-auto-start --skip-all-downloads`
- Note: Yes, this requires sudo. We do this because we don't want gerrit to actually be able to write to its config files, but the "init" process requires it. Puppet will fix permissions later.
- Re-enable & then run puppet. This will fix permissions, the config file back to exactly how we expect, and then restart Gerrit for us
Creating new repositories
Inspecting an account settings
Since Gerrit 2.15, accounts are stored in
All-Users.git. One first need to find the account reference, that can be done by checking which references a user can read on All-Users.git:
$ gerrit ls-user-refs --project All-Users --user 'firstname.lastname@example.org' refs/meta/config refs/users/34/1234 refs/users/self $
Note: for accounts having extended permissions on
All-Users.git, that will show all references which is not useful.
Then on the server side (or remotely if you have privileges), you can list the configuration files and dump their content:
$ cd /srv/gerrit/git/All-Users.git $ git ls-tree refs/users/34/1234 100644 blob xxx account.config 100644 blob yyy authorized_keys 100644 blob zzz preferences.confg 100644 blob ddd watch.config $ git show refs/users/34/1234:authorized_keys ssh-rsa AAAAxyz... RSA-1024
Disabling / Blocking an account
This action is limited to users in the ldap/ops or capability-access-database groups.
If an account needs to be disabled for some reason, there's three steps to complete:
- remove the ssh keys
- set the account to inactive
- make all Gerrit users re-login
The account_id can be found in the accounts table, if you don't know it.
$ ssh -p 29418 gerrit.wikimedia.org gerrit gsql gerrit> update accounts set inactive = 'Y' where account_id = 1234; gerrit> delete from account_ssh_keys where account_id = 1234;
Then flush the
web_sessions caches to make everyone re-login (aka, the sledgehammer to log one user out):
$ ssh -p 29418 gerrit.wikimedia.org gerrit flush-caches --cache web_sessions
Instead of setting account inactive via gsql you can alternatively use this command:
$ssh gerrit.wikimedia.org -p 29418 gerrit set-account --inactive <Username here>
Gerrit queue tasks, given you have the appropriate permission you can run either of:
$ ssh -p 29418 gerrit.wikimedia.org ps -w $ ssh -p 29418 gerrit.wikimedia.org gerrit show-queue -w
Tasks can be stuck which starve Gerrit processing. For example people would no more be able to fetch. In such a case, granted you are in the Administrators group you can kill a task by id:
$ ssh -p 29418 gerrit.wikimedia.org kill <SOMEID>
Forcing Replication re-runs
When forcing a replication run through gerrit's replication plugin, stay clear of the
--all switch, as it breaks renamed projects on github.
For example, both gerrit and github have a
mediawiki repository. But github's
mediawiki repository is actually
mediawiki/core in gerrit. As gerrit also has a
mediawiki repository, forcing replication on all projects would push gerrit's
mediawiki repository onto github's
mediawiki repository. Thereby, github's
mediawiki repository falls over, and for examples the release tags from github's
mediawiki are gone (cf. task T100409).
This currently (2015-05-28) affects us for at least for the following repos:
|Gerrit's name||Overloaded name on GitHub|
If you by accident forced replication with
--all, force replication of the effective gerrit repos to make up for it (i.e.:
As of July 2018 replication to github requires a repository to be manually created on github using the naming scheme gerrit expects, i.e.
/ replaced with
Github owners will be able to create these repositories.
Once a repository is created, replication to that repo can be forced using the gerrit replication ssh command.
$ ssh -p 29418 gerrit.wikimedia.org replication start operations/debs/trafficserver --wait
How to setup Gerrit in a Cloud VPS project
sudo -u gerrit2 /usr/lib/jvm/java-8-openjdk-amd64/bin/jstat -gcutil `pidof GerritCodeReview` 1000 3
Gerrit's logs are sent to logstash using log4j. You can find its logs by searching with
Logs are also available on the gerrit servers at: