rpm 升级不能用文件替换目录?

rpm upgrade can't replace directory with file?

我维护了一个以前版本的包,其中包含一个包含文件的子目录。升级发生在 RHEL/CentOS 7。例如我的版本 1.0 RPM 包含:

/opt/foo/etc/bar/x/y
/opt/foo/etc/bar/z

等在此包的较新版本中,我必须用同名文件替换整个 /opt/foo/etc/bar 目录(不幸的是,该工具需要这样做,对此我无能为力)。所以在新版本的包中,会包含

/opt/foo/etc/bar

这是一个文件。

如果我 运行 正常 rpm --upgrade pkg-2.0.rpm,我什至在调用任何规范脚本之前就收到错误消息:

file /opt/foo/etc/bar from install of pkg-2.0-1.x86_64 conflicts with file from package pkg-1.0-1.x86_64

为了避免这种情况,我必须在我的 rpm 命令行中添加 --replacefiles 选项,这很糟糕。

即使我这样做了,它仍然失败了,这次是在我的 preinst scriptlet 运行s 之后,出现如下错误:

error: unpacking of archive failed on file /opt/foo/etc/bar: cpio: rename failed - Is a directory
error: pkg-2.0-1.x86_64: install failed
error: pkg-1.0-1.x86_64: erase skipped

据我所知,我能做到这一点的唯一方法是修改我的 preinst 以删除目录,并将 --replacefiles 选项添加到 rpm。即使在我完成所有这些之后,虽然升级确实成功了,但它会为 "missing" (因为我删除了目录)的每个文件发出警告:

warning: file /opt/foo/etc/bar/x/y: remove failed: Not a directory
warning: file /opt/foo/etc/bar/z: remove failed: Not a directory

我不知道为什么会显示此错误,因为这些东西 不是 目录而且从来都不是,但无论如何。

我到处搜索关于这个特定问题的信息,虽然我发现了很多类似的错误,但它们都是针对不同情况的,例如人们试图安装两个文件重叠或类似的包.在这里,我肯定会尝试将一个版本的软件包升级到同一软件包的新版本。

似乎没有办法让这个在 RPM 中干净地工作;这只是 RPM 工具的缺陷还是我遗漏了什么?

这是rpm一直以来的突出问题。这是由CPIO引起的,它不能用文件替换目录(反之亦然)。

如果您不能更改路径名,那么您有两个选择 - 都是丑陋的技巧:

  1. 您从 A-1.0.rpm 开始,其中包括 /opt/foo/etc/bar/z 作为目录。然后你创建 A-transition-1.1.rpm 没有 /opt/foo/etc/bar/z 目录(事实上 - 它可以是空包)并且你将 Obsolete: A <= 0:1.0。前导零是纪元。我假设你过去没有使用过它。然后您将创建新的 A-1.0.rpm 和 Epoch: 1 并且您将 Obsolete: A-transition < 0:2.0 并且这次它可以包含 /opt/foo/etc/bar/z 作为文件。 RPM 将进行升级 0:A-1.0 -> A-transition -> 1:A-1.0

  2. 因为这是一个 CPIO 问题,您可以:

    %pre 如果 [ -d /opt/foo/etc/bar/z ];然后 rm -rf /opt/foo/etc/bar/z fi

RPM 会在删除旧包时大喊缺少 /opt/foo/etc/bar/z,但它应该会通过(你没有测试过)。