]> git.saurik.com Git - apt.git/commitdiff
do dpkg --configure before --remove/--purge --pending
authorDavid Kalnischkies <david@kalnischkies.de>
Mon, 22 Aug 2016 19:33:38 +0000 (21:33 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Tue, 23 Aug 2016 09:32:23 +0000 (11:32 +0200)
Commit 7ec343309b7bc6001b465c870609b3c570026149 got us most of the way,
but the last mile was botched by having the pending calls in the wrong
order as this way we potentially 'force' dpkg to remove/purge a package
it doesn't want to as another package still depends on it and the
replacement isn't fully installed yet.

So what we do now is a configure before remove and purge (all with
--no-triggers) and finishing off with another configure pending call to
take care of the triggers.

Note that in the bugreport example our current planner is forcing dpkg
to remove the package earlier via --force-depends which we could do for
the pending calls as well and could be used as a workaround, but we want
to do less forcing eventually.

Closes: 835094
apt-pkg/deb/dpkgpm.cc
test/integration/test-bug-835094-configure-before-purge [new file with mode: 0755]
test/integration/test-no-fds-leaked-to-maintainer-scripts

index 5759e6ba5d9091f1451c4f553a5b4ea6eef78009..b0700bcc6cea4cfc54524a2cca525cb456c3e85f 100644 (file)
@@ -1535,9 +1535,13 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
         if (I.Op == Item::Remove || I.Op == Item::Purge)
            toBeRemoved[I.Pkg->ID] = false;
 
-      if (std::find(toBeRemoved.begin(), toBeRemoved.end(), true) != toBeRemoved.end())
+      bool const RemovePending = std::find(toBeRemoved.begin(), toBeRemoved.end(), true) != toBeRemoved.end();
+      bool const PurgePending = approvedStates.Purge().empty() == false;
+      if (RemovePending != false || PurgePending != false)
+        List.emplace_back(Item::ConfigurePending, pkgCache::PkgIterator());
+      if (RemovePending)
         List.emplace_back(Item::RemovePending, pkgCache::PkgIterator());
-      if (approvedStates.Purge().empty() == false)
+      if (PurgePending)
         List.emplace_back(Item::PurgePending, pkgCache::PkgIterator());
 
       // support subpressing of triggers processing for special
@@ -1606,7 +1610,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
       unsigned long const Op = I->Op;
 
       if (NoTriggers == true && I->Op != Item::TriggersPending &&
-         I->Op != Item::ConfigurePending)
+         (I->Op != Item::ConfigurePending || std::next(I) != List.end()))
       {
         ADDARGC("--no-triggers");
       }
diff --git a/test/integration/test-bug-835094-configure-before-purge b/test/integration/test-bug-835094-configure-before-purge
new file mode 100755 (executable)
index 0000000..16a196c
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/sh
+set -e
+
+TESTDIR="$(readlink -f "$(dirname "$0")")"
+. "$TESTDIR/framework"
+setupenvironment
+configarchitecture 'amd64'
+
+buildsimplenativepackage 'kernel' 'amd64' '1' 'unstable' 'Depends: initramfs-tools | linux-initramfs-tool'
+
+#buildsimplenativepackage 'initramfs-tools' 'amd64' '1.0.16' 'unstable' 'Provides: linux-initramfs-tool'
+setupsimplenativepackage 'initramfs-tools' 'amd64' '1' 'unstable' 'Provides: linux-initramfs-tool'
+BUILDDIR='incoming/initramfs-tools-1'
+mkdir -p "${BUILDDIR}/debian/initramfs-tools/etc"
+echo 'foo2=bar2;' > "${BUILDDIR}/init.conf"
+echo 'init.conf        /etc/init.conf' >> "${BUILDDIR}/debian/install"
+buildpackage "$BUILDDIR" 'unstable' 'main' 'native'
+rm -rf "$BUILDDIR"
+
+buildsimplenativepackage 'dracut' 'amd64' '1' 'unstable' 'Provides: linux-initramfs-tool
+Conflicts: initramfs-tools'
+
+setupaptarchive
+
+testdpkgnotinstalled 'kernel' 'initramfs-tools' 'dracut'
+testsuccess apt install kernel -y
+testdpkginstalled 'kernel' 'initramfs-tools'
+testsuccess test -s rootdir/etc/init.conf
+testsuccessequal 'Reading package lists...
+Building dependency tree...
+Reading state information...
+The following packages will be REMOVED:
+  initramfs-tools*
+The following NEW packages will be installed:
+  dracut
+0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
+Purg initramfs-tools [1] [kernel:amd64 ]
+Inst dracut (1 unstable [amd64])
+Conf dracut (1 unstable [amd64])' apt install --purge dracut -s
+testsuccess apt install --purge dracut -y -o Debug::pkgDpkgPm=1 -o Dpkg::Use-Pty=0
+testsuccess apt install --purge dracut -y
+testdpkginstalled 'kernel' 'dracut'
+testdpkgnotinstalled 'initramfs-tools'
+testsuccess test ! -s rootdir/etc/init.conf
index 21b394055b442cbf8552a1e897df06ed6eec4b9e..baf85e3112e2eef383fc2e72d972e7594b83c44f 100755 (executable)
@@ -79,6 +79,7 @@ status half-configured $PKGNAME 1.0
 status half-installed $PKGNAME 1.0
 status config-files $PKGNAME 1.0
 status config-files $PKGNAME 1.0
+startup packages configure
 startup packages purge
 remove $PKGNAME 1.0 <none>
 purge $PKGNAME 1.0 <none>