log initTarget() calls
[platform/upstream/libzypp.git] / zypp / zypp_detail / ZYppImpl.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/zypp_detail/ZYppImpl.cc
10  *
11 */
12
13 #include <sys/utsname.h>
14 #include <iostream>
15 //#include "zypp/base/Logger.h"
16
17 #include "zypp/zypp_detail/ZYppImpl.h"
18 #include "zypp/detail/LanguageImpl.h"
19 #include "zypp/detail/ResImplTraits.h"
20 #include "zypp/solver/detail/Helper.h"
21 #include "zypp/NVRAD.h"
22 #include "zypp/Language.h"
23
24 using std::endl;
25
26 ///////////////////////////////////////////////////////////////////
27 namespace zypp
28 { /////////////////////////////////////////////////////////////////
29   ///////////////////////////////////////////////////////////////////
30   namespace zypp_detail
31   { /////////////////////////////////////////////////////////////////
32
33     inline Locale defaultTextLocale()
34     {
35       Locale ret( "en" );
36       char * envlist[] = { "LC_ALL", "LC_CTYPE", "LANG", NULL };
37       for ( char ** envvar = envlist; *envvar; ++envvar )
38         {
39           char * envlang = getenv( *envvar );
40           if ( envlang )
41             {
42               std::string envstr( envlang );
43               if ( envstr != "POSIX" && envstr != "C" )
44                 {
45                   Locale lang( envlang );
46                   if ( lang != Locale::noCode )
47                     {
48                       ret = lang;
49                       break;
50                     }
51                 }
52             }
53         }
54       return ret;
55     }
56
57     ///////////////////////////////////////////////////////////////////
58     //
59     //  METHOD NAME : ZYppImpl::ZYppImpl
60     //  METHOD TYPE : Constructor
61     //
62     ZYppImpl::ZYppImpl()
63     : _textLocale( defaultTextLocale() )
64     , _pool()
65     , _sourceFeed( _pool )
66     , _resolver( new Resolver(_pool.accessor()) )
67     {
68       MIL << "defaultTextLocale: '" << _textLocale << "'" << endl;
69
70       struct utsname buf;
71       if (uname (&buf) < 0) {
72         ERR << "Can't determine system architecture" << endl;
73       }
74       else {
75         MIL << "System architecture is '" << buf.machine << "'" << endl;
76         _architecture = Arch(buf.machine);
77       }
78
79     }
80
81     ///////////////////////////////////////////////////////////////////
82     //
83     //  METHOD NAME : ZYppImpl::~ZYppImpl
84     //  METHOD TYPE : Destructor
85     //
86     ZYppImpl::~ZYppImpl()
87     {
88     }
89
90     //------------------------------------------------------------------------
91     // add/remove resolvables
92
93     void ZYppImpl::addResolvables (const ResStore& store, bool installed)
94     {
95         _pool.insert(store.begin(), store.end(), installed);
96     }
97
98     void ZYppImpl::removeResolvables (const ResStore& store)
99     {
100         for (ResStore::iterator it = store.begin(); it != store.end(); ++it)
101         {
102             _pool.erase(*it);
103         }
104     }
105
106     void ZYppImpl::removeInstalledResolvables ()
107     {
108         for (ResPool::const_iterator it = pool().begin(); it != pool().end();)
109         {
110             ResPool::const_iterator next = it; ++next;
111             if (it->status().isInstalled())
112                 _pool.erase( *it );
113             it = next;
114         }
115     }
116
117     //------------------------------------------------------------------------
118     // target
119
120     Target_Ptr ZYppImpl::target() const
121     {
122       if (! _target)
123         ZYPP_THROW(Exception("Target not initialized."));
124       return _target;
125      }
126
127     void ZYppImpl::initTarget(const Pathname & root, bool commit_only)
128     {
129       MIL << "initTarget( " << root << ", " << commit_only << ")" << endl;
130       if (_target) {
131         if (_target->root() == root) {
132             MIL << "Repeated call to initTarget()" << endl;
133             return;
134         }
135         removeInstalledResolvables( );
136       }
137       _target = new Target( root );
138       if (!commit_only)
139       {
140         _target->enableStorage( root );
141         addResolvables( _target->resolvables(), true );
142       }
143     }
144
145     void ZYppImpl::finishTarget()
146     {
147       if (_target)
148         removeInstalledResolvables();
149       _target = 0;
150     }
151
152     //------------------------------------------------------------------------
153     // commit
154
155     /** \todo Remove workflow from target, lot's of it could be done here,
156     * and target used for transact. */
157     ZYpp::CommitResult ZYppImpl::commit( int medianr_r )
158     {
159       MIL << "Attempt to commit (medianr " << medianr_r << ")" << endl;
160       if (! _target)
161         ZYPP_THROW( Exception("Target not initialized.") );
162
163       ZYpp::CommitResult res;
164
165       // must redirect to Target::Impl. This kind of commit should not be
166       // in the Target interface.
167
168       res._result = _target->commit( pool(), medianr_r,
169                                      res._errors, res._remaining, res._srcremaining );
170
171       // reload new status from target
172
173       removeInstalledResolvables();
174       addResolvables( _target->resolvables(), true );
175
176       MIL << "Commit (medianr " << medianr_r << ") returned: "
177           << res._result
178           << " (errors " << res._errors.size()
179           << ", remaining " << res._remaining.size()
180           << ", srcremaining " << res._srcremaining.size()
181           << ")" << endl;
182
183       return res;
184     }
185
186
187     //------------------------------------------------------------------------
188     // locales
189
190     /** */
191     void ZYppImpl::setRequestedLocales( const LocaleSet & locales_r )
192     {
193         // check if each requested is also possible.
194
195         LocaleSet possible = getPossibleLocales();
196         bool changed = false;
197         for (LocaleSet::const_iterator it = locales_r.begin(); it != locales_r.end(); ++it) {
198             changed = possible.insert( *it ).second;
199             if ( (it->code() != it->language().code()) ) {
200                 changed = possible.insert( Locale( it->language().code() ) ).second;
201             }
202         }
203
204         // oops, some requested are not possbile, make them possible
205         //  this will actually generate 'uninstalled' language items we need below
206
207         if (changed) {
208             setPossibleLocales( possible );
209         }
210         
211         // now select the requested items for selection
212
213         for (LocaleSet::const_iterator it = locales_r.begin(); it != locales_r.end(); ++it) {
214             MIL << "Requested locale '" << *it << "'" << endl;
215
216 // remove unwanted ?        PoolItem installed( Helper::findInstalledByNameAndKind( _pool.accessor(), it->code(), ResTraits<Language>::kind ) );
217             PoolItem uninstalled( solver::detail::Helper::findUninstalledByNameAndKind( _pool.accessor(), it->code(), ResTraits<Language>::kind ) );
218             if (uninstalled) {
219                 if (!uninstalled.status().isLocked()) {
220                     uninstalled.status().setTransact( true, ResStatus::USER );
221                 }
222             }
223
224             // if lang_country is given, also enable lang (i.e. if "de_DE" is given, also enable "de")
225             if ( (it->code() != it->language().code()) ) {
226                 MIL << "Auto requesting locale '" << it->language().code() << "'" << endl;
227                 uninstalled = solver::detail::Helper::findUninstalledByNameAndKind( _pool.accessor(), it->language().code(), ResTraits<Language>::kind );
228                 if (uninstalled) {
229                     if (!uninstalled.status().isLocked()) {
230                         uninstalled.status().setTransact( true, ResStatus::USER );
231                     }
232                 }
233             }
234         }
235
236         _requested_locales = locales_r;
237
238     }
239
240     /** */
241     void ZYppImpl::setPossibleLocales( const LocaleSet & locales_r )
242     {
243         removeResolvables( _possible_locales );
244         _possible_locales.clear();
245
246         for (LocaleSet::const_iterator it = locales_r.begin(); it != locales_r.end(); ++it) {
247             NVRA nvra( it->code(), Edition(), Arch_noarch );
248             NVRAD ldata( nvra, Dependencies() );
249             detail::ResImplTraits<detail::LanguageImpl>::Ptr limpl = new detail::LanguageImpl();
250             Language::Ptr language = detail::makeResolvableFromImpl( ldata, limpl );
251             _possible_locales.insert( language );
252         }
253         addResolvables( _possible_locales, false );
254     }
255
256     /** */
257     ZYppImpl::LocaleSet ZYppImpl::getPossibleLocales() const
258     {
259         LocaleSet lset;
260         for (ResStore::const_iterator it = _possible_locales.begin(); it != _possible_locales.end(); ++it) {
261             lset.insert( Locale( (*it)->name() ) );
262         }
263         return lset;
264     }
265
266     /** */
267     ZYppImpl::LocaleSet ZYppImpl::getAvailableLocales() const
268     {
269         return _available_locales;
270     }
271
272     void ZYppImpl::availableLocale( const Locale & locale_r )
273     {
274         _available_locales.insert( locale_r );
275     }
276
277     //------------------------------------------------------------------------
278     // architecture
279
280     void ZYppImpl::setArchitecture( const Arch & arch )
281     {
282         _architecture = arch;
283         if (_resolver) _resolver->setArchitecture( arch );
284     }
285
286     //------------------------------------------------------------------------
287     // target store path
288
289     Pathname ZYppImpl::homePath() const
290     { return _home_path.empty() ? Pathname("/var/lib/zypp") : _home_path; }
291
292     void ZYppImpl::setHomePath( const Pathname & path )
293     { _home_path = path; }  
294     
295     /******************************************************************
296      **
297      ** FUNCTION NAME : operator<<
298      ** FUNCTION TYPE : std::ostream &
299     */
300     std::ostream & operator<<( std::ostream & str, const ZYppImpl & obj )
301     {
302       return str << "ZYppImpl";
303     }
304
305     /////////////////////////////////////////////////////////////////
306   } // namespace zypp_detail
307   ///////////////////////////////////////////////////////////////////
308   /////////////////////////////////////////////////////////////////
309 } // namespace zypp
310 ///////////////////////////////////////////////////////////////////