Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rhel-8.10: Fix for RHEL-68770 #1681

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 32 additions & 18 deletions libdnf/transaction/MergedTransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ static bool transaction_item_sort_function(const std::shared_ptr<TransactionItem
* Actions are merged using following rules:
* (old action) -> (new action) = (merged action)
*
* Erase/Obsolete -> Install/Obsoleting = Reinstall/Downgrade/Upgrade
* Erase/Obsolete -> Install/Obsoleting = Downgrade/Upgrade
*
* Reinstall/Reason change -> (new action) = (new action)
*
Expand All @@ -210,6 +210,9 @@ static bool transaction_item_sort_function(const std::shared_ptr<TransactionItem
*
* With complete transaction pair we need to get a new Upgrade/Downgrade package and
* compare versions with original package from pair.
*
* Additionally, if a package is installed both before and after the list of transactions
* with the same version, no action will be taken.
*/
std::vector< TransactionItemBasePtr >
MergedTransaction::getItems()
Expand Down Expand Up @@ -261,13 +264,17 @@ getItemIdentifier(ItemPtr item)

/**
* Resolve the difference between RPMs in the first and second transaction item
* and create a ItemPair of Upgrade, Downgrade or reinstall.
* Method is called when original package is being removed and than installed again.
* and create a ItemPair of Upgrade, Downgrade or remove the item from the merged
* transaction set in case of both packages are the same.
* Method is called when original package is being removed and then installed again.
* \param itemPairMap merged transaction set
* \param previousItemPair original item pair
* \param mTransItem new transaction item
* \return true if the original and new transaction item differ
*/
void
MergedTransaction::resolveRPMDifference(ItemPair &previousItemPair,
bool
MergedTransaction::resolveRPMDifference(ItemPairMap &itemPairMap,
ItemPair &previousItemPair,
TransactionItemBasePtr mTransItem)
{
auto firstItem = previousItemPair.first->getItem();
Expand All @@ -277,12 +284,11 @@ MergedTransaction::resolveRPMDifference(ItemPair &previousItemPair,
auto secondRPM = std::dynamic_pointer_cast< RPMItem >(secondItem);

if (firstRPM->getVersion() == secondRPM->getVersion() &&
firstRPM->getEpoch() == secondRPM->getEpoch()) {
// reinstall
mTransItem->setAction(TransactionItemAction::REINSTALL);
previousItemPair.first = mTransItem;
previousItemPair.second = nullptr;
return;
firstRPM->getEpoch() == secondRPM->getEpoch() &&
firstRPM->getRelease() == secondRPM->getRelease()) {
// Drop the item from merged transaction
itemPairMap.erase(getItemIdentifier(firstItem));
return false;
} else if ((*firstRPM) < (*secondRPM)) {
// Upgrade to secondRPM
previousItemPair.first->setAction(TransactionItemAction::UPGRADED);
Expand All @@ -293,20 +299,25 @@ MergedTransaction::resolveRPMDifference(ItemPair &previousItemPair,
mTransItem->setAction(TransactionItemAction::DOWNGRADE);
}
previousItemPair.second = mTransItem;
return true;
}

void
MergedTransaction::resolveErase(ItemPair &previousItemPair, TransactionItemBasePtr mTransItem)
MergedTransaction::resolveErase(ItemPairMap &itemPairMap,
ItemPair &previousItemPair,
TransactionItemBasePtr mTransItem)
{
/*
* The original item has been removed - it has to be installed now unless the rpmdb
* has changed. Resolve the difference between packages and mark it as Upgrade,
* Reinstall or Downgrade
* Downgrade or remove it from the transaction
*/
if (mTransItem->getAction() == TransactionItemAction::INSTALL) {
if (mTransItem->getItem()->getItemType() == ItemType::RPM) {
// resolve the difference between RPM packages
resolveRPMDifference(previousItemPair, mTransItem);
if (!resolveRPMDifference(itemPairMap, previousItemPair, mTransItem)) {
return;
}
} else {
// difference between comps can't be resolved
mTransItem->setAction(TransactionItemAction::REINSTALL);
Expand All @@ -323,11 +334,14 @@ MergedTransaction::resolveErase(ItemPair &previousItemPair, TransactionItemBaseP
* transaction - new package is used to complete the pair. Items are stored in pairs (Upgrade,
* Upgrade) or (Downgraded, Downgrade). With complete transaction pair we need to get the new
* Upgrade/Downgrade item and compare its version with the original item from the pair.
* \param itemPairMap merged transaction set
* \param previousItemPair original item pair
* \param mTransItem new transaction item
*/
void
MergedTransaction::resolveAltered(ItemPair &previousItemPair, TransactionItemBasePtr mTransItem)
MergedTransaction::resolveAltered(ItemPairMap &itemPairMap,
ItemPair &previousItemPair,
TransactionItemBasePtr mTransItem)
{
auto newState = mTransItem->getAction();
auto firstState = previousItemPair.first->getAction();
Expand Down Expand Up @@ -369,7 +383,7 @@ MergedTransaction::resolveAltered(ItemPair &previousItemPair, TransactionItemBas
} else {
if (mTransItem->getItem()->getItemType() == ItemType::RPM) {
// resolve the difference between RPM packages
resolveRPMDifference(previousItemPair, mTransItem);
resolveRPMDifference(itemPairMap, previousItemPair, mTransItem);
} else {
// difference between comps can't be resolved
previousItemPair.second->setAction(TransactionItemAction::REINSTALL);
Expand Down Expand Up @@ -405,7 +419,7 @@ MergedTransaction::mergeItem(ItemPairMap &itemPairMap, TransactionItemBasePtr mT
switch (firstState) {
case TransactionItemAction::REMOVE:
case TransactionItemAction::OBSOLETED:
resolveErase(previousItemPair, mTransItem);
resolveErase(itemPairMap, previousItemPair, mTransItem);
break;
case TransactionItemAction::INSTALL:
// the original package has been installed -> it may be either Removed, or altered
Expand All @@ -432,7 +446,7 @@ MergedTransaction::mergeItem(ItemPairMap &itemPairMap, TransactionItemBasePtr mT
case TransactionItemAction::UPGRADE:
case TransactionItemAction::UPGRADED:
case TransactionItemAction::OBSOLETE:
resolveAltered(previousItemPair, mTransItem);
resolveAltered(itemPairMap, previousItemPair, mTransItem);
break;
case TransactionItemAction::REINSTALLED:
break;
Expand Down
6 changes: 3 additions & 3 deletions libdnf/transaction/MergedTransaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ class MergedTransaction {
typedef std::map< std::string, ItemPair > ItemPairMap;

void mergeItem(ItemPairMap &itemPairMap, TransactionItemBasePtr transItem);
void resolveRPMDifference(ItemPair &previousItemPair, TransactionItemBasePtr mTransItem);
void resolveErase(ItemPair &previousItemPair, TransactionItemBasePtr mTransItem);
void resolveAltered(ItemPair &previousItemPair, TransactionItemBasePtr mTransItem);
bool resolveRPMDifference(ItemPairMap &itemPairMap, ItemPair &previousItemPair, TransactionItemBasePtr mTransItem);
void resolveErase(ItemPairMap &itemPairMap, ItemPair &previousItemPair, TransactionItemBasePtr mTransItem);
void resolveAltered(ItemPairMap &itemPairMap, ItemPair &previousItemPair, TransactionItemBasePtr mTransItem);
};

} // namespace libdnf
Expand Down
7 changes: 1 addition & 6 deletions tests/libdnf/transaction/MergedTransactionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -822,12 +822,7 @@ MergedTransactionTest::test_downgrade_upgrade_remove()
// test merging trans1, trans2
merged.merge(trans2);
auto items2 = merged.getItems();
CPPUNIT_ASSERT_EQUAL(1, (int)items2.size());
auto item2 = items2.at(0);
CPPUNIT_ASSERT_EQUAL(std::string("tour-4.8-1.noarch"), item2->getItem()->toStr());
CPPUNIT_ASSERT_EQUAL(std::string("repo1"), item2->getRepoid());
CPPUNIT_ASSERT_EQUAL(TransactionItemAction::REINSTALL, item2->getAction());
CPPUNIT_ASSERT_EQUAL(TransactionItemReason::USER, item2->getReason());
CPPUNIT_ASSERT_EQUAL(0, (int)items2.size());

// test merging trans1, trans2, trans3
merged.merge(trans3);
Expand Down
Loading