注意

本文档适用于 Ceph 的开发版本。

持续集成架构

在 Ceph 中,我们在开发中依赖多个 CI(持续集成)管道。这些管道中的大部分都围绕 Jenkins 展开。它们的配置是使用 Jenkins Job Builder 生成的。

让我们以 Jenkins 执行的 make check 为例。

ceph-pull-requests

ceph-pull-requests 是一个 jenkins 作业,由 GitHub 拉取请求或触发短语(如)触发

jenkins test make check

此 jenkins 作业涉及多方

digraph { rankdir="LR"; github [ label="<git> git_repo | <webhooks> webhooks | <api> api"; shape=record; href="https://github.com/ceph/ceph"; ]; subgraph cluster_lab { label="Sepia Lab"; href="https://wiki.sepia.ceph.com/doku.php"; shape=circle; apt_mirror [ href="http://apt-mirror.front.sepia.ceph.com"; ]; shaman [ href="https://shaman.ceph.com"; ]; chacra [ peripheries=3; href="https://chacra.ceph.com"; ]; subgraph cluster_jenkins { label="jenkins"; href="https://jenkins.ceph.com"; jenkins_controller [ label = "controller" ]; jenkins_agents [ label = "agents", peripheries=3 ]; }; }; { rank=same; package_repos [ peripheries=3 ]; pypi; npm; } github:webhooks -> jenkins_controller [ label = "notify", color = "crimson" ]; jenkins_controller -> jenkins_agents [ label = "schedule jobs" ]; jenkins_agents -> github:git [ label = "git pull" ]; jenkins_agents -> shaman [ label = "query for chacra repo URL" ]; jenkins_agents -> chacra [ label = "pull build dependencies" ]; jenkins_agents -> package_repos [ label = "pull build dependencies" ]; jenkins_agents -> pypi [ label = "pull Python packages" ]; jenkins_agents -> npm [ label = "pull JavaScript packages" ]; jenkins_agents -> apt_mirror [ label = "pull build dependencies" ]; jenkins_agents -> github:api [ label = "update", color = "crimson" ]; }

其中

Sepia 实验室

Sepia 实验室 是 Ceph 项目使用的测试实验室。该实验室提供了我们 CI 基础设施所需的存储和计算资源。

Jenkins 代理

是一组执行 CI 作业的机器。在这种情况下,它们会

  1. 从 GitHub 拉取 git 仓库,并且

  2. 根据最新的 master 分支重新设置拉取请求的基准

  3. 设置必要的环境变量

  4. 运行 run-make-check.sh

Chacra

是一个提供 RESTful API 的服务器,允许客户端存储和检索二进制包。它还会自动为上传的包创建仓库。一旦在 chacra 上创建了某个仓库,配置的 shaman 服务器也会随之更新,然后我们可以向 shaman 查询相应的仓库地址。Chacra 不仅托管 Ceph 包,还托管了许多其他包,例如各种构建依赖项。

Shaman

是一个提供 RESTful API 的服务器,允许客户端查询由 chacra 节点托管的仓库信息。Shaman 也以其 Web UI 而闻名。但请注意,shaman 不会构建包,它只提供有关构建的信息。

如下所示,chacra 管理着多个项目,其元数据存储在数据库中。这些元数据通过 Shaman 作为 Web 服务公开。chacractl 是一个与 chacra 服务交互的实用程序。

digraph { libboost [ shape=cylinder; ]; libzbd [ shape=cylinder; ]; other_repos [ label="..."; shape=cylinder; ]; postgresql [ shape=cylinder; style=filled; ] shaman -> postgresql; chacra -> postgresql; chacractl -> chacra; chacra -> libboost; chacra -> libzbd; chacra -> other_repos; }

构建依赖项

就像许多其他软件项目一样,Ceph 既有构建时依赖项,也有运行时依赖项。大多数情况下,我们倾向于使用发行版预构建的包。但在某些情况下,

  • 发行版中缺少必要的依赖项,或者

  • 它们的版本太旧,或者

  • 打包时未启用某些重要功能。

  • 我们希望确保某个运行时依赖项的版本与我们在实验室中测试的版本相同。

无论是什么原因,我们都需要从源代码构建它们,或者将它们打包成二进制包,而不是使用发行版附带的包。相当多的构建时依赖项包含为 git 子模块,但为了避免重复重建这些依赖项,我们预先构建了其中一些并将其上传到我们自己的仓库中。因此,在执行 make check 时,我们 CI 中的构建主机只是从我们内部托管这些包的仓库中拉取它们,而不是构建它们。

到目前为止,以下包已针对 ubuntu focal 预构建,然后上传到 chacra

