集成 Trac、Jenkins 和 Cobbler—为组织需求定制 Linux 操作系统
支持 Linux 操作系统的组织通常需要构建定制软件,以在生产系统上添加或替换软件包。这种需求源于客户与上游发行版维护者之间在时间和策略上的差异。在实践中,客户报告的错误和安全问题将被优先处理,以达到发行版维护者为所有客户提供支持的适当级别。这意味着客户通常需要支持补丁来填补空白,特别是对于独特的需求,直到发行版维护者解决这些错误。 </EndSoapBox>
希望在内部填补支持空白的客户应尽可能选择发行版维护者用于构建软件包的工具。然而,第三方软件包通常会给将其正确集成到发行版中带来挑战。通常,这些软件包不遵循打包指南,因此,不支持所有发行版配置或管理程序。这些软件包通常需要更通用的流程来解决不正确的打包问题。 </EndSoapBoxAgain>
从现在开始,本文中讨论的工具和方法特定于红帽企业 Linux (RHEL)。这些工具和方法也适用于衍生发行版,如 Scientific Linux 或社区企业操作系统 (CentOS)。一些工具确实包含对基于 Debian 的发行版的支持。但是,流程实施的具体细节侧重于与基于 RHEL 的系统的集成。
流程的构建阶段(在 2014 年 4 月号的 LJ 中“用于管理和定制 HPC 操作系统的流程”中描述)需要三个软件,可以使用 Trac、Cobbler 和 Jenkins 来完成。但是,这些软件并不能填补从下载源代码到创建覆盖仓库的所有空白。通过分析上游发行版的软件包管理流程和指南,可以获得进一步的工具和流程。
Fedora 软件包指南及其对应指南 EPEL 软件包指南 是关于如何为基于 RHEL 的系统正确打包软件的良好参考。这些指南指出了首次打包者经常忽略的具体细节。此外,流程中使用的工具,例如 Mock,与前面提到的软件配合良好。
Fedora 使用其他工具来管理软件包和仓库的构建。这些工具非常特定于 Fedora 打包需求,并且不够通用,无法在我们组织中使用。这主要是由于技术原因以及我在本文的 Jenkins 部分中将要介绍的功能。
本文的其余部分重点介绍 Trac、Cobbler、Jenkins 的实施以及这三个系统之间的差距。一些差距通过与这三个系统相关的原生插件来填补。但是,其他差距留待使用需要人工交互的脚本和流程来实现。在某些情况下,需要人工交互来促进小组之间的沟通,而在另一些情况下,流程缺少一个良好实施的软件。我将讨论 Trac、Cobbler 和 Jenkins 的设置、配置和集成,以及对社区支持的一些请求。
TracTrac 由问题跟踪系统和 wiki 环境组成,以支持软件开发项目。但是,Trac 也非常适合支持管理流程的维护和生产系统上的变更管理。我将讨论如何应用软件开发流程来管理生产系统的流程。
我知道,对于某些人来说,谈论问题跟踪和 wiki 软件是一个宗教话题。每个人都有自己喜欢的软件,这两种系统都有足够多的开源选项可供人们选择。我想专注于我们在 EMSL 发现的用于支持我们的 HPC 系统的功能,以及我们如何使用它们。
工单跟踪系统非常适合管理生产系统上的小变更。这些小变更可能包括单个关键更新、配置变更和用户请求。这些工单的目的是记录关于管理员和管理层变更的相关技术信息。这有助于所有利益相关者了解变更的成本和优先级。这些小变更可以聚合到里程碑中,这些里程碑对应于中断日期。这提供了一个起始框架来跟踪生产系统上发生的变更以及发生时间。
Trac 的 wiki 具有流程所需的功能。第一个是维护单个页面变更历史记录的能力。这非常适合存储文档和程序。另一个功能是从页面中引用里程碑的能力。此功能非常有用,因为通过在 wiki 中输入一行,它将在简单的一行中显示与里程碑关联的所有工单。这两个功能有助于在 wiki 中维护程序和中断页面。
管理程序记录在 wiki 中,它们包括但不限于软件配置、启动、关闭和重新安装。执行这些管理程序所需的时间也应在页面中注明。我们还确保使用纯文本选项来指定需要运行的命令,因为其他字体可能会使读者感到困惑。在许多情况下,我们已经在这些程序中指定了要运行的具体命令。对于复杂系统,为特定程序创建多个页面是明智之举。但是,应添加页面之间的交叉链接,以注明应遵循每个页面中程序的哪个部分。
Trac 的插件基础设施没有 Jenkins 或 Cobbler 的插件。但是,从 Trac 到持续集成或配置的插件有什么意义呢?大多数软件开发模型将工单系统限制为工单发布者和解决工单的人员之间的人工交互。一些例外情况是,当工单被视为已解决但正在等待集成测试时。当工单状态更改时,可以通过工单系统触发自动化测试。但是,将这些功能映射到管理生产系统的管理程序并不适用。
CobblerCobbler 非常适合同步基于 RPM 的仓库并使用这些仓库部署系统。RPM 每天从 Jenkins 和发行版维护者处同步。另一个重要功能是排除某些软件包不进行本地同步。这些功能提供了一个平台来部署具有特定定制软件包的系统,以供企业使用。
Cobbler 的初始设置是将您选择的发行版的主要仓库复制到 Cobbler 中的“repos”中。Scientific Linux 包含的仓库是基本操作系统、fastbugs 和 security。其他发行版具有类似的仓库配置(请参阅“仓库和位置”侧边栏)。要包含的另一个仓库是 EPEL,因为它包含 Mock 和其他用于构建 RPM 的工具。个人组织应研究其他仓库,尽管只需要这四个仓库。
仓库和位置-
企业 Linux 附加软件包:http://dl.fedoraproject.org/pub/epel/6/x86_64
-
Scientific Linux 66 基本版:http://ftp1.scientificlinux.org/linux/scientific/6/x86_64/os
-
Scientific Linux 6 安全:http://ftp1.scientificlinux.org/linux/scientific/6/x86_64/updates/security
-
Scientific Linux 6 Fastbugs:http://ftp1.scientificlinux.org/linux/scientific/6/x86_64/updates/fastbugs
-
CentOS 6 基本版:http://mirror.centos.org/centos/6/os/x86_64
-
CentOS 6 FastTrack:http://mirror.centos.org/centos/6/fasttrack/x86_64
-
CentOS 6 更新:http://mirror.centos.org/centos/6/updates/x86_64
-
RHEL 6 服务器基本版:rhel-x86_64-server-6 频道
-
RHEL 6 服务器 FasTrack:rhel-x86_64-server-fastrack-6 频道
-
RHEL 6 服务器可选:rhel-x86_64-server-optional-6 频道
-
RHEL 6 服务器可选 FasTrack:rhel-x86_64-server-optional-fastrack-6 频道
-
RHEL 6 服务器补充:rhel-x86_64-server-supplementary-6 频道
每日仓库要么每天从 Web 下载,要么从本地文件系统同步。每日仓库设置了“保持更新”标志,而测试和生产仓库则没有。对于从本地文件系统同步的每日仓库,“breed”应设置为 rsync,而从 Web 同步的每日仓库应将其“breed”设置为 yum。通过经验,选择此配置是因为某些 RPM 在新内核下无法很好地升级,也没有 Red Hat 或 Fedora 的标准更新流程。
仓库集的一个示例将如下所示
-
phi-6-x86_64-daily — 每天使用 rsync 从本地文件系统自动同步一次。
-
epel-6-x86_64-daily — 每天使用 reposync 从 Web 自动同步一次。
-
phi-6-x86_64-test — 使用 rsync 从 phi-6-x86_64-daily 手动同步。
-
epel-6-x86_64-test — 使用 rsync 从 epel-6-x86_64-daily 手动同步。
-
phi-6-x86_64-prod — 使用 rsync 从 phi-6-x86_64-test 手动同步。
-
epel-6-x86_64-prod — 使用 rsync 从 epel-6-x86_64-test 手动同步。
要从上游发行版中排除关键软件包,请在每日仓库上设置“yum options”标志以将其删除。例如,要从同步中排除内核软件包,请添加 exclude=kernel*
。管理员务必查阅 Cobbler 和 yum.conf 手册页以获得正确的语法。
以这种方式设置 Cobbler 允许管理员使用定制的关键软件包部署系统。Cobbler 也用于未来的阶段,在这些阶段中,仓库用于部署测试和生产集群。仓库及其关系是 Cobbler 支持软件包构建、测试集群和生产集群所需的一切。
JenkinsJenkins 是一个非常强大的持续集成工具,用于软件开发。但是,从系统管理的角度来看,Jenkins 是一个变异的类固醇 cron 任务。Jenkins 处理从源代码管理 (SCM) 仓库定期检出源代码,并通过 HTTP 或 FTP 下载已发布的源代码。然后,它运行一系列通用作业,这些作业构建、测试和部署生成的软件。这些通用接口非常适合构建和分发要包含在 Cobbler 中的 RPM。
Jenkins 在软件开发角色中的使用与构建 RPM 并没有太大的不同(有关这两个流程的比较,请参见表 1)。这两个流程的第一步不同之处在于(希望)构建步骤所需的软件开发代码位于一个位置。软件包开发人员至少需要两个位置来提取代码以继续构建。第一个位置用于补丁和 spec 文件,通常保存在 SCM 中。第二个位置用于已发布的源代码软件包。源代码以单个文件发布,通常采用某种容器格式(例如 tar、rar 或 zip)。这些文件通常不属于 SCM,更适合 S3 (http://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html)、swift (http://docs.openstack.org/api/openstack-object-storage/1.0/content) 或类似 blob 存储的接口。
表 1. 打包与开发软件开发 | RPM 打包 |
从 SCM 下载源代码。 | 下载已发布的源代码、spec 文件和补丁。 |
运行构建流程。 | 使用 Mock 构建 RPM。 |
运行测试套件。 | 使用 rpmlint 验证 RPM。 |
发布测试结果。 | 保存验证输出以供检查。 |
将源代码包保存到仓库。 | 保存构建的 RPM 以供稍后下载。 |
向相关的开发人员发送通知。 | 向相关的打包人员发送通知。 |
Jenkins 主要用于从一个且仅一个 SCM 下载代码。但是,您可以通过添加另一个构建步骤来解决此问题。这意味着 SCM 插件用于下载 spec 文件和补丁,而构建流程的第一步下载源代码包。完成这两个步骤后,可以使用特定于站点的自定义项修补源代码、补丁或 spec 文件。
下一步是使用 Mock 构建 RPM。这涉及多个任务,这些任务可以分解为各种构建步骤(请参阅“Jenkins 中的 Mock 构建”侧边栏)。所有这些步骤都使用 Jenkins 执行 shell 构建步骤来完成。我们使用的一些 Jenkins 作业是多配置作业,其中包含一个定义 Mock chroot 配置的轴。该 chroot 配置应从 Cobbler 中定义的每日仓库生成。遵循这些任务可以帮助您开始在 Jenkins 中使用 Mock(清单 1)。
清单 1. basic-mock-jenkins.sh
#!/bin/bash -xe
# keep in mind DIST is defined in multi-configuration axis
MOCK="/usr/bin/mock -r $DIST"
PKG=${JOB_NAME##*/}
# keep in mind VER could also be a multi-configuration axis
VER=${VER:-1.0}
# if you are ripping apart an RPM might have this one too
REL=${REL:-4.el6}
OUT=$PWD/output
wget -O $PKG-$VER.tar.gz
↪http://www.example.com/sources/$PKG-$VER.tar.gz
rm -f $OUT/*.src.rpm
if ! $MOCK --resultdir=$OUT --buildsrpm --spec=$PKG.spec
↪--sources=$PWD
then
more $OUT/*.log | cat
exit -1
fi
if ! $MOCK --resultdir=$OUT --rebuild $OUT/*.src.rpm
then
more $OUT/*.log | cat
exit -1
fi
rpmlint $OUT/*.rpm > rpmlint.log
Jenkins 中的 Mock 构建
-
准备源代码和 spec 文件。
-
运行 Mock 源代码 rpm 构建。
-
运行 Mock rpm 构建。
-
运行 rpm 验证。
构建 RPM 后,务必在生成的 RPM 上运行 rpmlint
。此输出为如何为目标平台正确打包 RPM 提供了有用的建议。此输出应像任何其他静态代码分析工具一样处理。应跟踪、计数和绘制一系列构建过程中警告和错误的数量。这很好地表明了错误是在一段时间内得到解决还是被引入。
生成的 RPM 和 rpmlint
输出需要存档以供将来使用。存档工件插件非常适合捕获这些文件。还有一个工件部署插件,可以将工件复制到 Cobbler 可以配置为从中同步的目录,以便在其流程中使用。
此流程还有一些改进空间,我在结论中概述了这一点。但是,这是开始使用 Jenkins 使用 Mock 和 rpmlint 构建 RPM 的基本框架。随着发行版和软件包开发人员推送新更新,流程的这一部分需要持续的关注和维护。Jenkins 确实有 Trac 和其他问题跟踪系统的插件。但是,它们未包含在此流程中,因为我们发现电子邮件是足够的沟通方式。使用 Jenkins 构建 RPM 的概述流程帮助我们跟踪我们用于操作系统重要软件包的 hack。
表 2. 软件角色 | 软件选择 |
持续集成 | Jenkins |
仓库管理 | Cobbler |
配置 | Cobbler |
工单跟踪 | Trac |
Wiki | Trac |
软件包构建 | Mock |
软件包指南 | Fedora 软件包指南 |
我已经讨论了一种设置工具的方法,用于针对 Cobbler 管理的自定义发行版开发 RPM。借助 Trac,软件包开发人员可以维护关键应用程序的更新 RPM,同时管理沟通。但是,此流程并非没有差距。首先,我将介绍 Jenkins 中存在的差距,讨论未发现的核心和插件差距。然后,我将讨论 Cobbler 在仓库管理方面的差距。这两个系统在集成方面存在不足,尽管可以解决。
MultiSCM 是 Jenkins 中的一项功能,可以简化软件包构建流程。有一个 MultiSCM 插件;但是,它被宣传为概念验证代码。希望 SCM 的单选按钮选择将变成一组复选框。存在相关的错误,但多年来一直没有受到关注。软件包开发是需要从多个位置下载和轮询代码更新的另一个很好的例子。
以下是有关 Jenkins 多 SCM 错误的信息链接
静态代码分析工具可以作为 Jenkins 插件使用,尽管这些插件不包括 rpmlint。这些插件创建图表来跟踪代码中警告和错误的数量随时间变化的情况。对打包执行相同的任务将非常有帮助。但是,您可以使用通用的 绘图插件 和每个作业的另一个构建步骤来解决此差距。
Mock 具有非常明确定义的接口和工作流程。在 Jenkins 中使用 Mock 的通用插件将非常有用。该插件应包括配置 chroot 配置。还可以创建两种构建作业,一种使用 spec 文件和源代码文件,另一种使用源代码 RPM。还需要创建一个测试来验证 Mock 是否可以在不提示用户密码的情况下运行。此插件对于自动化此流程非常有帮助,因为我们目前必须在作业之间复制脚本。
Cobbler 也有一些有用的补充,可以用于此流程。没有按仓库触发器。能够告诉 Trac 软件包已从仓库测试转移到仓库生产将非常有用。此外,能够告诉 Jenkins 构建软件包,因为依赖软件包已更新,这也将非常有用。
Cobbler 的另一个有用的补充是在从远程镜像同步时删除目标树中较旧的 RPM 的能力。如果 Cobbler 仓库的“breed”是 yum,则会以仅附加方式构建。可以通过删除 RPM,然后再次同步仓库来定期运行管理空间的流程。但是,这会使仓库处于损坏状态,直到流程完成。此功能在任何 Cobbler 部署中都可能很有用,因为它将确保仓库在不需要 RPM 时不会继续占用空间。
Trac 不需要任何额外的插件来更好地与 Cobbler 或 Jenkins 集成。我们发现 wiki 格式中操作大型表格存在一些可用性问题。一些使在 wiki 格式中更轻松地编辑大型表格的插件对我们很有用。此外,如果您无法在整个页面中添加注释,则编辑长页面会成为问题。我们通过让不熟悉该系统的小组成员阅读程序来验证我们的程序。读者应该能够评论但不能编辑页面的某些部分。我们已经解决了这些问题,或者在 Trac Hacks 页面上找到了插件来解决这些问题。
最后的请求是希望发行版维护者提供某种级别的认证,以认证第三方软件包。我们已应用于此流程的许多第三方软件包不支持所有发行版配置。发行版维护者提供的认证,验证第三方供应商分发的软件已针对发行版正确打包,这将有助于客户确定支持成本。
这绝不是组织构建定制关键应用程序的完整解决方案。系统中仍然存在一些差距,我们必须使用脚本或人工干预来解决这些差距。我们不断改进流程和工具,使其变得更好,因此欢迎任何改进建议。但是,这些工具确实满足了 EMSL 对 HPC 关键应用程序定制支持的需求。
致谢这项研究是使用 EMSL 进行的,EMSL 是一个国家科学用户设施,由美国能源部生物和环境研究办公室赞助,位于太平洋西北国家实验室。