PackageKit/PackageKit-zypp-backend-improve-refresh-cache.patch

135 lines
4.2 KiB
Diff

Index: PackageKit-1.1.4/backends/zypp/pk-backend-zypp.cpp
===================================================================
--- PackageKit-1.1.4.orig/backends/zypp/pk-backend-zypp.cpp
+++ PackageKit-1.1.4/backends/zypp/pk-backend-zypp.cpp
@@ -986,20 +986,27 @@ static gboolean
zypp_refresh_meta_and_cache (RepoManager &manager, RepoInfo &repo, bool force = false)
{
try {
- if (manager.checkIfToRefreshMetadata (repo, repo.url()) //RepoManager::RefreshIfNeededIgnoreDelay)
- != RepoManager::REFRESH_NEEDED)
- return TRUE;
-
sat::Pool pool = sat::Pool::instance ();
- // Erase old solv file
- pool.reposErase (repo.alias ());
+
manager.refreshMetadata (repo, force ?
RepoManager::RefreshForced :
RepoManager::RefreshIfNeededIgnoreDelay);
manager.buildCache (repo, force ?
RepoManager::BuildForced :
RepoManager::BuildIfNeeded);
- manager.loadFromCache (repo);
+ try
+ {
+ manager.loadFromCache (repo);
+ }
+ catch (const Exception &exp)
+ {
+ // cachefile has old fomat (or is corrupted): rebuild it
+ manager.cleanCache (repo);
+ manager.buildCache (repo, force ?
+ RepoManager::BuildForced :
+ RepoManager::BuildIfNeeded);
+ manager.loadFromCache (repo);
+ }
return TRUE;
} catch (const AbortTransactionException &ex) {
return FALSE;
@@ -1580,9 +1587,44 @@ zypp_refresh_cache (PkBackendJob *job, Z
if (zypp == NULL)
return FALSE;
filesystem::Pathname pathname("/");
- // This call is needed to refresh system rpmdb status while refresh cache
- zypp->finishTarget ();
- zypp->initializeTarget (pathname);
+
+ bool poolIsClean = sat::Pool::instance ().reposEmpty ();
+ // Erase and reload all if pool is too holey (densyity [100: good | 0 bad])
+ // NOTE sat::Pool::capacity() > 2 is asserted in division
+ if (!poolIsClean &&
+ sat::Pool::instance ().solvablesSize () * 100 / sat::Pool::instance ().capacity () < 33)
+ {
+ sat::Pool::instance ().reposEraseAll ();
+ poolIsClean = true;
+ }
+
+ Target_Ptr target = zypp->getTarget ();
+ if (!target)
+ {
+ zypp->initializeTarget (pathname); // initial target
+ target = zypp->getTarget ();
+ }
+ else
+ {
+ // interim storage to avoid delete while iterating
+ std::set<std::string> idsToDelete;
+ const std::set<Edition> &rpmdbKeys (zypp->target ()->rpmDb ().pubkeyEditions ());
+
+ // load rpmdb trusted keys into zypp keyring
+ target->rpmDb ().exportTrustedKeysInZyppKeyRing ();
+
+ // keys no longer stored in the rpmdb need to be removed from the zypp keyring!
+ for (const PublicKeyData &el : zypp->keyRing ()->trustedPublicKeyData ())
+ {
+ if(!rpmdbKeys.count (Edition(el.gpgPubkeyVersion (), el.gpgPubkeyRelease ())))
+ idsToDelete.insert (el.id ());
+ }
+
+ for (const std::string & idToDelete : idsToDelete)
+ zypp->keyRing ()->deleteKey (idToDelete, true);
+ }
+ // load installed packages to pool
+ target->load ();
pk_backend_job_set_status (job, PK_STATUS_ENUM_REFRESH_CACHE);
pk_backend_job_set_percentage (job, 0);
@@ -1600,6 +1642,22 @@ zypp_refresh_cache (PkBackendJob *job, Z
return FALSE;
}
+ if (!poolIsClean)
+ {
+ std::vector<std::string> aliasesToRemove;
+
+ for (const Repository &poolrepo : zypp->pool ().knownRepositories ())
+ {
+ if (!(poolrepo.isSystemRepo () || manager.hasRepo (poolrepo.alias ())))
+ aliasesToRemove.push_back (poolrepo.alias ());
+ }
+
+ for (const std::string &aliasToRemove : aliasesToRemove)
+ {
+ sat::Pool::instance ().reposErase (aliasToRemove);
+ }
+ }
+
int i = 1;
int num_of_repos = repos.size ();
gchar *repo_messages = NULL;
@@ -1614,7 +1672,11 @@ zypp_refresh_cache (PkBackendJob *job, Z
// skip disabled repos
if (repo.enabled () == false)
+ {
+ if (!poolIsClean)
+ sat::Pool::instance ().reposErase (repo.alias ());
continue;
+ }
// do as zypper does
if (!force && !repo.autorefresh())
@@ -1623,7 +1685,11 @@ zypp_refresh_cache (PkBackendJob *job, Z
// skip changeable media (DVDs and CDs). Without doing this,
// the disc would be required to be physically present.
if (repo.baseUrlsBegin ()->schemeIsVolatile())
+ {
+ if (!poolIsClean)
+ sat::Pool::instance ().reposErase (repo.alias ());
continue;
+ }
try {
// Refreshing metadata