如何强制 tar cf 获得可重现的结果?

如何强制 tar cf 获得可重现的结果?

前言:我们有一个复杂的构建过程,发现它在一个系统上工作,而在另一个系统上失败(不幸的是/Murphy,它在 Jenkins 构建服务器上工作,所以问题很长一段时间未被发现)。错误源原来是tar由某些外部组件将硬链接文件放入文件的顺序:

a并被b硬链接和tar红色,而后来,在提取 tar 文件时,仅a被提取。当然,当a第一次归档时,它可以工作,但如果b是 tar 中的第一个,Cannot hard link就会出现典型的错误。

当然,我们可以tar cf使用--hard-dereference,但这意味着更改外部工具中的脚本(这是要避免的),所以我的问题是不同的:

问题:我们的基本目标是获得独立于系统的可重复结果。目前,tar环序在一个系统上是可重现的,但在另一系统上可能会随机不同。我们可以tar在不提供选项tar或将tar呼叫拆分为多个呼叫的情况下强制执行文件顺序吗?

目前系统都是 Linux,但有时也可能是 FreeBSD 或 MacOS。

答案1

直接的方法是向 tar 提供来自 stdin 的文件列表,您可以控制该列表(例如先对其进行排序)。

但是,由于您说无法控制 tar 调用,因此您需要一种方法来控制目录条目的顺序。

ls -u您可以通过运行或查看目录条目的顺序find

要创建一个目录,其中的条目按照您想要的方式排序,请创建一个新目录,并按所需的顺序一次复制或移动一个文件。

检查一下find是否有效。使用脚本实现自动化并使其递归。

最后运行该工具。

答案2

我认为问题归结为您的构建过程分为两部分。

  • 机器 A 上的第 1 部分(生成您的成就)
  • 第 2 部分(使用您的存档完成构建)在机器 A 上运行,但在机器 B 上失败。

并且你无法创建内容机器 B 上的存档,因此必须在机器 A 上完成。

主意

在第 2 部分构建中添加一个步骤,以便在使用之前将存档清理为已知的顺序。

将文件提取到临时目录中,并按照您的首选顺序创建您自己的存档,在两台计算机 A 和 B 上执行此操作(这将是第 2 部分的步骤 0)。

或者,我的 tar (tar (GNU tar) 1.30) 版本有这个选项:

      -s, --preserve-order, --same-order
              Sort names to extract to match archive              

相关内容