add mkdir for services and modifyServices, which is used during refresh
[platform/upstream/libzypp.git] / zypp / RepoManager.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/RepoManager.h
10  *
11 */
12 #ifndef ZYPP_REPOMANAGER_H
13 #define ZYPP_REPOMANAGER_H
14
15 #include <iosfwd>
16 #include <list>
17
18 #include "zypp/base/PtrTypes.h"
19 #include "zypp/Pathname.h"
20 #include "zypp/ZConfig.h"
21 #include "zypp/RepoInfo.h"
22 #include "zypp/repo/RepoException.h"
23 #include "zypp/repo/RepoType.h"
24 #include "zypp/RepoStatus.h"
25 #include "zypp/ProgressData.h"
26
27 ///////////////////////////////////////////////////////////////////
28 namespace zypp
29 { /////////////////////////////////////////////////////////////////
30   class Service; //predef
31
32    /**
33     * Parses \a repo_file and returns a list of \ref RepoInfo objects
34     * corresponding to repositories found within the file.
35     *
36     * \param repo_file Valid URL of the repo file.
37     * \return found list<RepoInfo>
38     *
39     * \throws MediaException If the access to the url fails
40     * \throws ParseException If the file parsing fails
41     * \throws Exception On other errors.
42     */
43    std::list<RepoInfo> readRepoFile(const Url & repo_file);
44
45   /**
46    * Repo manager settings.
47    * Settings default to ZYpp global settings.
48    */
49   struct RepoManagerOptions
50   {
51     /** Default ctor following \ref ZConfig global settings.
52      * If an optional \c root_r directory is given, all paths  will
53      * be prefixed accordingly.
54      * \code
55      *    root_r\repoCachePath
56      *          \repoRawCachePath
57      *          \repoSolvCachePath
58      *          \repoPackagesCachePath
59      *          \knownReposPath
60      * \endcode
61      */
62     RepoManagerOptions( const Pathname & root_r = Pathname() );
63
64     /** Test setup adjusting all paths to be located below one \c root_r directory.
65      * \code
66      *    root_r\          - repoCachePath
67      *          \raw       - repoRawCachePath
68      *          \solv      - repoSolvCachePath
69      *          \packages  - repoPackagesCachePath
70      *          \repos.d   - knownReposPath
71      * \endcode
72      */
73     static RepoManagerOptions makeTestSetup( const Pathname & root_r );
74
75     Pathname repoCachePath;
76     Pathname repoRawCachePath;
77     Pathname repoSolvCachePath;
78     Pathname repoPackagesCachePath;
79     Pathname knownReposPath;
80     Pathname knownServicesPath;
81     bool probe;
82   };
83
84
85
86   /**
87    * \short creates and provides information about known sources.
88    *
89    */
90   class RepoManager
91   {
92     friend std::ostream & operator<<( std::ostream & str, const RepoManager & obj );
93
94   public:
95     /** Implementation  */
96     class Impl;
97
98     /** service typedefs */
99     typedef std::set<Service> ServiceSet;
100     typedef ServiceSet::const_iterator ServiceConstIterator;
101     typedef ServiceSet::size_type ServiceSizeType;
102
103   public:
104    RepoManager( const RepoManagerOptions &options = RepoManagerOptions() );
105    /** Dtor */
106     ~RepoManager();
107
108     enum RawMetadataRefreshPolicy
109     {
110       RefreshIfNeeded,
111       RefreshForced,
112       RefreshIfNeededIgnoreDelay
113     };
114
115     enum CacheBuildPolicy
116     {
117       BuildIfNeeded,
118       BuildForced
119     };
120
121     enum RepoRemovePolicy
122     {
123
124     };
125
126    /**
127     * \short List known repositories.
128     *
129     * The known repositories are read from
130     * \ref RepoManagerOptions::knownReposPath passed on the Ctor.
131     * Which defaults to ZYpp global settings.
132     * \return found list<RepoInfo>
133     */
134    std::list<RepoInfo> knownRepositories() const;
135
136    /**
137     * \short Status of local metadata
138     */
139     RepoStatus metadataStatus( const RepoInfo &info ) const;
140
141     /**
142      * Possibly return state of checkIfRefreshMEtadata function
143      */
144     enum RefreshCheckStatus {
145       REFRESH_NEEDED,  /**< refresh is needed */
146       REPO_UP_TO_DATE, /**< repository not changed */
147       REPO_CHECK_DELAYED     /**< refresh is delayed due to settings */
148     };
149
150     /**
151      * Checks whether to refresh metadata for specified repository and url.
152      * <p>
153      * The need for refresh is evaluated according to the following conditions,
154      * in that order:
155      * <ul>
156      * <li>the refresh policy (refresh may be forced)
157      * <li>the repo.refresh.delay ZConfig value compared to the difference between
158      *   cached index file timestamp and actual time
159      * <li>the timestamp of cached repo index file compared to the remote
160      *   index file timestamp.
161      * </ul>
162      * <p>
163      * This method checks the status against the specified url only. If more
164      * baseurls are defined for in the RepoInfo, each one must be check
165      * individually. Example:
166      *
167      * <code>
168      *
169      * RepoInfo info;
170      * // try urls one by one
171      * for ( RepoInfo::urls_const_iterator it = info.baseUrlsBegin();
172      *       it != info.baseUrlsEnd(); ++it )
173      * {
174      *   try
175      *   {
176      *     // check whether to refresh metadata
177      *     // if the check fails for this url, it throws, so another url will be checked
178      *     if (checkIfToRefreshMetadata(info, *it, policy)!=RepoInfo::REFRESH_NEEDED)
179      *       return;
180      *
181      *     // do the actual refresh
182      *   }
183      *   catch (const Exception & e)
184      *   {
185      *     ZYPP_CAUGHT(e);
186      *     ERR << *it << " doesn't look good. Trying another url." << endl;
187      *   }
188      * } // for all urls
189      *
190      * handle("No more URLs.");
191      *
192      * </code>
193      *
194      * \param info
195      * \param url
196      * \param policy
197      * \return state of repository
198      * \see RefreshCheckStatus
199      * \throws RepoUnknownTypeException
200      * \throws repo::RepoNoAliasException if can't figure an alias
201      * \throws Exception on unknown error
202      *
203      */
204     RefreshCheckStatus checkIfToRefreshMetadata( const RepoInfo &info,
205                                    const Url &url,
206                                    RawMetadataRefreshPolicy policy = RefreshIfNeeded);
207
208     /**
209      * \short Path where the metadata is downloaded and kept
210      *
211      * Given a repoinfo, tells where \ref RepoManager will download
212      * and keep the raw metadata.
213      *
214      * \param info Repository information
215      *
216      * \throws repo::RepoNoAliasException if can't figure an alias
217      */
218     Pathname metadataPath( const RepoInfo &info ) const;
219
220
221     /**
222      * \short Path where the rpm packages are downloaded and kept
223      *
224      * Given a repoinfo, tells where \ref RepoProvidePackage will download
225      * and keep the .rpm files.
226      *
227      * \param info Repository information
228      *
229      * \throws repo::RepoNoAliasException if can't figure an alias
230      */
231     Pathname packagesPath( const RepoInfo &info ) const;
232
233
234    /**
235     * \short Refresh local raw cache
236     *
237     * Will try to download the metadata
238     *
239     * In case of falure the metadata remains
240     * as it was before.
241     *
242     * \throws repo::RepoNoUrlException if no urls are available.
243     * \throws repo::RepoNoAliasException if can't figure an alias
244     * \throws repo::RepoUnknownTypeException if the metadata is unknown
245     * \throws repo::RepoException if the repository is invalid
246     *         (no valid metadata found at any of baseurls)
247     */
248    void refreshMetadata( const RepoInfo &info,
249                          RawMetadataRefreshPolicy policy = RefreshIfNeeded,
250                          const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
251
252    /**
253     * \short Clean local metadata
254     *
255     * Empty local metadata.
256     *
257     * \throws repo::RepoNoAliasException if can't figure an alias
258     * \throws Exception on unknown error.
259     */
260    void cleanMetadata( const RepoInfo &info,
261                        const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
262
263    /**
264     * \short Clean local package cache
265     *
266     * Empty local directory with downloaded packages
267     *
268     * \throws repo::RepoNoAliasException if can't figure an alias
269     * \throws Exception on unknown error.
270     */
271    void cleanPackages( const RepoInfo &info,
272                        const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
273
274    /**
275     * \short Status of metadata cache
276     */
277     RepoStatus cacheStatus( const RepoInfo &info ) const;
278
279    /**
280     * \short Refresh local cache
281     *
282     * Will try to build the cache from local metadata.
283     *
284     * If the cache exists it will be overwriten.
285     *
286     * \note the local metadata must be valid.
287     *
288     * \throws repo::RepoNoAliasException if can't figure
289     *     an alias to look in cache
290     * \throws repo::RepoMetadataException if the metadata
291     *     is not enough to build a cache (empty, incorrect, or
292     *     refresh needed)
293     * \throws repo::RepoUnknownTypeException
294     * \throws parser::ParseException if parser encounters an error.
295     * \throws Exception on unknown error.
296     */
297    void buildCache( const RepoInfo &info,
298                     CacheBuildPolicy policy = BuildIfNeeded,
299                     const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
300
301    /**
302     * \short clean local cache
303     *
304     * Clean the cached version of the metadata
305     *
306     * \note the local metadata must be valid.
307     *
308     * \throws repo::RepoNoAliasException if can't figure an alias to look in cache
309     * \throws cache::CacheRecordNotFoundException if the cache could not be
310     *     cleaned because of repository record not found.
311     * \throws Exception on unknown error.
312     */
313    void cleanCache( const RepoInfo &info,
314                     const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
315
316    /**
317     * \short Whether a repository exists in cache
318     *
319     * \param RepoInfo to be checked.
320     */
321     bool isCached( const RepoInfo &info ) const;
322
323
324     /**
325     * \short Load resolvables into the pool
326     *
327     * Creating from cache requires that the repository is
328     * refreshed (metadata downloaded) and cached
329     *
330     * \throws repo::RepoNoAliasException if can't figure an alias to look in cache
331     * \throw RepoNotCachedException When the source is not cached.
332     */
333    void loadFromCache( const RepoInfo &info,
334                        const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
335    /**
336     * \short Probe repo metadata type.
337     *
338     * \todo FIXME Should this be private?
339     */
340    repo::RepoType probe( const Url &url ) const;
341
342
343    /**
344     * \short Adds a repository to the list of known repositories.
345     *
346     *
347     *
348     * \throws repo::RepoAlreadyExistsException If the repo clash some
349     *         unique attribute like alias
350     * \throws RepoUnknownType If repository type can't be determined
351     * \throws RepoException If the access to the url fails (while probing).
352     * \throws Exception On other errors.
353     */
354    void addRepository( const RepoInfo &info,
355                        const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
356
357    /**
358     * \short Adds repositores from a repo file to the list of known repositories.
359     * \param url Url of the repo file
360     *
361     * \throws repo::RepoAlreadyExistsException If the repo clash some
362     * unique attribute like alias
363     *
364     * \throws RepoAlreadyExistsException
365     * \throws MediaException If the access to the url fails
366     * \throws ParseException If the file parsing fails
367     * \throws RepoUnknownType If repository type can't be determined
368     * \throws RepoException ON other repository related errors
369     * \throws Exception On other errors.
370     */
371     void addRepositories( const Url &url,
372                          const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
373     /**
374      * \short Remove the best matching repository from known repos list
375      *
376      * \throws RepoNotFoundException If no repo match
377      */
378     void removeRepository( const RepoInfo & info,
379                            const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
380
381     /**
382      * \short Modify repository attributes
383      *
384      * \throws RepoAlreadyExistsException if the alias specified in newinfo
385      *         is already used by another repository
386      * \throws RepoNotFoundException If no repo match
387      * \throws ParseException If the file parsing fails
388      * \throws Exception On other errors.
389      */
390     void modifyRepository( const std::string &alias,
391                            const RepoInfo & newinfo,
392                            const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
393
394     /**
395      * \short Find a matching repository info
396      *
397      * \note if multiple repositories incorrectly share the
398      * same alias, the first one found will be returned.
399      *
400      * \param alias Repository alias
401      * \param progressrcv Progress reporting function
402      * \return RepoInfo of the found repository
403      * \throws RepoNotFoundException If no repo match the alias
404      * \throws ParseException If the file parsing fails
405      * \throws Exception On other errors.
406      */
407     RepoInfo getRepositoryInfo( const std::string &alias,
408                                 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
409
410     /**
411      * \short Find repository info by URL.
412      *
413      * \param url URL to find.
414      * \param urlview url::ViewOption to influence URL matching.
415      * \param progressrcv Progress receiver function.
416      * \return RepoInfo of the found repository.
417      *
418      * \note if multpile repositories incorrectly share the
419      * same URL, the first one found will be returned.
420      *
421      * \note the string representation of the URLs are compared.
422      *       The \a urlview can be used to influence which
423              parts of the URL are to be compared.
424      *
425      * \throws RepoNotFoundException If no repo match
426      * \throws ParseException If the file parsing fails
427      * \throws Exception On other errors.
428      */
429     RepoInfo getRepositoryInfo( const Url & url,
430                                 const url::ViewOption & urlview = url::ViewOption::DEFAULTS,
431                                 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
432
433     void addService( const std::string& name, const Url& url );
434
435     void removeService( const std::string& name );
436
437     bool serviceEmpty() const;
438
439     ServiceSizeType serviceSize() const;
440
441     ServiceConstIterator serviceBegin() const;
442
443     ServiceConstIterator serviceEnd() const;
444
445     const Service& getService( const std::string& name ) const;
446
447     void refreshServices();
448
449     /**
450      * modify service, except name change
451      * ( you need remove and add if you want change name )
452      */
453     void modifyService(const Service& service) const;
454
455   protected:
456     RepoStatus rawMetadataStatus( const RepoInfo &info );
457     void setCacheStatus( const RepoInfo &info, const RepoStatus &status );
458
459     /**
460      * Update timestamp of repository index file for the specified repository \a info.
461      * Used in \ref checkIfToRefreshMetadata() for repo.refresh.delay feature.
462      */
463     void touchIndexFile(const RepoInfo & info);
464
465   public:
466
467   private:
468     /** Pointer to implementation */
469     RWCOW_pointer<Impl> _pimpl;
470   };
471   ///////////////////////////////////////////////////////////////////
472
473   /** \relates RepoManager Stream output */
474   std::ostream & operator<<( std::ostream & str, const RepoManager & obj );
475
476   /////////////////////////////////////////////////////////////////
477 } // namespace zypp
478 ///////////////////////////////////////////////////////////////////
479 #endif // ZYPP2_REPOMANAGER_H