summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2018-10-05 12:29:39 +0200
committerJulian Andres Klode <julian.klode@canonical.com>2018-10-09 11:34:57 +0200
commit0ce6bc5ec70ff84eb2829f91f286a93687e77a46 (patch)
treefb37ba15f426c225ddf61af2858135551d496e14
parent9f9973de79bb8f2d3c2a6755e402cf5c2127c0ae (diff)
downloadapt-0ce6bc5ec70ff84eb2829f91f286a93687e77a46.tar.gz
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.cc3
-rw-r--r--apt-pkg/deb/dpkgpm.cc3
-rwxr-xr-xtest/integration/test-frontend-lock80
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'