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