Imported Upstream version 17.25.4
[platform/upstream/libzypp.git] / zypp / sat / detail / PoolImpl.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/detail/PoolImpl.h
10  *
11 */
12 #ifndef ZYPP_SAT_DETAIL_POOLIMPL_H
13 #define ZYPP_SAT_DETAIL_POOLIMPL_H
14 extern "C"
15 {
16 #include <solv/pool.h>
17 #include <solv/repo.h>
18 #include <solv/solvable.h>
19 #include <solv/poolarch.h>
20 #include <solv/repo_solv.h>
21 }
22 #include <iosfwd>
23
24 #include <zypp/base/Hash.h>
25 #include <zypp/base/NonCopyable.h>
26 #include <zypp/base/SerialNumber.h>
27 #include <zypp/base/SetTracker.h>
28 #include <zypp/sat/detail/PoolMember.h>
29 #include <zypp/sat/SolvableSpec.h>
30 #include <zypp/sat/Queue.h>
31 #include <zypp/RepoInfo.h>
32 #include <zypp/Locale.h>
33 #include <zypp/Capability.h>
34 #include <zypp/IdString.h>
35
36 ///////////////////////////////////////////////////////////////////
37 namespace zypp
38 { /////////////////////////////////////////////////////////////////
39   ///////////////////////////////////////////////////////////////////
40   namespace sat
41   { /////////////////////////////////////////////////////////////////
42     class SolvableSet;
43     ///////////////////////////////////////////////////////////////////
44     namespace detail
45     { /////////////////////////////////////////////////////////////////
46
47       ///////////////////////////////////////////////////////////////////
48       //
49       //        CLASS NAME : PoolImpl
50       //
51       /** */
52       class PoolImpl : private base::NonCopyable
53       {
54         public:
55           /** Default ctor */
56           PoolImpl();
57
58           /** Dtor */
59           ~PoolImpl();
60
61           /** Pointer style access forwarded to sat-pool. */
62           CPool * operator->()
63           { return _pool; }
64
65         public:
66           /** Serial number changing whenever the content changes. */
67           const SerialNumber & serial() const
68           { return _serial; }
69
70           /** Serial number changing whenever resusePoolIDs==true was used. ResPool must also invalidate it's PoolItems! */
71           const SerialNumber & serialIDs() const
72           { return _serialIDs; }
73
74           /** Update housekeeping data (e.g. whatprovides).
75            * \todo actually requires a watcher.
76            */
77           void prepare() const;
78
79         private:
80           /** Invalidate housekeeping data (e.g. whatprovides) if the
81            *  pools content changed.
82            */
83           void setDirty( const char * a1 = 0, const char * a2 = 0, const char * a3 = 0 );
84
85           /** Invalidate locale related housekeeping data.
86            */
87           void localeSetDirty( const char * a1 = 0, const char * a2 = 0, const char * a3 = 0 );
88
89           /** Invalidate housekeeping data (e.g. whatprovides) if dependencies changed.
90            */
91           void depSetDirty( const char * a1 = 0, const char * a2 = 0, const char * a3 = 0 );
92
93           /** Callback to resolve namespace dependencies (language, modalias, filesystem, etc.). */
94           static detail::IdType nsCallback( CPool *, void * data, detail::IdType lhs, detail::IdType rhs );
95
96         public:
97           /** Reserved system repository alias \c @System. */
98           static const std::string & systemRepoAlias();
99
100           bool isSystemRepo( CRepo * repo_r ) const
101           { return repo_r && _pool->installed == repo_r; }
102
103           CRepo * systemRepo() const
104           { return _pool->installed; }
105
106           /** Get rootdir (for file conflicts check) */
107           Pathname rootDir() const
108           {
109             const char * rd = ::pool_get_rootdir( _pool );
110             return( rd ? rd : "/" );
111           }
112
113           /** Set rootdir (for file conflicts check) */
114           void rootDir( const Pathname & root_r )
115           {
116             if ( root_r.empty() || root_r == "/" )
117               ::pool_set_rootdir( _pool, nullptr );
118             else
119               ::pool_set_rootdir( _pool, root_r.c_str() );
120           }
121
122         public:
123           /** \name Actions invalidating housekeeping data.
124            *
125            * All methods expect valid arguments being passed.
126            */
127           //@{
128           /** Creating a new repo named \a name_r. */
129           CRepo * _createRepo( const std::string & name_r );
130
131           /** Delete repo \a repo_r from pool. */
132           void _deleteRepo( CRepo * repo_r );
133
134           /** Adding solv file to a repo.
135            * Except for \c isSystemRepo_r, solvables of incompatible architecture
136            * are filtered out.
137           */
138           int _addSolv( CRepo * repo_r, FILE * file_r );
139
140           /** Adding helix file to a repo.
141            * Except for \c isSystemRepo_r, solvables of incompatible architecture
142            * are filtered out.
143           */
144           int _addHelix( CRepo * repo_r, FILE * file_r );
145
146           /** Adding testtags file to a repo.
147            * Except for \c isSystemRepo_r, solvables of incompatible architecture
148            * are filtered out.
149           */
150           int _addTesttags( CRepo * repo_r, FILE * file_r );
151
152           /** Adding Solvables to a repo. */
153           detail::SolvableIdType _addSolvables( CRepo * repo_r, unsigned count_r );
154           //@}
155
156           /** Helper postprocessing the repo after adding solv or helix files. */
157           void _postRepoAdd( CRepo * repo_r );
158
159         public:
160           /** a \c valid \ref Solvable has a non NULL repo pointer. */
161           bool validSolvable( const CSolvable & slv_r ) const
162           { return slv_r.repo; }
163           /** \overload Check also for id_r being in range of _pool->solvables. */
164           bool validSolvable( SolvableIdType id_r ) const
165           { return id_r < unsigned(_pool->nsolvables) && validSolvable( _pool->solvables[id_r] ); }
166           /** \overload Check also for slv_r being in range of _pool->solvables. */
167           bool validSolvable( const CSolvable * slv_r ) const
168           { return _pool->solvables <= slv_r && slv_r <= _pool->solvables+_pool->nsolvables && validSolvable( *slv_r ); }
169
170         public:
171           CPool * getPool() const
172           { return _pool; }
173
174           /** \todo a quick check whether the repo was meanwhile deleted. */
175           CRepo * getRepo( RepoIdType id_r ) const
176           { return id_r; }
177
178           /** Return pointer to the sat-solvable or NULL if it is not valid.
179            * \see \ref validSolvable.
180            */
181           CSolvable * getSolvable( SolvableIdType id_r ) const
182           {
183             if ( validSolvable( id_r ) )
184               return &_pool->solvables[id_r];
185             return 0;
186           }
187
188         public:
189           /** Get id of the first valid \ref Solvable.
190            * This is the next valid after the system solvable.
191            */
192           SolvableIdType getFirstId()  const
193           { return getNextId( 1 ); }
194
195           /** Get id of the next valid \ref Solvable.
196            * This goes round robbin. At the end it returns \ref noSolvableId.
197            * Passing \ref noSolvableId it returns the 1st valid  \ref Solvable.
198            * \see \ref validSolvable.
199            */
200           SolvableIdType getNextId( SolvableIdType id_r ) const
201           {
202             for( ++id_r; id_r < unsigned(_pool->nsolvables); ++id_r )
203             {
204               if ( validSolvable( _pool->solvables[id_r] ) )
205                 return id_r;
206             }
207             return noSolvableId;
208           }
209
210         public:
211           /** */
212           const RepoInfo & repoInfo( RepoIdType id_r )
213           { return _repoinfos[id_r]; }
214           /** Also adjust repo priority and subpriority accordingly. */
215           void setRepoInfo( RepoIdType id_r, const RepoInfo & info_r );
216           /** */
217           void eraseRepoInfo( RepoIdType id_r )
218           { _repoinfos.erase( id_r ); }
219
220         public:
221           /** Returns the id stored at \c offset_r in the internal
222            * whatprovidesdata array.
223           */
224           const sat::detail::IdType whatProvidesData( unsigned offset_r )
225           { return _pool->whatprovidesdata[offset_r]; }
226
227           /** Returns offset into the internal whatprovidesdata array.
228            * Use \ref whatProvidesData to get the stored Id.
229           */
230           unsigned whatProvides( Capability cap_r )
231           { prepare(); return ::pool_whatprovides( _pool, cap_r.id() ); }
232
233         public:
234           /// \name Requested locales.
235           /// The requested LocaleSets managed in _requestedLocalesTracker
236           /// are unexpanded; i.e. they contain just the pure user selection.
237           /// The resolver however uses expanded sets ('de_DE' will also
238           /// include its fallback locales 'de', (en); here in the namespace:
239           /// callback and in the Resolver itself).
240           //@{
241           /** */
242           void setTextLocale( const Locale & locale_r );
243
244
245           /** Start tracking changes based on this \a locales_r.
246            * Usually called on TargetInit.
247            */
248           void initRequestedLocales( const LocaleSet & locales_r );
249
250           /** Added since last initRequestedLocales. */
251           const LocaleSet & getAddedRequestedLocales() const
252           { return _requestedLocalesTracker.added(); }
253
254           /** Removed since last initRequestedLocales. */
255           const LocaleSet & getRemovedRequestedLocales() const
256           { return _requestedLocalesTracker.removed(); }
257
258           /** Current set of requested Locales. */
259           const LocaleSet & getRequestedLocales() const
260           { return _requestedLocalesTracker.current(); }
261
262           bool isRequestedLocale( const Locale & locale_r ) const
263           { return _requestedLocalesTracker.contains( locale_r ); }
264
265           /** User change (tracked). */
266           void setRequestedLocales( const LocaleSet & locales_r );
267           /** User change (tracked). */
268           bool addRequestedLocale( const Locale & locale_r );
269           /** User change (tracked). */
270           bool eraseRequestedLocale( const Locale & locale_r );
271
272           /** All Locales occurring in any repo. */
273           const LocaleSet & getAvailableLocales() const;
274
275           bool isAvailableLocale( const Locale & locale_r ) const
276           {
277             const LocaleSet & avl( getAvailableLocales() );
278             LocaleSet::const_iterator it( avl.find( locale_r ) );
279             return it != avl.end();
280           }
281
282           typedef base::SetTracker<IdStringSet> TrackedLocaleIds;
283
284           /** Expanded _requestedLocalesTracker for solver.*/
285           const TrackedLocaleIds & trackedLocaleIds() const;
286           //@}
287
288         public:
289           /** \name Multiversion install. */
290           //@{
291           typedef SolvableSet MultiversionList;
292
293           const MultiversionList & multiversionList() const;
294
295           bool isMultiversion( const Solvable & solv_r ) const;
296
297           void multiversionSpecChanged();
298           //@}
299
300         public:
301           /** \name Installed on behalf of a user request hint. */
302           //@{
303           /** Get ident list of all autoinstalled solvables. */
304           StringQueue autoInstalled() const
305           { return _autoinstalled; }
306
307           /** Set ident list of all autoinstalled solvables. */
308           void setAutoInstalled( const StringQueue & autoInstalled_r )
309           { _autoinstalled = autoInstalled_r; }
310
311           bool isOnSystemByUser( IdString ident_r ) const
312           { return !_autoinstalled.contains( ident_r.id() ); }
313
314           bool isOnSystemByAuto( IdString ident_r ) const
315           { return _autoinstalled.contains( ident_r.id() ); }
316           //@}
317
318         public:
319           /** \name Solvables which should trigger the reboot-needed hint if installed/updated. */
320           //@{
321           /** Set new Solvable specs.*/
322           void setNeedrebootSpec( sat::SolvableSpec needrebootSpec_r )
323           {
324             _needrebootSpec = std::move(needrebootSpec_r);
325             _needrebootSpec.setDirty();
326           }
327
328           /** Whether \a solv_r matches the spec.*/
329           bool isNeedreboot( const Solvable & solv_r ) const
330           { return _needrebootSpec.contains( solv_r ); }
331           //@}
332
333         public:
334           /** accessor for etc/sysconfig/storage reading file on demand */
335           const std::set<std::string> & requiredFilesystems() const;
336
337         private:
338           /** sat-pool. */
339           CPool * _pool;
340           /** Serial number - changes with each Pool content change. */
341           SerialNumber _serial;
342           /** Serial number of IDs - changes whenever resusePoolIDs==true - ResPool must also invalidate it's PoolItems! */
343           SerialNumber _serialIDs;
344           /** Watch serial number. */
345           SerialNumberWatcher _watcher;
346           /** Additional \ref RepoInfo. */
347           std::map<RepoIdType,RepoInfo> _repoinfos;
348
349           /**  */
350           base::SetTracker<LocaleSet> _requestedLocalesTracker;
351           mutable scoped_ptr<TrackedLocaleIds> _trackedLocaleIdsPtr;
352
353           mutable scoped_ptr<LocaleSet> _availableLocalesPtr;
354
355           /**  */
356           void multiversionListInit() const;
357           mutable scoped_ptr<MultiversionList> _multiversionListPtr;
358
359           /**  */
360           sat::StringQueue _autoinstalled;
361
362           /** Solvables which should trigger the reboot-needed hint if installed/updated. */
363           sat::SolvableSpec _needrebootSpec;
364
365           /** filesystems mentioned in /etc/sysconfig/storage */
366           mutable scoped_ptr<std::set<std::string> > _requiredFilesystemsPtr;
367       };
368       ///////////////////////////////////////////////////////////////////
369
370       /////////////////////////////////////////////////////////////////
371     } // namespace detail
372     ///////////////////////////////////////////////////////////////////
373     /////////////////////////////////////////////////////////////////
374   } // namespace sat
375   ///////////////////////////////////////////////////////////////////
376   /////////////////////////////////////////////////////////////////
377 } // namespace zypp
378 ///////////////////////////////////////////////////////////////////
379 #define POOL_SETDIRTY
380 #endif // ZYPP_SAT_DETAIL_POOLIMPL_H