How do you create a fake install of a debian package for use in testing?
Asked Answered
B

3

6

I have a package that previously only targeted RPM based distros for which I am now building .deb packages for Debian based distros.

The aim is to simulate a test installation from user-space that is isolated from the system you are building on. It may be multi-user and you do not want to require root access just to build the software. Many of our tests simulate the installation directory structure already. This is for the next step up to simulate an actual installation using packages built.

For the RPM packages I was able to create test installations using:

WSDIR=/where/I/want/my/tests/to/run
rpmdb --initdb --dbpath "$WSDIR"/rpmdb
rpm --relocate /opt="$WSDIR"/opt --dbpath $WSDIR/rpmdb -i <package>.rpm 

The equivalent in the Debian world is something like:

dpkg --force-not-root --admindir=$WSDIR/dpkg --root=$WSDIR/install --install "$DEB" 

However, I am stuck over the equivalent to the rpmdb --initdb step.

Note that I can just unpack the archive using:

dpkg-deb -x "$DEB" $WSDIR/install

But I would prefer to be closer to how a real package is installed. Also I don't think this will run preinstall and postinstall scripts.

Similar questions have suggested using deboostrap to create a chroot environment but this creates a complete new installation. As well as being overkill it is too slow for an automated test. I intend to use this for quick tests of the installation package prior to further testing in actual test environments.

My experiments so far:

(cd $WSDIR/dpkg && mkdir alternatives info parts triggers updates)
cp /var/lib/dpkg/status $WSDIR/dpkg/status

have at best resulted in:

dpkg: error: unable to access dpkg status area: No such file or directory

which does not indicate clear what is wrong.

So how do you create a dpkg admin directory?

Cross posted as https://superuser.com/questions/1271145/how-do-you-create-a-dpkg-admin-directory


Update 24/11/2017

I've tried copying using the dpkg dir from an environment created by [cowdancer][1] (which uses deboostrap under the hood) or copying the real one from /var/lib/dpkg but I still get the same error message so perhaps the error (and/or the --admindir option) doesn't mean quite what I think it means.

Note that:

sudo dpkg --force-not-root --root=$WSDIR/install  --admindir=/var/lib/dpkg --install "$DEB"

does work. So it is something to do with the admin dir. I've also retitled the question as "How do you create a dpkg admin directory" is interesting question but the answer is not necessarily the solution to my problem.

Bromic answered 3/11, 2017 at 15:16 Comment(1)
I think this question probably belongs on superuser rather than here. I am unable to move it so I'm going to cross post and delete/close once the bounty is over.Bromic
B
1

I eventually found an answer for this. Thanks to Guillem Jover for some of this. Pasting a copy of it here:

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

Some points to note:

  • --force-not-root is not enough. fakeroot is required.

  • ldconfig and start-stop-daemon must be on the path. (hence PATH=/sbin:/usr/sbin:$PATH)

  • The log file needs to be relocated from the default /var/log/dpkg.log

  • The order of arguments is significant. If used --root must be before --instdir and --admindir.

  • The admindir is supposed to have a the installation dir as a prefix.

  • If the package contains any pre or post installation scripts (preinst,postinst) then --force-script-chrootless is required as these scripts are normally run via chroot() which gives operation not permitted when attempted under fakeroot.


Its worth mentioning that a modern solution would be to do a normal install in a docker sandbox environment.

Bromic answered 19/2, 2019 at 11:17 Comment(0)
O
1

The minimal way to create a dpkg database is something like this:

$ mkdir -p db/{updates,info}
$ touch db/{status,diversions,statoverride}

If you want to use that as non-root, currently the best way is to use fakeroot.

$ mkdir -p fsys
$ PATH=/sbin:/usr/sbin:$PATH fakeroot dpkg --log=/dev/null --admindir=db --instdir=fsys -i pkg.deb

But take into account that passing --root after --admindir or --instdir will reset those paths, which is I think the problem you have been having here.

Also using sudo and --force-not-root does not make much sense? :) And is definitely less confined than using just fakeroot. In the near future it will be possible to run dpkg fully unprivileged in some local tree.

Oilcup answered 6/12, 2017 at 18:12 Comment(0)
B
1

I eventually found an answer for this. Thanks to Guillem Jover for some of this. Pasting a copy of it here:

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

Some points to note:

  • --force-not-root is not enough. fakeroot is required.

  • ldconfig and start-stop-daemon must be on the path. (hence PATH=/sbin:/usr/sbin:$PATH)

  • The log file needs to be relocated from the default /var/log/dpkg.log

  • The order of arguments is significant. If used --root must be before --instdir and --admindir.

  • The admindir is supposed to have a the installation dir as a prefix.

  • If the package contains any pre or post installation scripts (preinst,postinst) then --force-script-chrootless is required as these scripts are normally run via chroot() which gives operation not permitted when attempted under fakeroot.


Its worth mentioning that a modern solution would be to do a normal install in a docker sandbox environment.

Bromic answered 19/2, 2019 at 11:17 Comment(0)
F
0

For a quick test of trivial dependencies, you can directly install on the system using 'dpkg -i' then 'dpkg -P' and 'apt-get autoremove' to purge the package and clean the dependencies.

An other more secure but slower solution could be to use the autopkgtest package: https://people.debian.org/~mpitt/autopkgtest/README.package-tests.html

Faux answered 3/11, 2017 at 15:33 Comment(2)
The whole point is to have my build isolated from the system I'm building on. dpkg -i wouldn't have that isolation. Also I presume it would require root access to modify /var/lib/dpkg.Bromic
autopkgtest looks interesting but I am not looking for another test framework. Particularly as I still need to support non-debian platforms.Bromic

© 2022 - 2024 — McMap. All rights reserved.