00001
00002
00003
00004
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
00064
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
00078 _keyring = new KeyRing();
00079
00080
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
00091
00092
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 }
00121 }
00122 }
00123 }
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
00150
00151
00152 ZYppImpl::~ZYppImpl()
00153 {}
00154
00155
00156
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
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
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
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
00255
00257 void ZYppImpl::setRequestedLocales( const LocaleSet & locales_r )
00258 {
00259 ResPool mpool( pool() );
00260
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
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
00277 if ( select.installedEmpty() )
00278 {
00279 if ( select.availableEmpty() )
00280 {
00281
00282 _pool.insert( Language::availableInstance( Locale((*it)->name()) ) );
00283 select = nameKindProxy<Language>( mpool, (*it)->name() );
00284 }
00285
00286 select.availableBegin()->status().setTransactValue( ResStatus::TRANSACT, ResStatus::USER );
00287 }
00288 else
00289 {
00290
00291 select.installedBegin()->status().setTransactValue( ResStatus::KEEP_STATE, ResStatus::USER );
00292 if ( ! select.availableEmpty() )
00293 {
00294
00295 select.availableBegin()->status().resetTransact( ResStatus::USER );
00296 }
00297 }
00298 }
00299 else
00300 {
00301
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() )
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
00350
00351 void ZYppImpl::setArchitecture( const Arch & arch )
00352 {
00353 _architecture = arch;
00354 if (_resolver) _resolver->setArchitecture( arch );
00355 }
00356
00357
00358
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
00369
00370
00371 std::ostream & operator<<( std::ostream & str, const ZYppImpl & obj )
00372 {
00373 return str << "ZYppImpl";
00374 }
00375
00377 }
00380 }