summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/packagemanager.cc19
-rwxr-xr-xtest/integration/test-essential-force-loopbreak36
2 files changed, 39 insertions, 16 deletions
diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc
index ad7612bc3..1a2850a2a 100644
--- a/apt-pkg/packagemanager.cc
+++ b/apt-pkg/packagemanager.cc
@@ -654,6 +654,9 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg, DepIterator const * const D
bool IsEssential = false;
if ((Pkg->Flags & pkgCache::Flag::Essential) != 0)
IsEssential = true;
+ bool IsProtected = false;
+ if ((Pkg->Flags & pkgCache::Flag::Important) != 0)
+ IsProtected = true;
/* Check for packages that are the dependents of essential packages and
promote them too */
@@ -661,13 +664,17 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg, DepIterator const * const D
{
for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() == false &&
IsEssential == false; ++D)
- if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
+ if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) {
if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0)
IsEssential = true;
+ if ((D.ParentPkg()->Flags & pkgCache::Flag::Important) != 0)
+ IsProtected = true;
+ }
}
if (IsEssential == true)
{
+ // FIXME: Unify messaging with Protected below.
if (_config->FindB("APT::Force-LoopBreak",false) == false)
return _error->Error(_("This installation run will require temporarily "
"removing the essential package %s due to a "
@@ -678,6 +685,16 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg, DepIterator const * const D
// dpkg will auto-deconfigure it, no need for the big remove hammer
else if (Dep != NULL && (*Dep)->Type == pkgCache::Dep::DpkgBreaks)
return true;
+ else if (IsProtected == true)
+ {
+ // FIXME: Message should talk about Protected, not Essential, and unified.
+ if (_config->FindB("APT::Force-LoopBreak",false) == false)
+ return _error->Error(_("This installation run will require temporarily "
+ "removing the essential package %s due to a "
+ "Conflicts/Pre-Depends loop. This is often bad, "
+ "but if you really want to do it, activate the "
+ "APT::Force-LoopBreak option."),Pkg.FullName().c_str());
+ }
bool Res = SmartRemove(Pkg);
if (Cache[Pkg].Delete() == false)
diff --git a/test/integration/test-essential-force-loopbreak b/test/integration/test-essential-force-loopbreak
index 2eba0a96a..d2f663201 100755
--- a/test/integration/test-essential-force-loopbreak
+++ b/test/integration/test-essential-force-loopbreak
@@ -36,35 +36,41 @@ setupaptarchive
cp -a rootdir/var/lib/dpkg/status dpkg.status.backup
testforcebreak() {
+ package="sid-$1"
+ prefix="$2"
cp -a dpkg.status.backup rootdir/var/lib/dpkg/status
rm -f rootdir/var/lib/apt/extended_states
testfailureequal "Reading package lists...
Building dependency tree...
The following additional packages will be installed:
- sysvinit
+ ${prefix}sysvinit
The following NEW packages will be installed:
- systemd-sysv
+ ${prefix}systemd-sysv
The following packages will be upgraded:
- sysvinit
+ ${prefix}sysvinit
1 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
-E: This installation run will require temporarily removing the essential package sysvinit:$(getarchitecture 'native') due to a Conflicts/Pre-Depends loop. This is often bad, but if you really want to do it, activate the APT::Force-LoopBreak option.
-E: Internal Error, Could not early remove sysvinit:$(dpkg --print-architecture) (2)" aptget install systemd-sysv -t "$1" -s
+E: This installation run will require temporarily removing the essential package ${prefix}sysvinit:$(getarchitecture 'native') due to a Conflicts/Pre-Depends loop. This is often bad, but if you really want to do it, activate the APT::Force-LoopBreak option.
+E: Internal Error, Could not early remove ${prefix}sysvinit:$(dpkg --print-architecture) (2)" aptget install ${prefix}systemd-sysv -t "$package" -s
# ensure that really nothing happens
- testfailure aptget install systemd-sysv -y -t "$1"
- testdpkginstalled 'sysvinit'
- testdpkgnotinstalled 'systemd-sysv'
+ testfailure aptget install ${prefix}systemd-sysv -y -t "$package"
+ testdpkginstalled "${prefix}sysvinit"
+ testdpkgnotinstalled "${prefix}systemd-sysv"
# 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
+ testsuccess aptget install ${prefix}systemd-sysv -y -t "$package" -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'
+ if [ "$prefix" = "protected-" ]; then
+ testsuccess grep -- "--force-remove-protected --remove ${prefix}sysvinit" apt.output
+ else
+ testsuccess grep -- "--force-remove-essential --remove ${prefix}sysvinit" apt.output
+ fi
+ testsuccess aptget install ${prefix}systemd-sysv -y -t "$package" -o APT::Force-LoopBreak=1
+ testdpkginstalled "${prefix}sysvinit" "${prefix}systemd-sysv"
}
-testforcebreak 'sid-conflict'
-testforcebreak 'sid-break'
+testforcebreak 'conflict'
+testforcebreak 'break'
testnoforcebreak() {
cp -a dpkg.status.backup rootdir/var/lib/dpkg/status
@@ -105,5 +111,5 @@ Conf protected-sysvinit (2 sid [$(getarchitecture 'native')])" aptget install pr
testdpkginstalled 'protected-sysvinit' 'protected-systemd-sysv'
}
-testnoforcebreak 'conflict'
+testforcebreak 'conflict' 'protected-'
testnoforcebreak 'break'