我有一个自制的 Debian 软件包,它安装了两个脚本文件、两个 systemd 服务和一个 tar 文件。手工制作的维护者脚本是 preinst、post inst、prerm 和 postrm。
我目前遇到的问题是当我运行dpkg --purge <PACKAGE>
进程时被某些东西杀死(我不确定是什么):
root@host:/data# dpkg --purge <PACKAGE>
(Reading database ... 32393 files and directories currently installed.)
Removing <PACKAGE> (<VERSION) ...
Terminated
root@host:/data# echo $?
143
root@host:/data#
我第二次运行完全相同的命令时,效果很好。
root@host:/data# dpkg --purge <PACKAGE>
(Reading database ... 32393 files and directories currently installed.)
Removing <PACKAGE> (<VERSION>) ...
dpkg: warning: while removing <PACKAGE>, unable to remove directory '/data': Device or resource busy - directory may be a mount point?
Purging configuration files for <PACKAGE> (<VERSION>) ...
dpkg: warning: while removing web-chroot, unable to remove directory '/data': Device or resource busy - directory may be a mount point?
root@host:/data#
笔记: /data
实际上是一个挂载点,并且它不属于任何其他 Debian 软件包,因此dpkg
尝试(但失败)删除它。这应该是 Debian 实现的预期行为dpkg
。
我的问题是,为什么 dpkg --purge 进程在第一次运行时被终止?什么会杀死它?
我尝试过检查各种日志,包括:
/var/log/dpkg.log
/var/log/apt/history.log
/var/log/apt/term.log
/var/lib/dpkg/info/<PACKAGE>.*
(.list
,.prerm
,.postrm
,.preinst
,.postinst
)
但没有任何东西给我任何有用的指示来说明正在发生的事情。
笔记:Debian 软件包安装到 Debian 8 32 位系统上
细节:
Debian 软件包将文件安装在以下位置:
/~/start-fs.sh
/~/stop-fs.sh
/data/file-system_<VERSION>.tar.gz
/etc/systemd/system/file-system.service
/etc/systemd/system/file-system-helper.service
维护者脚本如下:
preinst
#!/bin/bash
# Stop services if they are running and disable them
systemctl is-active --quiet file-system && systemctl stop file-system > /dev/null 2>&1 || true
sleep 1
systemctl disable --quiet file-system.service || true
systemctl is-active --quiet file-system-helper && systemctl stop file-system-helper > /dev/null 2>&1 || true
# Remove any previous tars that could share the same name as the tar artifact
rm -f /data/file-system*.tar.gz
exit 0
postinst
#!/bin/bash
error() {
echo "$1"
exit 1
}
# Untar the artifact in the /data directory
tar -xzf /data/file-system*.tar.gz --directory /data || error "Could not untar artifact"
# Remove tar artifact, as it has already been untarred
rm -f /data/file-system*.tar.gz
# Restart systemctl daemon to let it know about new service files
systemctl daemon-reload
# Enable service if it is not running and enable it
systemctl is-active --quiet file-system || systemctl start file-system
systemctl enable --quiet file-system.service
exit 0
prerm
#!/bin/bash
# Stop services if they are running and disable them
systemctl is-active --quiet file-system && systemctl stop file-system.service > /dev/null 2>&1 || true
sleep 3
systemctl disable --quiet file-system.service || true
systemctl is-active --quiet file-system-helper && systemctl stop file-system-helper.service > /dev/null 2>&1 || true
exit 0
postrm
#!/bin/bash
# Remove scripts
rm -f /root/start-fs.sh
rm -f /root/stop-fs.sh
# Remove fs in data dir
rm -rf /data/file-system/
# Remove any possible leftover artifacts (shouldn't be any)
rm -f /data/file-system*.tar.gz
# Remove systemd services
rm -f /etc/systemd/system/file-system-helper.service
rm -f /etc/systemd/system/file-system.service
exit 0
当我dpkg -s <PACKAGE>
第一次运行时,它变成了half-configured
根据dpkg
手段The package is unpacked and configuration has been started, but not yet completed for some reason.
root@host:/data# dpkg -s <PACKAGE>
[...]
Status: purge ok half-configured
[...]
另外,如果我手动运行脚本,然后在安装包后./prerm
手动运行脚本,则成功卸载并正确删除文件。./postrm
dpkg -i <PACKAGE>
答案1
看起来您正在尝试在维护者脚本中重新实现 dpkg 应该执行的操作,但没有考虑这些调用的所有方式。
例如 prerm 和 postrm 也会在升级过程中被调用!
我的建议是避免使用 tar 进行奇怪的舞蹈,直接在 .deb 中提供这些文件,并停止手动删除 .deb 中附带的任何文件。只需让 dpkg 在需要时处理拆包和移除即可。
然后,对于何时调用 systemd 的内容,您应该检查维护者脚本流程图,无论是从 Debian 政策还是从各种 deb-man 页面(尽管这些目前还不太详细)。