ZYppImpl.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00013 #include <sys/utsname.h>
00014 #include <iostream>
00015 #include <fstream>
00016 #include "zypp/base/Logger.h"
00017 
00018 #include "zypp/zypp_detail/ZYppImpl.h"
00019 #include "zypp/detail/ResImplTraits.h"
00020 #include "zypp/solver/detail/Helper.h"
00021 #include "zypp/target/TargetImpl.h"
00022 #include "zypp/ZYpp.h"
00023 #include "zypp/NVRAD.h"
00024 #include "zypp/Language.h"
00025 #include "zypp/DiskUsageCounter.h"
00026 #include "zypp/NameKindProxy.h"
00027 
00028 using std::endl;
00029 
00031 namespace zypp
00032 { 
00033 
00034   namespace zypp_detail
00035   { 
00036 
00037     inline Locale defaultTextLocale()
00038     {
00039       Locale ret( "en" );
00040       char * envlist[] = { "LC_ALL", "LC_CTYPE", "LANG", NULL };
00041       for ( char ** envvar = envlist; *envvar; ++envvar )
00042         {
00043           char * envlang = getenv( *envvar );
00044           if ( envlang )
00045             {
00046               std::string envstr( envlang );
00047               if ( envstr != "POSIX" && envstr != "C" )
00048                 {
00049                   Locale lang( envlang );
00050                   if ( lang != Locale::noCode )
00051                     {
00052                       ret = lang;
00053                       break;
00054                     }
00055                 }
00056             }
00057         }
00058       return ret;
00059     }
00060 
00062     //
00063     //  METHOD NAME : ZYppImpl::ZYppImpl
00064     //  METHOD TYPE : Constructor
00065     //
00066     ZYppImpl::ZYppImpl()
00067     : _textLocale( defaultTextLocale() )
00068     , _pool()
00069     , _sourceFeed( _pool )
00070     , _target(0)
00071     , _resolver( new Resolver(_pool.accessor()) )
00072     , _disk_usage()
00073     {
00074       MIL << "defaultTextLocale: '" << _textLocale << "'" << endl;
00075 
00076       MIL << "initializing keyring..." << std::endl;
00077       //_keyring = new KeyRing(homePath() + Pathname("/keyring/all"), homePath() + Pathname("/keyring/trusted"));
00078       _keyring = new KeyRing();
00079 
00080       // detect the true architecture
00081       struct utsname buf;
00082       if (uname (&buf) < 0) {
00083         ERR << "Can't determine system architecture" << endl;
00084       }
00085       else {
00086         _architecture = Arch( buf.machine );
00087 
00088         MIL << "uname architecture is '" << buf.machine << "'" << endl;
00089 
00090         // some CPUs report i686 but dont implement cx8 and cmov
00091         // check for both flags in /proc/cpuinfo and downgrade
00092         // to i586 if either is missing (cf bug #18885)
00093 
00094         if (_architecture == Arch_i686)
00095         {
00096             std::ifstream cpuinfo ("/proc/cpuinfo");
00097             if (!cpuinfo)
00098             {
00099                 ERR << "Cant open /proc/cpuinfo" << endl;
00100             }
00101             else
00102             {
00103                 char infoline[1024];
00104                 while (cpuinfo.good())
00105                 {
00106                     if (!cpuinfo.getline (infoline, 1024, '\n'))
00107                     {
00108                         if (cpuinfo.eof())
00109                             break;
00110                     }
00111                     if (strncmp (infoline, "flags", 5) == 0)
00112                     {
00113                         std::string flagsline (infoline);
00114                         if ((flagsline.find( "cx8" ) == std::string::npos)
00115                             || (flagsline.find( "cmov" ) == std::string::npos))
00116                         {
00117                             _architecture = Arch_i586;
00118                         }
00119                         break;
00120                     } // flags found
00121                 } // read proc/cpuinfo
00122             } // proc/cpuinfo opened
00123         } // i686 extra flags check
00124 
00125         MIL << "System architecture is '" << _architecture << "'" << endl;
00126       }
00127     
00128 
00129       
00130       if ( getenv("ZYPP_TESTSUITE_FAKE_ARCH") ) 
00131       {
00132         Arch already_set = _architecture;
00133         
00134         std::string fakearch(getenv("ZYPP_TESTSUITE_FAKE_ARCH"));
00135         try
00136         { 
00137           _architecture = Arch( fakearch );
00138           MIL << "ZYPP_TESTSUITE_FAKE_ARCH: Setting fake system architecture for test purpuses (warning! commit will be disabled!) to: '" << _architecture << "'" << endl;
00139         }
00140         catch(...)
00141         {
00142           ERR << "ZYPP_TESTSUITE_FAKE_ARCH: Wrong architecture specified on env variable, using: '" << _architecture << "'" << endl;
00143         }
00144       }
00145     }
00146 
00148     //
00149     //  METHOD NAME : ZYppImpl::~ZYppImpl
00150     //  METHOD TYPE : Destructor
00151     //
00152     ZYppImpl::~ZYppImpl()
00153     {}
00154 
00155     //------------------------------------------------------------------------
00156     // add/remove resolvables
00157 
00158     void ZYppImpl::addResolvables (const ResStore& store, bool installed)
00159     {
00160         _pool.insert(store.begin(), store.end(), installed);
00161     }
00162 
00163     void ZYppImpl::removeResolvables (const ResStore& store)
00164     {
00165         for (ResStore::iterator it = store.begin(); it != store.end(); ++it)
00166         {
00167             _pool.erase(*it);
00168         }
00169     }
00170 
00171     void ZYppImpl::removeInstalledResolvables ()
00172     {
00173         for (ResPool::const_iterator it = pool().begin(); it != pool().end();)
00174         {
00175             ResPool::const_iterator next = it; ++next;
00176             if (it->status().isInstalled())
00177                 _pool.erase( *it );
00178             it = next;
00179         }
00180     }
00181 
00182     DiskUsageCounter::MountPointSet ZYppImpl::diskUsage()
00183     { return _disk_usage.disk_usage(pool()); }
00184 
00185     void ZYppImpl::setPartitions(const DiskUsageCounter::MountPointSet &mp)
00186     { _disk_usage.setMountPoints(mp); }
00187 
00188     //------------------------------------------------------------------------
00189     // target
00190 
00191     Target_Ptr ZYppImpl::target() const
00192     {
00193       if (! _target)
00194         ZYPP_THROW(Exception("Target not initialized."));
00195       return _target;
00196      }
00197 
00198     void ZYppImpl::initTarget(const Pathname & root, bool commit_only)
00199     {
00200       MIL << "initTarget( " << root << ", " << commit_only << ")" << endl;
00201       if (_target) {
00202         if (_target->root() == root) {
00203             MIL << "Repeated call to initTarget()" << endl;
00204             return;
00205         }
00206         removeInstalledResolvables( );
00207       }
00208       _target = new Target( root );
00209       if (!commit_only)
00210       {
00211         _target->enableStorage( root );
00212         addResolvables( _target->resolvables(), true );
00213       }
00214     }
00215 
00216     void ZYppImpl::finishTarget()
00217     {
00218       if (_target)
00219         removeInstalledResolvables();
00220       _target = 0;
00221     }
00222 
00223     //------------------------------------------------------------------------
00224     // commit
00225 
00228     ZYppCommitResult ZYppImpl::commit( const ZYppCommitPolicy & policy_r )
00229     {
00230       if ( getenv("ZYPP_TESTSUITE_FAKE_ARCH") )
00231       {
00232         ZYPP_THROW( Exception("ZYPP_TESTSUITE_FAKE_ARCH set. Commit not allowed and disabled.") );
00233       }
00234         
00235       MIL << "Attempt to commit (" << policy_r << ")" << endl;
00236       if (! _target)
00237         ZYPP_THROW( Exception("Target not initialized.") );
00238 
00239       ZYppCommitResult res = _target->_pimpl->commit( pool(), policy_r );
00240 
00241       if (! policy_r.dryRun() ) {
00242         // reload new status from target
00243         removeInstalledResolvables();
00244         addResolvables( _target->resolvables(), true );
00245       }
00246 
00247       MIL << "Commit (" << policy_r << ") returned: "
00248           << res << endl;
00249       return res;
00250     }
00251 
00252 
00253     //------------------------------------------------------------------------
00254     // locales
00255 
00257     void ZYppImpl::setRequestedLocales( const LocaleSet & locales_r )
00258     {
00259       ResPool mpool( pool() );
00260       // assert all requested are available
00261       for ( LocaleSet::const_iterator it = locales_r.begin();
00262             it != locales_r.end(); ++it )
00263         {
00264           NameKindProxy select( nameKindProxy<Language>( mpool, it->code() ) );
00265           if ( select.installedEmpty() && select.availableEmpty() )
00266             _pool.insert( Language::availableInstance( *it ) );
00267         }
00268 
00269       // now adjust status
00270       for ( ResPool::byKind_iterator it = mpool.byKindBegin<Language>();
00271             it != mpool.byKindEnd<Language>(); ++it )
00272         {
00273           NameKindProxy select( nameKindProxy<Language>( mpool, (*it)->name() ) );
00274           if ( locales_r.find( Locale( (*it)->name() ) ) != locales_r.end() )
00275             {
00276               // Language is requested
00277               if ( select.installedEmpty() )
00278                 {
00279                   if ( select.availableEmpty() )
00280                     {
00281                       // no item ==> provide available to install
00282                       _pool.insert( Language::availableInstance( Locale((*it)->name()) ) );
00283                       select = nameKindProxy<Language>( mpool, (*it)->name() );
00284                     }
00285                   // available only ==> to install
00286                   select.availableBegin()->status().setTransactValue( ResStatus::TRANSACT, ResStatus::USER );
00287                 }
00288               else
00289                 {
00290                   // installed ==> keep it
00291                   select.installedBegin()->status().setTransactValue( ResStatus::KEEP_STATE, ResStatus::USER );
00292                   if ( ! select.availableEmpty() )
00293                     {
00294                       // both items ==> keep
00295                       select.availableBegin()->status().resetTransact( ResStatus::USER );
00296                     }
00297                 }
00298             }
00299           else
00300             {
00301               // Language is NOT requested
00302               if ( ! select.installedEmpty() )
00303                 select.installedBegin()->status().setTransactValue( ResStatus::TRANSACT, ResStatus::USER );
00304               if ( ! select.availableEmpty() )
00305                 select.availableBegin()->status().resetTransact( ResStatus::USER );
00306             }
00307         }
00308     }
00309 
00311     ZYppImpl::LocaleSet ZYppImpl::getAvailableLocales() const
00312     {
00313       ZYpp::LocaleSet ret;
00314       ResPool mpool( pool() );
00315       for ( ResPool::byKind_iterator it = mpool.byKindBegin<Language>();
00316             it != mpool.byKindEnd<Language>(); ++it )
00317         {
00318           if ( (*it).status().isUninstalled() ) // available!
00319             ret.insert( Locale( (*it)->name() ) );
00320         }
00321       return ret;
00322     }
00323 
00325     ZYppImpl::LocaleSet ZYppImpl::getRequestedLocales() const
00326     {
00327       ZYpp::LocaleSet ret;
00328       ResPool mpool( pool() );
00329       for ( ResPool::byKind_iterator it = mpool.byKindBegin<Language>();
00330             it != mpool.byKindEnd<Language>(); ++it )
00331         {
00332           NameKindProxy select( nameKindProxy<Language>( mpool, (*it)->name() ) );
00333           if ( ! select.installedEmpty()
00334                && select.installedBegin()->status().getTransactValue() != ResStatus::TRANSACT )
00335             ret.insert( Locale( (*it)->name() ) );
00336           else if ( ! select.availableEmpty()
00337                     && select.availableBegin()->status().getTransactValue() == ResStatus::TRANSACT )
00338             ret.insert( Locale( (*it)->name() ) );
00339         }
00340       return ret;
00341     }
00342 
00343     void ZYppImpl::availableLocale( const Locale & locale_r )
00344     {
00345       _pool.insert( Language::availableInstance( locale_r ) );
00346     }
00347 
00348     //------------------------------------------------------------------------
00349     // architecture
00350 
00351     void ZYppImpl::setArchitecture( const Arch & arch )
00352     {
00353         _architecture = arch;
00354         if (_resolver) _resolver->setArchitecture( arch );
00355     }
00356 
00357     //------------------------------------------------------------------------
00358     // target store path
00359 
00360     Pathname ZYppImpl::homePath() const
00361     { return _home_path.empty() ? Pathname("/var/lib/zypp") : _home_path; }
00362 
00363     void ZYppImpl::setHomePath( const Pathname & path )
00364     { _home_path = path; }
00365 
00366     /******************************************************************
00367      **
00368      ** FUNCTION NAME : operator<<
00369      ** FUNCTION TYPE : std::ostream &
00370     */
00371     std::ostream & operator<<( std::ostream & str, const ZYppImpl & obj )
00372     {
00373       return str << "ZYppImpl";
00374     }
00375 
00377   } // namespace zypp_detail
00380 } // namespace zypp

Generated on Mon Jun 5 19:10:46 2006 for zypp by  doxygen 1.4.6