1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/RepoManager.h
12 #ifndef ZYPP_REPOMANAGER_H
13 #define ZYPP_REPOMANAGER_H
18 #include "zypp/base/PtrTypes.h"
19 #include "zypp/base/Iterator.h"
21 #include "zypp/Pathname.h"
22 #include "zypp/ZConfig.h"
23 #include "zypp/RepoInfo.h"
24 #include "zypp/repo/RepoException.h"
25 #include "zypp/repo/RepoType.h"
26 #include "zypp/repo/ServiceType.h"
27 #include "zypp/RepoStatus.h"
28 #include "zypp/ProgressData.h"
30 ///////////////////////////////////////////////////////////////////
32 { /////////////////////////////////////////////////////////////////
33 class ServiceInfo; //predef
36 * Parses \a repo_file and returns a list of \ref RepoInfo objects
37 * corresponding to repositories found within the file.
39 * \param repo_file Valid URL of the repo file.
40 * \return found list<RepoInfo>
42 * \throws MediaException If the access to the url fails
43 * \throws ParseException If the file parsing fails
44 * \throws Exception On other errors.
46 std::list<RepoInfo> readRepoFile(const Url & repo_file);
49 * Repo manager settings.
50 * Settings default to ZYpp global settings.
52 struct RepoManagerOptions
54 /** Default ctor following \ref ZConfig global settings.
55 * If an optional \c root_r directory is given, all paths will
56 * be prefixed accordingly.
58 * root_r\repoCachePath
61 * \repoPackagesCachePath
65 RepoManagerOptions( const Pathname & root_r = Pathname() );
67 /** Test setup adjusting all paths to be located below one \c root_r directory.
69 * root_r\ - repoCachePath
70 * \raw - repoRawCachePath
71 * \solv - repoSolvCachePath
72 * \packages - repoPackagesCachePath
73 * \repos.d - knownReposPath
76 static RepoManagerOptions makeTestSetup( const Pathname & root_r );
78 Pathname repoCachePath;
79 Pathname repoRawCachePath;
80 Pathname repoSolvCachePath;
81 Pathname repoPackagesCachePath;
82 Pathname knownReposPath;
83 Pathname knownServicesPath;
86 * Target distro ID to be used when refreshing repo index services.
87 * Repositories not maching this ID will be skipped/removed.
89 * The value is initialized upon construction to
90 * \ref Target::targetDistribution() if the Target is already initialized,
91 * otherwise the value is initially empty.
93 * If empty, no repositories contained in the index will be skipped.
95 std::string servicesTargetDistro;
101 * \short creates and provides information about known sources.
106 friend std::ostream & operator<<( std::ostream & str, const RepoManager & obj );
109 /** Implementation */
112 /** ServiceInfo typedefs */
113 typedef std::set<ServiceInfo> ServiceSet;
114 typedef ServiceSet::const_iterator ServiceConstIterator;
115 typedef ServiceSet::size_type ServiceSizeType;
117 /** RepoInfo typedefs */
118 typedef std::set<RepoInfo> RepoSet;
119 typedef RepoSet::const_iterator RepoConstIterator;
120 typedef RepoSet::size_type RepoSizeType;
123 RepoManager( const RepoManagerOptions &options = RepoManagerOptions() );
127 enum RawMetadataRefreshPolicy
131 RefreshIfNeededIgnoreDelay
134 enum CacheBuildPolicy
140 enum RepoRemovePolicy
146 * \short List known repositories.
148 * The known repositories are read from
149 * \ref RepoManagerOptions::knownReposPath passed on the Ctor.
150 * Which defaults to ZYpp global settings.
151 * \return found list<RepoInfo>
153 std::list<RepoInfo> knownRepositories() const;
155 bool repoEmpty() const;
156 RepoSizeType repoSize() const;
157 RepoConstIterator repoBegin() const;
158 RepoConstIterator repoEnd() const;
162 * \short Status of local metadata
164 RepoStatus metadataStatus( const RepoInfo &info ) const;
167 * Possibly return state of checkIfRefreshMEtadata function
169 enum RefreshCheckStatus {
170 REFRESH_NEEDED, /**< refresh is needed */
171 REPO_UP_TO_DATE, /**< repository not changed */
172 REPO_CHECK_DELAYED /**< refresh is delayed due to settings */
176 * Checks whether to refresh metadata for specified repository and url.
178 * The need for refresh is evaluated according to the following conditions,
181 * <li>the refresh policy (refresh may be forced)
182 * <li>the repo.refresh.delay ZConfig value compared to the difference between
183 * cached index file timestamp and actual time
184 * <li>the timestamp of cached repo index file compared to the remote
185 * index file timestamp.
188 * This method checks the status against the specified url only. If more
189 * baseurls are defined for in the RepoInfo, each one must be check
190 * individually. Example:
195 * // try urls one by one
196 * for ( RepoInfo::urls_const_iterator it = info.baseUrlsBegin();
197 * it != info.baseUrlsEnd(); ++it )
201 * // check whether to refresh metadata
202 * // if the check fails for this url, it throws, so another url will be checked
203 * if (checkIfToRefreshMetadata(info, *it, policy)!=RepoInfo::REFRESH_NEEDED)
206 * // do the actual refresh
208 * catch (const Exception & e)
211 * ERR << *it << " doesn't look good. Trying another url." << endl;
215 * handle("No more URLs.");
222 * \return state of repository
223 * \see RefreshCheckStatus
224 * \throws RepoUnknownTypeException
225 * \throws repo::RepoNoAliasException if can't figure an alias
226 * \throws Exception on unknown error
229 RefreshCheckStatus checkIfToRefreshMetadata( const RepoInfo &info,
231 RawMetadataRefreshPolicy policy = RefreshIfNeeded);
234 * \short Path where the metadata is downloaded and kept
236 * Given a repoinfo, tells where \ref RepoManager will download
237 * and keep the raw metadata.
239 * \param info Repository information
241 * \throws repo::RepoNoAliasException if can't figure an alias
243 Pathname metadataPath( const RepoInfo &info ) const;
247 * \short Path where the rpm packages are downloaded and kept
249 * Given a repoinfo, tells where \ref RepoProvidePackage will download
250 * and keep the .rpm files.
252 * \param info Repository information
254 * \throws repo::RepoNoAliasException if can't figure an alias
256 Pathname packagesPath( const RepoInfo &info ) const;
260 * \short Refresh local raw cache
262 * Will try to download the metadata
264 * In case of falure the metadata remains
267 * \throws repo::RepoNoUrlException if no urls are available.
268 * \throws repo::RepoNoAliasException if can't figure an alias
269 * \throws repo::RepoUnknownTypeException if the metadata is unknown
270 * \throws repo::RepoException if the repository is invalid
271 * (no valid metadata found at any of baseurls)
273 void refreshMetadata( const RepoInfo &info,
274 RawMetadataRefreshPolicy policy = RefreshIfNeeded,
275 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
278 * \short Clean local metadata
280 * Empty local metadata.
282 * \throws repo::RepoNoAliasException if can't figure an alias
283 * \throws Exception on unknown error.
285 void cleanMetadata( const RepoInfo &info,
286 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
289 * \short Clean local package cache
291 * Empty local directory with downloaded packages
293 * \throws repo::RepoNoAliasException if can't figure an alias
294 * \throws Exception on unknown error.
296 void cleanPackages( const RepoInfo &info,
297 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
300 * \short Status of metadata cache
302 RepoStatus cacheStatus( const RepoInfo &info ) const;
305 * \short Refresh local cache
307 * Will try to build the cache from local metadata.
309 * If the cache exists it will be overwriten.
311 * \note the local metadata must be valid.
313 * \throws repo::RepoNoAliasException if can't figure
314 * an alias to look in cache
315 * \throws repo::RepoMetadataException if the metadata
316 * is not enough to build a cache (empty, incorrect, or
318 * \throws repo::RepoUnknownTypeException
319 * \throws parser::ParseException if parser encounters an error.
320 * \throws Exception on unknown error.
322 void buildCache( const RepoInfo &info,
323 CacheBuildPolicy policy = BuildIfNeeded,
324 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
327 * \short clean local cache
329 * Clean the cached version of the metadata
331 * \note the local metadata must be valid.
333 * \throws repo::RepoNoAliasException if can't figure an alias to look in cache
334 * \throws cache::CacheRecordNotFoundException if the cache could not be
335 * cleaned because of repository record not found.
336 * \throws Exception on unknown error.
338 void cleanCache( const RepoInfo &info,
339 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
342 * \short Whether a repository exists in cache
344 * \param RepoInfo to be checked.
346 bool isCached( const RepoInfo &info ) const;
350 * \short Load resolvables into the pool
352 * Creating from cache requires that the repository is
353 * refreshed (metadata downloaded) and cached
355 * \throws repo::RepoNoAliasException if can't figure an alias to look in cache
356 * \throw RepoNotCachedException When the source is not cached.
358 void loadFromCache( const RepoInfo &info,
359 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
362 * \short Probe repo metadata type.
364 repo::RepoType probe( const Url &url ) const;
368 * \short Adds a repository to the list of known repositories.
372 * \throws repo::RepoAlreadyExistsException If the repo clash some
373 * unique attribute like alias
374 * \throws RepoUnknownType
375 * If RepoManagerOptions::probe is true
376 * and repository type can't be determined.
377 * \throws RepoException
378 * If RepoManagerOptions::probe is true and access to the url fails.
379 * \throws Exception On other errors.
381 void addRepository( const RepoInfo &info,
382 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
385 * \short Adds repositores from a repo file to the list of known repositories.
386 * \param url Url of the repo file
388 * \throws repo::RepoAlreadyExistsException If the repo clash some
389 * unique attribute like alias
390 * \throws MediaException If the access to the url fails
391 * \throws ParseException If the file parsing fails
392 * \throws RepoUnknownType If repository type can't be determined
393 * \throws RepoException ON other repository related errors
394 * \throws Exception On other errors.
396 void addRepositories( const Url &url,
397 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
399 * \short Remove the best matching repository from known repos list
401 * \throws RepoNotFoundException If no repo match
403 void removeRepository( const RepoInfo & info,
404 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
407 * \short Modify repository attributes
409 * \throws RepoAlreadyExistsException if the alias specified in newinfo
410 * is already used by another repository
411 * \throws RepoNotFoundException If no repo match
412 * \throws ParseException If the file parsing fails
413 * \throws Exception On other errors.
415 void modifyRepository( const std::string &alias,
416 const RepoInfo & newinfo,
417 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
420 * \short Find a matching repository info
422 * \note if multiple repositories incorrectly share the
423 * same alias, the first one found will be returned.
425 * \param alias Repository alias
426 * \param progressrcv Progress reporting function
427 * \return RepoInfo of the found repository
428 * \throws RepoNotFoundException If no repo match the alias
429 * \throws ParseException If the file parsing fails
430 * \throws Exception On other errors.
432 RepoInfo getRepositoryInfo( const std::string &alias,
433 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
436 * \short Find repository info by URL.
438 * \param url URL to find.
439 * \param urlview url::ViewOption to influence URL matching.
440 * \param progressrcv Progress receiver function.
441 * \return RepoInfo of the found repository.
443 * \note if multpile repositories incorrectly share the
444 * same URL, the first one found will be returned.
446 * \note the string representation of the URLs are compared.
447 * The \a urlview can be used to influence which
448 parts of the URL are to be compared.
450 * \throws RepoNotFoundException If no repo match
451 * \throws ParseException If the file parsing fails
452 * \throws Exception On other errors.
454 RepoInfo getRepositoryInfo( const Url & url,
455 const url::ViewOption & urlview = url::ViewOption::DEFAULTS,
456 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
459 * \short Probe the type or the service.
461 repo::ServiceType probeService( const Url &url ) const;
464 * Adds new service by it's alias and url
466 * \param alias unique identifier of the service
467 * \param url url to service
469 * \throws FIXME RepoAlreadyExistException and as reponame is service name
471 void addService( const std::string & alias, const Url& url );
476 * \param service service info
478 * \throws FIXME RepoAlreadyExistException and as reponame is service name
480 void addService( const ServiceInfo & service );
483 * Removes service specified by its name
485 * \param alias unique indientifier of the service to remove
487 * \throws RepoException if service is not found or file with ServiceInfo cannot be deleted
488 * \throws Exception if file contain more services and rewrite file failed
490 void removeService( const std::string & alias );
492 void removeService( const ServiceInfo & service );
495 * Gets true if no service is in RepoManager (so no one in specified location)
497 * \return true if any ServiceInfo is in RepoManager
499 bool serviceEmpty() const;
502 * Gets count of service in RepoManager (in specified location)
504 * \return count of service
506 ServiceSizeType serviceSize() const;
509 * Iterator to first service in internal storage.
510 * \note Iterator is immutable, so you cannot change pointed ServiceInfo
511 * \return Iterator to first service
513 ServiceConstIterator serviceBegin() const;
516 * Iterator to place behind last service in internal storage.
517 * \return iterator to end
519 ServiceConstIterator serviceEnd() const;
522 * Finds ServiceInfo by alias or return noService
524 * \param alias unique identifier of service
525 * \return information about service
527 ServiceInfo getService( const std::string & alias ) const;
530 * Refreshes all enabled services.
532 * \see refreshService(ServiceInfo)
534 void refreshServices();
537 * Refresh specific service.
539 * \param name service structure
540 * \throws MediaException If there's a problem downloading the repo index file.
542 void refreshService( const ServiceInfo & service );
545 * Modifies service file (rewrites it with new values) and underlying
546 * repositories if needed.
548 * Modifications of a service can lead to rewrite of all .repo files of
549 * contained repositories. Particularily, disabling a service (changing
550 * ServiceInfo::enabled() from true to false) will disable all contained
551 * repositories. Renaming of a service will modify the "service" key
552 * of all contained repositories.
554 * \param oldAlias Old alias of the service
555 * \param service ServiceInfo object containing new data
557 * \throws RepoException if sservice with oldAlias is not known
558 * \throws Exception if have problems with files
560 void modifyService(const std::string & oldAlias, const ServiceInfo & service);
564 * Functor thats filter RepoInfo by service which belongs to.
566 struct MatchServiceAlias
569 MatchServiceAlias( const std::string & alias_ ) : alias(alias_) {}
570 bool operator()( const RepoInfo & info ) const { return info.service() == alias; }
578 * fill to output iterator repositories in service name. This output iterator can perform
579 * any action on with Repo or service Container, because it is sets and it isn't dynamic recreate.
581 * \note Don't use this function with RepoManager::removeRepository(), it will lead to segfaults
582 * due to invalidated internal iterators. FIXME can this be solved (using STL) so that this
583 * warning would not be needed?
585 * \param alias service alias
586 * \param out output iterator which get all the repositories belonging to
589 * example how set priority for each RepoInfo in this service:
592 * class ChangePriority
597 * ChangePriority(int prio) : priority(prio) {}
598 * // missing rewrite priority back via RepoManager::modifyRepo
599 * void doIt( RepoInfo info ) { info.setPriority(priority); }
602 * //somewhere in code
603 * ChangePriority changer(10);
604 * getRepositoriesInService(name,
605 * boost::make_function_output_iterator(
606 * bind(&ChangePriority::doIt, &changer, _1)));
609 template<typename OutputIterator>
610 void getRepositoriesInService( const std::string & alias,
611 OutputIterator out ) const
613 MatchServiceAlias filter(alias);
615 std::copy( boost::make_filter_iterator( filter, repoBegin(), repoEnd() ),
616 boost::make_filter_iterator( filter, repoEnd(), repoEnd() ),
621 RepoStatus rawMetadataStatus( const RepoInfo &info );
622 void setCacheStatus( const RepoInfo &info, const RepoStatus &status );
625 * Update timestamp of repository index file for the specified repository \a info.
626 * Used in \ref checkIfToRefreshMetadata() for repo.refresh.delay feature.
628 void touchIndexFile(const RepoInfo & info);
633 /** Pointer to implementation */
634 RWCOW_pointer<Impl> _pimpl;
636 ///////////////////////////////////////////////////////////////////
638 /** \relates RepoManager Stream output */
639 std::ostream & operator<<( std::ostream & str, const RepoManager & obj );
641 /////////////////////////////////////////////////////////////////
643 ///////////////////////////////////////////////////////////////////
644 #endif // ZYPP2_REPOMANAGER_H