这篇文章最初发布在 stackoverflow 上(https://stackoverflow.com/questions/47099045/how-do-you-create-a-dpkg-admin-directory)但可能更适合这里
我有一个以前仅针对基于 RPM 的发行版的包,现在我正在为基于 Debian 的发行版构建 .deb 包。
目的是从与您正在构建的系统隔离的用户空间模拟测试安装。它可能有多用户,并且您不希望仅构建软件就需要 root 访问权限。我们的许多测试已经模拟了安装目录结构。这是下一步使用构建的包模拟实际安装。
对于 RPM 包,我可以使用以下命令创建测试安装:
WSDIR=/where/I/want/my/tests/to/run
rpmdb --initdb --dbpath "$WSDIR"/rpmdb
rpm --relocate /opt="$WSDIR"/opt --dbpath $WSDIR/rpmdb -i <package>.rpm
Debian 世界中的对应内容如下:
dpkg --force-not-root --admindir=$WSDIR/dpkg --root=$WSDIR/install --install "$DEB"
然而,我却被相当于这个rpmdb --initdb
步骤的问题难住了。
请注意,我可以使用以下方法解压档案:
dpkg-deb -x "$DEB" $WSDIR/install
但我更希望更接近真实软件包的安装方式。另外,我不认为这会运行preinstall
脚本postinstall
。
类似的问题建议使用deboostrap
来创建chroot
环境,但这会创建一个全新的安装。除了过度使用之外,对于自动化测试来说,它太慢了。我打算在实际测试环境中进行进一步测试之前,使用它来快速测试安装包。
我迄今为止的实验:
(cd $WSDIR/dpkg && mkdir alternatives info parts triggers updates)
cp /var/lib/dpkg/status $WSDIR/dpkg/status
最好的结果是:
dpkg: error: unable to access dpkg status area: No such file or directory
这并没有明确指出问题出在哪里。
又怎样做您创建了 dpkg 管理目录吗?
更新 2017/11/24
我尝试使用 dpkg 目录从以下环境创建的环境中进行复制牛舞者(在底层使用 deboostrap)或从 /var/lib/dpkg 复制真正的版本,但我仍然收到相同的错误消息,所以也许错误(和/或 --admindir 选项)并不意味着我所想的那样。
注意:
sudo dpkg --force-not-root --root=$WSDIR/install --admindir=/var/lib/dpkg --install "$DEB"
确实有效。所以这与 admind 目录有关。
我还将这个问题重新命名为“如何创建 dpkg 管理目录”,这是一个有趣的问题,但答案不一定能解决我的问题。
答案1
感谢 Guillem Jover(见https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=883700) 并深入研究了 dpkg 源代码。我现在有一个解决方案:
mkdir fake
mkdir fake/install
mkdir -p fake/dpkg/info
mkdir -p fake/dpkg/updates
touch fake/dpkg/status
PATH=/sbin:/usr/sbin:$PATH fakeroot dpkg --force-script-chrootless --log=`pwd`/fake/dpkg.log --root=`pwd`/fake --instdir `pwd`/fake --admindir=`pwd`/fake/dpkg --install *.deb
需要注意的几点:
--force-not-root
还不够。fakeroot
是必需的。ldconfig
并且start-stop-daemon
必须在路径上。(因此 PATH=/sbin:/usr/sbin:$PATH)日志文件需要从默认位置重新定位
/var/log/dpkg.log
参数的顺序很重要。如果使用,
--root
必须位于--instdir
和之前--admindir
。admindir 应该以安装目录作为前缀。
如果软件包中包含任何安装前或安装后脚本(preinst、postinst),那么就需要 --force-script-chrootless,因为这些脚本通常通过 chroot() 运行,而当在 fakeroot 下尝试时,会导致操作不允许。