summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
1044354)
In most cases apt was already skipping the (re)setting of packages as
to be removed/purged if dpkg had told us that it already did, but we
haven't dealt with it in the most obvious of the cases: Selections set
for packages we touched in this operation which either restores
selections even dpkg would have overridden or e.g. tries to restore a
purge selection for a package which was just purged – does not happen
with apt itself as it isn't using selections in this way, but higher
frontends like aptitude do.
The result in the later case is a warning printed by dpkg that we try to
set selections for an unknown package, which is harmless per se, but can
be confusing for users and we really shouldn't cause warnings in dpkg if
we can help it.
Reported-By: Guillem Jover on IRC
std::distance(List.cbegin(), List.cend());
ExpandPendingCalls(List, Cache);
std::distance(List.cbegin(), List.cend());
ExpandPendingCalls(List, Cache);
- auto const StripAlreadyDoneFromPending = [&](APT::VersionVector & Pending) {
+ /* if dpkg told us that it has already done everything to the package we wanted it to do,
+ we shouldn't ask it for "more" later. That can e.g. happen if packages without conffiles
+ are purged as they will have pass through the purge states on remove already */
+ auto const StripAlreadyDoneFrom = [&](APT::VersionVector & Pending) {
Pending.erase(std::remove_if(Pending.begin(), Pending.end(), [&](pkgCache::VerIterator const &Ver) {
auto const PN = Ver.ParentPkg().FullName();
Pending.erase(std::remove_if(Pending.begin(), Pending.end(), [&](pkgCache::VerIterator const &Ver) {
auto const PN = Ver.ParentPkg().FullName();
- return PackageOps[PN].size() <= PackageOpsDone[PN];
+ auto const POD = PackageOpsDone.find(PN);
+ if (POD == PackageOpsDone.end())
+ return false;
+ return PackageOps[PN].size() <= POD->second;
else if (I->Op == Item::RemovePending)
{
++I;
else if (I->Op == Item::RemovePending)
{
++I;
- StripAlreadyDoneFromPending(approvedStates.Remove());
+ StripAlreadyDoneFrom(approvedStates.Remove());
if (approvedStates.Remove().empty())
continue;
}
if (approvedStates.Remove().empty())
continue;
}
++I;
// explicit removes of packages without conffiles passthrough the purge states instantly, too.
// Setting these non-installed packages up for purging generates 'unknown pkg' warnings from dpkg
++I;
// explicit removes of packages without conffiles passthrough the purge states instantly, too.
// Setting these non-installed packages up for purging generates 'unknown pkg' warnings from dpkg
- StripAlreadyDoneFromPending(approvedStates.Purge());
+ StripAlreadyDoneFrom(approvedStates.Purge());
if (approvedStates.Purge().empty())
continue;
std::remove_reference<decltype(approvedStates.Remove())>::type approvedRemoves;
if (approvedStates.Purge().empty())
continue;
std::remove_reference<decltype(approvedStates.Remove())>::type approvedRemoves;
if (d->dpkg_error.empty() == false)
{
// no point in reseting packages we already completed removal for
if (d->dpkg_error.empty() == false)
{
// no point in reseting packages we already completed removal for
- StripAlreadyDoneFromPending(approvedStates.Remove());
- StripAlreadyDoneFromPending(approvedStates.Purge());
+ StripAlreadyDoneFrom(approvedStates.Remove());
+ StripAlreadyDoneFrom(approvedStates.Purge());
APT::StateChanges undo;
auto && undoRem = approvedStates.Remove();
std::move(undoRem.begin(), undoRem.end(), std::back_inserter(undo.Install()));
APT::StateChanges undo;
auto && undoRem = approvedStates.Remove();
std::move(undoRem.begin(), undoRem.end(), std::back_inserter(undo.Install()));
if (undo.Save(false) == false)
_error->Error("Couldn't revert dpkg selection for approved remove/purge after an error was encountered!");
}
if (undo.Save(false) == false)
_error->Error("Couldn't revert dpkg selection for approved remove/purge after an error was encountered!");
}
+
+ StripAlreadyDoneFrom(currentStates.Remove());
+ StripAlreadyDoneFrom(currentStates.Purge());
if (currentStates.Save(false) == false)
_error->Error("Couldn't restore dpkg selection states which were present before this interaction!");
if (currentStates.Save(false) == false)
_error->Error("Couldn't restore dpkg selection states which were present before this interaction!");
if expr match "$2" '^-dy\?' >/dev/null 2>&1; then return; fi # download-only mode
shift
done
if expr match "$2" '^-dy\?' >/dev/null 2>&1; then return; fi # download-only mode
shift
done
- testfailure grep '^dpkg: warning:.*ignor.*' "${TMPWORKINGDIRECTORY}/rootdir/tmp-before/${TESTCALL}.output"
+ testfailure grep '^dpkg: warning:.*\(ignor\|unknown\).*' "${TMPWORKINGDIRECTORY}/rootdir/tmp-before/${TESTCALL}.output"
}
aptautotest_aptget_install() { testaptautotestnodpkgwarning "$@"; }
}
aptautotest_aptget_install() { testaptautotestnodpkgwarning "$@"; }
Remv foo-multi2-2 [1]
Remv foo-plus-1 [1]
Remv foo-plus-2 [1]' apt autoremove -s
Remv foo-multi2-2 [1]
Remv foo-plus-1 [1]
Remv foo-plus-2 [1]' apt autoremove -s
+
+testdpkgstatus 'pi' '1' 'unrelated'
+testsuccess apt purge unrelated -y