libboost

打包 boost。包的名称已从 libboost-* 更改为 ceph-libboost-*,并且它们被安装到 /opt/ceph 中,因此它们不会干扰发行版附带的官方 libboost 包。它的构建脚本托管在 https://github.com/ceph/ceph-boost。有关如何提升版本号的示例,请参阅 https://github.com/ceph/ceph-boost/commit/2a8ae02932b2a1fd6a68072da8ca0df2b99b805c。在纯净的 Ubuntu Focal 操作系统上构建 1.79 所使用的命令如下。

sudo apt install debhelper dctrl-tools chrpath libbz2-dev libicu-dev bison \
  flex docbook-to-man help2man xsltproc doxygen dh-python python3-all-dev graphviz
wget http://download.ceph.com/qa/boost_1_79_0.tar.bz2
git clone https://github.com/ceph/ceph-boost
tar xjf boost_1_79_0.tar.bz2
cp -ra ceph-boost/debian boost_1_79_0/
pushd boost_1_79_0
export DEB_BUILD_OPTIONS='parallel=6 nodoc'
dpkg-buildpackage -us -uc -b
popd
BOOST_SHA=$(git ls-remote https://github.com/ceph/ceph-boost main | awk '{ print $1 }')
ls *.deb | chacractl binary create \
  libboost/master/$BOOST_SHA/ubuntu/focal/amd64/flavors/default
libzbd

打包 libzbd 。上游 libzbd 已经包含 debian 打包。

libpmem

打包 pmdk 。请注意,ndctl 是 pmdk 的构建依赖项之一,有关更新的 debian 打包,请参阅 https://github.com/ceph/ceph-ndctl

注意

请确保在更新/升级打包时正确更新包版本和打包的发布编号,否则很难判断安装了哪个版本的包。我们在 install-deps.sh 中尝试升级之前会检查包版本。

但除了这些库之外,ceph-mgr-dashboard 的前端使用了许多 JavaScript 包。其中相当一部分没有被发行版打包。更不用说测试这些包的不同版本组合的麻烦了。因此,我们决定使用 make-dist 将这些 JavaScript 包包含在我们的 dist tarball 中。

此外,由于我们的下游在重新分发预编译的 Ceph 包时可能不想使用预打包的二进制文件,我们还需要将这些库包含在我们的 dist tarball 中。它们是

  • boost

  • liburing

  • pmdk

make-dist 是我们的 CI 管道用于创建 dist tarball 的脚本,以便 tarball 可以在洁净室环境中用于构建 Ceph 包。当我们需要升级这些第三方库时,我们应该

  • 更新 CMake 脚本

  • 重建预构建的包,并且

  • 更新此脚本以反映更改。

上传依赖项

为了确保 jenkins 代理可以访问预构建的包,我们需要将它们上传到 apt-mirror.front.sepia.ceph.comchacra。将包上传到前者需要我们的实验室管理员的帮助,因此如果我们想定期维护包仓库,更好的选择是使用 chacractl 管理它们。chacra 使用资源层次结构表示包仓库,例如

<project>/<branch>/<ref>/<distro>/<distro-version>/<arch>

其中

项目

通常用于表示一组相关的包。例如 libboost

分支

项目的分支。这反映了 Git 仓库的概念。

ref

给定版本的一组包的唯一 ID。此 ID 用于引用 <project>/<branch> 下的这组包。对打包配方进行版本控制是一个好习惯,例如用于构建 DEB 包的 debian 目录和用于构建 RPM 包的 spec,并使用打包配方的 SHA1 作为 ref。但您也可以使用随机字符串作为 ref,例如已构建源代码树的标签名称。

发行版

构建包所针对的发行版名称。目前支持以下发行版

  • centos

  • debian

  • fedora

  • rhel

  • ubuntu

发行版版本

发行版的版本。例如,如果包是在 ubuntu focal 上构建的,则 distro-version 应该是 20.04

架构

包的架构。它可以是

  • arm64

  • amd64

  • noarch

因此,例如,我们可以将预构建的 boost 包上传到 chacra,如下所示

ls *.deb | chacractl binary create \
  libboost/master/099c0fd56b4a54457e288a2eff8fffdc0d416f7a/ubuntu/focal/amd64/flavors/default

更新 install-deps.sh

我们还需要更新 install-deps.sh 以将构建脚本指向新的仓库。有关更多详细信息,请参阅脚本

由 Ceph 基金会为您呈现

Ceph 文档是由非营利性 Ceph 基金会 资助和托管的社区资源。如果您希望支持这项工作和我们的其他努力,请考虑 立即加入