import libdnf-0.39.1-5.el8

This commit is contained in:
CentOS Sources 2020-04-28 05:42:58 -04:00 committed by Andrew Lukoshko
parent 2c9dc79ea8
commit 18700c9dc6
23 changed files with 60008 additions and 24957 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/libdnf-0.35.1.tar.gz
SOURCES/libdnf-0.39.1.tar.gz

View File

@ -1 +1 @@
91fcde5c3c2e716bc3baad1e9be118f51effac13 SOURCES/libdnf-0.35.1.tar.gz
a74a37b029439749298705ff3c1ccfbd0f0fd821 SOURCES/libdnf-0.39.1.tar.gz

View File

@ -0,0 +1,131 @@
From 1dffef87fc2f07763f64eeabc1ea891e68d23541 Mon Sep 17 00:00:00 2001
From: Michal Domonkos <mdomonko@redhat.com>
Date: Tue, 26 Nov 2019 13:05:49 +0100
Subject: [PATCH] [user-agent] Drop the whitelist
- Stop checking os-release(5) data against a hard-coded whitelist and
just use them as they are, to avoid a maintenance burden in the
future (see [1] for details)
- Clean up the getUserAgent() function a bit
Note that, by removing the whitelist, there's a risk of leaking a
"unique" value from the os-release file now, but a rather small one.
[1] https://github.com/rpm-software-management/libdnf/pull/851
---
libdnf/utils/os-release.cpp | 58 ++++++++++++++++++++--------------------------------------
libdnf/utils/os-release.hpp | 7 ++-----
2 files changed, 22 insertions(+), 43 deletions(-)
diff --git a/libdnf/utils/os-release.cpp b/libdnf/utils/os-release.cpp
index 57be110..1d8a95b 100644
--- a/libdnf/utils/os-release.cpp
+++ b/libdnf/utils/os-release.cpp
@@ -36,17 +36,8 @@
namespace libdnf {
// sorted by precedence (see os-release(5) for details)
-static const std::array<const std::string, 2> paths = {"/etc/os-release", "/usr/lib/os-release"};
-// whitelists used for sanity-checking the os-release data when constructing a
-// User-Agent string (to avoid reporting rare systems or platforms that could
-// be tracked)
-static const std::map<std::string, std::vector<std::string>> distros = {
- // taken from the {fedora,generic}-release.spec files
- { "Fedora", { "cinnamon", "cloud", "container", "coreos", "generic", "iot",
- "kde", "matecompiz", "server", "silverblue", "snappy", "soas",
- "workstation", "xfce" } },
-};
-std::array<const std::string, 1> canons = { "Linux" };
+static const std::array<const std::string, 2>
+paths = {"/etc/os-release", "/usr/lib/os-release"};
std::map<std::string, std::string> getOsReleaseData()
{
@@ -118,47 +109,38 @@ std::string getUserAgent(const std::map<std::string, std::string> & osReleaseDat
{
std::ostringstream oss;
auto logger(Log::getLogger());
- std::string msg = "os-release: falling back to basic User-Agent";
- // start with the basic libdnf string
oss << USER_AGENT;
+ std::string fallback = oss.str();
- // mandatory OS data (bail out if missing or unknown)
if (!osReleaseData.count("NAME") || !osReleaseData.count("VERSION_ID")) {
- logger->debug(tfm::format("%s: missing NAME or VERSION_ID", msg));
- return oss.str();
+ logger->debug(tfm::format(
+ "User-Agent: falling back to '%s': missing NAME or VERSION_ID",
+ fallback
+ ));
+ return fallback;
}
std::string name = osReleaseData.at("NAME");
std::string version = osReleaseData.at("VERSION_ID");
- if (!distros.count(name)) {
- logger->debug(tfm::format("%s: distro %s not whitelisted", msg, name));
- return oss.str();
- }
+ std::string variant = "generic";
+ if (osReleaseData.count("VARIANT_ID"))
+ variant = osReleaseData.at("VARIANT_ID");
- // mandatory platform data from RPM (bail out if missing or unknown)
std::string canon = getCanonOs();
std::string arch = getBaseArch();
- if (canon.empty() || arch.empty()
- || std::find(canons.begin(), canons.end(), canon) == canons.end()) {
- logger->debug(tfm::format("%s: could not detect canonical OS or basearch", msg));
- return oss.str();
- }
-
- // optional OS data (use fallback values if missing or unknown)
- std::string variant = "generic";
- auto list = distros.at(name);
- if (osReleaseData.count("VARIANT_ID")) {
- std::string value = osReleaseData.at("VARIANT_ID");
- if (std::find(list.begin(), list.end(), value) != list.end())
- variant = value;
+ if (canon.empty() || arch.empty()) {
+ logger->debug(tfm::format(
+ "User-Agent: falling back to '%s': could not detect OS or basearch",
+ fallback
+ ));
+ return fallback;
}
- // good to go!
- oss << " (" << name << " " << version << "; " << variant << "; "
- << canon << "." << arch << ")";
+ oss << " (" << name << " " << version << "; " << variant << "; " << canon
+ << "." << arch << ")";
std::string result = oss.str();
- logger->debug(tfm::format("os-release: User-Agent constructed: %s", result));
+ logger->debug(tfm::format("User-Agent: constructed: '%s'", result));
return result;
}
diff --git a/libdnf/utils/os-release.hpp b/libdnf/utils/os-release.hpp
index ef4d14f..e7b24a7 100644
--- a/libdnf/utils/os-release.hpp
+++ b/libdnf/utils/os-release.hpp
@@ -50,11 +50,8 @@ getOsReleaseData();
* libdnf (NAME VERSION_ID; VARIANT_ID; OS.BASEARCH)
*
* where NAME, VERSION_ID and VARIANT_ID are OS identifiers read from the
- * passed os-release data, and OS and BASEARCH (if found) are the canonical OS
- * name and base architecture, respectively, detected using RPM.
- *
- * Note that the OS part (enclosed in parentheses) will only be included for
- * whitelisted values.
+ * passed os-release data, and OS and BASEARCH are the canonical OS name and
+ * base architecture, respectively, detected using RPM.
*
* @param osReleaseData a map containing os-release data (will be loaded from
* disk if not specified)
--
libgit2 0.28.2

View File

@ -1,265 +0,0 @@
From d267539801ce0a32392d3a86d94e6ea37b6dc2ba Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Fri, 12 Jul 2019 06:51:25 +0200
Subject: [PATCH 1/5] [context] Fix: Correctly detach libsolv repo
(RhBug:1727343)
Seting repoImpl->libsolvRepo = nullptr and repoImpl->nrefs = 1 is not sufficient.
The libsolvRepo inernally points back to us. And during destroying
it destroy us too because nrefs was set to 1.
Solution is to do full detach using detachLibsolvRepo().
It fixes https://bugzilla.redhat.com/show_bug.cgi?id=1727343
and probably https://bugzilla.redhat.com/show_bug.cgi?id=1727424
---
libdnf/dnf-repo.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libdnf/dnf-repo.cpp b/libdnf/dnf-repo.cpp
index a358356a9..45c6c7e5b 100644
--- a/libdnf/dnf-repo.cpp
+++ b/libdnf/dnf-repo.cpp
@@ -1403,9 +1403,9 @@ dnf_repo_check_internal(DnfRepo *repo,
}
/* init */
- repoImpl->libsolvRepo = nullptr;
+ if (repoImpl->libsolvRepo)
+ repoImpl->detachLibsolvRepo();
repoImpl->needs_internalizing = false;
- repoImpl->nrefs = 1;
repoImpl->state_main = _HY_NEW;
repoImpl->state_filelists = _HY_NEW;
repoImpl->state_presto = _HY_NEW;
From f1e2e534d7d375d051c4eae51431c5bb3649f9f1 Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Fri, 12 Jul 2019 07:59:15 +0200
Subject: [PATCH 2/5] [Repo] Remove unused delReference
---
libdnf/repo/Repo.cpp | 7 -------
libdnf/repo/Repo.hpp | 2 --
2 files changed, 9 deletions(-)
diff --git a/libdnf/repo/Repo.cpp b/libdnf/repo/Repo.cpp
index 23638839a..fd2415fa5 100644
--- a/libdnf/repo/Repo.cpp
+++ b/libdnf/repo/Repo.cpp
@@ -1441,13 +1441,6 @@ std::vector<std::string> Repo::getMirrors() const
return mirrors;
}
-void Repo::delReference()
-{
- if (--pImpl->nrefs > 0)
- return;
- delete this;
-}
-
int PackageTargetCB::end(TransferStatus status, const char * msg) { return 0; }
int PackageTargetCB::progress(double totalToDownload, double downloaded) { return 0; }
int PackageTargetCB::mirrorFailure(const char *msg, const char *url) { return 0; }
diff --git a/libdnf/repo/Repo.hpp b/libdnf/repo/Repo.hpp
index cbf4ed147..785c6e9d5 100644
--- a/libdnf/repo/Repo.hpp
+++ b/libdnf/repo/Repo.hpp
@@ -275,8 +275,6 @@ struct Repo {
~Repo();
- void delReference();
-
class Impl;
private:
friend struct PackageTarget;
From 4c35d135bc79939d58844e99e0d5ed924ba86fd5 Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Fri, 12 Jul 2019 08:50:54 +0200
Subject: [PATCH 3/5] [Repo] Add locking and asserts
Add locking and asserts into attachLibsolvRepo(), detachLibsolvRepo()
and hy_repo_free()
---
libdnf/dnf-repo.cpp | 3 +--
libdnf/repo/Repo-private.hpp | 5 +++++
libdnf/repo/Repo.cpp | 34 ++++++++++++++++++++++++++--------
3 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/libdnf/dnf-repo.cpp b/libdnf/dnf-repo.cpp
index 45c6c7e5b..c30d99d17 100644
--- a/libdnf/dnf-repo.cpp
+++ b/libdnf/dnf-repo.cpp
@@ -1403,8 +1403,7 @@ dnf_repo_check_internal(DnfRepo *repo,
}
/* init */
- if (repoImpl->libsolvRepo)
- repoImpl->detachLibsolvRepo();
+ repoImpl->detachLibsolvRepo();
repoImpl->needs_internalizing = false;
repoImpl->state_main = _HY_NEW;
repoImpl->state_filelists = _HY_NEW;
diff --git a/libdnf/repo/Repo-private.hpp b/libdnf/repo/Repo-private.hpp
index 23acf3622..333eb7bfd 100644
--- a/libdnf/repo/Repo-private.hpp
+++ b/libdnf/repo/Repo-private.hpp
@@ -43,6 +43,7 @@
#include <cctype>
#include <map>
+#include <mutex>
#include <set>
#include <string.h>
@@ -177,6 +178,10 @@ class Repo::Impl {
int main_nrepodata{0};
int main_end{0};
+ // Lock attachLibsolvRepo(), detachLibsolvRepo() and hy_repo_free() to ensure atomic behavior
+ // in threaded environment such as PackageKit.
+ std::mutex attachLibsolvMutex;
+
private:
Repo * owner;
std::unique_ptr<LrResult> lrHandlePerform(LrHandle * handle, const std::string & destDirectory,
diff --git a/libdnf/repo/Repo.cpp b/libdnf/repo/Repo.cpp
index fd2415fa5..86531fe9b 100644
--- a/libdnf/repo/Repo.cpp
+++ b/libdnf/repo/Repo.cpp
@@ -60,7 +60,6 @@
#include <iostream>
#include <list>
#include <map>
-#include <mutex>
#include <set>
#include <sstream>
#include <type_traits>
@@ -1335,8 +1334,10 @@ LrHandle * Repo::Impl::getCachedHandle()
void Repo::Impl::attachLibsolvRepo(LibsolvRepo * libsolvRepo)
{
+ std::lock_guard<std::mutex> guard(attachLibsolvMutex);
+ assert(!this->libsolvRepo);
++nrefs;
- libsolvRepo->appdata = owner;
+ libsolvRepo->appdata = owner; // The libsolvRepo references back to us.
libsolvRepo->subpriority = -owner->getCost();
libsolvRepo->priority = -owner->getPriority();
this->libsolvRepo = libsolvRepo;
@@ -1344,11 +1345,23 @@ void Repo::Impl::attachLibsolvRepo(LibsolvRepo * libsolvRepo)
void Repo::Impl::detachLibsolvRepo()
{
- libsolvRepo->appdata = nullptr;
- if (--nrefs > 0)
- this->libsolvRepo = nullptr;
- else
+ attachLibsolvMutex.lock();
+ if (!libsolvRepo) {
+ // Nothing to do, libsolvRepo is not attached.
+ attachLibsolvMutex.unlock();
+ return;
+ }
+
+ libsolvRepo->appdata = nullptr; // Removes reference to this object from libsolvRepo.
+ this->libsolvRepo = nullptr;
+
+ if (--nrefs <= 0) {
+ // There is no reference to this object, we are going to destroy it.
+ // Mutex is part of this object, we must unlock it before destroying.
+ attachLibsolvMutex.unlock();
delete owner;
+ } else
+ attachLibsolvMutex.unlock();
}
void Repo::setMaxMirrorTries(int maxMirrorTries)
@@ -2057,7 +2070,12 @@ hy_repo_get_string(HyRepo repo, int which)
void
hy_repo_free(HyRepo repo)
{
- if (--libdnf::repoGetImpl(repo)->nrefs > 0)
- return;
+ auto repoImpl = libdnf::repoGetImpl(repo);
+ {
+ std::lock_guard<std::mutex> guard(repoImpl->attachLibsolvMutex);
+ if (--repoImpl->nrefs > 0)
+ return; // There is still a reference to this object. Don't destroy it.
+ }
+ assert(!repoImpl->libsolvRepo);
delete repo;
}
From 3a61d4c590612427bfeb7302236e4429acae90b0 Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Fri, 12 Jul 2019 11:21:48 +0200
Subject: [PATCH 4/5] Fix: crash in repo_internalize_trigger() without HyRepo
attached
The repo_internalize_trigger() uses needs_internalizing from HyRepo.
If HyRepo is not attached we will assume needs_internalizing==true.
---
libdnf/repo/Repo.cpp | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/libdnf/repo/Repo.cpp b/libdnf/repo/Repo.cpp
index 86531fe9b..210ecde8f 100644
--- a/libdnf/repo/Repo.cpp
+++ b/libdnf/repo/Repo.cpp
@@ -1826,15 +1826,19 @@ repo_internalize_all_trigger(Pool *pool)
void
repo_internalize_trigger(Repo * repo)
{
- if (repo) {
- auto hrepo = static_cast<HyRepo>(repo->appdata);
+ if (!repo)
+ return;
+
+ if (auto hrepo = static_cast<HyRepo>(repo->appdata)) {
+ // HyRepo is attached. The hint needs_internalizing will be used.
auto repoImpl = libdnf::repoGetImpl(hrepo);
assert(repoImpl->libsolvRepo == repo);
if (!repoImpl->needs_internalizing)
return;
repoImpl->needs_internalizing = false;
- repo_internalize(repo);
}
+
+ repo_internalize(repo);
}
void
From e4cabf803e1dbb6283330636d06ccb4a26e89ad4 Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Sun, 14 Jul 2019 10:45:27 +0200
Subject: [PATCH 5/5] [Repo] attachLibsolvRepo() can reattach repo to another
libsolvRepo
---
libdnf/repo/Repo.cpp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/libdnf/repo/Repo.cpp b/libdnf/repo/Repo.cpp
index 210ecde8f..70c6a7411 100644
--- a/libdnf/repo/Repo.cpp
+++ b/libdnf/repo/Repo.cpp
@@ -1335,8 +1335,14 @@ LrHandle * Repo::Impl::getCachedHandle()
void Repo::Impl::attachLibsolvRepo(LibsolvRepo * libsolvRepo)
{
std::lock_guard<std::mutex> guard(attachLibsolvMutex);
- assert(!this->libsolvRepo);
- ++nrefs;
+
+ if (this->libsolvRepo)
+ // A libsolvRepo was attached to this object before. Remove it's reference to this object.
+ this->libsolvRepo->appdata = nullptr;
+ else
+ // The libsolvRepo will reference this object. Increase reference counter.
+ ++nrefs;
+
libsolvRepo->appdata = owner; // The libsolvRepo references back to us.
libsolvRepo->subpriority = -owner->getCost();
libsolvRepo->priority = -owner->getPriority();

View File

@ -0,0 +1,88 @@
From c398ea4431ea539b0847fdf7fddf1892655081de Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Sun, 15 Dec 2019 16:43:01 +0100
Subject: [PATCH] [context] wildcard support in dnf_context_repo_set_data
(RhBug:1781420)
Adds support for wildcard pattern in repo_id to these functions:
gboolean dnf_context_repo_enable(DnfContext *context,
const gchar *repo_id, GError **error);
gboolean dnf_context_repo_disable(DnfContext *context,
const gchar *repo_id, GError **error);
For example, it is used by microdnf for enable and disable repositories
(arguments "--enablerepo=" and "--disablerepo=").
---
libdnf/dnf-context.cpp | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/libdnf/dnf-context.cpp b/libdnf/dnf-context.cpp
index 061bf6f85..4b0a009fc 100644
--- a/libdnf/dnf-context.cpp
+++ b/libdnf/dnf-context.cpp
@@ -52,6 +52,7 @@
#include <fcntl.h>
#include <unistd.h>
#endif
+#include <fnmatch.h>
#include <unistd.h>
#include "log.hpp"
@@ -2273,20 +2274,19 @@ dnf_context_repo_set_data(DnfContext *context,
GError **error)
{
DnfContextPrivate *priv = GET_PRIVATE(context);
- DnfRepo *repo = NULL;
- guint i;
+ bool found = false;
- /* find a repo with a matching ID */
- for (i = 0; i < priv->repos->len; i++) {
- auto repo_tmp = static_cast<DnfRepo *>(g_ptr_array_index(priv->repos, i));
- if (g_strcmp0(dnf_repo_get_id(repo_tmp), repo_id) == 0) {
- repo = repo_tmp;
- break;
+ /* set repos with a matching ID */
+ for (guint i = 0; i < priv->repos->len; ++i) {
+ auto repo = static_cast<DnfRepo *>(g_ptr_array_index(priv->repos, i));
+ if (fnmatch(repo_id, dnf_repo_get_id(repo), 0) == 0) {
+ dnf_repo_set_enabled(repo, enabled);
+ found = true;
}
}
/* nothing found */
- if (repo == NULL) {
+ if (!found) {
g_set_error(error,
DNF_ERROR,
DNF_ERROR_INTERNAL_ERROR,
@@ -2294,8 +2294,6 @@ dnf_context_repo_set_data(DnfContext *context,
return FALSE;
}
- /* this is runtime only */
- dnf_repo_set_enabled(repo, enabled);
return TRUE;
}
@@ -2305,7 +2303,8 @@ dnf_context_repo_set_data(DnfContext *context,
* @repo_id: A repo_id, e.g. "fedora-rawhide"
* @error: A #GError or %NULL
*
- * Enables a specific repo.
+ * Enables a specific repo(s).
+ * Wildcard pattern is supported.
*
* This must be done before dnf_context_setup() is called.
*
@@ -2329,7 +2328,8 @@ dnf_context_repo_enable(DnfContext *context,
* @repo_id: A repo_id, e.g. "fedora-rawhide"
* @error: A #GError or %NULL
*
- * Disables a specific repo.
+ * Disables a specific repo(s).
+ * Wildcard pattern is supported.
*
* This must be done before dnf_context_setup() is called.
*

View File

@ -0,0 +1,339 @@
From b36464f01ffadab9ca49eed1a06ab480626b28c2 Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Mon, 16 Dec 2019 10:10:51 +0100
Subject: [PATCH 1/2] Add new query filter upgrades_by_priority
It returns upgrades only from repository with the lowest priority.
---
libdnf/hy-types.h | 3 +-
libdnf/sack/query.cpp | 60 ++++++++++++++++++++++++++++++++++
python/hawkey/hawkeymodule.cpp | 1 +
python/hawkey/query-py.cpp | 5 ++-
4 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/libdnf/hy-types.h b/libdnf/hy-types.h
index b34988d89..380a0d5cc 100644
--- a/libdnf/hy-types.h
+++ b/libdnf/hy-types.h
@@ -97,7 +97,8 @@ enum _hy_key_name_e {
* @brief Use for strings of whole NEVRA (missing epoch is handled as epoch 0)
* Allowed compare types - only HY_EQ or HY_NEQ
*/
- HY_PKG_NEVRA_STRICT = 36
+ HY_PKG_NEVRA_STRICT = 36,
+ HY_PKG_UPGRADES_BY_PRIORITY = 37,
};
enum _hy_comparison_type_e {
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
index eea0ce1b1..ecfd3110f 100644
--- a/libdnf/sack/query.cpp
+++ b/libdnf/sack/query.cpp
@@ -148,6 +148,13 @@ NameArchSolvableComparator(const Solvable * first, const Solvable * second)
return first->arch < second->arch;
}
+static bool
+NamePrioritySolvableKey(const Solvable * first, const Solvable * second)
+{
+ if (first->name != second->name)
+ return first->name < second->name;
+ return first->repo->priority > second->repo->priority;
+}
static bool
match_type_num(int keyname) {
@@ -158,6 +165,7 @@ match_type_num(int keyname) {
case HY_PKG_LATEST_PER_ARCH:
case HY_PKG_UPGRADABLE:
case HY_PKG_UPGRADES:
+ case HY_PKG_UPGRADES_BY_PRIORITY:
case HY_PKG_DOWNGRADABLE:
case HY_PKG_DOWNGRADES:
return true;
@@ -690,6 +698,7 @@ class Query::Impl {
void filterAdvisory(const Filter & f, Map *m, int keyname);
void filterLatest(const Filter & f, Map *m);
void filterUpdown(const Filter & f, Map *m);
+ void filterUpdownByPriority(const Filter & f, Map *m);
void filterUpdownAble(const Filter &f, Map *m);
void filterDataiterator(const Filter & f, Map *m);
int filterUnneededOrSafeToRemove(const Swdb &swdb, bool debug_solver, bool safeToRemove);
@@ -1732,6 +1741,54 @@ Query::Impl::filterUpdown(const Filter & f, Map *m)
}
}
+void
+Query::Impl::filterUpdownByPriority(const Filter & f, Map *m)
+{
+ Pool *pool = dnf_sack_get_pool(sack);
+ auto resultPset = result.get();
+
+ dnf_sack_make_provides_ready(sack);
+ auto repoInstalled = pool->installed;
+ if (!repoInstalled) {
+ return;
+ }
+
+ for (auto match_in : f.getMatches()) {
+ if (match_in.num == 0)
+ continue;
+ std::vector<Solvable *> upgradeCandidates;
+ upgradeCandidates.reserve(resultPset->size());
+ Id id = -1;
+ while ((id = resultPset->next(id)) != -1) {
+ Solvable *candidate = pool_id2solvable(pool, id);
+ if (candidate->repo == repoInstalled)
+ continue;
+ upgradeCandidates.push_back(candidate);
+ }
+ if (upgradeCandidates.empty()) {
+ continue;
+ }
+ std::sort(upgradeCandidates.begin(), upgradeCandidates.end(), NamePrioritySolvableKey);
+ Id name = 0;
+ int priority = 0;
+ for (auto * candidate: upgradeCandidates) {
+ if (name != candidate->name) {
+ name = candidate->name;
+ priority = candidate->repo->priority;
+ id = pool_solvable2id(pool, candidate);
+ if (what_upgrades(pool, id) > 0) {
+ MAPSET(m, id);
+ }
+ } else if (priority == candidate->repo->priority) {
+ id = pool_solvable2id(pool, candidate);
+ if (what_upgrades(pool, id) > 0) {
+ MAPSET(m, id);
+ }
+ }
+ }
+ }
+}
+
void
Query::Impl::filterUpdownAble(const Filter &f, Map *m)
{
@@ -1949,6 +2006,9 @@ Query::Impl::apply()
case HY_PKG_UPGRADES:
filterUpdown(f, &m);
break;
+ case HY_PKG_UPGRADES_BY_PRIORITY:
+ filterUpdownByPriority(f, &m);
+ break;
default:
filterDataiterator(f, &m);
}
diff --git a/python/hawkey/hawkeymodule.cpp b/python/hawkey/hawkeymodule.cpp
index 0f05f46c2..4351e96e1 100644
--- a/python/hawkey/hawkeymodule.cpp
+++ b/python/hawkey/hawkeymodule.cpp
@@ -281,6 +281,7 @@ PYCOMP_MOD_INIT(_hawkey)
PyModule_AddIntConstant(m, "PKG_SUPPLEMENTS", HY_PKG_SUPPLEMENTS);
PyModule_AddIntConstant(m, "PKG_UPGRADABLE", HY_PKG_UPGRADABLE);
PyModule_AddIntConstant(m, "PKG_UPGRADES", HY_PKG_UPGRADES);
+ PyModule_AddIntConstant(m, "PKG_UPGRADES_BY_PRIORITY", HY_PKG_UPGRADES_BY_PRIORITY);
PyModule_AddIntConstant(m, "PKG_URL", HY_PKG_URL);
PyModule_AddIntConstant(m, "PKG_VERSION", HY_PKG_VERSION);
diff --git a/python/hawkey/query-py.cpp b/python/hawkey/query-py.cpp
index 116ffa1b0..286e306d3 100644
--- a/python/hawkey/query-py.cpp
+++ b/python/hawkey/query-py.cpp
@@ -89,6 +89,7 @@ static const int keyname_int_matches[] = {
HY_PKG_SUPPLEMENTS,
HY_PKG_UPGRADABLE,
HY_PKG_UPGRADES,
+ HY_PKG_UPGRADES_BY_PRIORITY,
HY_PKG_URL,
HY_PKG_VERSION
};
@@ -128,6 +129,7 @@ static const char * const keyname_char_matches[] = {
"supplements",
"upgradable",
"upgrades",
+ "upgrades_by_priority",
"url",
"version",
NULL
@@ -273,7 +275,8 @@ filter_add(HyQuery query, key_t keyname, int cmp_type, PyObject *match)
keyname == HY_PKG_LATEST_PER_ARCH ||
keyname == HY_PKG_LATEST ||
keyname == HY_PKG_UPGRADABLE ||
- keyname == HY_PKG_UPGRADES) {
+ keyname == HY_PKG_UPGRADES ||
+ keyname == HY_PKG_UPGRADES_BY_PRIORITY) {
int val;
if (!PyInt_Check(match) || cmp_type != HY_EQ) {
From 4b83ae692f90d0d3cbc377c7f93bdb7e99e477ef Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Mon, 16 Dec 2019 18:34:37 +0100
Subject: [PATCH 2/2] Add new query filter obsoletes_by_priority
---
libdnf/hy-types.h | 1 +
libdnf/sack/query.cpp | 65 ++++++++++++++++++++++++++++++++++
python/hawkey/hawkeymodule.cpp | 1 +
python/hawkey/query-py.cpp | 5 ++-
4 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/libdnf/hy-types.h b/libdnf/hy-types.h
index 380a0d5cc..e96459c25 100644
--- a/libdnf/hy-types.h
+++ b/libdnf/hy-types.h
@@ -99,6 +99,7 @@ enum _hy_key_name_e {
*/
HY_PKG_NEVRA_STRICT = 36,
HY_PKG_UPGRADES_BY_PRIORITY = 37,
+ HY_PKG_OBSOLETES_BY_PRIORITY = 38,
};
enum _hy_comparison_type_e {
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
index ecfd3110f..6e9e4715f 100644
--- a/libdnf/sack/query.cpp
+++ b/libdnf/sack/query.cpp
@@ -179,6 +179,7 @@ match_type_pkg(int keyname) {
switch (keyname) {
case HY_PKG:
case HY_PKG_OBSOLETES:
+ case HY_PKG_OBSOLETES_BY_PRIORITY:
return true;
default:
return false;
@@ -692,6 +693,7 @@ class Query::Impl {
void filterArch(const Filter & f, Map *m);
void filterSourcerpm(const Filter & f, Map *m);
void filterObsoletes(const Filter & f, Map *m);
+ void filterObsoletesByPriority(const Filter & f, Map *m);
void filterProvidesReldep(const Filter & f, Map *m);
void filterReponame(const Filter & f, Map *m);
void filterLocation(const Filter & f, Map *m);
@@ -702,6 +704,7 @@ class Query::Impl {
void filterUpdownAble(const Filter &f, Map *m);
void filterDataiterator(const Filter & f, Map *m);
int filterUnneededOrSafeToRemove(const Swdb &swdb, bool debug_solver, bool safeToRemove);
+ void obsoletesByPriority(Pool * pool, Solvable * candidate, Map * m, const Map * target, int obsprovides);
bool isGlob(const std::vector<const char *> &matches) const;
};
@@ -1469,6 +1472,65 @@ Query::Impl::filterObsoletes(const Filter & f, Map *m)
}
}
+void
+Query::Impl::obsoletesByPriority(Pool * pool, Solvable * candidate, Map * m, const Map * target, int obsprovides)
+{
+ if (!candidate->repo)
+ return;
+ for (Id *r_id = candidate->repo->idarraydata + candidate->obsoletes; *r_id; ++r_id) {
+ Id r, rr;
+ FOR_PROVIDES(r, rr, *r_id) {
+ if (!MAPTST(target, r))
+ continue;
+ assert(r != SYSTEMSOLVABLE);
+ Solvable *so = pool_id2solvable(pool, r);
+ if (!obsprovides && !pool_match_nevr(pool, so, *r_id))
+ continue; /* only matching pkg names */
+ MAPSET(m, pool_solvable2id(pool, candidate));
+ break;
+ }
+ }
+}
+
+void
+Query::Impl::filterObsoletesByPriority(const Filter & f, Map *m)
+{
+ Pool *pool = dnf_sack_get_pool(sack);
+ int obsprovides = pool_get_flag(pool, POOL_FLAG_OBSOLETEUSESPROVIDES);
+ Map *target;
+ auto resultPset = result.get();
+
+ assert(f.getMatchType() == _HY_PKG);
+ assert(f.getMatches().size() == 1);
+ target = dnf_packageset_get_map(f.getMatches()[0].pset);
+ dnf_sack_make_provides_ready(sack);
+ std::vector<Solvable *> obsoleteCandidates;
+ obsoleteCandidates.reserve(resultPset->size());
+ Id id = -1;
+ while ((id = resultPset->next(id)) != -1) {
+ Solvable *candidate = pool_id2solvable(pool, id);
+ obsoleteCandidates.push_back(candidate);
+ }
+ if (obsoleteCandidates.empty()) {
+ return;
+ }
+ std::sort(obsoleteCandidates.begin(), obsoleteCandidates.end(), NamePrioritySolvableKey);
+ Id name = 0;
+ int priority = 0;
+ for (auto * candidate: obsoleteCandidates) {
+ if (candidate->repo == pool->installed) {
+ obsoletesByPriority(pool, candidate, m, target, obsprovides);
+ }
+ if (name != candidate->name) {
+ name = candidate->name;
+ priority = candidate->repo->priority;
+ obsoletesByPriority(pool, candidate, m, target, obsprovides);
+ } else if (priority == candidate->repo->priority) {
+ obsoletesByPriority(pool, candidate, m, target, obsprovides);
+ }
+ }
+}
+
void
Query::Impl::filterProvidesReldep(const Filter & f, Map *m)
{
@@ -1969,6 +2031,9 @@ Query::Impl::apply()
filterObsoletes(f, &m);
}
break;
+ case HY_PKG_OBSOLETES_BY_PRIORITY:
+ filterObsoletesByPriority(f, &m);
+ break;
case HY_PKG_PROVIDES:
assert(f.getMatchType() == _HY_RELDEP);
filterProvidesReldep(f, &m);
diff --git a/python/hawkey/hawkeymodule.cpp b/python/hawkey/hawkeymodule.cpp
index 4351e96e1..82d05e2cb 100644
--- a/python/hawkey/hawkeymodule.cpp
+++ b/python/hawkey/hawkeymodule.cpp
@@ -270,6 +270,7 @@ PYCOMP_MOD_INIT(_hawkey)
PyModule_AddIntConstant(m, "PKG_NEVRA", HY_PKG_NEVRA);
PyModule_AddIntConstant(m, "PKG_NEVRA_STRICT", HY_PKG_NEVRA_STRICT);
PyModule_AddIntConstant(m, "PKG_OBSOLETES", HY_PKG_OBSOLETES);
+ PyModule_AddIntConstant(m, "PKG_OBSOLETES_BY_PRIORITY", HY_PKG_OBSOLETES_BY_PRIORITY);
PyModule_AddIntConstant(m, "PKG_PROVIDES", HY_PKG_PROVIDES);
PyModule_AddIntConstant(m, "PKG_RECOMMENDS", HY_PKG_RECOMMENDS);
PyModule_AddIntConstant(m, "PKG_RELEASE", HY_PKG_RELEASE);
diff --git a/python/hawkey/query-py.cpp b/python/hawkey/query-py.cpp
index 286e306d3..9178a6d0c 100644
--- a/python/hawkey/query-py.cpp
+++ b/python/hawkey/query-py.cpp
@@ -78,6 +78,7 @@ static const int keyname_int_matches[] = {
HY_PKG_NEVRA,
HY_PKG_NEVRA_STRICT,
HY_PKG_OBSOLETES,
+ HY_PKG_OBSOLETES_BY_PRIORITY,
HY_PKG_PROVIDES,
HY_PKG_RECOMMENDS,
HY_PKG_RELEASE,
@@ -118,6 +119,7 @@ static const char * const keyname_char_matches[] = {
"nevra",
"nevra_strict",
"obsoletes",
+ "obsoletes_by_priority",
"provides",
"recommends",
"release",
@@ -342,7 +344,8 @@ filter_add(HyQuery query, key_t keyname, int cmp_type, PyObject *match)
// match is a sequence now:
switch (keyname) {
case HY_PKG:
- case HY_PKG_OBSOLETES: {
+ case HY_PKG_OBSOLETES:
+ case HY_PKG_OBSOLETES_BY_PRIORITY: {
// It could be a sequence of packages or reldep/strings. Lets try packages first.
auto pset = pyseq_to_packageset(match, query->getSack());
if (!pset) {

View File

@ -1,26 +0,0 @@
From b84fe340840169d201714a5b3a015b9d1142013c Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Wed, 3 Jul 2019 13:48:58 +0200
Subject: [PATCH] Typo in error message (RhBug:1726661)
https://bugzilla.redhat.com/show_bug.cgi?id=1726661
---
libdnf/module/ModulePackageContainer.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libdnf/module/ModulePackageContainer.cpp b/libdnf/module/ModulePackageContainer.cpp
index ddef174..1c8e0d5 100644
--- a/libdnf/module/ModulePackageContainer.cpp
+++ b/libdnf/module/ModulePackageContainer.cpp
@@ -1637,7 +1637,7 @@ void ModulePackageContainer::updateFailSafeData()
if (!updateFile(filePath, modulePackage->getYaml().c_str())) {
auto logger(Log::getLogger());
logger->debug(tfm::format(
- _("Unable to safe a modular Fail Safe data to '%s'"), filePath));
+ _("Unable to save a modular Fail Safe data to '%s'"), filePath));
}
}
--
libgit2 0.28.2

View File

@ -0,0 +1,98 @@
From dc3b2a2b22106fa4c0033a5557584f3b08c942e2 Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Fri, 3 Jan 2020 12:35:33 +0100
Subject: [PATCH] Remove killGpgAgent function (RhBug:1781601)
Instead ensure that /run/user/$UID directory exists so gpgagent could
create its socket in it.
The solution with KILLAGENT caused race condition with gpgme_release()
call and that resulted in dnf being possibly terminated by SIGPIPE after
importing the first repository gpg key.
https://bugzilla.redhat.com/show_bug.cgi?id=1781601
---
libdnf/repo/Repo.cpp | 56 +++++++++++++++++++++++---------------------
1 file changed, 29 insertions(+), 27 deletions(-)
diff --git a/libdnf/repo/Repo.cpp b/libdnf/repo/Repo.cpp
index 850e5b4a8..c1891cce9 100644
--- a/libdnf/repo/Repo.cpp
+++ b/libdnf/repo/Repo.cpp
@@ -846,27 +846,35 @@ std::vector<Key> Repo::Impl::retrieve(const std::string & url)
return keyInfos;
}
-static void killGpgAgent(gpgme_ctx_t context, const std::string & gpgDir)
-{
+/*
+ * Creates the '/run/user/$UID' directory if it doesn't exist. If this
+ * directory exists, gpgagent will create its sockets under
+ * '/run/user/$UID/gnupg'.
+ *
+ * If this directory doesn't exist, gpgagent will create its sockets in gpg
+ * home directory, which is under '/var/cache/yum/metadata/' and this was
+ * causing trouble with container images, see [1].
+ *
+ * Previous solution was to send the agent a "KILLAGENT" message, but that
+ * would cause a race condition with calling gpgme_release(), see [2], [3],
+ * [4].
+ *
+ * Since the agent doesn't clean up its sockets properly, by creating this
+ * directory we make sure they are in a place that is not causing trouble with
+ * container images.
+ *
+ * [1] https://bugzilla.redhat.com/show_bug.cgi?id=1650266
+ * [2] https://bugzilla.redhat.com/show_bug.cgi?id=1769831
+ * [3] https://github.com/rpm-software-management/microdnf/issues/50
+ * [4] https://bugzilla.redhat.com/show_bug.cgi?id=1781601
+ */
+static void ensure_socket_dir_exists() {
auto logger(Log::getLogger());
-
- auto gpgErr = gpgme_set_protocol(context, GPGME_PROTOCOL_ASSUAN);
- if (gpgErr != GPG_ERR_NO_ERROR) {
- auto msg = tfm::format(_("%s: gpgme_set_protocol(): %s"), __func__, gpgme_strerror(gpgErr));
- logger->warning(msg);
- return;
- }
- std::string gpgAgentSock = gpgDir + "/S.gpg-agent";
- gpgErr = gpgme_ctx_set_engine_info(context, GPGME_PROTOCOL_ASSUAN, gpgAgentSock.c_str(), gpgDir.c_str());
- if (gpgErr != GPG_ERR_NO_ERROR) {
- auto msg = tfm::format(_("%s: gpgme_ctx_set_engine_info(): %s"), __func__, gpgme_strerror(gpgErr));
- logger->warning(msg);
- return;
- }
- gpgErr = gpgme_op_assuan_transact_ext(context, "KILLAGENT", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- if (gpgErr != GPG_ERR_NO_ERROR) {
- auto msg = tfm::format(_("%s: gpgme_op_assuan_transact_ext(): %s"), __func__, gpgme_strerror(gpgErr));
- logger->debug(msg);
+ std::string dirname = "/run/user/" + std::to_string(getuid());
+ int res = mkdir(dirname.c_str(), 0700);
+ if (res != 0 && errno != EEXIST) {
+ logger->debug(tfm::format("Failed to create directory \"%s\": %d - %s",
+ dirname, errno, strerror(errno)));
}
}
@@ -876,6 +884,7 @@ void Repo::Impl::importRepoKeys()
auto gpgDir = getCachedir() + "/pubring";
auto knownKeys = keyidsFromPubring(gpgDir);
+ ensure_socket_dir_exists();
for (const auto & gpgkeyUrl : conf->gpgkey().getValue()) {
auto keyInfos = retrieve(gpgkeyUrl);
for (auto & keyInfo : keyInfos) {
@@ -908,13 +917,6 @@ void Repo::Impl::importRepoKeys()
gpgImportKey(ctx, keyInfo.rawKey);
- // Running gpg-agent kept opened sockets on the system.
- // It tries to exit gpg-agent. Path to the communication socket is derived from homedir.
- // The gpg-agent automaticaly removes all its socket before exit.
- // Newer gpg-agent creates sockets under [/var]/run/user/{pid}/... if directory exists.
- // In this case gpg-agent will not be exited.
- killGpgAgent(ctx, gpgDir);
-
logger->debug(tfm::format(_("repo %s: imported key 0x%s."), id, keyInfo.getId()));
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,45 +0,0 @@
From 5923a9cc15b9fe541e71a9ef4bb550b6ddc481fc Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Wed, 12 Jun 2019 13:22:31 +0200
Subject: [PATCH] [context] Fix: Don't disable nonexistent but required repositories (RhBug:1689331)
The nonexistent local/media repositories were automatically disabled
during check (in function dnf_repo_check_internal). So application
(the Packagekit daemon) that reuses the deactivated repository object
then silently skip the repository as disabled.
We should not to disable repositories which are required
(skip_if_unavailable=0).
Fix for https://bugzilla.redhat.com/show_bug.cgi?id=1689331
---
libdnf/dnf-repo.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libdnf/dnf-repo.cpp b/libdnf/dnf-repo.cpp
index d49c306..a358356 100644
--- a/libdnf/dnf-repo.cpp
+++ b/libdnf/dnf-repo.cpp
@@ -1312,7 +1312,8 @@ dnf_repo_check_internal(DnfRepo *repo,
/* has the media repo vanished? */
if (priv->kind == DNF_REPO_KIND_MEDIA &&
!g_file_test(priv->location, G_FILE_TEST_EXISTS)) {
- priv->enabled = DNF_REPO_ENABLED_NONE;
+ if (!dnf_repo_get_required(repo))
+ priv->enabled = DNF_REPO_ENABLED_NONE;
g_set_error(error,
DNF_ERROR,
DNF_ERROR_REPO_NOT_AVAILABLE,
@@ -1323,7 +1324,8 @@ dnf_repo_check_internal(DnfRepo *repo,
/* has the local repo vanished? */
if (priv->kind == DNF_REPO_KIND_LOCAL &&
!g_file_test(priv->location, G_FILE_TEST_EXISTS)) {
- priv->enabled = DNF_REPO_ENABLED_NONE;
+ if (!dnf_repo_get_required(repo))
+ priv->enabled = DNF_REPO_ENABLED_NONE;
g_set_error(error,
DNF_ERROR,
DNF_ERROR_REPO_NOT_AVAILABLE,
--
libgit2 0.28.2

View File

@ -0,0 +1,126 @@
From 594560870c416d0133b08a64e0632a53a6217f71 Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Mon, 20 Jan 2020 09:58:03 +0100
Subject: [PATCH] Fix filtering packages by advisory (RhBug:1770125)
Currently the filter does not work well in situation when more versions
and architectures of advisory packages are available.
Let's have package gjs-1.56.2-6.fc30.x86_64
and two advisories related to gjs package:
FEDORA-2019-f4eb34cf4c
gjs-1.56.2-1.fc30.src
gjs-1.56.2-1.fc30.x86_64
FEDORA-2019-57b5902ed1
gjs-1.56.2-6.fc30.src
gjs-1.56.2-6.fc30.x86_64
In this case the FEDORA-2019-57b5902ed1 advisory is not matched for
gjs-1.56.2-6.fc30.x86_64 package (considering >= operator as in 'dnf
update --bugfix') because only the package of `src` architecture as been
checked. The checking of other versions/architectures was missing.
https://bugzilla.redhat.com/show_bug.cgi?id=1770125
---
libdnf/sack/query.cpp | 63 +++++++++++++++----------------------------
1 file changed, 22 insertions(+), 41 deletions(-)
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
index 6e9e4715f..122a50df6 100644
--- a/libdnf/sack/query.cpp
+++ b/libdnf/sack/query.cpp
@@ -518,9 +518,9 @@ advisoryPkgCompareSolvable(const AdvisoryPkg &first, const Solvable &s)
{
if (first.getName() != s.name)
return first.getName() < s.name;
- if (first.getEVR() != s.evr)
- return first.getEVR() < s.evr;
- return first.getArch() < s.arch;
+ if (first.getArch() != s.arch)
+ return first.getArch() < s.arch;
+ return first.getEVR() < s.evr;
}
static bool
@@ -1607,13 +1607,12 @@ Query::Impl::filterLocation(const Filter & f, Map *m)
/**
* @brief Reduce query to security filters. It reflect following compare types: HY_EQ, HY_GT, HY_LT.
-* In case HY_GT or HY_LT, it first find all advisory packages that EQ to packages in result.
-* Then it adds packages from Result to Map *m if Name and Arch is EQ, and EVR comparison is
-* according to one of selected compare type (HY_EQ, HY_GT, HY_LT).
*
-* @param f p_f:...
-* @param m p_m:...
-* @param keyname p_keyname:...
+* @param f: Filter that should be applied on advisories
+* @param m: Map of query results complying the filter
+* @param keyname: how are the advisories matched. HY_PKG_ADVISORY, HY_PKG_ADVISORY_BUG,
+* HY_PKG_ADVISORY_CVE, HY_PKG_ADVISORY_TYPE and HY_PKG_ADVISORY_SEVERITY
+* are supported
*/
void
Query::Impl::filterAdvisory(const Filter & f, Map *m, int keyname)
@@ -1668,7 +1667,6 @@ Query::Impl::filterAdvisory(const Filter & f, Map *m, int keyname)
// convert nevras (from DnfAdvisoryPkg) to pool ids
Id id = -1;
int cmp_type = f.getCmpType();
- bool cmpTypeGreaterOrLower = cmp_type & HY_GT || cmp_type & HY_LT;
while (true) {
if (pkgs.size() == 0)
break;
@@ -1676,40 +1674,23 @@ Query::Impl::filterAdvisory(const Filter & f, Map *m, int keyname)
if (id == -1)
break;
Solvable* s = pool_id2solvable(pool, id);
- auto low = std::lower_bound(pkgs.begin(), pkgs.end(), *s, advisoryPkgCompareSolvable);
- if (low != pkgs.end() && low->nevraEQ(s)) {
- if (cmpTypeGreaterOrLower) {
- pkgsSecondRun.push_back(*low);
- } else {
+ if (cmp_type == HY_EQ) {
+ auto low = std::lower_bound(pkgs.begin(), pkgs.end(), *s, advisoryPkgCompareSolvable);
+ if (low != pkgs.end() && low->nevraEQ(s)) {
MAPSET(m, id);
}
- }
- }
- if (!cmpTypeGreaterOrLower) {
- return;
- }
- std::sort(pkgsSecondRun.begin(), pkgsSecondRun.end(), advisoryPkgSort);
- id = -1;
- while (true) {
- if (pkgsSecondRun.size() == 0)
- break;
- id = resultPset->next(id);
- if (id == -1)
- break;
- Solvable* s = pool_id2solvable(pool, id);
- auto low = std::lower_bound(pkgsSecondRun.begin(), pkgsSecondRun.end(), *s,
- advisoryPkgCompareSolvableNameArch);
- while (low != pkgsSecondRun.end() && low->getName() == s->name &&
- low->getArch() == s->arch) {
-
- int cmp = pool_evrcmp(pool, s->evr, low->getEVR(), EVRCMP_COMPARE);
- if ((cmp > 0 && cmp_type & HY_GT) ||
- (cmp < 0 && cmp_type & HY_LT) ||
- (cmp == 0 && cmp_type & HY_EQ)) {
- MAPSET(m, id);
- break;
+ } else {
+ auto low = std::lower_bound(pkgs.begin(), pkgs.end(), *s, advisoryPkgCompareSolvableNameArch);
+ while (low != pkgs.end() && low->getName() == s->name && low->getArch() == s->arch) {
+ int cmp = pool_evrcmp(pool, s->evr, low->getEVR(), EVRCMP_COMPARE);
+ if ((cmp > 0 && cmp_type & HY_GT) ||
+ (cmp < 0 && cmp_type & HY_LT) ||
+ (cmp == 0 && cmp_type & HY_EQ)) {
+ MAPSET(m, id);
+ break;
+ }
+ ++low;
}
- ++low;
}
}
}

View File

@ -1,35 +0,0 @@
From 9e670738044166cdd0bf566325bf610bfb802821 Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Mon, 24 Jun 2019 16:34:47 +0200
Subject: [PATCH] [config] ignore trailing blank lines of multiline value (RhBug:1722493)
Parser supports multiline values. Example:
key = value first line
value second line
If a line starts with whitespaces and it is not a section name,
it is treated as continuation of previous key=value line.
This commit ignores trailing blank lines. So newline characters
are trimmed out from the end of line.
---
libdnf/utils/iniparser/iniparser.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/libdnf/utils/iniparser/iniparser.cpp b/libdnf/utils/iniparser/iniparser.cpp
index c77c5ca..14fef74 100644
--- a/libdnf/utils/iniparser/iniparser.cpp
+++ b/libdnf/utils/iniparser/iniparser.cpp
@@ -81,6 +81,9 @@ IniParser::IniParser(std::unique_ptr<std::istream> && inputStream)
}
void IniParser::trimValue() noexcept {
+ auto end = value.find_last_not_of(DELIMITER);
+ if (end != value.npos)
+ value.resize(end + 1);
if (value.length() > 1 &&
value.front() == value.back() &&
(value.front() == '\"' || value.front() == '\'')) {
--
libgit2 0.28.2

View File

@ -1,27 +0,0 @@
From f1cf6f12157da3cf555e49d1b5f0af5c81d0c101 Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Fri, 28 Jun 2019 18:47:19 +0200
Subject: [PATCH] Re-size includes map before re-computation (RhBug:1725213)
It resolves problems with incorrect reads.
https://bugzilla.redhat.com/show_bug.cgi?id=1725213
---
libdnf/dnf-sack.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/libdnf/dnf-sack.cpp b/libdnf/dnf-sack.cpp
index 33fbe4a..c0c1cc5 100644
--- a/libdnf/dnf-sack.cpp
+++ b/libdnf/dnf-sack.cpp
@@ -356,6 +356,7 @@ dnf_sack_recompute_considered(DnfSack *sack)
if (priv->module_excludes)
map_subtract(pool->considered, priv->module_excludes);
if (priv->pkg_includes) {
+ map_grow(priv->pkg_includes, pool->nsolvables);
Map pkg_includes_tmp;
map_init_clone(&pkg_includes_tmp, priv->pkg_includes);
--
libgit2 0.28.2

View File

@ -1,142 +0,0 @@
From 12acb4b30c9a88b9082f7dcbda0257b47bed9c87 Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Sat, 13 Apr 2019 18:46:28 +0200
Subject: [PATCH 1/3] Add HY_PKG_CONFLICTS for conversion into reldep
Sequence of HY_PKG_CONFLICTS requires conversion into reldep.
---
python/hawkey/query-py.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/python/hawkey/query-py.cpp b/python/hawkey/query-py.cpp
index d90f9c95..5bc8d123 100644
--- a/python/hawkey/query-py.cpp
+++ b/python/hawkey/query-py.cpp
@@ -350,6 +350,7 @@ filter_add(HyQuery query, key_t keyname, int cmp_type, PyObject *match)
break;
}
+ case HY_PKG_CONFLICTS:
case HY_PKG_PROVIDES:
case HY_PKG_REQUIRES:
case HY_PKG_ENHANCES:
--
2.21.0
From db4118aeab5d8ed0006d7fe8b924304c7f52d34d Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Sat, 13 Apr 2019 19:38:29 +0200
Subject: [PATCH 2/3] Add support of PY string sequence for HY_PKG_OBSOLETES
---
python/hawkey/query-py.cpp | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/python/hawkey/query-py.cpp b/python/hawkey/query-py.cpp
index 5bc8d123..e9d220b6 100644
--- a/python/hawkey/query-py.cpp
+++ b/python/hawkey/query-py.cpp
@@ -340,10 +340,26 @@ filter_add(HyQuery query, key_t keyname, int cmp_type, PyObject *match)
switch (keyname) {
case HY_PKG:
case HY_PKG_OBSOLETES: {
+ // It could be a sequence of packages or reldep/strings. Lets try packages first.
auto pset = pyseq_to_packageset(match, query->getSack());
-
- if (!pset)
+ if (!pset) {
+ if (auto PyError = PyErr_Occurred()) {
+ // It was not a sequence of packages.
+ if (PyErr_GivenExceptionMatches(PyError, PyExc_TypeError)) {
+ PyErr_Clear();
+ auto reldeplist = pyseq_to_reldeplist(match, query->getSack(), cmp_type);
+ if (reldeplist == NULL)
+ return 1;
+
+ int ret = query->addFilter(keyname, reldeplist.get());
+ if (ret) {
+ return raise_bad_filter();
+ }
+ break;
+ }
+ }
return 1;
+ }
int ret = query->addFilter(keyname, cmp_type, pset.get());
if (ret)
return raise_bad_filter();
--
2.21.0
From 247f05ef7c3083953e02948ba629cc9ef4184e05 Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Mon, 15 Apr 2019 09:54:12 +0200
Subject: [PATCH 3/3] Add conversion for sequence to reldep in c/c++ interface
This conversion is supported from Python, but was not implemented in
c/c++ code.
When sequence that requires conversion was used, it failed on assertion.
---
libdnf.spec | 2 +-
libdnf/sack/query.cpp | 29 ++++++++++++++++++++++++++++-
2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/libdnf.spec b/libdnf.spec
index d7b3270a..5f0b6529 100644
--- a/libdnf.spec
+++ b/libdnf.spec
@@ -37,7 +37,7 @@
%{nil}
Name: libdnf
-Version: 0.35.1
+Version: 0.35.2
Release: 1%{?dist}
Summary: Library providing simplified C and Python API to libsolv
License: LGPLv2+
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
index d5b29a66..949b5ab9 100644
--- a/libdnf/sack/query.cpp
+++ b/libdnf/sack/query.cpp
@@ -882,7 +882,34 @@ Query::addFilter(int keyname, int cmp_type, const char **matches)
if (!valid_filter_str(keyname, cmp_type))
return DNF_ERROR_BAD_QUERY;
pImpl->applied = false;
- pImpl->filters.push_back(Filter(keyname, cmp_type, matches));
+ switch (keyname) {
+ case HY_PKG_CONFLICTS:
+ case HY_PKG_ENHANCES:
+ case HY_PKG_OBSOLETES:
+ case HY_PKG_PROVIDES:
+ case HY_PKG_RECOMMENDS:
+ case HY_PKG_REQUIRES:
+ case HY_PKG_SUGGESTS:
+ case HY_PKG_SUPPLEMENTS: {
+ DnfSack *sack = pImpl->sack;
+ const unsigned nmatches = g_strv_length((gchar**)matches);
+ DependencyContainer reldeplist(sack);
+ if (cmp_type == HY_GLOB) {
+ for (unsigned int i = 0; i < nmatches; ++i) {
+ reldeplist.addReldepWithGlob(matches[i]);
+ }
+ } else {
+ for (unsigned int i = 0; i < nmatches; ++i) {
+ reldeplist.addReldep(matches[i]);
+ }
+ }
+ return addFilter(keyname, &reldeplist);
+ }
+ default: {
+ pImpl->filters.push_back(Filter(keyname, cmp_type, matches));
+ return 0;
+ }
+ }
return 0;
}
--
2.21.0

View File

@ -1,160 +0,0 @@
From d66dfc2815153b315f5b3fd9d3f93be670def26a Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Tue, 3 Sep 2019 12:55:51 +0200
Subject: [PATCH 09/10] Added dnf_move_recursive()
Moves a directory and its contents. If native move operations are
supported then this is used, otherwise a copy + delete fallback is used.
---
libdnf/hy-iutil-private.hpp | 1 +
libdnf/hy-iutil.cpp | 95 +++++++++++++++++++++++++++++++++++--
2 files changed, 93 insertions(+), 3 deletions(-)
diff --git a/libdnf/hy-iutil-private.hpp b/libdnf/hy-iutil-private.hpp
index 8b2b06d5..4920ad39 100644
--- a/libdnf/hy-iutil-private.hpp
+++ b/libdnf/hy-iutil-private.hpp
@@ -41,6 +41,7 @@ char *abspath(const char *path);
int is_readable_rpm(const char *fn);
int mkcachedir(char *path);
gboolean mv(const char *old_path, const char *new_path, GError **error);
+gboolean dnf_move_recursive(const gchar *src_dir, const gchar *dst_dir, GError **error);
char *this_username(void);
/* misc utils */
diff --git a/libdnf/hy-iutil.cpp b/libdnf/hy-iutil.cpp
index 2c5af481..d3b57c79 100644
--- a/libdnf/hy-iutil.cpp
+++ b/libdnf/hy-iutil.cpp
@@ -20,12 +20,14 @@
#include <assert.h>
#include <errno.h>
+#include <dirent.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <pwd.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
@@ -41,9 +43,6 @@ extern "C" {
#include <solv/pool_parserpmrichdep.h>
}
-// glib
-#include <glib.h>
-
// hawkey
#include "dnf-advisory-private.hpp"
#include "dnf-types.h"
@@ -58,6 +57,12 @@ extern "C" {
#include "utils/bgettext/bgettext-lib.h"
#include "sack/packageset.hpp"
+// glib
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <string>
+
#define BUF_BLOCK 4096
#define CHKSUM_TYPE REPOKEY_TYPE_SHA256
#define CHKSUM_IDENT "H000"
@@ -328,6 +333,90 @@ mv(const char* old_path, const char* new_path, GError** error)
return TRUE;
}
+static gboolean
+copyFile(const std::string & srcPath, const std::string & dstPath, GError ** error)
+{
+ g_autoptr(GFile) src = g_file_new_for_path(srcPath.c_str());
+ g_autoptr(GFile) dest = g_file_new_for_path(dstPath.c_str());
+ return g_file_copy(src, dest,
+ static_cast<GFileCopyFlags>(G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA)
+ , NULL, NULL, NULL, error);
+}
+
+static gboolean
+copyRecursive(const std::string & srcPath, const std::string & dstPath, GError ** error)
+{
+ struct stat info;
+ if (!stat(srcPath.c_str(), &info)) {
+ if (S_ISDIR(info.st_mode)) {
+ if (mkdir(dstPath.c_str(), info.st_mode) == -1) {
+ auto err = errno;
+ g_set_error(error,
+ DNF_ERROR,
+ DNF_ERROR_INTERNAL_ERROR,
+ _("cannot create directory %1$s: %2$s"),
+ dstPath.c_str(), strerror(err));
+ return FALSE;
+ }
+ if (auto fd = opendir(srcPath.c_str())) {
+ int ret = TRUE;
+ while (auto dent = readdir(fd)) {
+ auto name = dent->d_name;
+ if (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
+ continue;
+ std::string srcItem = srcPath + "/" + name;
+ std::string dstItem = dstPath + "/" + name;
+ ret = copyRecursive(srcItem, dstItem, error);
+ if (!ret)
+ break;
+ }
+ closedir(fd);
+ return ret;
+ } else {
+ auto err = errno;
+ g_set_error(error,
+ DNF_ERROR,
+ DNF_ERROR_INTERNAL_ERROR,
+ _("cannot open directory %1$s: %2$s"),
+ srcPath.c_str(), strerror(err));
+ return FALSE;
+ }
+ } else {
+ return copyFile(srcPath, dstPath, error);
+ }
+ } else {
+ auto err = errno;
+ g_set_error(error,
+ DNF_ERROR,
+ DNF_ERROR_INTERNAL_ERROR,
+ _("cannot stat path %1$s: %2$s"),
+ srcPath.c_str(), strerror(err));
+ return FALSE;
+ }
+}
+
+/**
+ * dnf_move_recursive:
+ * @src_dir: A source directory path
+ * @dst_dir: A destination directory path
+ * @error: A #GError, or %NULL
+ *
+ * Moves a directory and its contents. Native move is preferred,
+ * if not supported copy and delete fallback is used.
+ *
+ * Returns: %TRUE on successful move, %FALSE otherwise
+ **/
+gboolean
+dnf_move_recursive(const char * srcDir, const char * dstDir, GError ** error)
+{
+ if (rename(srcDir, dstDir) == -1) {
+ if (!copyRecursive(srcDir, dstDir, error))
+ return FALSE;
+ return dnf_remove_recursive(srcDir, error);
+ }
+ return TRUE;
+}
+
char *
this_username(void)
{
--
2.21.0

View File

@ -1,100 +0,0 @@
From 99d35011a057a112957c6e878f4ac0b7ab0d0e7a Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Tue, 3 Sep 2019 13:13:31 +0200
Subject: [PATCH 10/10] Use copy+delete fallback if moving of directory failed
(RhBug:1700341)
Uses dnf_move_recursive() instead of g_rename()/rename() for
move a directories.
The dnf_move_recursive() uses copy+delete fallback if native moving
of directory failed (eg. moving between filesystems, overlayfs).
https://bugzilla.redhat.com/show_bug.cgi?id=1700341
---
libdnf/dnf-repo.cpp | 19 +++++++++----------
libdnf/repo/Repo.cpp | 12 ++++++++----
2 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/libdnf/dnf-repo.cpp b/libdnf/dnf-repo.cpp
index a358356a..568e4262 100644
--- a/libdnf/dnf-repo.cpp
+++ b/libdnf/dnf-repo.cpp
@@ -36,6 +36,7 @@
#include "conf/OptionBool.hpp"
#include "hy-repo-private.hpp"
+#include "hy-iutil-private.hpp"
#include <strings.h>
#include <fcntl.h>
@@ -1826,14 +1827,13 @@ dnf_repo_update(DnfRepo *repo,
/* move the packages directory from the old cache to the new cache */
if (g_file_test(priv->packages, G_FILE_TEST_EXISTS)) {
- rc = g_rename(priv->packages, priv->packages_tmp);
- if (rc != 0) {
- ret = FALSE;
+ ret = dnf_move_recursive(priv->packages, priv->packages_tmp, &error_local);
+ if (!ret) {
g_set_error(error,
DNF_ERROR,
DNF_ERROR_CANNOT_FETCH_SOURCE,
- "cannot move %s to %s",
- priv->packages, priv->packages_tmp);
+ "cannot move %s to %s: %s",
+ priv->packages, priv->packages_tmp, error_local->message);
goto out;
}
}
@@ -1844,14 +1844,13 @@ dnf_repo_update(DnfRepo *repo,
goto out;
/* rename .tmp actual name */
- rc = g_rename(priv->location_tmp, priv->location);
- if (rc != 0) {
- ret = FALSE;
+ ret = dnf_move_recursive(priv->location_tmp, priv->location, &error_local);
+ if (!ret) {
g_set_error(error,
DNF_ERROR,
DNF_ERROR_CANNOT_FETCH_SOURCE,
- "cannot move %s to %s",
- priv->location_tmp, priv->location);
+ "cannot move %s to %s: %s",
+ priv->location_tmp, priv->location, error_local->message);
goto out;
}
ret = lr_handle_setopt(priv->repo_handle, error,
diff --git a/libdnf/repo/Repo.cpp b/libdnf/repo/Repo.cpp
index 23638839..0dbeed8b 100644
--- a/libdnf/repo/Repo.cpp
+++ b/libdnf/repo/Repo.cpp
@@ -31,6 +31,7 @@
#include "../hy-iutil.h"
#include "../hy-repo-private.hpp"
#include "../hy-util-private.hpp"
+#include "../hy-iutil-private.hpp"
#include "../hy-types.h"
#include "libdnf/conf/ConfigParser.hpp"
#include "libdnf/utils/File.hpp"
@@ -1155,10 +1156,13 @@ void Repo::Impl::fetch(const std::string & destdir, std::unique_ptr<LrHandle> &&
}
}
auto tempElement = tmpdir + "/" + elName;
- if (rename(tempElement.c_str(), targetElement.c_str()) == -1) {
- const char * errTxt = strerror(errno);
- throw std::runtime_error(tfm::format(
- _("Cannot rename directory \"%s\" to \"%s\": %s"), tempElement, targetElement, errTxt));
+ GError * error = NULL;
+ if (!dnf_move_recursive(tempElement.c_str(), targetElement.c_str(), &error)) {
+ std::string errTxt = tfm::format(
+ _("Cannot rename directory \"%s\" to \"%s\": %s"),
+ tempElement, targetElement, error->message);
+ g_error_free(error);
+ throw std::runtime_error(errTxt);
}
}
}
--
2.21.0

View File

@ -1,100 +0,0 @@
From 865b0b958c044af966f89520ed97fad9b987f006 Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Thu, 5 Sep 2019 09:20:20 +0200
Subject: [PATCH 11/13] Expose dnf_copy_file and dnf_copy_recursive in private
hpp
Renaming:
copyFile -> dnf_copy_file
copyRecursive -> dnf_copy_recursice
Exposes newnames in private hpp to be possible use it internally
in libdnf.
Closes: #789
Approved by: m-blaha
---
libdnf/hy-iutil-private.hpp | 2 ++
libdnf/hy-iutil.cpp | 20 ++++++++++----------
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/libdnf/hy-iutil-private.hpp b/libdnf/hy-iutil-private.hpp
index 4920ad39..2d84cc21 100644
--- a/libdnf/hy-iutil-private.hpp
+++ b/libdnf/hy-iutil-private.hpp
@@ -41,6 +41,8 @@ char *abspath(const char *path);
int is_readable_rpm(const char *fn);
int mkcachedir(char *path);
gboolean mv(const char *old_path, const char *new_path, GError **error);
+gboolean dnf_copy_file(const std::string & srcPath, const std::string & dstPath, GError ** error);
+gboolean dnf_copy_recursive(const std::string & srcPath, const std::string & dstPath, GError ** error);
gboolean dnf_move_recursive(const gchar *src_dir, const gchar *dst_dir, GError **error);
char *this_username(void);
diff --git a/libdnf/hy-iutil.cpp b/libdnf/hy-iutil.cpp
index d3b57c79..5401a9cf 100644
--- a/libdnf/hy-iutil.cpp
+++ b/libdnf/hy-iutil.cpp
@@ -333,18 +333,18 @@ mv(const char* old_path, const char* new_path, GError** error)
return TRUE;
}
-static gboolean
-copyFile(const std::string & srcPath, const std::string & dstPath, GError ** error)
+gboolean
+dnf_copy_file(const std::string & srcPath, const std::string & dstPath, GError ** error)
{
g_autoptr(GFile) src = g_file_new_for_path(srcPath.c_str());
g_autoptr(GFile) dest = g_file_new_for_path(dstPath.c_str());
return g_file_copy(src, dest,
- static_cast<GFileCopyFlags>(G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA)
- , NULL, NULL, NULL, error);
+ static_cast<GFileCopyFlags>(G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA),
+ NULL, NULL, NULL, error);
}
-static gboolean
-copyRecursive(const std::string & srcPath, const std::string & dstPath, GError ** error)
+gboolean
+dnf_copy_recursive(const std::string & srcPath, const std::string & dstPath, GError ** error)
{
struct stat info;
if (!stat(srcPath.c_str(), &info)) {
@@ -359,14 +359,14 @@ copyRecursive(const std::string & srcPath, const std::string & dstPath, GError *
return FALSE;
}
if (auto fd = opendir(srcPath.c_str())) {
- int ret = TRUE;
+ gboolean ret = TRUE;
while (auto dent = readdir(fd)) {
auto name = dent->d_name;
if (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
continue;
std::string srcItem = srcPath + "/" + name;
std::string dstItem = dstPath + "/" + name;
- ret = copyRecursive(srcItem, dstItem, error);
+ ret = dnf_copy_recursive(srcItem, dstItem, error);
if (!ret)
break;
}
@@ -382,7 +382,7 @@ copyRecursive(const std::string & srcPath, const std::string & dstPath, GError *
return FALSE;
}
} else {
- return copyFile(srcPath, dstPath, error);
+ return dnf_copy_file(srcPath, dstPath, error);
}
} else {
auto err = errno;
@@ -410,7 +410,7 @@ gboolean
dnf_move_recursive(const char * srcDir, const char * dstDir, GError ** error)
{
if (rename(srcDir, dstDir) == -1) {
- if (!copyRecursive(srcDir, dstDir, error))
+ if (!dnf_copy_recursive(srcDir, dstDir, error))
return FALSE;
return dnf_remove_recursive(srcDir, error);
}
--
2.21.0

View File

@ -1,60 +0,0 @@
From 842c0057f82a587f8dd2649d920420b7d888fddf Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Thu, 5 Sep 2019 13:55:00 +0200
Subject: [PATCH 12/13] Add dnf_remove_recursive_v2() that support unlink of
file
The dnf_remove_recursive() accepts only directory as argument.
The new function supports unlink of files.
Closes: #789
Approved by: m-blaha
---
libdnf/hy-iutil-private.hpp | 1 +
libdnf/hy-iutil.cpp | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/libdnf/hy-iutil-private.hpp b/libdnf/hy-iutil-private.hpp
index 2d84cc21..bf1714e9 100644
--- a/libdnf/hy-iutil-private.hpp
+++ b/libdnf/hy-iutil-private.hpp
@@ -41,6 +41,7 @@ char *abspath(const char *path);
int is_readable_rpm(const char *fn);
int mkcachedir(char *path);
gboolean mv(const char *old_path, const char *new_path, GError **error);
+gboolean dnf_remove_recursive_v2(const gchar *path, GError **error);
gboolean dnf_copy_file(const std::string & srcPath, const std::string & dstPath, GError ** error);
gboolean dnf_copy_recursive(const std::string & srcPath, const std::string & dstPath, GError ** error);
gboolean dnf_move_recursive(const gchar *src_dir, const gchar *dst_dir, GError **error);
diff --git a/libdnf/hy-iutil.cpp b/libdnf/hy-iutil.cpp
index 5401a9cf..e1a1906a 100644
--- a/libdnf/hy-iutil.cpp
+++ b/libdnf/hy-iutil.cpp
@@ -333,6 +333,24 @@ mv(const char* old_path, const char* new_path, GError** error)
return TRUE;
}
+/**
+ * dnf_remove_recursive_v2:
+ * @directory: A directory path
+ * @error: A #GError, or %NULL
+ *
+ * Removes a file or a directory and its contents.
+ *
+ * Returns: %FALSE if an error was set
+ **/
+gboolean
+dnf_remove_recursive_v2(const gchar *path, GError **error)
+{
+ if (g_file_test(path, G_FILE_TEST_IS_DIR))
+ return dnf_remove_recursive(path, error);
+ else
+ return dnf_ensure_file_unlinked(path, error);
+}
+
gboolean
dnf_copy_file(const std::string & srcPath, const std::string & dstPath, GError ** error)
{
--
2.21.0

View File

@ -1,42 +0,0 @@
From dab2ade3727dbf61dbcfd58d7a2a3fdbbb36116e Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Thu, 5 Sep 2019 14:01:26 +0200
Subject: [PATCH 13/13] Fix: dnf_move_recursive() for file in fallback mode
The dnf_move_recursive() had problem with moving a file in the fallback
mode. The file was copied but removing of its source failed.
The dnf_remove_recursive_v2() is used now to resolve the issue.
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1700341
Closes: #789
Approved by: m-blaha
---
libdnf/hy-iutil.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libdnf/hy-iutil.cpp b/libdnf/hy-iutil.cpp
index e1a1906a..0bd0e245 100644
--- a/libdnf/hy-iutil.cpp
+++ b/libdnf/hy-iutil.cpp
@@ -419,7 +419,7 @@ dnf_copy_recursive(const std::string & srcPath, const std::string & dstPath, GEr
* @dst_dir: A destination directory path
* @error: A #GError, or %NULL
*
- * Moves a directory and its contents. Native move is preferred,
+ * Moves a file or a directory and its contents. Native move is preferred,
* if not supported copy and delete fallback is used.
*
* Returns: %TRUE on successful move, %FALSE otherwise
@@ -430,7 +430,7 @@ dnf_move_recursive(const char * srcDir, const char * dstDir, GError ** error)
if (rename(srcDir, dstDir) == -1) {
if (!dnf_copy_recursive(srcDir, dstDir, error))
return FALSE;
- return dnf_remove_recursive(srcDir, error);
+ return dnf_remove_recursive_v2(srcDir, error);
}
return TRUE;
}
--
2.21.0

View File

@ -1,46 +0,0 @@
From a9e281087d075f798ac64dad657d34816d533d2a Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Tue, 3 Sep 2019 11:01:23 +0200
Subject: [PATCH] Mark job goal.upgrade with sltr as targeted
It allows to keep installed packages in upgrade set.
It also prevents from reinstalling of modified packages with same NEVRA.
---
libdnf/goal/Goal.cpp | 2 +-
libdnf/goal/Goal.hpp | 6 ++++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/libdnf/goal/Goal.cpp b/libdnf/goal/Goal.cpp
index b69be19..a38cbb4 100644
--- a/libdnf/goal/Goal.cpp
+++ b/libdnf/goal/Goal.cpp
@@ -767,7 +767,7 @@ void
Goal::upgrade(HySelector sltr)
{
pImpl->actions = static_cast<DnfGoalActions>(pImpl->actions | DNF_UPGRADE);
- sltrToJob(sltr, &pImpl->staging, SOLVER_UPDATE);
+ sltrToJob(sltr, &pImpl->staging, SOLVER_UPDATE|SOLVER_TARGETED);
}
void
diff --git a/libdnf/goal/Goal.hpp b/libdnf/goal/Goal.hpp
index f33dfa2..d701317 100644
--- a/libdnf/goal/Goal.hpp
+++ b/libdnf/goal/Goal.hpp
@@ -86,8 +86,10 @@ public:
/**
* @brief If selector ill formed, it rises std::runtime_error()
*
- * @param sltr p_sltr: It should contain only upgrades with obsoletes otherwise it can try to
- * reinstall installonly packages.
+ * @param sltr p_sltr: It contains upgrade-to packages and obsoletes. The presence of installed
+ * packages prevents reinstalling packages with the same NEVRA but changed contant. To honor repo
+ * priority all relevant packages must be present. To upgrade package foo from priority repo, all
+ * installed and available packages of the foo must be in selector plus obsoletes of foo.
*/
void upgrade(HySelector sltr);
void userInstalled(DnfPackage *pkg);
--
libgit2 0.28.2

View File

@ -1,34 +0,0 @@
From c235dae84d1b45911f6de1c5d31fedf4856c0d42 Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Wed, 11 Sep 2019 13:26:43 +0200
Subject: [PATCH] Apply targeted upgrade only for selector with packages
It resolves problem when selector with name filter is used. Then
targeted transaction ignores obsoletes.
Closes: #793
Approved by: jrohel
---
libdnf/goal/Goal.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/libdnf/goal/Goal.cpp b/libdnf/goal/Goal.cpp
index a38cbb4..88e7b8c 100644
--- a/libdnf/goal/Goal.cpp
+++ b/libdnf/goal/Goal.cpp
@@ -767,7 +767,11 @@ void
Goal::upgrade(HySelector sltr)
{
pImpl->actions = static_cast<DnfGoalActions>(pImpl->actions | DNF_UPGRADE);
- sltrToJob(sltr, &pImpl->staging, SOLVER_UPDATE|SOLVER_TARGETED);
+ auto flags = SOLVER_UPDATE;
+ if (sltr->getPkgs()) {
+ flags |= SOLVER_TARGETED;
+ }
+ sltrToJob(sltr, &pImpl->staging, flags);
}
void
--
libgit2 0.28.2

View File

@ -1,9 +1,20 @@
%global libsolv_version 0.7.4-1
%global libsolv_version 0.7.7
%global libmodulemd_version 1.6.1
%global librepo_version 1.10.0
%global dnf_conflict 4.2.7-7
%global librepo_version 1.11.0
%global dnf_conflict 4.2.13
%global swig_version 3.0.12
# set sphinx package name according to distro
%global requires_python2_sphinx python2-sphinx
%global requires_python3_sphinx python3-sphinx
%if 0%{?rhel} == 7
%global requires_python2_sphinx python-sphinx
%endif
%if 0%{?suse_version}
%global requires_python2_sphinx python2-Sphinx
%global requires_python3_sphinx python3-Sphinx
%endif
%bcond_with valgrind
# Do not build bindings for python3 for RHEL <= 7
@ -13,12 +24,6 @@
%bcond_without python3
%endif
%if 0%{?rhel}
%global rpm_version 4.14.2
%else
%global rpm_version 4.14.2.1-4
%endif
%if 0%{?rhel} > 7 || 0%{?fedora} > 29
# Disable python2 build by default
%bcond_with python2
@ -32,33 +37,29 @@
%bcond_with rhsm
%endif
%if 0%{?rhel}
%bcond_with zchunk
%else
%bcond_without zchunk
%endif
%global _cmake_opts \\\
-DENABLE_RHSM_SUPPORT=%{?with_rhsm:ON}%{!?with_rhsm:OFF} \\\
%{nil}
Name: libdnf
Version: 0.35.1
Release: 9%{?dist}
Version: 0.39.1
Release: 5%{?dist}
Summary: Library providing simplified C and Python API to libsolv
License: LGPLv2+
URL: https://github.com/rpm-software-management/libdnf
Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz
# Temporary patch to not fail on modular RPMs without modular metadata
# until the infrastructure is ready
Patch2: 0002-Fix-attaching-and-detaching-of-libsolvRepo.patch
Patch3: 0003-Typo-in-error-message-RhBug1726661.patch
Patch4: 0004-Update-localizations-from-zanata-RhBug1689991.patch
Patch5: 0005-context-Fix-Dont-disable-nonexistent-but-required-repositories-RhBug1689331.patch
Patch6: 0006-config-ignore-trailing-blank-lines-of-multiline-value-RhBug1722493.patch
Patch7: 0007-Re-size-includes-map-before-re-computation-RhBug1725213.patch
Patch8: 0008-Add-suport-for-query-sequence-conversions.patch
Patch9: 0009-Added-dnf_move_recursive.patch
Patch10: 0010-Use-copy-delete-fallback-if-moving-of-directory-fail.patch
Patch11: 0011-Expose-dnf_copy_file-and-dnf_copy_recursive-in-priva.patch
Patch12: 0012-Add-dnf_remove_recursive_v2-that-support-unlink-of-f.patch
Patch13: 0013-Fix-dnf_move_recursive-for-file-in-fallback-mode.patch
Patch14: 0014-Mark-job-goalupgrade-with-sltr-as-targeted.patch
Patch15: 0015-Apply-targeted-upgrade-only-for-selector-with-packages.patch
Patch1: 0001-user-agent-Drop-the-whitelist.patch
Patch2: 0002-context-wildcard-support-in-dnf_context_repo_set_data-RhBug1781420.patch
Patch3: 0003-Add-2-query-filters.patch
Patch4: 0004-Remove-killGpgAgent-function-RhBug1781601.patch
Patch5: 0005-Update-translations-from-zanata-RhBug-1754965.patch
Patch6: 0006-Fix-filtering-packages-by-advisory-RhBug-1770125.patch
BuildRequires: cmake
BuildRequires: gcc
@ -71,10 +72,13 @@ BuildRequires: valgrind
%endif
BuildRequires: pkgconfig(gio-unix-2.0) >= 2.46.0
BuildRequires: pkgconfig(gtk-doc)
BuildRequires: rpm-devel >= %{rpm_version}
BuildRequires: rpm-devel >= 4.11.0
%if %{with rhsm}
BuildRequires: pkgconfig(librhsm) >= 0.0.3
%endif
%if %{with zchunk}
BuildRequires: pkgconfig(zck) >= 0.9.11
%endif
BuildRequires: pkgconfig(sqlite3)
BuildRequires: pkgconfig(json-c)
BuildRequires: pkgconfig(cppunit)
@ -88,6 +92,16 @@ Requires: libmodulemd%{?_isa} >= %{libmodulemd_version}
Requires: libsolv%{?_isa} >= %{libsolv_version}
Requires: librepo%{?_isa} >= %{librepo_version}
%if %{without python2}
# Obsoleted from here so we can track the fast growing version easily.
# We intentionally only obsolete and not provide, this is a broken upgrade
# prevention, not providing the removed functionality.
Obsoletes: python2-%{name} < %{version}-%{release}
Obsoletes: python2-hawkey < %{version}-%{release}
Obsoletes: python2-hawkey-debuginfo < %{version}-%{release}
Obsoletes: python2-libdnf-debuginfo < %{version}-%{release}
%endif
%description
A Library providing simplified C and Python API to libsolv.
@ -105,11 +119,12 @@ Development files for %{name}.
Summary: Python 2 bindings for the libdnf library.
Requires: %{name}%{?_isa} = %{version}-%{release}
BuildRequires: python2-devel
%if !0%{?mageia}
BuildRequires: %{requires_python2_sphinx}
%endif
%if 0%{?rhel} == 7
BuildRequires: python-sphinx
BuildRequires: swig3 >= %{swig_version}
%else
BuildRequires: python2-sphinx
BuildRequires: swig >= %{swig_version}
%endif
@ -123,7 +138,7 @@ Python 2 bindings for the libdnf library.
Summary: Python 3 bindings for the libdnf library.
Requires: %{name}%{?_isa} = %{version}-%{release}
BuildRequires: python3-devel
BuildRequires: python3-sphinx
BuildRequires: %{requires_python3_sphinx}
BuildRequires: swig >= %{swig_version}
%description -n python3-%{name}
@ -181,39 +196,49 @@ mkdir build-py3
%build
%if %{with python2}
pushd build-py2
%cmake -DPYTHON_DESIRED:FILEPATH=%{__python2} -DWITH_MAN=OFF ../ %{!?with_valgrind:-DDISABLE_VALGRIND=1} %{_cmake_opts}
%if 0%{?mageia} || 0%{?suse_version}
cd ..
%define _cmake_builddir build-py2
%define __builddir build-py2
%endif
%cmake -DPYTHON_DESIRED:FILEPATH=%{__python2} -DWITH_MAN=OFF ../ %{!?with_zchunk:-DWITH_ZCHUNK=OFF} %{!?with_valgrind:-DDISABLE_VALGRIND=1} %{_cmake_opts}
%make_build
popd
%endif # with python2
%if %{with python3}
pushd build-py3
%cmake -DPYTHON_DESIRED:FILEPATH=%{__python3} -DWITH_GIR=0 -DWITH_MAN=0 -Dgtkdoc=0 ../ %{!?with_valgrind:-DDISABLE_VALGRIND=1} %{_cmake_opts}
%if 0%{?mageia} || 0%{?suse_version}
cd ..
%define _cmake_builddir build-py3
%define __builddir build-py3
%endif
%cmake -DPYTHON_DESIRED:FILEPATH=%{__python3} -DWITH_GIR=0 -DWITH_MAN=0 -Dgtkdoc=0 ../ %{!?with_zchunk:-DWITH_ZCHUNK=OFF} %{!?with_valgrind:-DDISABLE_VALGRIND=1} %{_cmake_opts}
%make_build
popd
%endif
%check
if [ "$(id -u)" == "0" ] ; then
cat <<ERROR 1>&2
Package tests cannot be run under superuser account.
Please build the package as non-root user.
ERROR
exit 1
fi
%if %{with python2}
pushd build-py2
make ARGS="-V" test
popd
%endif # with python2
%if %{with python3}
# Run just the Python tests, not all of them, since
# we have coverage of the core from the first build
# If we didn't run the general tests yet, do it now.
%if %{without python2}
pushd build-py3
make ARGS="-V" test
popd
%else
# Otherwise, run just the Python tests, not all of
# them, since we have coverage of the core from the
# first build
pushd build-py3/python/hawkey/tests
make ARGS="-V" test
popd
%endif
%endif
%install
%if %{with python2}
@ -229,7 +254,7 @@ popd
%find_lang %{name}
%if 0%{?rhel} && 0%{?rhel} <= 7
%if (0%{?rhel} && 0%{?rhel} <= 7) || 0%{?suse_version}
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%else
@ -271,6 +296,68 @@ popd
%endif
%changelog
* Tue Feb 18 2020 Ales Matej <amatej@redhat.com> - 0.39.1-5
- Fix filtering of packages by advisory (RhBug:1770125)
* Fri Jan 31 2020 Marek Blaha <mblaha@redhat.com> - 0.39.1-4
- [translations] Update translations from zanata (RhBug:1754965)
* Mon Jan 13 2020 Ales Matej <amatej@redhat.com> - 0.39.1-3
- Add two new query filters: obsoletes_by_priority, upgrades_by_priority (RhBug:1769466)
- [context] Add wildcard support in dnf_context_repo_set_data (RhBug:1781420)
- Remove killGpgAgent function (RhBug:1781601)
* Thu Dec 12 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 0.39.1-2
- [user-agent] Stop checking os-release(5) data against a hard-coded whitelist (RhBug:1777255)
* Mon Nov 25 2019 Ales Matej <amatej@redhat.com> - 0.39.1-1
- Update to 0.39.1
- Report reason how package was excluded (RhBug:1649754)
- Additional Arm detection improvements (RhBug:1691430)
- Set skip_if_unavailable for media repos to skip their update (RhBug:1716067)
- Add support of xml:base for remote and local url in context (RhBug:1734350,1717865)
* Wed Nov 13 2019 Ales Matej <amatej@redhat.com> - 0.38.1-1
- Update to 0.38.1
- Change the best option default to false
- Use more descriptive message when failed to retrieve GPG key (RhBug:1605117)
- Add removeMetadataTypeFromDownload function to the API
- Context part of libdnf can now read vars (urlvars) from dirs and environment
- Throw exception immediately if file cannot be opened
- Add test when there is no primary metadata in compatible format (RhBug:1744960)
- Various improvements to countme features
- Don't abort on rpmdb checksum calculation failure
- Enable module dependency trees when using set_modules_enabled_by_pkgset() (RhBug:1762314)
- Resolve problem with --best and search in provides (RhBug:1737469)
- New method "Query::filterSubject()", replaces Solution::getBestSolution()
- The Solution class was removed
- Add query argument into get_best_query and get_best_solution
- Add module reset function into dnf_context
- Add method to get all repository metadata locations
- Catch NoModuleException in case of not existent value was used in persistor (RhBug:1761773)
* Tue Oct 22 2019 Ales Matej <amatej@redhat.com> - 0.35.5-1
- Update to 0.35.5
- Make libdnf own its plugin directory (RhBug:1714265)
- Set priority of dnf.conf.d drop-ins
- Fix toString() to not insert [] (RhBug:1584442)
- Fix handling large number of filenames on input (RhBug:1690915)
- Detect armv7 with crypto extension only on arm version >= 8
- A new standardized User-Agent field consisting of the libdnf and OS version
(including the variant) (RhBug:1156007)
- Add basic countme support (RhBug:1647454)
- Fix crash in PackageKit (RhBug:1636803)
- Do not create @System.solv files (RhBug:1707995)
- Set LRO_CACHEDIR so zchunk works again (RhBug:1739867)
- Improve detection of extras packages by comparing (name, arch) pair instead
of full NEVRA (RhBuh:1684517)
- Improve handling multilib packages in the history command (RhBug:1728637)
- Repo download: use full error description into the exception text (RhBug:1741442)
- Properly close hawkey.log (RhBug:1594016)
- Fix dnf updateinfo --update to not list advisories for packages updatable
only from non-enabled modules
- Apply modular filtering by package name (RhBug:1702729)
* Wed Oct 16 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 0.35.1-9
- Prevent reinstalling modified packages with same NEVRA (RhBug:1728252,1644241,1760825)