Gerrit—编译(配置lfs及oauth)

1、安装bazel及JDK

curl -Lo bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64

mv bazelisk-linux-amd64 bazel
chmod +x bazel
mv bazel /usr/local/bin/
#使用openjdk 21来编译
vim /etc/profile
内容如下:
        JAVA_HOME=/opt/jdk-21
        PATH=$PATH:$JAVA_HOME/bin
        export JAVA_HOME PATH
#编译前要在gerrit的源码目录中确认Java的版本
java -version

2、克隆gerrit及lfs源码

源码目录:源码/gerrit-refs_heads_stable-3.9.tar.gz

注意:不要使用3.12.1,不要使用3.12.1,不要使用3.12.1,有阻塞性bug

git clone https://gerrit.googlesource.com/gerrit
cd gerrit 
git checkout v3.11.4    #可以通过git tag -l | grep 3.11来查看具体的版本号
git submodule update --init

2、拉取想要lfs及oauth的插件到gerrit中,配置成默认插件一起编译

cd plugins

# 克隆lfs,在gerrit为v3.11.4的情况下,lfs必须使用master分支
git clone https://gerrit.googlesource.com/plugins/lfs

#克隆oauth
git clone https://gerrit.googlesource.com/plugins/oauth
cd oauth && git checkout stable-3.4

3、修改tools/bzl/plugins.bzl(gerrit源码根路径)文件,添加如下内容

CORE_PLUGINS = [
    "codemirror-editor",
    "commit-message-length-validator",
    "delete-project",
    "download-commands",
    "gitiles",
    "hooks",
    "plugin-manager",
    "replication",
    "replication:replication-api",
    "reviewnotes",
    "singleusergroup",
    "webhooks",
    "lfs",
    "oauth",
]

4、修改oauth插件中的BUILD文件,添加两个jackson的信赖,否则后续运行会报错

# vim plugins/oauth/BUILD
gerrit_plugin(
    name = "oauth",
    srcs = glob(["src/main/java/**/*.java"]),
    manifest_entries = [
        "Gerrit-PluginName: gerrit-oauth-provider",
        "Gerrit-Module: com.googlesource.gerrit.plugins.oauth.Module",
        "Gerrit-HttpModule: com.googlesource.gerrit.plugins.oauth.HttpModule",
        "Gerrit-InitStep: com.googlesource.gerrit.plugins.oauth.InitOAuth",
        "Implementation-Title: Gerrit OAuth authentication provider",
        "Implementation-URL: https://github.com/davido/gerrit-oauth-provider",
    ],
    resources = glob(["src/main/resources/**/*"]),
    deps = [
        "@commons-codec//jar:neverlink",
        "@jackson-databind//jar",
        "@scribejava-apis//jar",
        "@scribejava-core//jar",
        "@jackson-core//jar",
        "@jackson-annotations//jar",
    ],
)

5、修改gerrit源码/WORKSPACE(位于gerrit源码根路径)

由于你在上面的oauth插件中的BUILD文件中添加了两个信赖,而由于gerrit的新版本已经移除了自动为插件引入信赖的机制,因此需要在gerrit的WORKSPACE中引入oauth插件需要的信赖;虽然我们同时也增了lfs的插件,但是lfs的配置中没有引入外部依赖的相关配置,所以我们只配置与oauth相关的信赖即可。

先查看oauth需要的scribejava与jackson的版本号

cat plugins/oauth/external_plugin_deps.bzl
def external_plugin_deps(omit_commons_codec = True):
    JACKSON_VERS = "2.10.2"
    SCRIBEJAVA_VERS = "6.9.0"
......

按照上面显示的版本号在gerrit的源码的WORKSPACE中添加相关信赖。

vim gerrit/WORKSPACE

注意:一定要下面的代码放在external_plugin_deps()的前面,否则会不生效。

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "rules_jvm_external",
    sha256 = "b17d7388feb9bfa7f2fa09031b32707df529f26c91ab9e5d909eb1676badd9a6",
    strip_prefix = "rules_jvm_external-4.5",
    url = "https://github.com/bazelbuild/rules_jvm_external/archive/4.5.zip",
)

