diff --git a/client/api.c b/client/api.c index 7336012d4..c74f041f2 100644 --- a/client/api.c +++ b/client/api.c @@ -438,33 +438,52 @@ TDNFClean( if (nCleanType & CLEANTYPE_METADATA) { pr_info(" metadata"); - dwError = TDNFRepoRemoveCache(pTdnf, pRepo->pszId); + dwError = TDNFRepoRemoveCache(pTdnf, pRepo); BAIL_ON_TDNF_ERROR(dwError); } if (nCleanType & CLEANTYPE_DBCACHE) { pr_info(" dbcache"); - dwError = TDNFRemoveSolvCache(pTdnf, pRepo->pszId); + dwError = TDNFRemoveSolvCache(pTdnf, pRepo); BAIL_ON_TDNF_ERROR(dwError); } if (nCleanType & CLEANTYPE_PACKAGES) { pr_info(" packages"); - dwError = TDNFRemoveRpmCache(pTdnf, pRepo->pszId); + dwError = TDNFRemoveRpmCache(pTdnf, pRepo); BAIL_ON_TDNF_ERROR(dwError); } if (nCleanType & CLEANTYPE_KEYS) { pr_info(" keys"); - dwError = TDNFRemoveKeysCache(pTdnf, pRepo->pszId); + dwError = TDNFRemoveKeysCache(pTdnf, pRepo); BAIL_ON_TDNF_ERROR(dwError); } if (nCleanType & CLEANTYPE_EXPIRE_CACHE) { pr_info(" expire-cache"); - dwError = TDNFRemoveLastRefreshMarker(pTdnf, pRepo->pszId); + dwError = TDNFRemoveLastRefreshMarker(pTdnf, pRepo); BAIL_ON_TDNF_ERROR(dwError); } + + /* remove the top level repo cache dir if it's not empty */ + dwError = TDNFRepoRemoveCacheDir(pTdnf, pRepo); + if (dwError == ERROR_TDNF_SYSTEM_BASE + ENOTEMPTY) + { + /* if we did a 'clean all' the directory should be empty now. If + not we either missed something or someone other than us + put a file there, so warn about it, but don't bail out. + If we did clean just one part it's not expected to be empty + unless the other parts were already cleaned. + */ + if (nCleanType == CLEANTYPE_ALL) + { + pr_err("Cache directory for %s not removed because it's not empty.\n", pRepo->pszId); + } + dwError = 0; + } + BAIL_ON_TDNF_ERROR(dwError); + pr_info("\n"); } cleanup: diff --git a/client/gpgcheck.c b/client/gpgcheck.c index a60143642..e74b084f0 100644 --- a/client/gpgcheck.c +++ b/client/gpgcheck.c @@ -564,6 +564,7 @@ TDNFFetchRemoteGPGKey( char* pszRealTopKeyCacheDir = NULL; char* pszDownloadCacheDir = NULL; char* pszKeyLocation = NULL; + PTDNF_REPO_DATA pRepo = NULL; if(!pTdnf || IsNullOrEmptyString(pszRepoName || IsNullOrEmptyString(pszUrlGPGKey))) { @@ -578,12 +579,12 @@ TDNFFetchRemoteGPGKey( } BAIL_ON_TDNF_ERROR(dwError); - dwError = TDNFJoinPath( - &pszTopKeyCacheDir, - pTdnf->pConf->pszCacheDir, - pszRepoName, - "keys", - NULL); + dwError = TDNFFindRepoById(pTdnf, pszRepoName, &pRepo); + BAIL_ON_TDNF_ERROR(dwError); + + dwError = TDNFGetCachePath(pTdnf, pRepo, + "keys", NULL, + &pszTopKeyCacheDir); BAIL_ON_TDNF_ERROR(dwError); dwError = TDNFNormalizePath(pszTopKeyCacheDir, diff --git a/client/init.c b/client/init.c index 6be4bb4b7..20cf70c40 100644 --- a/client/init.c +++ b/client/init.c @@ -284,11 +284,9 @@ TDNFRefreshSack( unless requested to ignore. lMetadataExpire < 0 means never expire. */ if(pRepo->lMetadataExpire >= 0 && !pTdnf->pArgs->nCacheOnly) { - dwError = TDNFJoinPath( - &pszRepoCacheDir, - pTdnf->pConf->pszCacheDir, - pRepo->pszId, - NULL); + dwError = TDNFGetCachePath(pTdnf, pRepo, + NULL, NULL, + &pszRepoCacheDir); BAIL_ON_TDNF_ERROR(dwError); dwError = TDNFShouldSyncMetadata( @@ -316,14 +314,14 @@ TDNFRefreshSack( goto cleanup; } - dwError = TDNFRepoRemoveCache(pTdnf, pRepo->pszId); + dwError = TDNFRepoRemoveCache(pTdnf, pRepo); if (dwError == ERROR_TDNF_FILE_NOT_FOUND) { dwError = 0;//Ignore non existent folders } BAIL_ON_TDNF_ERROR(dwError); - dwError = TDNFRemoveSolvCache(pTdnf, pRepo->pszId); + dwError = TDNFRemoveSolvCache(pTdnf, pRepo); if (dwError == ERROR_TDNF_FILE_NOT_FOUND) { dwError = 0;//Ignore non existent folders diff --git a/client/prototypes.h b/client/prototypes.h index 9efff8db3..78f8a8c1e 100644 --- a/client/prototypes.h +++ b/client/prototypes.h @@ -162,26 +162,32 @@ TDNFRepoGetUserPass( uint32_t TDNFRepoGetRpmCacheDir( PTDNF pTdnf, - const char* pszRepo, + PTDNF_REPO_DATA pRepo, char** ppszRpmCacheDir ); +uint32_t +TDNFRepoRemoveCacheDir( + PTDNF pTdnf, + PTDNF_REPO_DATA pRepo + ); + uint32_t TDNFRepoRemoveCache( PTDNF pTdnf, - const char* pszRepoId + PTDNF_REPO_DATA pRepo ); uint32_t TDNFRemoveRpmCache( PTDNF pTdnf, - const char* pszRepoId + PTDNF_REPO_DATA pRepo ); uint32_t TDNFRemoveLastRefreshMarker( PTDNF pTdnf, - const char* pszRepoId + PTDNF_REPO_DATA pRepo ); uint32_t @@ -192,13 +198,13 @@ TDNFRemoveTmpRepodata( uint32_t TDNFRemoveSolvCache( PTDNF pTdnf, - const char* pszRepoId + PTDNF_REPO_DATA pRepo ); uint32_t TDNFRemoveKeysCache( PTDNF pTdnf, - const char* pszRepoId + PTDNF_REPO_DATA pRepo ); uint32_t @@ -704,6 +710,15 @@ TDNFGetSkipDigestOption( uint32_t *pdwSkipDigest ); +uint32_t +TDNFGetCachePath( + PTDNF pTdnf, + PTDNF_REPO_DATA pRepo, + const char *pszSubDir, + const char *pszFileName, + char **ppszPath +); + uint32_t TDNFGetRepoById( PTDNF pTdnf, diff --git a/client/repo.c b/client/repo.c index e20af30b1..eb262b62e 100644 --- a/client/repo.c +++ b/client/repo.c @@ -32,26 +32,22 @@ TDNFInitRepo( char* pszRepoDataDir = NULL; char* pszRepoCacheDir = NULL; PTDNF_REPO_METADATA pRepoMD = NULL; - PTDNF_CONF pConf = NULL; Repo* pRepo = NULL; Pool* pPool = NULL; int nUseMetaDataCache = 0; PSOLV_REPO_INFO_INTERNAL pSolvRepoInfo = NULL; - if (!pTdnf || !pTdnf->pConf || !pRepoData || !pSack || !pSack->pPool) + if (!pTdnf || !pRepoData || !pSack || !pSack->pPool) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } - pConf = pTdnf->pConf; pPool = pSack->pPool; - dwError = TDNFJoinPath( - &pszRepoCacheDir, - pConf->pszCacheDir, - pRepoData->pszId, - NULL); + dwError = TDNFGetCachePath(pTdnf, pRepoData, + NULL, NULL, + &pszRepoCacheDir); BAIL_ON_TDNF_ERROR(dwError); dwError = TDNFJoinPath( @@ -81,6 +77,7 @@ TDNFInitRepo( BAIL_ON_TDNF_ERROR(dwError); } pSolvRepoInfo->pRepo = pRepo; + pSolvRepoInfo->pszRepoCacheDir = pszRepoCacheDir; pRepo->appdata = pSolvRepoInfo; dwError = SolvCalculateCookieForFile(pRepoMD->pszRepoMD, pSolvRepoInfo->cookie); @@ -121,9 +118,9 @@ TDNFInitRepo( if(pTdnf) { - TDNFRepoRemoveCache(pTdnf, pRepoData->pszId); - TDNFRemoveSolvCache(pTdnf, pRepoData->pszId); - TDNFRemoveLastRefreshMarker(pTdnf, pRepoData->pszId); + TDNFRepoRemoveCache(pTdnf, pRepoData); + TDNFRemoveSolvCache(pTdnf, pRepoData); + TDNFRemoveLastRefreshMarker(pTdnf, pRepoData); } } goto cleanup; @@ -504,7 +501,7 @@ TDNFStoreBaseURLFromMetalink( { uint32_t dwError = 0; char *pszBaseUrlFile = NULL; - PTDNF_REPO_DATA pRepos = NULL; + PTDNF_REPO_DATA pRepo = NULL; if (!pTdnf || !pTdnf->pConf || @@ -514,34 +511,30 @@ TDNFStoreBaseURLFromMetalink( dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } - pRepos = pTdnf->pRepos; - if (!pRepos) + + if (!pTdnf->pRepos) { dwError = ERROR_TDNF_NO_REPOS; BAIL_ON_TDNF_ERROR(dwError); } - while(pRepos) + for (pRepo = pTdnf->pRepos; pRepo; pRepo = pRepo->pNext) { - if(!strcmp(pszRepo, pRepos->pszId)) + if(!strcmp(pszRepo, pRepo->pszId)) { break; } - pRepos = pRepos->pNext; } - if (!pRepos) + if (!pRepo) { dwError = ERROR_TDNF_NO_REPOS; BAIL_ON_TDNF_ERROR(dwError); } - dwError = TDNFJoinPath(&pszBaseUrlFile, - pTdnf->pConf->pszCacheDir, - pRepos->pszId, - "tmp", - TDNF_REPO_BASEURL_FILE_NAME, - NULL); + dwError = TDNFGetCachePath(pTdnf, pRepo, + "tmp", TDNF_REPO_BASEURL_FILE_NAME, + &pszBaseUrlFile); BAIL_ON_TDNF_ERROR(dwError); dwError = TDNFCreateAndWriteToFile(pszBaseUrlFile, pszRepoMDURL); @@ -704,11 +697,9 @@ TDNFGetRepoMD( (void **)&pRepoMDRel); BAIL_ON_TDNF_ERROR(dwError); - dwError = TDNFJoinPath( - &pRepoMDRel->pszRepoCacheDir, - pTdnf->pConf->pszCacheDir, - pRepoData->pszId, - NULL); + dwError = TDNFGetCachePath(pTdnf, pRepoData, + NULL, NULL, + &pRepoMDRel->pszRepoCacheDir); BAIL_ON_TDNF_ERROR(dwError); dwError = TDNFAllocateString(pszRepoMDFile, &pRepoMDRel->pszRepoMD); @@ -781,12 +772,9 @@ TDNFGetRepoMD( { pr_info("Refreshing metadata for: '%s'\n", pRepoData->pszName); /* always download to tmp */ - dwError = TDNFJoinPath( - &pszTmpRepoDataDir, - pTdnf->pConf->pszCacheDir, - pRepoData->pszId, - "tmp", - NULL); + dwError = TDNFGetCachePath(pTdnf, pRepoData, + "tmp", NULL, + &pszTmpRepoDataDir); BAIL_ON_TDNF_ERROR(dwError); dwError = TDNFUtilsMakeDirs(pszTmpRepoDataDir); @@ -925,12 +913,12 @@ TDNFGetRepoMD( { /* Remove the old repodata, solvcache and lastRefreshMarker before replacing the new repomd file and metalink files. */ - TDNFRepoRemoveCache(pTdnf, pRepoData->pszId); - TDNFRemoveSolvCache(pTdnf, pRepoData->pszId); - TDNFRemoveLastRefreshMarker(pTdnf, pRepoData->pszId); + TDNFRepoRemoveCache(pTdnf, pRepoData); + TDNFRemoveSolvCache(pTdnf, pRepoData); + TDNFRemoveLastRefreshMarker(pTdnf, pRepoData); if (!nKeepCache) { - TDNFRemoveRpmCache(pTdnf, pRepoData->pszId); + TDNFRemoveRpmCache(pTdnf, pRepoData); } dwError = TDNFUtilsMakeDirs(pszRepoDataDir); BAIL_ON_TDNF_ERROR(dwError); @@ -940,12 +928,9 @@ TDNFGetRepoMD( if (nNewRepoMDFile) { - dwError = TDNFJoinPath( - &pszLastRefreshMarker, - pTdnf->pConf->pszCacheDir, - pRepoData->pszId, - TDNF_REPO_METADATA_MARKER, - NULL); + dwError = TDNFGetCachePath(pTdnf, pRepoData, + TDNF_REPO_METADATA_MARKER, NULL, + &pszLastRefreshMarker); BAIL_ON_TDNF_ERROR(dwError); dwError = TDNFTouchFile(pszLastRefreshMarker); BAIL_ON_TDNF_ERROR(dwError); @@ -1416,12 +1401,9 @@ TDNFDownloadMetadata( else { /* if printing only we use the already downloaded repomd.xml */ - dwError = TDNFJoinPath( - &pszRepoMDPath, - pTdnf->pConf->pszCacheDir, - pRepo->pszId, - TDNF_REPO_METADATA_FILE_PATH, - NULL); + dwError = TDNFGetCachePath(pTdnf, pRepo, + TDNF_REPO_METADATA_FILE_PATH, NULL, + &pszRepoMDPath); BAIL_ON_TDNF_ERROR(dwError); pr_info("%s\n", pszRepoMDUrl); diff --git a/client/repolist.c b/client/repolist.c index fe4a651df..6ffc254f7 100644 --- a/client/repolist.c +++ b/client/repolist.c @@ -645,27 +645,38 @@ TDNFRepoListFinalize( } /* Now that the overrides are applied, replace config vars - for the repos that are enabled. */ + for all repos. */ for(pRepo = pTdnf->pRepos; pRepo; pRepo = pRepo->pNext) { - if(pRepo->nEnabled) + if(pRepo->pszName) { - if(pRepo->pszName) - { - dwError = TDNFConfigReplaceVars(pTdnf, &pRepo->pszName); - BAIL_ON_TDNF_ERROR(dwError); - } - if(pRepo->pszBaseUrl) - { - dwError = TDNFConfigReplaceVars(pTdnf, &pRepo->pszBaseUrl); - BAIL_ON_TDNF_ERROR(dwError); - } - if(pRepo->pszMetaLink) - { - dwError = TDNFConfigReplaceVars(pTdnf, &pRepo->pszMetaLink); - BAIL_ON_TDNF_ERROR(dwError); - } + dwError = TDNFConfigReplaceVars(pTdnf, &pRepo->pszName); + BAIL_ON_TDNF_ERROR(dwError); + } + if(pRepo->pszBaseUrl) + { + dwError = TDNFConfigReplaceVars(pTdnf, &pRepo->pszBaseUrl); + BAIL_ON_TDNF_ERROR(dwError); + } + if(pRepo->pszMetaLink) + { + dwError = TDNFConfigReplaceVars(pTdnf, &pRepo->pszMetaLink); + BAIL_ON_TDNF_ERROR(dwError); } + + if (pRepo->pszMetaLink) + { + dwError = SolvCreateRepoCacheName(pRepo->pszId, + pRepo->pszMetaLink, + &pRepo->pszCacheName); + } + else if (pRepo->pszBaseUrl) + { + dwError = SolvCreateRepoCacheName(pRepo->pszId, + pRepo->pszBaseUrl, + &pRepo->pszCacheName); + } + BAIL_ON_TDNF_ERROR(dwError); } cleanup: return dwError; @@ -788,6 +799,7 @@ TDNFFreeReposInternal( TDNF_SAFE_FREE_STRINGARRAY(pRepo->ppszUrlGPGKeys); TDNF_SAFE_FREE_MEMORY(pRepo->pszUser); TDNF_SAFE_FREE_MEMORY(pRepo->pszPass); + TDNF_SAFE_FREE_MEMORY(pRepo->pszCacheName); pRepos = pRepo->pNext; TDNF_SAFE_FREE_MEMORY(pRepo); } diff --git a/client/repoutils.c b/client/repoutils.c index 99c6062e7..f501ccab4 100644 --- a/client/repoutils.c +++ b/client/repoutils.c @@ -42,24 +42,24 @@ TDNFRepoMakeCacheDirs( uint32_t TDNFRepoSetBaseUrl( PTDNF pTdnf, - PTDNF_REPO_DATA pszRepo, + PTDNF_REPO_DATA pRepo, const char *pszBaseUrlFile ) { uint32_t dwError = 0; char *pszBaseUrl = NULL; - if (!pTdnf || !pszRepo || IsNullOrEmptyString(pszBaseUrlFile)) + if (!pTdnf || !pRepo || IsNullOrEmptyString(pszBaseUrlFile)) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } - TDNF_SAFE_FREE_MEMORY(pszRepo->pszBaseUrl); + TDNF_SAFE_FREE_MEMORY(pRepo->pszBaseUrl); dwError = TDNFFileReadAllText(pszBaseUrlFile, &pszBaseUrl, NULL); BAIL_ON_TDNF_ERROR(dwError); - pszRepo->pszBaseUrl = pszBaseUrl; + pRepo->pszBaseUrl = pszBaseUrl; cleanup: return dwError; @@ -180,14 +180,14 @@ TDNFRepoGetUserPass( uint32_t TDNFRepoGetRpmCacheDir( PTDNF pTdnf, - const char* pszRepoId, + PTDNF_REPO_DATA pRepo, char** ppszRpmCacheDir ) { uint32_t dwError = 0; char* pszRpmCacheDir = NULL; - if(!pTdnf || IsNullOrEmptyString(pszRepoId) || !ppszRpmCacheDir) + if(!pTdnf || !pRepo || !ppszRpmCacheDir) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); @@ -199,12 +199,9 @@ TDNFRepoGetRpmCacheDir( BAIL_ON_TDNF_ERROR(dwError); } - dwError = TDNFJoinPath( - &pszRpmCacheDir, - pTdnf->pConf->pszCacheDir, - pszRepoId, - TDNF_RPM_CACHE_DIR_NAME, - NULL); + dwError = TDNFGetCachePath(pTdnf, pRepo, + TDNF_RPM_CACHE_DIR_NAME, NULL, + &pszRpmCacheDir); BAIL_ON_TDNF_ERROR(dwError); if(access(pszRpmCacheDir, F_OK)) @@ -229,27 +226,59 @@ TDNFRepoGetRpmCacheDir( goto cleanup; } +/* remove the repo top level cache dir */ +uint32_t +TDNFRepoRemoveCacheDir( + PTDNF pTdnf, + PTDNF_REPO_DATA pRepo + ) +{ + uint32_t dwError = 0; + char* pszRepoCacheDir = NULL; + + if(!pTdnf || !pRepo) + { + dwError = ERROR_TDNF_INVALID_PARAMETER; + BAIL_ON_TDNF_ERROR(dwError); + } + + dwError = TDNFGetCachePath(pTdnf, pRepo, + NULL, NULL, + &pszRepoCacheDir); + BAIL_ON_TDNF_ERROR(dwError); + + if (rmdir(pszRepoCacheDir) != 0 && errno != ENOENT) + { + dwError = errno; + BAIL_ON_TDNF_SYSTEM_ERROR(dwError); + } + +cleanup: + TDNF_SAFE_FREE_MEMORY(pszRepoCacheDir); + return dwError; + +error: + goto cleanup; +} + uint32_t TDNFRepoRemoveCache( PTDNF pTdnf, - const char* pszRepoId + PTDNF_REPO_DATA pRepo ) { uint32_t dwError = 0; char* pszRepoCacheDir = NULL; - if(!pTdnf || !pTdnf->pConf || IsNullOrEmptyString(pszRepoId)) + if(!pTdnf || !pRepo || !pTdnf->pConf) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } - dwError = TDNFJoinPath( - &pszRepoCacheDir, - pTdnf->pConf->pszCacheDir, - pszRepoId, - TDNF_REPODATA_DIR_NAME, - NULL); + dwError = TDNFGetCachePath(pTdnf, pRepo, + TDNF_REPODATA_DIR_NAME, NULL, + &pszRepoCacheDir); BAIL_ON_TDNF_ERROR(dwError); dwError = TDNFRecursivelyRemoveDir(pszRepoCacheDir); @@ -270,19 +299,19 @@ TDNFRepoRemoveCache( uint32_t TDNFRemoveRpmCache( PTDNF pTdnf, - const char* pszRepoId + PTDNF_REPO_DATA pRepo ) { uint32_t dwError = 0; char* pszRpmCacheDir = NULL; - if (!pTdnf || !pTdnf->pConf || IsNullOrEmptyString(pszRepoId)) + if (!pTdnf || !pRepo || !pTdnf->pConf) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } - dwError = TDNFRepoGetRpmCacheDir(pTdnf, pszRepoId, &pszRpmCacheDir); + dwError = TDNFRepoGetRpmCacheDir(pTdnf, pRepo, &pszRpmCacheDir); BAIL_ON_TDNF_ERROR(dwError); if (!IsNullOrEmptyString(pszRpmCacheDir)) @@ -330,24 +359,21 @@ TDNFRemoveTmpRepodata( uint32_t TDNFRemoveLastRefreshMarker( PTDNF pTdnf, - const char* pszRepoId + PTDNF_REPO_DATA pRepo ) { uint32_t dwError = 0; char* pszLastRefreshMarker = NULL; - if(!pTdnf || !pTdnf->pConf || IsNullOrEmptyString(pszRepoId)) + if(!pTdnf || !pRepo || !pTdnf->pConf) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } - dwError = TDNFJoinPath( - &pszLastRefreshMarker, - pTdnf->pConf->pszCacheDir, - pszRepoId, - TDNF_REPO_METADATA_MARKER, - NULL); + dwError = TDNFGetCachePath(pTdnf, pRepo, + TDNF_REPO_METADATA_MARKER, NULL, + &pszLastRefreshMarker); BAIL_ON_TDNF_ERROR(dwError); if (pszLastRefreshMarker) { @@ -367,24 +393,21 @@ TDNFRemoveLastRefreshMarker( uint32_t TDNFRemoveSolvCache( PTDNF pTdnf, - const char* pszRepoId + PTDNF_REPO_DATA pRepo ) { uint32_t dwError = 0; char* pszSolvCacheDir = NULL; - if(!pTdnf || !pTdnf->pConf || IsNullOrEmptyString(pszRepoId)) + if(!pTdnf || !pRepo || !pTdnf->pConf) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } - dwError = TDNFJoinPath( - &pszSolvCacheDir, - pTdnf->pConf->pszCacheDir, - pszRepoId, - TDNF_SOLVCACHE_DIR_NAME, - NULL); + dwError = TDNFGetCachePath(pTdnf, pRepo, + TDNF_SOLVCACHE_DIR_NAME, NULL, + &pszSolvCacheDir); BAIL_ON_TDNF_ERROR(dwError); dwError = TDNFRecursivelyRemoveDir(pszSolvCacheDir); @@ -404,24 +427,21 @@ TDNFRemoveSolvCache( uint32_t TDNFRemoveKeysCache( PTDNF pTdnf, - const char* pszRepoId + PTDNF_REPO_DATA pRepo ) { uint32_t dwError = 0; char* pszKeysDir = NULL; - if(!pTdnf || !pTdnf->pConf || IsNullOrEmptyString(pszRepoId)) + if(!pTdnf || !pRepo || !pTdnf->pConf) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } - dwError = TDNFJoinPath( - &pszKeysDir, - pTdnf->pConf->pszCacheDir, - pszRepoId, - "keys", - NULL); + dwError = TDNFGetCachePath(pTdnf, pRepo, + "keys", NULL, + &pszKeysDir); BAIL_ON_TDNF_ERROR(dwError); dwError = TDNFRecursivelyRemoveDir(pszKeysDir); @@ -613,6 +633,38 @@ TDNFRepoApplySSLSettings( goto cleanup; } +uint32_t +TDNFGetCachePath( + PTDNF pTdnf, + PTDNF_REPO_DATA pRepo, + const char *pszSubDir, + const char *pszFileName, + char **ppszPath +) +{ + uint32_t dwError = 0; + + if(!pTdnf || !pRepo || !ppszPath) + { + dwError = ERROR_TDNF_INVALID_PARAMETER; + BAIL_ON_TDNF_ERROR(dwError); + } + + dwError = TDNFJoinPath( + ppszPath, + pTdnf->pConf->pszCacheDir, + pRepo->pszCacheName ? pRepo->pszCacheName : pRepo->pszId, + pszSubDir, + pszFileName, + NULL); + BAIL_ON_TDNF_LIBSOLV_ERROR(dwError); + +cleanup: + return dwError; +error: + goto cleanup; +} + uint32_t TDNFFindRepoById( PTDNF pTdnf, diff --git a/include/tdnftypes.h b/include/tdnftypes.h index bd9036c25..0b2554628 100644 --- a/include/tdnftypes.h +++ b/include/tdnftypes.h @@ -280,6 +280,7 @@ typedef struct _TDNF_REPO_DATA int nSkipMDFileLists; int nSkipMDUpdateInfo; int nSkipMDOther; + char *pszCacheName; struct _TDNF_REPO_DATA* pNext; }TDNF_REPO_DATA, *PTDNF_REPO_DATA; diff --git a/pytests/CMakeLists.txt b/pytests/CMakeLists.txt index 63f038475..20733a0bc 100644 --- a/pytests/CMakeLists.txt +++ b/pytests/CMakeLists.txt @@ -19,7 +19,7 @@ configure_file( ) add_custom_target(check - COMMAND pytest + COMMAND ${CMAKE_COMMAND} -E env LD_LIBRARY_PATH="${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" pytest WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Running tests.." ) diff --git a/pytests/tests/test_cache.py b/pytests/tests/test_cache.py index 6648be14a..c5b83fee4 100644 --- a/pytests/tests/test_cache.py +++ b/pytests/tests/test_cache.py @@ -7,6 +7,7 @@ # import os +import fnmatch import pytest @@ -74,6 +75,14 @@ def check_package_in_cache(utils, pkgname): return False +def find_cache_dir(utils, reponame): + cache_dir = utils.tdnf_config.get('main', 'cachedir') + for f in os.listdir(cache_dir): + if fnmatch.fnmatch(f, '{}-*'.format(reponame)): + return os.path.join(cache_dir, f) + return None + + def test_install_without_cache(utils): clean_cache(utils) disable_cache(utils) @@ -116,8 +125,9 @@ def test_install_with_keepcache_false(utils): def test_disable_repo_make_cache(utils): - cache_dir = utils.tdnf_config.get('main', 'cachedir') - lastrefresh = os.path.join(cache_dir, 'photon-test/lastrefresh') + cache_dir = find_cache_dir(utils, 'photon-test') + assert(cache_dir is not None) + lastrefresh = os.path.join(cache_dir, 'lastrefresh') before = os.path.getmtime(lastrefresh) utils.run(['tdnf', '--disablerepo=*', 'makecache']) after = os.path.getmtime(lastrefresh) @@ -125,8 +135,9 @@ def test_disable_repo_make_cache(utils): def test_enable_repo_make_cache(utils): - cache_dir = utils.tdnf_config.get('main', 'cachedir') - lastrefresh = os.path.join(cache_dir, 'photon-test/lastrefresh') + cache_dir = find_cache_dir(utils, 'photon-test') + assert(cache_dir is not None) + lastrefresh = os.path.join(cache_dir, 'lastrefresh') before = os.path.getmtime(lastrefresh) utils.run(['tdnf', '--disablerepo=*', '--enablerepo=photon-test', 'makecache']) after = os.path.getmtime(lastrefresh) @@ -135,8 +146,9 @@ def test_enable_repo_make_cache(utils): # -v (verbose) prints progress data def test_enable_repo_make_cache_verbose(utils): - cache_dir = utils.tdnf_config.get('main', 'cachedir') - lastrefresh = os.path.join(cache_dir, 'photon-test/lastrefresh') + cache_dir = find_cache_dir(utils, 'photon-test') + assert(cache_dir is not None) + lastrefresh = os.path.join(cache_dir, 'lastrefresh') before = os.path.getmtime(lastrefresh) utils.run(['tdnf', '-v', '--disablerepo=*', '--enablerepo=photon-test', 'makecache']) after = os.path.getmtime(lastrefresh) diff --git a/pytests/tests/test_installroot.py b/pytests/tests/test_installroot.py index 786df86b0..488f1b618 100644 --- a/pytests/tests/test_installroot.py +++ b/pytests/tests/test_installroot.py @@ -9,6 +9,7 @@ import os import shutil import pytest +import fnmatch INSTALLROOT = '/root/installroot' REPOFILENAME = 'photon-test.repo' @@ -76,6 +77,14 @@ def erase_package(utils, pkgname, installroot=INSTALLROOT, pkgversion=None): assert(not check_package(utils, pkgname)) +def find_cache_dir(reponame): + cache_dir = os.path.join(INSTALLROOT, 'var/cache/tdnf') + for f in os.listdir(cache_dir): + if fnmatch.fnmatch(f, '{}-*'.format(reponame)): + return os.path.join(cache_dir, f) + return None + + def test_install(utils): install_root(utils) pkgname = utils.config["mulversion_pkgname"] @@ -98,7 +107,7 @@ def test_makecache(utils): '--installroot', INSTALLROOT, '--releasever=4.0'], noconfig=True) assert(ret['retval'] == 0) - assert(os.path.isdir(os.path.join(INSTALLROOT, 'var/cache/tdnf', 'photon-test'))) + assert(find_cache_dir('photon-test') is not None) shutil.rmtree(INSTALLROOT) diff --git a/pytests/tests/test_skip_md.py b/pytests/tests/test_skip_md.py index b8442c351..8f194f8d3 100644 --- a/pytests/tests/test_skip_md.py +++ b/pytests/tests/test_skip_md.py @@ -10,7 +10,7 @@ import os import pytest import glob - +import fnmatch REPOFILENAME = "photon-skip.repo" REPOID = "photon-skip" @@ -61,6 +61,14 @@ def get_cache_dir(utils): return '/var/cache/tdnf/' +def find_cache_dir(utils, reponame): + cache_dir = utils.tdnf_config.get('main', 'cachedir') + for f in os.listdir(cache_dir): + if fnmatch.fnmatch(f, '{}-*'.format(reponame)): + return os.path.join(cache_dir, f) + return None + + # enable/disable md part, expect/do not expect download of the associated file def check_skip_md_part(utils, mdpart, skipped): repoconf = os.path.join(utils.config['repo_path'], "yum.repos.d", REPOFILENAME) @@ -68,7 +76,7 @@ def check_skip_md_part(utils, mdpart, skipped): utils.run(['tdnf', '--repoid={}'.format(REPOID), 'clean', 'all']) utils.run(['tdnf', '--repoid={}'.format(REPOID), 'makecache']) - md_dir = os.path.join(get_cache_dir(utils), REPOID, 'repodata') + md_dir = os.path.join(find_cache_dir(utils, REPOID), 'repodata') assert((len(glob.glob('{}/*{}*'.format(md_dir, mdpart))) == 0) == skipped) diff --git a/python/setup.py.in b/python/setup.py.in index 69bbbe04b..089a018de 100644 --- a/python/setup.py.in +++ b/python/setup.py.in @@ -10,11 +10,7 @@ from setuptools import setup from distutils.core import Extension cflags = [ - '-I@PYTDNF_INC_DIR@' -] - -link_args = [ - '-Wl,-rpath=@PYTDNF_LIB_DIR@' + '-I@PYTDNF_INC_DIR@', ] pytdnf_sources = [ @@ -29,8 +25,7 @@ tdnfmodule = Extension('tdnf._tdnf', libraries=['tdnf'], library_dirs=['${PYTDNF_LIB_DIR}'], sources=pytdnf_sources, - extra_compile_args=cflags, - extra_link_args=link_args) + extra_compile_args=cflags) setup(name='@PYTDNF_PACKAGE_NAME@', version='@PYTDNF_VERSION@', diff --git a/solv/prototypes.h b/solv/prototypes.h index a2cfdc77d..c0bac8097 100644 --- a/solv/prototypes.h +++ b/solv/prototypes.h @@ -46,6 +46,7 @@ typedef struct _SOLV_REPO_INFO_INTERNAL_ Repo* pRepo; unsigned char cookie[SOLV_COOKIE_LEN]; int nCookieSet; + char *pszRepoCacheDir; }SOLV_REPO_INFO_INTERNAL, *PSOLV_REPO_INFO_INTERNAL; extern Id allDepKeyIds[]; @@ -576,6 +577,13 @@ SolvCalculateCookieForFile( unsigned char* pszCookie ); +uint32_t +SolvCreateRepoCacheName( + const char *pszName, + const char *pszUrl, + char **ppszCacheName + ); + uint32_t SolvGetMetaDataCachePath( PSOLV_REPO_INFO_INTERNAL pSolvRepoInfo, diff --git a/solv/tdnfrepo.c b/solv/tdnfrepo.c index dee0d051c..f7952fd19 100644 --- a/solv/tdnfrepo.c +++ b/solv/tdnfrepo.c @@ -278,6 +278,7 @@ SolvReadInstalledRpms( Repo *pRepo = NULL; FILE *pCacheFile = NULL; int dwFlags = 0; + if(!pPool || !ppRepo) { dwError = ERROR_TDNF_INVALID_PARAMETER; @@ -295,6 +296,7 @@ SolvReadInstalledRpms( { /* coverity[toctou] */ pCacheFile = fopen(pszCacheFileName, "r"); + if(!pCacheFile) { dwError = errno; @@ -377,6 +379,52 @@ SolvCalculateCookieForFile( goto cleanup; } +/* Create a name for the repo cache path based on repo name and + a hash of the url. +*/ +uint32_t +SolvCreateRepoCacheName( + const char *pszName, + const char *pszUrl, + char **ppszCacheName + ) +{ + uint32_t dwError = 0; + Chksum *pChkSum = NULL; + unsigned char pCookie[SOLV_COOKIE_LEN] = {0}; + char pszCookie[9] = {0}; + char *pszCacheName; + + if (!pszName || !pszUrl || !ppszCacheName) + { + dwError = ERROR_TDNF_INVALID_PARAMETER; + BAIL_ON_TDNF_LIBSOLV_ERROR(dwError); + } + + pChkSum = solv_chksum_create(REPOKEY_TYPE_SHA256); + if (!pChkSum) + { + dwError = ERROR_TDNF_SOLV_CHKSUM; + BAIL_ON_TDNF_LIBSOLV_ERROR(dwError); + } + solv_chksum_add(pChkSum, pszUrl, strlen(pszUrl)); + solv_chksum_free(pChkSum, pCookie); + + snprintf(pszCookie, sizeof(pszCookie), "%.2x%.2x%.2x%.2x", + pCookie[0], pCookie[1], pCookie[2], pCookie[3]); + + dwError = TDNFAllocateStringPrintf(&pszCacheName, "%s-%s", pszName, pszCookie); + BAIL_ON_TDNF_LIBSOLV_ERROR(dwError); + + *ppszCacheName = pszCacheName; +cleanup: + return dwError; + +error: + TDNF_SAFE_FREE_MEMORY(pszCacheName); + goto cleanup; +} + uint32_t SolvGetMetaDataCachePath( PSOLV_REPO_INFO_INTERNAL pSolvRepoInfo, @@ -398,9 +446,8 @@ SolvGetMetaDataCachePath( { dwError = TDNFAllocateStringPrintf( &pszCachePath, - "%s/%s/%s/%s.solv", - pSack->pszCacheDir, - pRepo->name, + "%s/%s/%s.solv", + pSolvRepoInfo->pszRepoCacheDir, TDNF_SOLVCACHE_DIR_NAME, pRepo->name); BAIL_ON_TDNF_ERROR(dwError); @@ -566,12 +613,10 @@ SolvCreateMetaDataCache( pRepo = pSolvRepoInfo->pRepo; dwError = TDNFJoinPath( &pszSolvCacheDir, - pSack->pszCacheDir, - pRepo->name, + pSolvRepoInfo->pszRepoCacheDir, TDNF_SOLVCACHE_DIR_NAME, NULL); BAIL_ON_TDNF_LIBSOLV_ERROR(dwError); - if (access(pszSolvCacheDir, W_OK | X_OK)) { if(errno != ENOENT)