GLEP 25:Distfile 修补支持
作者 | Brian Harring <ferringb@gentoo.org> |
---|---|
类型 | 标准跟踪 |
状态 | 延期 |
版本 | 1 |
创建日期 | 2004-03-06 |
上次修改日期 | 2014-01-17 |
发布历史 | 2004-04-04, 2004-11-11 |
GLEP 源代码 | glep-0025.rst |
内容
摘要
本 GLEP 的目的是建议为 Portage 创建修补支持,并完善其实现细节。
状态
超时
动机
通过减少版本升级时传输的字节数来减少对镜像的带宽负载。此举的附带好处是显着减少缺乏宽带用户的下载需求。
二进制补丁与 GNUDiff 补丁
大多数人熟悉 diff 补丁(例如统一 diff)- 本 GLEP 特别建议使用实际的二进制差异工具。原因是 diff 补丁是基于行的 - 您更改一行中的单个字符,则必须在补丁中包含整行。二进制差异工具在字节级别工作 - 它只编码该字节。因此,二进制补丁通常比 diff 补丁更有效。
此外,能够反转统一补丁是因为 diff 包含**原始行和修改行**。作者不知道任何能够创建可反转的补丁的二进制差异工具 - 基本上它们是单向的,生成的补丁只能用于升级或降级版本,不能同时用于两者。此限制的好处是补丁大小显着减少。
选择二进制补丁而不是 diff 补丁几乎归结为它们更小 - 例如,kdelibs 3.1.4->3.1.5 的二进制补丁为 75kb,等效的 diff 补丁为 123kb,并且无法生成正确的 md5 [1]。
目前,本 GLEP 仅建议使用二进制补丁 - 这并不意味着它不能(通过大量工作)扩展以支持标准 diff。
基本原理
源代码发行版之间的差异通常并不大,尤其是对于次要发行版。例如,kdelibs-3.1.4.tar.bz2 为 10.53 MB,kdelibs-3.1.5.tar.bz2 为 10.54 MB。这两个版本之间的 bzip2 压缩补丁为 75.6 kb [2],不到 3.1.5 的 tbz2 大小的 1%。
规范
Gentoo 的相当一部分受到影响 - 镜像、Portage 树和 Portage 本身。
对树的添加
为了将补丁信息添加到树中,本 GLEP 建议使用全局补丁列表(存储在配置文件中,名为 patches.global),以及存储在相关包目录中的各个补丁列表(名为 patches)。以内核包为例,全局补丁列表使我们能够创建一个补丁,添加一个条目,并且所有内核包都能从该条目中获益。patches.global 和各个包补丁文件共享相同的格式
MD5 md5-value patch-url size MD5 md5-value ref-file size UMD5 md5-value new-file size
对于熟悉摘要文件布局的人来说,这应该很熟悉。本质上,chksum 类型、值、文件名、大小。UMD5 chksum 类型只是文件的未压缩 md5/大小 - 因此,如果 UMD5 是针对 bzip2 压缩文件,它将是未压缩文件的 md5 值/大小。示例如下
MD5 ccd5411b3558326cbce0306fcae32e26 http://dev.gentoo.org/~ferringb/patches/kdelibs-3.1.4-3.1.5.patch.bz2 75687 MD5 82c265de78d53c7060a09c5cb1a78942 kdelibs-3.1.4.tar.bz2 10537433 UMD5 0b1908a51e739c07ff5a88e189d2f7a9 kdelibs-3.1.5.tar.bz2 48056320
在上面的示例中,http://dev.gentoo.org/~ferringb/patches/kdelibs-3.1.4-3.1.5.patch.bz2 的 md5sum 被计算出来,与存储的值进行比较,然后检查文件大小。唯一的区别是 UMD5 校验和类型 - md5 值和大小特定于未压缩文件。继续,对于补丁将驻留在我们的镜像之一的情况,补丁文件名就足够了。
最后,请注意,这是一个单向补丁 - 使用上面的示例,kdelibs-3.1.4-3.1.5 只能用于从 3.1.4 升级到 3.1.5,不能反向使用(最初在二进制补丁与 GNUDiff 补丁 中解释)。
Portage 实现
本 GLEP 建议修补支持应该(在这个阶段)是可选的 - 具体来说,通过 FEATURES="patching" 启用。
获取
当启用修补时,会读取全局补丁列表和包补丁列表。从那里,Portage 确定哪些文件可以用作修补到所需文件的基准 - 此外,还要确定是否值得进行修补(不进行修补的情况是在目标文件小于所需补丁的总和时)。任何要使用的补丁都会被获取并进行 md5 验证。
重建
获取并进行 md5 验证补丁后,会重建所需文件。假设重建没有返回任何错误,则目标文件的未压缩 md5sum 将被计算并验证,然后重新压缩并计算压缩后的 md5sum。此时,如果压缩后的 md5 与树中存储的 md5 相匹配,则 Portage 将文件传输到 distfiles,并继续其快乐的旅程。
如果压缩后的 md5 与树中的值不同,则(建议)更新 md5 数据库以包含新的压缩后的 md5。此数据库(以及它解决的问题)的详细信息如下。
压缩的 MD5sum
在某些情况下,文件会被完美地重建、重新压缩,并且重新压缩后的 md5sum 与树中存储的值不同 - 问题在于压缩文件的 md5sum 本质上与用于压缩原始源代码的压缩器版本/选项相关联。
详细问题
此问题的一个很好的例子与用于压缩的 bzip2 版本有关。在 bzip2 0.9x 和 bzip2 1.x 之间,压缩器发生了一些细微的改变,导致压缩结果略微改善 - 最终导致不同的文件,例如不同的 md5sum。假设压缩器版本相同,还存在目标源代码最初压缩到的压缩级别的问题 - 它是否使用 -9、-8 或 -7 压缩?这仅仅是必须考虑的各种原始设置的一个样本,而且这仅限于 gzip/bzip2;其他压缩器会增加要考虑的变量数量,以准确地重新创建压缩后的 md5sum。
跟踪最初使用的压缩器版本和选项实际上不是一个有效的选择 - 假设所有选项都被考虑在内,客户端仍然需要安装同一个压缩器的多个版本,仅仅是为了重新创建压缩后的 md5sum,即使未压缩源代码的 md5 已经被验证了。
提出的解决方案
创建客户端平面文件/数据库,其中包含有效的备用 md5/大小对,将使 Portage 能够处理完美重建的文件,这些文件由于压缩差异而具有不同的 md5sum。建议的格式如下
MD5 md5sum orig-file size MD5 md5sum [ optional new-name ] size
示例
MD5 984146931906a7d53300b29f58f6a899 OOo_1.0.3_source.tar.bz2 165475319 MD5 0733dd85ed44d88d1eabed704d579721 165444187
仅当未压缩源代码的 md5/大小已被验证,但重新压缩后 md5 不同时,才会添加文件的备用 md5/大小对。为了从该数据库中清除旧的 md5/大小对,需要一个实用程序 - 作者建议在 Portage 中添加一个 distfiles 清理实用程序,该实用程序能够在用于创建该对的文件不再存在于 distfiles 中时,清除旧的 md5/大小对。
数据库的存储位置值得商榷 - /etc/portage 或 /var/cache/edb 都是明确的选择。
允许使用可选的新名称的理由是,如果有人试图扩展 Portage 以允许客户端更改源代码的压缩方式(例如,将所有 gzip 文件重新压缩为 bzip2),则它可以提供必要的功能。当然,没有进行过这样的代码或尝试,但是如果提出此请求/尝试,则不会有任何损失。
添加此支持的潜在问题是,在 distfiles 目录被共享给多个系统环境中,此数据库也必须被共享。
Distfile 镜像添加
一个争论点是这些文件实际上将存储在哪里。在本 GLEP 编写时,一个完整的 distfiles 镜像大约为 40 gb - 作者粗略估计,每个版本的补丁的空间需求总计约为 4gb。请注意,这还不是一个确切的数字,目前正在检查更精确的数字。
无论确切的空间数字是多少,寻找一个存储补丁的地方都是一个问题。扩展所需的镜像空间(基本上只是吞并补丁存储需求)不太可能,因为这是反对现在已废弃的 glep9 尝试 [2] 的主要论据之一。已经提出了一些处理额外空间需求的想法,如下:
1) 确定愿意处理额外空间需求的镜像 - 本质上创建额外的补丁镜像层。
2) 仅镜像某些包版本的补丁,而不是完整的源代码。以 kdelibs-3.1.5 为例,只镜像补丁(而不是完整的 10.53 MB 源代码)。这种方法的缺点是,第一次下载 kdelibs 的用户要么需要从原始 SRC_URI 中获取它(将负担转移到上游镜像),要么获取 3.1.4 版本和补丁 - 比直接获取完整版本多获取 63k。kdelibs 3.1.4/3.1.5 的示例是一个比较理想的情况 - 并非所有版本都会有如此微小的补丁。
3) 以上想法的一种变体,本质上只镜像包的最旧版本(版本)的补丁;例如,kdelibs 目前有版本 3.05、3.1.5、3.2.0 和 3.2.1 - 镜像只包含 3.05 的补丁,而不是完整源代码 (想想 RESTRICT="fetch")。这样做的一个优点是,降级版本的补丁比升级版本的补丁要小 - 当然也有例外,但很难找到。这种方法的主要缺点是 A) 用户需要同步才能获得该版本的补丁列表,B) 创建一组用于版本降级的补丁 (参见 二进制补丁与 GNUDiff 补丁)。
在上面列出的选项中,第一个是最容易的,尽管第二个也可以实现。欢迎提供反馈和任何可能的替代方案。
补丁创建
补丁列表的维护和实际的补丁创建应由高级脚本管理 - 本质上,开发者会说“我想要这个版本和那个版本之间的补丁:生成它”,脚本会自行创建/更新补丁列表,并在本地生成补丁。然后,该工具将新补丁上传到 dev.gentoo.org 上的 /space/distfiles-local (如果它不是本地生成的补丁,则除外),并使用 repoman 提交更新的补丁列表。
更可取的是 (尽管可能是异想天开),如果可以利用硬件来自动生成补丁,而不是强加给开发者 - 类似于新 ebuild 如何自动拉取到镜像上。
最初的补丁大部分将由作者生成,以便简化过渡,并为用户提供补丁进行测试。
向后兼容性
如 提出的解决方案 中所述,使用补丁并将 distfiles 共享出去的系统必须共享其备用 md5 数据库。任何使用 distfiles 共享的系统也必须支持备用 md5 数据库。如果这被认为是一个问题,可以将重建的源代码与备用 md5 放在 distdir 的子目录中 - portage 只会查看 distdir 内,不会深入子目录。
另请注意,Distfile 镜像添加 可能会添加额外的向后兼容性问题,具体取决于接受的解决方案。
参考实现
待办事项
参考文献
[1] | http://dev.gentoo.org/~ferringb/patches/kdelibs-3.1.4-3.1.5.{patch,diff}.bz2。 |
[2] | (1, 2) kdelibs-3.1.4-3.1.5.patch.bz2,切换格式补丁,使用 diffball-0.4_pre4 创建 (diffball 可在 http://sourceforge.net/projects/diffball 获取) Bzip2 -9 压缩,补丁大小为 75,687 字节,解压缩后为 337,649 字节。该补丁可在 http://dev.gentoo.org/~ferringb/kdelibs-3.1.4-3.1.5.patch.bz2 获取,供有兴趣的使用者参考。 |
[3] | Glep9,“Gentoo 包更新系统” (https://gentoolinux.cn/glep/glep-0009.html) |
版权
本作品采用 Creative Commons Attribution-ShareAlike 3.0 Unported License 许可。要查看此许可证的副本,请访问 https://creativecommons.org/licenses/by-sa/3.0/.