如何在不启动软件包相关服务的情况下安装软件包?


13

您可能已经知道,默认情况下,在基于Debian或Ubuntu的系统上安装软件包时,如果该软件包包含服务,则通常会在安装该软件包时启用并自动启动该服务。

这对我来说是个问题。

我发现自己需要管理用于构建LXC容器的模板。有几个容器,每个容器对应一个Debian或Ubuntu版本。(也有基于Red Hat的容器,但此处与它们无关。)

/var/lib/libvirt/filesystems/debian6_template
/var/lib/libvirt/filesystems/debian7_template
/var/lib/libvirt/filesystems/ubuntu1004_template
/var/lib/libvirt/filesystems/ubuntu1204_template

有时,我会发现模板缺少软件包或需要其他更改,因此我将chroot放入其中以安装软件包。不幸的是,当我这样做时,我得到了运行包服务的多个副本!

举例来说,我发现模板没有syslog守护程序,因此我安装了一个:

for template in /var/lib/libvirt/filesystems/{debian,ubuntu}*_template; do
    chroot $template apt-get install rsyslog
done

并迅速结束运行rsyslog的四个副本。更不用说exim4的两个副本了。糟糕!


我读到某个地方(尽管现在找不到了),它不应该在chroot中运行时启动服务,但是显然这没有发生。

一个可能可行的讨厌的黑客呼吁暂时替换实际上启动服务的各种命令,例如start-stop-daemoninitctl,尽管这比我真正想做的工作要多得多。不过,如果我别无选择,...

对于基于Debian的系统,这里的理想解决方案是停止执行此操作,但是如果失败了,也许对于apt-get

如果还不清楚,我真的想保持与管理模板任何事情,如果可能的模板。

Answers:


23

对于debian,您可以使用policy-rc.d进行此操作。这是一个解释

软件包的维护者脚本应该仅通过invoke-rc.d,update-rc.d和LSB init脚本头与init系统进行交互... invoke-rc.d将在执行其操作之前检查是否/usr/sbin/policy-rc.d是可执行文件,将在其命令行上使用各自的服务名称和当前运行级别编号对其进行调用,并根据其退出代码进行操作。例如,返回值101将阻止采取计划的操作。这包括在安装软件包时自动启动服务,以及在删除软件包时停止服务,并将软件包升级过程中的stop-upgrade-restart仪式减少为仅执行升级,这可能会使服务的旧版本继续运行

由于您不希望任何服务启动,因此您的policy-rc.d脚本可以很简单

#!/bin/sh
exit 101

这是pbuilder和Docker的mkimage-debootstrap等工具使用的技术。

不幸的是,该技术不适用于Ubuntu chroots。在安装过程中,与新贵的init系统集成的软件包将调用/ usr / sbin / initctl而不是invoke-rc.d,并且initctl不会参考policy-rc.d。据新贵的作者介绍,解决方法是用chroot中的/ bin / true符号链接替换/ sbin / initctl。您也可以在mkimage-debootstrap中看到它,

dpkg-divert --local --rename --add /sbin/initctl
ln -sf /bin/true sbin/initctl

这看起来很干净,尽管在从模板创建容器之前也必须将其删除。
迈克尔·汉普顿

1
谢谢你 我可能最终只需要删除Docker的mkimage-debootstrap脚本,因为它们似乎已经解决了大多数问题。
迈克尔·汉普顿

4

你可以做:

export RUNLEVEL=1
for template in /var/lib/libvirt/filesystems/{debian,ubuntu}*_template; do
    chroot $template apt-get install rsyslog
done
exit

我尚未使用chroot对其进行测试,但它应该可以工作。首先,它设置RUNLEVEL环境变量,因此由apt-get启动的进程将不会启动任何服务,因为它们会“认为”系统正在单模式下运行。由于修改了环境可能会影响将来的命令,因此,当不再需要修改后的环境时,需要退出shell,这可以通过最后的exit命令来完成。有可能不会以单一模式(但据我所知这在大多数情况下,应该不会有问题)正确安装一些(少见?)封装。


export RUNLEVEL=1的重要组成部分,在这里?它究竟会导致什么发生?
迈克尔·汉普顿

@MichaelHampton我相信RUNLEVEL环境变量将提供当前的运行级别。在这种情况下,他只是覆盖它,因此任何应用程序都将认为它在1上运行。这有点“笨拙”,但足够了。
WinkyWolly 2014年

在原始答案中添加了解释。基本上这就是@WinkyWolly所说的。
DavisNT 2014年

不幸的是,rsyslog碰巧是试图以这种方式安装时完全炸毁的“稀有”软件包之一。不过,这可能仍然有用,因此您可以保持投票:)
Michael Hampton
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.