From 8af6afa21dcf2d3b3fa59bbc2b1ef89a48dd072e Mon Sep 17 00:00:00 2001 From: Shivani Agarwal Date: Tue, 26 Sep 2023 06:55:02 +0000 Subject: [PATCH] tdnf: Add check to identify duplicate repo id --- client/defines.h | 1 + client/repolist.c | 14 ++++++++++- include/tdnferror.h | 2 ++ pytests/tests/test_baseurls.py | 3 +-- pytests/tests/test_installroot.py | 3 ++- pytests/tests/test_repolist.py | 34 +++++++++++++++++++++++++++ pytests/tests/test_setopt_reposdir.py | 3 ++- 7 files changed, 55 insertions(+), 5 deletions(-) diff --git a/client/defines.h b/client/defines.h index bf3c40d5..fd8fa5d8 100644 --- a/client/defines.h +++ b/client/defines.h @@ -232,6 +232,7 @@ typedef enum {ERROR_TDNF_INVALID_INPUT, "ERROR_TDNF_INVALID_INPUT", "Invalid input."},\ {ERROR_TDNF_CACHE_DISABLED, "ERROR_TDNF_CACHE_DISABLED", "cache only is set, but no repo data found"},\ {ERROR_TDNF_CACHE_DIR_OUT_OF_DISK_SPACE, "ERROR_TDNF_CACHE_DIR_OUT_OF_DISK_SPACE", "Insufficient disk space at cache directory /var/cache/tdnf (unless specified differently in config). Try freeing space first."},\ + {ERROR_TDNF_DUPLICATE_REPO_ID, "ERROR_TDNF_DUPLICATE_REPO_ID", "Duplicate repo id"}, \ {ERROR_TDNF_EVENT_CTXT_ITEM_NOT_FOUND, "ERROR_TDNF_EVENT_CTXT_ITEM_NOT_FOUND", "An event context item was not found. This is usually related to plugin events. Try --noplugins to deactivate all plugins or --disableplugin= to deactivate a specific one. You can permanently deactivate an offending plugin by setting enable=0 in the plugin config file."},\ {ERROR_TDNF_EVENT_CTXT_ITEM_INVALID_TYPE, "ERROR_TDNF_EVENT_CTXT_ITEM_INVALID_TYPE", "An event item type had a mismatch. This is usually related to plugin events. Try --noplugins to deactivate all plugins or --disableplugin= to deactivate a specific one. You can permanently deactivate an offending plugin by setting enable=0 in the plugin config file."},\ {ERROR_TDNF_NO_GPGKEY_CONF_ENTRY, "ERROR_TDNF_NO_GPGKEY_CONF_ENTRY", "gpgkey entry is missing for this repo. please add gpgkey in repo file or use --nogpgcheck to ignore."}, \ diff --git a/client/repolist.c b/client/repolist.c index 1bb1168f..808fe40f 100644 --- a/client/repolist.c +++ b/client/repolist.c @@ -28,6 +28,8 @@ TDNFLoadRepoData( DIR *pDir = NULL; struct dirent *pEnt = NULL; char **ppszUrlIdTuple = NULL; + PTDNF_REPO_DATA pRepoParsePre = NULL; + PTDNF_REPO_DATA pRepoParseNext = NULL; if(!pTdnf || !pTdnf->pConf || !pTdnf->pArgs || !ppReposAll) { @@ -115,12 +117,22 @@ TDNFLoadRepoData( TDNF_SAFE_FREE_MEMORY(pszRepoFilePath); pszRepoFilePath = NULL; - /* may have added multiple repos, go to last one */ while (*ppRepoNext) ppRepoNext = &((*ppRepoNext)->pNext); } + for (pRepoParsePre = pReposAll; pRepoParsePre; pRepoParsePre = pRepoParsePre->pNext) { + + for (pRepoParseNext = pRepoParsePre->pNext; pRepoParseNext; pRepoParseNext = pRepoParseNext->pNext) { + if (!strcmp(pRepoParsePre->pszId, pRepoParseNext->pszId)) { + pr_err("ERROR: Duplicate Repoid (%s)\n", pRepoParsePre->pszId); + dwError = ERROR_TDNF_DUPLICATE_REPO_ID; + BAIL_ON_TDNF_ERROR(dwError); + } + } + } + *ppReposAll = pReposAll; cleanup: if(pDir) diff --git a/include/tdnferror.h b/include/tdnferror.h index 7e6246f7..c9349a06 100644 --- a/include/tdnferror.h +++ b/include/tdnferror.h @@ -72,6 +72,8 @@ extern "C" { #define ERROR_TDNF_DOWNGRADE_NOT_ALLOWED 1035 // cache directory out of memory #define ERROR_TDNF_CACHE_DIR_OUT_OF_DISK_SPACE 1036 +// There are duplicate repo id +#define ERROR_TDNF_DUPLICATE_REPO_ID 1037 //curl errors #define ERROR_TDNF_CURL_INIT 1200 diff --git a/pytests/tests/test_baseurls.py b/pytests/tests/test_baseurls.py index 7ebeb847..c5de8f5d 100644 --- a/pytests/tests/test_baseurls.py +++ b/pytests/tests/test_baseurls.py @@ -12,7 +12,6 @@ WORKDIR = '/root/baseurls/workdir' REPOFILENAME = 'baseurls.repo' -TESTREPO = 'photon-test' REPONAME = 'baseurls-repo' @@ -33,7 +32,7 @@ def teardown_test(utils): def test_multiple_baseurls(utils): - reponame = TESTREPO + reponame = REPONAME workdir = WORKDIR utils.makedirs(workdir) diff --git a/pytests/tests/test_installroot.py b/pytests/tests/test_installroot.py index 89bb279e..ea436217 100644 --- a/pytests/tests/test_installroot.py +++ b/pytests/tests/test_installroot.py @@ -27,7 +27,8 @@ def setup_test(utils): def teardown_test(utils): if os.path.isdir(INSTALLROOT): shutil.rmtree(INSTALLROOT) - pass + if os.path.isdir(REPODIR): + shutil.rmtree(REPODIR) def install_root(utils, no_reposd=False): diff --git a/pytests/tests/test_repolist.py b/pytests/tests/test_repolist.py index 2b0e4229..1abfbf38 100644 --- a/pytests/tests/test_repolist.py +++ b/pytests/tests/test_repolist.py @@ -50,6 +50,8 @@ def setup_test(utils): def teardown_test(utils): os.remove(os.path.join(utils.config['repo_path'], 'yum.repos.d', 'foo.repo')) os.remove(os.path.join(utils.config['repo_path'], 'yum.repos.d', 'bar.repo')) + os.remove(os.path.join(utils.config['repo_path'], "yum.repos.d", 'test.repo')) + os.remove(os.path.join(utils.config['repo_path'], "yum.repos.d", 'test1.repo')) def find_repo(repolist, id): @@ -126,3 +128,35 @@ def test_repolist_invalid(utils): def test_repolist_memcheck(utils): ret = utils.run_memcheck(['tdnf', 'repolist']) assert ret['retval'] == 0 + + +# multiple repoid +def test_multiple_repoid(utils): + reponame = 'test.repo' + repofile_test = os.path.join(utils.config['repo_path'], 'yum.repos.d', reponame) + utils.edit_config( + { + 'name': 'Test Repo', + 'enabled': '1', + 'baseurl': 'http://pkgs.test.org/test' + }, + section='test', + filename=repofile_test + ) + + reponame = 'test1.repo' + repofile_test1 = os.path.join(utils.config['repo_path'], 'yum.repos.d', reponame) + utils.edit_config( + { + 'name': 'Test Repo', + 'enabled': '1', + 'baseurl': 'http://pkgs.test1.org/test1' + }, + section='test', + filename=repofile_test1 + ) + + ret = utils.run(['tdnf', + '--disablerepo=*', '--enablerepo={}'.format(reponame), + 'makecache']) + assert ret['retval'] == 1037 diff --git a/pytests/tests/test_setopt_reposdir.py b/pytests/tests/test_setopt_reposdir.py index aefe903c..3d4f71f2 100644 --- a/pytests/tests/test_setopt_reposdir.py +++ b/pytests/tests/test_setopt_reposdir.py @@ -11,7 +11,7 @@ import pytest REPODIR = '/root/yum.repos.d' -REPOFILENAME = 'reposync.repo' +REPOFILENAME = 'setopt.repo' REPONAME = "reposdir-test" @@ -32,4 +32,5 @@ def test_setopt_reposdir(utils): "http://foo.bar.com/packages", REPONAME) ret = utils.run(['tdnf', '--setopt=reposdir={}'.format(REPODIR), 'repolist']) + assert ret['retval'] == 0 assert REPONAME in "\n".join(ret['stdout'])