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设置为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)
<[email protected]>"

检查primary.xml.gz

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

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

<data type="primary">
  <location href="repodata/primary.xml.gz"/>
  <checksum type="sha">6eb7ecc041f69a5ffeabdebcb466c443aa5e8028</checksum>
  <timestamp>1413137274</timestamp>
  <open-checksum type="sha">0b08c81e46081059cbe56d2f0871017ef8073d93</open-checksum>
</data>

注意:这个文件的路径不总是这么简单明了。有的时候,这个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中的示例数据如下:

  <package type="rpm">
    <name>jake</name>
    <arch>x86_64</arch>
    <version epoch="87" rel="3.el6" ver="1.0"/>
    <checksum pkgid="YES" type="sha">ea721867eb0389e28bcd32e2deef7d4472c6ced8</checksum>
    <summary>jake douglas is a very nice young man.</summary>
    <description>as it so happens, jake douglas is a very nice young man.</description>
    <packager></packager>
    <url>https://twitter.com/jakedouglas</url>
    <time build="1401650103" file="1413137269"/>
    <size archive="4536" installed="4280" package="3740"/>
    <location href="jake-1.0-3.el6.x86_64.rpm"/>
    <format>
      <rpm:license>GPL</rpm:license>

filelists.xml.gz 和 other.xml.gz

对filelists.xml.gz和other.xml.gz重复上述过程,来检查这些文件:

  1. 从repomd.xml中获取文件路径和校验和。
  2. 使用 curl -Ls <url> | shasum 来检查校验和是否和repomd.xml中的匹配。
  3. 使用 curl -Ls <url> | zless 来查看文件内容。

结论

yum仓库的元数据由一组XML文件、校验和以及某些情况下的GPG签名组成。元数据描述在存储库中可以找到哪些包、每个包的各种属性、文件和目录清单,以及变更日志信息。

yum仓库的元数据可以通过curl, less/zless, gpgshasum命令来查看和校验。如果你要排查一些yum仓库的问题话(包缺失、依赖缺失、错误的版本等),或者你对操作系统最重要的一部分之一好奇的话,那这些工具是非常有用的。

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.