Просмотр исходного кода

pass --force-remove-essential to dpkg only if needed

APT (usually) knows which package is essential or not, so we can avoid
passing this force flag to dpkg unconditionally  if the user hasn't
chosen a non-default essential handling obscuring the information.
David Kalnischkies лет назад: 10
Родитель
Сommit
d3930f8716

+ 13 - 2
apt-pkg/deb/dpkgpm.cc

@@ -1233,6 +1233,15 @@ void pkgDPkgPM::StopPtyMagic()						/*{{{*/
  */
 bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
 {
+   auto const ItemIsEssential = [](pkgDPkgPM::Item const &I) {
+      static auto const cachegen = _config->Find("pkgCacheGen::Essential");
+      if (cachegen == "none" || cachegen == "native")
+	 return true;
+      if (unlikely(I.Pkg.end()))
+	 return true;
+      return (I.Pkg->Flags & pkgCache::Flag::Essential) != 0;
+   };
+
    pkgPackageManager::SigINTStop = false;
    d->progress = progress;
 
@@ -1350,13 +1359,15 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
       {
 	 case Item::Remove:
 	 ADDARGC("--force-depends");
-	 ADDARGC("--force-remove-essential");
+	 if (std::any_of(I, J, ItemIsEssential))
+	    ADDARGC("--force-remove-essential");
 	 ADDARGC("--remove");
 	 break;
 
 	 case Item::Purge:
 	 ADDARGC("--force-depends");
-	 ADDARGC("--force-remove-essential");
+	 if (std::any_of(I, J, ItemIsEssential))
+	    ADDARGC("--force-remove-essential");
 	 ADDARGC("--purge");
 	 break;
 

+ 3 - 0
test/integration/test-essential-force-loopbreak

@@ -43,6 +43,9 @@ E: Internal Error, Could not early remove sysvinit:$(dpkg --print-architecture)
 
 	# with enough force however …
 	cp -a dpkg.status.backup rootdir/var/lib/dpkg/status
+	testsuccess aptget install systemd-sysv -y -t "$1" -o APT::Force-LoopBreak=1 -o Debug::pkgDpkgPm=1
+	cp rootdir/tmp/testsuccess.output apt.output
+	testsuccess grep -- '--force-remove-essential --remove sysvinit' apt.output
 	testsuccess aptget install systemd-sysv -y -t "$1" -o APT::Force-LoopBreak=1
 	testdpkginstalled 'sysvinit' 'systemd-sysv'
 }

+ 4 - 0
test/integration/test-ubuntu-bug-761175-remove-purge

@@ -30,6 +30,8 @@ runtests() {
 	testsuccess aptget install compiz-core-${PKG} -t "${RELEASE}" "$@"
 	testdpkginstalled compiz-core-${PKG}
 
+	testsuccess aptget remove compiz-core-${PKG} -y "$@" -o Debug::pkgDpkgPm=1
+	testfailure grep -- '--force-remove-essential' rootdir/tmp/testsuccess.output
 	testsuccess aptget remove compiz-core-${PKG} -y "$@"
 	testdpkgnotinstalled compiz-core-${PKG}
 	testdpkgstatus 'rc' '1' "compiz-core-${PKG}"
@@ -61,6 +63,8 @@ The following packages will be REMOVED:
 0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
 Purg compiz-core-${PKG}" aptget purge compiz-core-${PKG} -s "$@"
 	fi
+	testsuccess aptget purge compiz-core-${PKG} -y "$@" -o Debug::pkgDpkgPm=1
+	testfailure grep -- '--force-remove-essential' rootdir/tmp/testsuccess.output
 	testsuccess aptget purge compiz-core-${PKG} -y "$@"
 	echo -n '' > rootdir/var/lib/dpkg/available # dpkg -l < 1.16.2 reads the available file by default, where the package can be found
 	testequalor2 "dpkg-query: no packages found matching compiz-core-${PKG}" "No packages found matching compiz-core-${PKG}." dpkg -l compiz-core-${PKG}