回滚 Debian 安装程序中 PostInst 脚本中的错误

Rollback on Error in PostInst Script in Debian Installer

对于Debian 安装脚本,如果postinst 脚本出现错误或者用户使用Ctrl+C 终止进程,是否可以回滚整个安装?看起来即使我 return 一个非零退出代码,它仍然会安装程序。

没有

嗯,这可能 可能 ,因为 postinst 以 root 身份运行,可以做各种棘手的事情来破坏系统。但是 dpkg 尝试使用锁尽可能地防止这种情况发生,因为维护者脚本不应该改变包的“期望”状态。

我没有验证过,但我猜如果你用Ctrl+C取消一个postinst脚本,它算作postinst失败,包被标记为在 half-configured 状态。所以,它并没有完全安装,但是,是的,用户可能很难分辨出区别。

那么,一些适合您的潜在解决方案:

  1. 如果您的包裹提供服务,您可以设置一个标志(例如,某个地方的文件,如/var/lib/$yourpackage)仅当软件包完全安装时(在 postinst 结束时)。该服务将在启动时检查此标志,如果不存在,则服务不会启动,甚至可能会打印一条关于未完全安装的警告消息。该解决方案在某些方面类似于完全卸载软件包。请记住在 prermpostinst 的开头取消设置标志或删除文件(以防在升级期间而不是在第一次安装时出现 Ctrl+C)。

  2. 您可以在 postinst 中按下 Ctrl+C (SIGINT),并打印一条消息,内容类似于“This package will be left in the Failed-Config state. To remove it entirely, run (dpkg -P/apt purge/whatever). To attempt to complete installation, run dpkg --configure -a.”(然后退出postinst 使用非零退出代码,以便 dpkg 知道失败。)

  3. 如果您能够做到这一点,请让您的用户更加清楚他们何时安装了损坏的软件包,以便他们可以快速做出重新安装或删除的决定。

  4. 您可以将 postinst 中最有可能被 Ctrl+C 组合的任何内容移至 preinst。如果 preinst 失败,则 dpkg 将使用 abort-install 操作调用 postrmpostrm 预计会清除 preinst 已经完成的所有操作。如果 postrm 成功,则该包将干净利落地完全卸载。当然,如果 postinst 的这一步需要您的包中的文件被解压并呈现,那么这不是一个真正的选择。