diff options
author | Julian Andres Klode <julian.klode@canonical.com> | 2018-10-05 12:29:39 +0200 |
---|---|---|
committer | Julian Andres Klode <julian.klode@canonical.com> | 2018-10-09 11:34:57 +0200 |
commit | 0ce6bc5ec70ff84eb2829f91f286a93687e77a46 (patch) | |
tree | fb37ba15f426c225ddf61af2858135551d496e14 | |
parent | 9f9973de79bb8f2d3c2a6755e402cf5c2127c0ae (diff) |
Set DPKG_FRONTEND_LOCKED when running {pre,post}-invoke scripts
Some post-invoke scripts install packages, which fails because
the environment variable is not set. This sets the variable for
all three kinds of scripts {pre,post-}invoke and pre-install-pkgs,
but we will only allow post-invoke at a later time.
Gbp-Dch: full
(cherry picked from commit 6675601c81de85b40dc89772c1d6d17f1811c5ba)
LP: #1796808
-rw-r--r-- | apt-pkg/contrib/fileutl.cc | 3 | ||||
-rw-r--r-- | apt-pkg/deb/dpkgpm.cc | 3 | ||||
-rwxr-xr-x | test/integration/test-frontend-lock | 80 |
3 files changed, 86 insertions, 0 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 85d7b36c7..eab05de4f 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -24,6 +24,7 @@ #include <apt-pkg/error.h> #include <apt-pkg/fileutl.h> #include <apt-pkg/macros.h> +#include <apt-pkg/pkgsystem.h> #include <apt-pkg/sptr.h> #include <apt-pkg/strutl.h> @@ -101,6 +102,8 @@ bool RunScripts(const char *Cnf) // This is the child if (Child == 0) { + if (_system != nullptr && _system->IsLocked() == true && (stringcasecmp(Cnf, "dpkg::post-invoke") == 0 || stringcasecmp(Cnf, "dpkg::pre-invoke") == 0)) + setenv("DPKG_FRONTEND_LOCKED", "true", 1); if (_config->FindDir("DPkg::Chroot-Directory","/") != "/") { std::cerr << "Chrooting into " diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 790019b98..c8e55fe14 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -480,6 +480,9 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) strprintf(hookfd, "%d", InfoFD); setenv("APT_HOOK_INFO_FD", hookfd.c_str(), 1); + if (_system != nullptr && _system->IsLocked() == true && stringcasecmp(Cnf, "DPkg::Pre-Install-Pkgs") == 0) + setenv("DPKG_FRONTEND_LOCKED", "true", 1); + debSystem::DpkgChrootDirectory(); const char *Args[4]; Args[0] = "/bin/sh"; diff --git a/test/integration/test-frontend-lock b/test/integration/test-frontend-lock new file mode 100755 index 000000000..939344afc --- /dev/null +++ b/test/integration/test-frontend-lock @@ -0,0 +1,80 @@ +#!/bin/sh +set -e + +TESTDIR="$(readlink -f "$(dirname "$0")")" +. "$TESTDIR/framework" + +setupenvironment +configarchitecture 'i386' + +insertinstalledpackage 'package1' 'i386' '1.0' +insertinstalledpackage 'package2' 'i386' '1.0' +insertinstalledpackage 'package3' 'i386' '1.0' +insertinstalledpackage 'package4' 'i386' '1.0' +insertinstalledpackage 'package5' 'i386' '1.0' +insertinstalledpackage 'package6' 'i386' '1.0' +buildsimplenativepackage 'foo' 'all' '1' + +setupaptarchive + +buildsimplenativepackage 'bar' 'all' '1' + + +# Checks that the correct variable is set +msgmsg 'Post-Invoke script has DPKG_FRONTEND_LOCKED set' +testsuccess aptget -q -y -o Dpkg::Post-Invoke::="echo DPKG_FRONTEND_LOCKED=\$DPKG_FRONTEND_LOCKED" remove package1 +cp rootdir/tmp/testsuccess.output install.output +testsuccess grep DPKG_FRONTEND_LOCKED=true install.output + +msgmsg 'Pre-Invoke script has DPKG_FRONTEND_LOCKED set' +testsuccess aptget -q -y -o Dpkg::Pre-Invoke::="echo DPKG_FRONTEND_LOCKED=\$DPKG_FRONTEND_LOCKED" remove package2 +cp rootdir/tmp/testsuccess.output install.output +testsuccess grep DPKG_FRONTEND_LOCKED=true install.output + +msgmsg 'Pre-Install-Pkgs script has DPKG_FRONTEND_LOCKED set' +testsuccess aptget -q -y -o DPkg::Pre-Install-Pkgs::="echo DPKG_FRONTEND_LOCKED=\$DPKG_FRONTEND_LOCKED" remove package3 +cp rootdir/tmp/testsuccess.output install.output +testsuccess grep DPKG_FRONTEND_LOCKED=true install.output + + +# Check that the frontend lock is hold by apt-get +msgmsg 'Post-Invoke script runs while frontend is locked' +testfailure aptget -q -y -o Dpkg::Post-Invoke::="apt-get remove" remove package4 +cp rootdir/tmp/testfailure.output install.output +testsuccess grep "E: Unable to acquire the dpkg frontend lock (${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/lock-frontend), is another process using it?" install.output +testsuccess grep "E: Problem executing scripts DPkg::Post-Invoke 'apt-get remove'" install.output + +msgmsg 'Pre-Invoke script runs while frontend is locked' +testfailure aptget -q -y -o Dpkg::Pre-Invoke::="apt-get remove" remove package5 +cp rootdir/tmp/testfailure.output install.output +testsuccess grep "E: Unable to acquire the dpkg frontend lock (${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/lock-frontend), is another process using it?" install.output +testsuccess grep "E: Problem executing scripts DPkg::Pre-Invoke 'apt-get remove'" install.output + +msgmsg 'Pre-Install-Pkgs runs while frontend is locked' +testfailure aptget -q -y -o DPkg::Pre-Install-Pkgs::="apt-get remove" remove package6 +cp rootdir/tmp/testfailure.output install.output +testsuccess grep "E: Unable to acquire the dpkg frontend lock (${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/lock-frontend), is another process using it?" install.output +testsuccess grep "E: Sub-process apt-get remove returned an error code (100)" install.output +testsuccess grep "Failure running script apt-get remove" install.output + + +# Applied test case from DonKult +msgmsg 'Applied case of frontend locking' +cat > ./post-invoke <<EOF +#!/bin/sh +set -e +#export DPKG_FRONTEND_LOCKED=true +${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg -i ${TMPWORKINGDIRECTORY}/incoming/bar_1_all.deb +EOF +chmod +x ./post-invoke +echo "dpkg::post-invoke:: \"${TMPWORKINGDIRECTORY}/post-invoke\";" > rootdir/etc/apt/apt.conf.d/01dpkgpostinvoke + +testdpkgnotinstalled 'foo' 'bar' +testsuccess apt show foo +testfailure apt show bar + +testsuccess apt install foo -s +testdpkgnotinstalled 'foo' 'bar' + +testsuccess apt install foo +testdpkginstalled 'foo' 'bar' |