From 07cc9a1bdac10c202d4861c0605ba633c4282f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Fri, 1 Nov 2019 16:31:45 +0100 Subject: [PATCH 1/2] Only the pkg knows whether it is local or remote (RhBug:1734350, 1717865) Repository can have remote and local packages at the same time using xml:base, we have to ask the pkg if it is local. The package needs to have specified repository otherwise we cannot tell with certainty if it is local or remote. https://bugzilla.redhat.com/show_bug.cgi?id=1734350 https://bugzilla.redhat.com/show_bug.cgi?id=1717865 --- libdnf/dnf-package.cpp | 32 ++++++++++++++++++++++++++++---- libdnf/dnf-package.h | 1 + 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/libdnf/dnf-package.cpp b/libdnf/dnf-package.cpp index 7ed2542adf..c2767e2266 100644 --- a/libdnf/dnf-package.cpp +++ b/libdnf/dnf-package.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -89,6 +90,29 @@ dnf_package_get_priv(DnfPackage *pkg) return priv; } +/** + * dnf_package_is_local: + * @pkg: a #DnfPackage *instance. + * + * Returns: %TRUE if the pkg is a pkg on local or media filesystem + * + * Since: 0.38.2 + **/ +gboolean +dnf_package_is_local(DnfPackage *pkg) +{ + DnfPackagePrivate *priv; + priv = dnf_package_get_priv(pkg); + + assert(priv->repo); + + if (!dnf_repo_is_local(priv->repo)) + return FALSE; + + const gchar *url_location = dnf_package_get_baseurl(pkg); + return (!url_location || (url_location && g_str_has_prefix(url_location, "file:/"))); +} + /** * dnf_package_get_filename: * @pkg: a #DnfPackage *instance. @@ -114,7 +138,7 @@ dnf_package_get_filename(DnfPackage *pkg) /* default cache filename location */ if (!priv->filename) { - if (dnf_repo_is_local(priv->repo)) { + if (dnf_package_is_local(pkg)) { const gchar *url_location = dnf_package_get_baseurl(pkg); if (!url_location){ url_location = dnf_repo_get_location(priv->repo); @@ -660,9 +684,9 @@ dnf_package_check_filename(DnfPackage *pkg, gboolean *valid, GError **error) if (!g_file_test(path, G_FILE_TEST_EXISTS)) { *valid = FALSE; - /* a missing file in a local repo is an error since we can't - download it. */ - if (dnf_repo_is_local (dnf_package_get_repo (pkg))) { + /* a missing file in a local repo is an error, unless it is remote via base:url, + * since we can't download it */ + if (dnf_package_is_local(pkg)) { ret = FALSE; g_set_error(error, DNF_ERROR, diff --git a/libdnf/dnf-package.h b/libdnf/dnf-package.h index 7d712cb7b8..1ea4585a55 100644 --- a/libdnf/dnf-package.h +++ b/libdnf/dnf-package.h @@ -78,6 +78,7 @@ void dnf_package_set_user_action (DnfPackage *pkg, gboolean user_action); gboolean dnf_package_is_gui (DnfPackage *pkg); gboolean dnf_package_is_devel (DnfPackage *pkg); +gboolean dnf_package_is_local (DnfPackage *pkg); gboolean dnf_package_is_downloaded (DnfPackage *pkg); gboolean dnf_package_is_installonly (DnfPackage *pkg); const gchar *dnf_package_get_pkgid (DnfPackage *pkg); From 394edbbdb180d1448ef10b1a5d40158681f6e3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Thu, 21 Nov 2019 09:40:09 +0100 Subject: [PATCH 2/2] Dont use repo's packages as path to local pkgs (RhBug:1734350, 1717865) Repos packages attribute is solely used for path to packages cache, path to packages of a local repository is calculated using repos attribute location anyway. https://bugzilla.redhat.com/show_bug.cgi?id=1734350 https://bugzilla.redhat.com/show_bug.cgi?id=1717865 --- libdnf/dnf-repo.cpp | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/libdnf/dnf-repo.cpp b/libdnf/dnf-repo.cpp index 9eca7eb8b1..f97caade27 100644 --- a/libdnf/dnf-repo.cpp +++ b/libdnf/dnf-repo.cpp @@ -1010,7 +1010,10 @@ dnf_repo_set_keyfile_data(DnfRepo *repo, GError **error) if (url != NULL && strncasecmp(url, "file://", 7) == 0) { if (g_strstr_len(url, -1, "$testdatadir") == NULL) priv->kind = DNF_REPO_KIND_LOCAL; - dnf_repo_set_location(repo, url + 7); + g_free(priv->location); + g_free(priv->keyring); + priv->location = dnf_repo_substitute(repo, url + 7); + priv->keyring = g_build_filename(url + 7, "gpgdir", NULL); } } @@ -1018,19 +1021,22 @@ dnf_repo_set_keyfile_data(DnfRepo *repo, GError **error) if (!lr_handle_setopt(priv->repo_handle, error, LRO_LOCAL, 0L)) return FALSE; - if (priv->location == NULL) { - g_autofree gchar *tmp = NULL; - /* make each repo's cache directory name has releasever and basearch as its suffix */ - g_autofree gchar *file_name = g_strjoin("-", repoId, - dnf_context_get_release_ver(priv->context), - dnf_context_get_base_arch(priv->context), NULL); + /* set repos cache dir */ + g_autofree gchar *cache_path = NULL; + /* make each repo's cache directory name has releasever and basearch as its suffix */ + g_autofree gchar *cache_file_name = g_strjoin("-", repoId, + dnf_context_get_release_ver(priv->context), + dnf_context_get_base_arch(priv->context), NULL); - tmp = g_build_filename(dnf_context_get_cache_dir(priv->context), - file_name, NULL); - dnf_repo_set_location(repo, tmp); + cache_path = g_build_filename(dnf_context_get_cache_dir(priv->context), cache_file_name, NULL); + if (priv->packages == NULL) { + dnf_repo_set_packages(repo, g_build_filename(cache_path, "packages", NULL)); + } + if (priv->location == NULL) { + dnf_repo_set_location(repo, cache_path); } - /* set temp location for remote repos */ + /* set temp location used for updating remote repos */ if (priv->kind == DNF_REPO_KIND_REMOTE) { g_autoptr(GString) tmp = NULL; tmp = g_string_new(priv->location); @@ -2162,22 +2168,11 @@ dnf_repo_download_packages(DnfRepo *repo, if (!dnf_repo_set_keyfile_data(repo, error)) goto out; - /* we should never be asked to download from a local repo. if - this happens, it's a bug somewhere else. */ - if (dnf_repo_is_local(repo)) { - g_set_error(error, - DNF_ERROR, - DNF_ERROR_INTERNAL_ERROR, - "Refusing to download from local repository \"%s\"", - priv->repo->getId().c_str()); - goto out; - } - /* if nothing specified then use cachedir */ if (directory == NULL) { directory_slash = g_build_filename(priv->packages, "/", NULL); if (!g_file_test(directory_slash, G_FILE_TEST_EXISTS)) { - if (g_mkdir(directory_slash, 0755) != 0) { + if (g_mkdir_with_parents(directory_slash, 0755) != 0) { g_set_error(error, DNF_ERROR, DNF_ERROR_INTERNAL_ERROR,