From f8ff3afcd42d8b2e6506bc6f44a894149bf87442 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 23 Feb 2021 18:23:30 +0100 Subject: Do not require force-loopbreak on Protected packages dpkg will be changed in 1.20.8 to not require --force-remove for deconfiguration anymore, but we want to decouple our changes from the dpkg ones, so let's always pass --force-remove-protected when installing packages such that we can deconfigure protected packages. Closes: #983014 --- test/integration/test-essential-force-loopbreak | 57 ++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) (limited to 'test/integration/test-essential-force-loopbreak') diff --git a/test/integration/test-essential-force-loopbreak b/test/integration/test-essential-force-loopbreak index f585e9c42..2eba0a96a 100755 --- a/test/integration/test-essential-force-loopbreak +++ b/test/integration/test-essential-force-loopbreak @@ -18,6 +18,19 @@ Breaks: sysvinit-core' buildsimplenativepackage 'systemd-sysv' 'native' '2~break' 'sid-break' 'Breaks: sysvinit (<< 2), sysvinit-core' +# one more time, with Protected +insertinstalledpackage 'protected-sysvinit' 'native' '1' 'Protected: yes' + +buildsimplenativepackage 'protected-sysvinit' 'native' '2' 'sid' 'Pre-Depends: protected-sysvinit-core | protected-systemd-sysv +Protected: yes' +buildsimplenativepackage 'protected-sysvinit-core' 'native' '2' 'sid' + +buildsimplenativepackage 'protected-systemd-sysv' 'native' '2~conflict' 'sid-conflict' 'Conflicts: protected-sysvinit (<< 2) +Breaks: protected-sysvinit-core' + +buildsimplenativepackage 'protected-systemd-sysv' 'native' '2~break' 'sid-break' 'Breaks: protected-sysvinit (<< 2), protected-sysvinit-core' + + setupaptarchive cp -a rootdir/var/lib/dpkg/status dpkg.status.backup @@ -33,7 +46,7 @@ The following NEW packages will be installed: systemd-sysv The following packages will be upgraded: sysvinit -1 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. +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 # ensure that really nothing happens @@ -52,3 +65,45 @@ E: Internal Error, Could not early remove sysvinit:$(dpkg --print-architecture) testforcebreak 'sid-conflict' testforcebreak 'sid-break' + +testnoforcebreak() { + cp -a dpkg.status.backup rootdir/var/lib/dpkg/status + rm -f rootdir/var/lib/apt/extended_states + testequalor2 "Reading package lists... +Building dependency tree... +The following additional packages will be installed: + protected-sysvinit +The following NEW packages will be installed: + protected-systemd-sysv +The following packages will be upgraded: + protected-sysvinit +1 upgraded, 1 newly installed, 0 to remove and 1 not upgraded. +Inst protected-systemd-sysv (2~$1 sid-$1 [$(getarchitecture 'native')]) [protected-systemd-sysv:$(getarchitecture 'native') on protected-sysvinit:$(getarchitecture 'native')] [] +Conf protected-systemd-sysv:$(getarchitecture 'native') broken + Breaks:protected-sysvinit:$(getarchitecture 'native') + [] +Inst protected-sysvinit [1] (2 sid [$(getarchitecture 'native')]) +Conf protected-sysvinit (2 sid [$(getarchitecture 'native')]) +E: Conf Broken protected-systemd-sysv:$(getarchitecture 'native')" "Reading package lists... +Building dependency tree... +The following additional packages will be installed: + protected-sysvinit +The following NEW packages will be installed: + protected-systemd-sysv +The following packages will be upgraded: + protected-sysvinit +1 upgraded, 1 newly installed, 0 to remove and 1 not upgraded. +Remv protected-sysvinit [1] +Inst protected-systemd-sysv (2~conflict sid-conflict [$(getarchitecture 'native')]) +Conf protected-systemd-sysv (2~conflict sid-conflict [$(getarchitecture 'native')]) +Inst protected-sysvinit [1] (2 sid [$(getarchitecture 'native')]) +Conf protected-sysvinit (2 sid [$(getarchitecture 'native')])" aptget install protected-systemd-sysv -t "sid-$1" -s + + # we check with 'real' packages here as the simulation reports a 'Conf broken' + cp -a dpkg.status.backup rootdir/var/lib/dpkg/status + testsuccess aptget install protected-systemd-sysv -y -t "sid-$1" + testdpkginstalled 'protected-sysvinit' 'protected-systemd-sysv' +} + +testnoforcebreak 'conflict' +testnoforcebreak 'break' -- cgit v1.2.3-70-g09d2 From 0d51cf142884801c903df0cddaec5545f0174553 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 1 Mar 2021 21:43:03 +0100 Subject: regression fix: do require force-loopbreak for Conflicts Conflicts do require removing the package temporarily, so they really should not be used. We need to improve that eventually such that we can deconfigure packages when we have to remove their dependencies due to conflicts. --- apt-pkg/packagemanager.cc | 19 ++++++++++++- test/integration/test-essential-force-loopbreak | 36 ++++++++++++++----------- 2 files changed, 39 insertions(+), 16 deletions(-) (limited to 'test/integration/test-essential-force-loopbreak') 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' -- cgit v1.2.3-70-g09d2