load("@rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
    artifacts = [
        "com.github.scribejava:scribejava-apis:6.9.0",
        "com.github.scribejava:scribejava-core:6.9.0",
        "com.fasterxml.jackson.core:jackson-databind:2.10.2",
        "com.fasterxml.jackson.core:jackson-core:2.10.2",
        "com.fasterxml.jackson.core:jackson-annotations:2.10.2",
        "com.unboundid:unboundid-ldapsdk:6.0.7",  # 替代 JNDI
    ],
    repositories = ["https://repo1.maven.org/maven2"],
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar")
http_jar(
    name = "scribejava-apis",
    url = "https://repo1.maven.org/maven2/com/github/scribejava/scribejava-apis/6.9.0/scribejava-apis-6.9.0.jar",
    sha256 = "c563bcd2bae1f3e671d034ebb18006ddb214174fc0ec8a68ac9fa4cc3fc81000",
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar")
http_jar(
    name = "scribejava-core",
    url = "https://repo1.maven.org/maven2/com/github/scribejava/scribejava-core/6.9.0/scribejava-core-6.9.0.jar",
    sha256 = "7901774ed1b3d1634a2e50320a0687d499389a6fecf83f788f5297900f6338c0",
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar")
http_jar(
    name = "jackson-databind",
    url = "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.10.2/jackson-databind-2.10.2.jar",
    sha256 = "42c25644e35fadfbded1b7f35a8d1e70a86737f190e43aa2c56cea4b96cbda88",
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar")
http_jar(
    name = "jackson-core",
    url = "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.10.2/jackson-core-2.10.2.jar",
    sha256 = "4c41f22a48f6ebb28752baeb6d25bf09ba4ff0ad8bfb82650dde448928b9da4f",
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar")
http_jar(
    name = "jackson-annotations",
    url = "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.10.2/jackson-annotations-2.10.2.jar",
    sha256 = "8c3cba89bf3e03b35a0e6f892c2eb17ed8fdde2e214c3a4c18703d63796bae46",
)

6、编译gerrit

bazel build :release

#编译后的文件存放在gerrit源码的bazel-bin目录下
bazel-bin/release.war

如果你只是想编译出同gerrit相同版本的插件,那么到这里就可以结束了,将编译好的插件拷贝到gerrit的plugins目录下就行了,插件都放在编译后的release.war包的WEB-INF/plugins/目录下。

7、编译成docker

# vim Dockerfile

FROM eclipse-temurin:21-jdk-jammy

RUN apt-get update && \
        apt install -y openssh-client git vim coreutils bash \
        curl vim less iputils-ping  net-tools procps
RUN rm -rf /var/lib/apt/lists/*

ENV GERRIT_VERSION=3.9.1
ENV GERRIT_SITE=/var/gerrit

RUN useradd -d ${GERRIT_SITE} -m -s /bin/bash gerrit && \
        mkdir -p ${GERRIT_SITE}/bin ${GERRIT_SITE}/cache ${GERRIT_SITE}/db \
        ${GERRIT_SITE}/git ${GERRIT_SITE}/index ${GERRIT_SITE}/etc && \
        chown -R gerrit:gerrit ${GERRIT_SITE}

ADD release.war /var/gerrit/bin/gerrit.war
COPY --chmod=755 docker-entrypoint.sh /entrypoint.sh

ENV CANONICAL_WEB_URL=
ENV HTTPD_LISTEN_URL=

EXPOSE 8080 29418

USER gerrit

VOLUME ["/var/gerrit/git", "/var/gerrit/index", "/var/gerrit/cache", "/var/gerrit/db", "/var/gerrit/etc"]

ENTRYPOINT ["/entrypoint.sh"]

# vim docker-entrypoint.sh

#!/bin/bash -e

export JAVA_OPTS='--add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED'

if [ ! -d /var/gerrit/git/All-Projects.git ] || [ "$1" == "init" ]
then
  echo "Initializing Gerrit site ..."
  java $JAVA_OPTS -jar /var/gerrit/bin/gerrit.war init --batch --install-all-plugins -d /var/gerrit
  java $JAVA_OPTS -jar /var/gerrit/bin/gerrit.war reindex -d /var/gerrit
  git config -f /var/gerrit/etc/gerrit.config --add container.javaOptions "-Djava.security.egd=file:/dev/./urandom"
  git config -f /var/gerrit/etc/gerrit.config --add container.javaOptions "--add-opens java.base/java.net=ALL-UNNAMED"
  git config -f /var/gerrit/etc/gerrit.config --add container.javaOptions "--add-opens java.base/java.lang.invoke=ALL-UNNAMED"
fi

git config -f /var/gerrit/etc/gerrit.config gerrit.canonicalWebUrl "${CANONICAL_WEB_URL:-http://$HOSTNAME/}"
if [ ${HTTPD_LISTEN_URL} ];
then
  git config -f /var/gerrit/etc/gerrit.config httpd.listenUrl ${HTTPD_LISTEN_URL}
fi

if [ "$1" != "init" ]
then
  echo "Running Gerrit ..."
  exec java -jar /var/gerrit/bin/gerrit.war daemon -d $GERRIT_SITE
#  exec /var/gerrit/bin/gerrit.sh run
fi

编译命令

docker build -t qly-gerrit-3-12-1:1.1 .

8、配置gitee的oauth应用

打开gitee.com,进入「设置」 –> 「第三方应用」 –> 创建应用

  • 应用名称:随意
  • 应用主页:你的gerrit的外网地址,如http://code.xxxx.org
  • 应用回调地址:你部署的dex服务外网地址/dex,如https://dex.xxxx.org/dex/callback

9、使用docker运行dex服务

注意:oauth有很多种实现,gerrit中引用的oauth只是一种协议插件,而并不是实现。需要部署一个oauth的实现服务才能实现gerrit的oauth登录。

docker run -d 5556:5556 \
-v /本地地址/config.yaml:/etc/dex/config.docker.yaml \
dexidp/dex:v2.43.1-alpine

config.yaml配置文件如下:

issuer: https://dex.xxxx.com/dex

staticClients:
- id: Gerrit
  redirectURIs:
  - 'http://code.xxxx.com/oauth'
  name: 'Gerrit'
  secret: d1ce7d5784e08aa23a9c7bbbeac3b6b

connectors:
- type: oauth
  id: oauthCoding
  name: oauthCoding
  config:
    clientID: "ea648733ff0645fb05f11ad735504fbe9da5"  #gitee中的clientID
    clientSecret: "fffe2034431a25b35bac8e1937d277"    #gitee中的clientSecret
    redirectURI: "https://dex.xxxx.com/dex/callback"  #gitee中的应用调地址
    authorizationURL: "https://gitee.com/oauth/authorize"
    tokenURL: "https://gitee.com/oauth/token"
    userInfoURL: "https://gitee.com/api/v5/user"
    scopes:
      - "user_info"
      - "emails"
    claims:
      name: ["name"]
      email: ["email"]
      preferred_username: ["login"]
    claimMapping:
      userNameKey: "name"
      emailKey: "email"
      preferredUsernameKey: "name"

enablePasswordDB: false

storage:
  type: "sqlite3"
  config:
    file: "/var/dex/dex.db"

web:
  http: 0.0.0.0:5556
  #tlsCert: /data/ssl/fullchain1.pem
  #tlsKey: /data/ssl/privkey1.pem

10、gerrit的配置

[auth]
    type = OAUTH
	gitBasicAuth = true
    gitBasicAuthPolicy = HTTP
    userNameCaseInsensitive = true

[plugin "gerrit-oauth-provider-dex-oauth"]
    client-id = Gerrit
	client-secret = d1ce7d5784e08aa23a9c7bbbeac3b6b  #与dex配置文件中配置的secret一致
    root-url = https://dex.xxxx.com   #dex外网的访问地址
    scope = user_info emails          #权限范围与dex的scope配置及gitee中要一致
    link-to-existing-openid-accounts = true
    remove-domain-from-username = true

11、常用到的一些命令

查看gerrit版本号

docker exec 容器名/id java -jar /var/gerrit/bin/gerrit.war version

查看已经安装的所有插件

ssh -p 29418 root@gerrit.baidu.com gerrit plugin ls