为什么apt-get安装比指定包支持的更新的依赖项

我遇到了一个问题,在特定版本的软件包需要另一个软件包,也在特定版本,但Apt-Get选择较新版本的依赖项,然后失败。

我已经通过Puppet Lab的MCollective和Nginx Mainline PPA以及可能的其他软件包体验过这一点,所以我的问题是关于Apt-Get依赖解析的一般方法,但我将使用Nginx作为我的例子。

我有一个包镜像(用Aptly构建),包含nginx-full软件包的v1.7.5及其所有依赖项以及更新的v1.7.6软件包及其所有依赖项。

如果我执行apt-get install nginx-full=1.7.5-1+trusty1则安装失败并显示以下消息:

 The following packages have unmet dependencies: nginx-full : Depends: nginx-common (= 1.7.5-1+trusty1) but 1.7.6-1+trusty1 is to be installed 

但是,如果我执行apt-get install nginx-full=1.7.5-1+trusty1 nginx-common=1.7.5-1+trusty1那么安装成功。

当我在镜像上有nginx-common软件包的1.7.5和1.7.6版本时,nginx-full软件包明确声明它需要1.7.5的nginx-common,而nginx-full是我要求的软件包,为什么apt-get仍然选择不兼容的1.7.6版本的nginx-common?

这是安装1.7.5后dpkg -s nginx-full的输出,显示了确切的版本依赖性约束:

 Version: 1.7.5-1+trusty1 Depends: nginx-common (= 1.7.5-1+trusty1), libc6 (>= 2.14), ... 

在这种情况下,所需的确切版本链很短,因此解决方法很容易,但对我来说至少有两个问题:

  1. 其他包具有更长的依赖链,这些依赖链很难发现,然后附加到apt-get命令行。
  2. 在将新版本的依赖项发布到包镜像之前,很容易意识到即将发生的问题。

我无法理解的是,依赖解析显然忽略了指定包上的确切版本约束。 更重要的是,我想知道如何让Apt-Get遵守约束,而不必手动将包元数据复制到我的apt-get参数上。

您遇到的问题是apt / apt-get没有您想象的那么聪明。

尝试降级软件包或安装较旧的软件包版本时,会出现此问题,而不是存储库具有的最新版本(关于您的apt优先级固定和有关存储库优先级的其他策略)。 当您降级软件包时,实际上必须为每个单独的依赖项指定要降级的版本,或者在这种情况下,您实际要安装哪个特定版本。

对于nginx包, nginx-fullnginx-common相互依赖,你必须明确告诉apt安装指定版本的每个包 。 这是因为1.7.6-1+trusty1取代版本号1.7.5-1+trusty1 。 因此,您必须具体说“仅安装此特定版本的软件包”,因为已存在已取代的版本,即apt-get install nginx-full=1.7.5-1+trusty1 nginx-common=1.7.5-1+trusty1

与您的问题无关,但是当您从具有比其他版本更低的apt固定优先级的存储库安装时也会发生这种情况,在这种情况下,您必须指定要手动安装的版本和/或源,即sudo apt-get install nginx-full/trusty-proposed nginx-common/trusty-proposed是尝试从建议的存储库安装包和依赖项的一个主要示例,该存储库具有比PPA或主存储库低得多的优先级。