yum仓库内部原理

本文是yum repository internals的翻译。

TL;DR

这篇博客将会检查各种yum仓库中的索引文件,从而深入了解yum仓库的细节。我们将介绍每个索引文件的含义,并研究用户如何检查这些元数据。

什么是yum仓库?

Yum仓库就是一些RPM包的集合,加上一些yum命令能够读取的元数据。有一个yum仓库能够让你安装、删除、升级软件包或者软件组。

yum仓库对于存储、管理、交付软件非常重要。

使用createrepo命令创建一个yum仓库

在详细了解yum仓库元数据之前,先让我们看看如何用开源命令行工具createrepo架设一个yum仓库。

使用命令行工具createrepo,你能创建一个yum仓库。你能在CentOS或Red Hat系统中使用如下命令安装这个工具:

$ sudo yum install createrepo

createrepo 最简单的用法就是使用一个命令行参数:yum仓库元数据的保存目录。

假设你在当前目录有一些RPM文件,那你就能一条命令来生成一个yum仓库:

$ createrepo .

这个命令会创建一个名字为repodata的文件夹,包含了yum仓库的元数据。我们接下来会深入了解这些元数据。

你还可以使用GPG来签名这些元数据。这样就能保证yum仓库的用户使用的是你生成的元数据。这个和rpmrpmsigin不一样:

$ gpg –detach-sign –armor myrepo/repodata/repomd.xml

关于GPG签名RPM包和yum仓库的更多细节,你可以在之前的文章找到。

如果你也想让其他用户访问你的yum仓库,你要假设Apache,nginx或者其他web服务器,并将网站目录指向到仓库的根目录。当然,我们推荐你获取一个SSL证书,确保软件包能安全的传输到最终系统上。

当然,使用packagecloud是更加快速、简单的解决办法,而且自带SSL、GPG支持,可以与其他人协作等特性。

yum仓库元数据

yum仓库元数据是由一系列XML文件组成的。这些文件包含了其他文件的校验和包含的包。

通常,在yum仓库中能找到的元数据文件有这几种:

  • repomd.xml:包含了其他XML元数据文件的位置、校验和和时间戳的一个索引文件。
  • repomd.xml.asc:只有仓库创建者使用GPG签名了repomd.xml文件时,才会生成这个文件。如前所述,如果用户安装了pygpgme包,那么yum就会下载并校验这个文件。
  • primary.xml.gz:包含了仓库里每个包的详细信息,比如名字、版本、授权协议、依赖信息、时间戳、大小等信息。
  • filelists.xml.gz:包含了每个包的每个文件和目录。
  • other.xml.gz:包含了每个包的changelog记录,这些记录来自RPM SPEC文件。

还有一些其他文件,但是它们没有得到广泛应用。对于大多数yum仓库,上面这些文件就足够了。

典型的,yum仓库的元数据存储在repodata URL下,或者repodata目录下。

将相同架构的软件存放在一起,这是一个常用的实践。这样,你的软件仓库的元数据就能够按照架构类型分开,从而减少服务端到客户端的流量。

一个典型的x86_64和i386架构的repomd.xml链接(来自packagecloud)一般是:

大多数公开的软件仓库也有同样的结构。比如CentOS 7的repomd.xml文件:

检查并校验yum仓库的元数据

你可以使用一些命令行工具来检查yum仓库的元数据、计算校验和、校验GPG签名。

让我们以位于https://packagecloud.io/computology/packagecloud-cookbook-test-public/el/7 的CentOS 7仓库为例:

首先检查 repomd.xml

你必须首先用curl命令检查repomd.xml文件。其他的索引文件以及校验和都在这个文件中:

$ curl -Ls \
https://packagecloud.io/computology/packagecloud-cookbook-test-public/el/7/x86\_64/repodata/repomd.xml

(提示: 如果你需要更详细的信息,或者需要调试信息,你可以使用curl的-Lv命令来开启详细输出模式。)

校验repomd.xml的GPG签名

yum会自动尝试校验仓库的GPG签名(如果yum的配置中,[repo_gpgcheck](https://blog.packagecloud.io/eng/2014/11/24/howto-gpg-sign-verify-rpm-packages-yum-repositories/)设置为1),但是你也可以手动校验。

如果仓库是GPG签名过的,而且你已经导入了GPG公钥,那你可以通过gpg --verify来校验下载下来的repomd.xml文件和repomd.xml.asc文件:

$ curl -Ls \
https://packagecloud.io/computology/packagecloud-cookbook-test-public/el/7/x86\_64/repodata/repomd.xml

repomd.xml
$ curl -Ls \
https://packagecloud.io/computology/packagecloud-cookbook-test-public/el/7/x86\_64/repodata/repomd.xml.asc
repomd.xml.asc
$ gpg –verify repomd.xml.asc repomd.xml
gpg: Signature made Sun Oct 12 11:07:54 2014 PDT using RSA key ID 7AD95B3F
gpg: Good signature from “packagecloud ops (production key)
ops@packagecloud.io

检查primary.xml.gz

接下来,让我们检查primary.xml.gz。如前所述,这个文件包含了仓库中的包信息。

repomd.xml文件指出了这个文件的位置:

6eb7ecc041f69a5ffeabdebcb466c443aa5e8028 1413137274 0b08c81e46081059cbe56d2f0871017ef8073d93

注意:这个文件的路径不总是这么简单明了。有的时候,这个URL会包含SHA或MD5校验和。

这个位置是相对于仓库根目录的。

首先检验SHA校验和是不是和repomd.xml中的匹配。_open-checksum_节点列出的校验和是压缩之后的文件的校验和。

$ curl -Ls https://packagecloud.io/computology/packagecloud-cookbook-test-public/el/7/x86\_64/repodata/primary.xml.gz | shasuma
6eb7ecc041f69a5ffeabdebcb466c443aa5e8028 -

很好!校验和是一致的!让我们用zless 来浏览它:

$ curl -Ls \
https://packagecloud.io/computology/packagecloud-cookbook-test-public/el/7/x86\_64/repodata/primary.xml.gz \
| zless

primary.xml.gz中的示例数据如下:

jake x86\_64 ea721867eb0389e28bcd32e2deef7d4472c6ced8 jake douglas is a very nice young man. as it so happens, jake douglas is a very nice young man. https://twitter.com/jakedouglas
作者

Robert Lu

发布于

2019-06-29

许可协议

评论