1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/zypp_detail/ZYppImpl.cc
13 #include <sys/utsname.h>
17 #include "zypp/TmpPath.h"
18 #include "zypp/base/Logger.h"
19 #include "zypp/base/String.h"
21 #include "zypp/zypp_detail/ZYppImpl.h"
22 #include "zypp/solver/detail/Helper.h"
23 #include "zypp/target/TargetImpl.h"
24 #include "zypp/ZYpp.h"
25 #include "zypp/NVRAD.h"
26 #include "zypp/Language.h"
27 #include "zypp/DiskUsageCounter.h"
28 #include "zypp/NameKindProxy.h"
29 #include "zypp/Locks.h"
33 ///////////////////////////////////////////////////////////////////
35 { /////////////////////////////////////////////////////////////////
36 ///////////////////////////////////////////////////////////////////
38 { /////////////////////////////////////////////////////////////////
40 /** The locale to be used for texts and messages.
42 * For the encoding to be used the preference is
44 * LC_ALL, LC_CTYPE, LANG
46 * For the language of the messages to be used, the preference is
48 * LANGUAGE, LC_ALL, LC_MESSAGES, LANG
50 * Note that LANGUAGE can contain more than one locale name, it can be
51 * a list of locale names like for example
53 * LANGUAGE=ja_JP.UTF-8:de_DE.UTF-8:fr_FR.UTF-8
55 * \todo Support dynamic fallbacklists defined by LANGUAGE
57 inline Locale defaultTextLocale()
60 const char * envlist[] = { "LC_ALL", "LC_MESSAGES", "LANG", NULL };
61 for ( const char ** envvar = envlist; *envvar; ++envvar )
63 const char * envlang = getenv( *envvar );
66 std::string envstr( envlang );
67 if ( envstr != "POSIX" && envstr != "C" )
69 Locale lang( envlang );
70 if ( ! lang.code().empty() )
81 Arch defaultArchitecture()
85 // detect the true architecture
87 if ( uname( &buf ) < 0 )
89 ERR << "Can't determine system architecture" << endl;
93 architecture = Arch( buf.machine );
94 DBG << "uname architecture is '" << buf.machine << "'" << endl;
96 // some CPUs report i686 but dont implement cx8 and cmov
97 // check for both flags in /proc/cpuinfo and downgrade
98 // to i586 if either is missing (cf bug #18885)
100 if ( architecture == Arch_i686 )
102 std::ifstream cpuinfo( "/proc/cpuinfo" );
105 ERR << "Cant open /proc/cpuinfo" << endl;
110 while ( cpuinfo.good() )
112 if ( !cpuinfo.getline( infoline, 1024, '\n' ) )
117 if ( strncmp( infoline, "flags", 5 ) == 0 )
119 std::string flagsline( infoline );
120 if ( flagsline.find( "cx8" ) == std::string::npos
121 || flagsline.find( "cmov" ) == std::string::npos )
123 architecture = Arch_i586;
124 DBG << "CPU lacks 'cx8' or 'cmov': architecture downgraded to '" << architecture << "'" << endl;
128 } // read proc/cpuinfo
129 } // proc/cpuinfo opened
130 } // i686 extra flags check
133 if ( getenv( "ZYPP_TESTSUITE_FAKE_ARCH" ) )
135 architecture = Arch( getenv( "ZYPP_TESTSUITE_FAKE_ARCH" ) );
136 WAR << "ZYPP_TESTSUITE_FAKE_ARCH: Setting fake system architecture for test purpuses to: '" << architecture << "'" << endl;
141 ///////////////////////////////////////////////////////////////////
143 // METHOD NAME : ZYppImpl::ZYppImpl
144 // METHOD TYPE : Constructor
147 : _textLocale( defaultTextLocale() )
149 , _resolver( new Resolver( ResPool::instance()) )
150 , _architecture( defaultArchitecture() )
152 MIL << "libzypp: " << VERSION << " built " << __DATE__ << " " << __TIME__ << endl;
153 MIL << "defaultTextLocale: '" << _textLocale << "'" << endl;
154 MIL << "System architecture is '" << _architecture << "'" << endl;
156 MIL << "initializing keyring..." << std::endl;
157 //_keyring = new KeyRing(homePath() + Pathname("/keyring/all"), homePath() + Pathname("/keyring/trusted"));
158 _keyring = new KeyRing(tmpPath());
161 ///////////////////////////////////////////////////////////////////
163 // METHOD NAME : ZYppImpl::~ZYppImpl
164 // METHOD TYPE : Destructor
166 ZYppImpl::~ZYppImpl()
169 //------------------------------------------------------------------------
170 // add/remove resolvables
172 DiskUsageCounter::MountPointSet ZYppImpl::diskUsage()
176 setPartitions( DiskUsageCounter::detectMountPoints() );
178 return _disk_usage->disk_usage(pool());
181 void ZYppImpl::setPartitions(const DiskUsageCounter::MountPointSet &mp)
183 _disk_usage.reset(new DiskUsageCounter());
184 _disk_usage->setMountPoints(mp);
187 DiskUsageCounter::MountPointSet ZYppImpl::getPartitions() const
190 return _disk_usage->getMountPoints();
192 return DiskUsageCounter::detectMountPoints();
195 //------------------------------------------------------------------------
198 Target_Ptr ZYppImpl::target() const
201 ZYPP_THROW(Exception("Target not initialized."));
205 void ZYppImpl::initializeTarget(const Pathname & root)
207 MIL << "initTarget( " << root << endl;
209 if (_target->root() == root) {
210 MIL << "Repeated call to initializeTarget()" << endl;
213 #warning NEED SOME NEW WAY TO INDICATE NEDD OF TARGET RELOAD
215 removeInstalledResolvables( );
218 _target = new Target( root );
219 _target->enableStorage( root );
222 void ZYppImpl::finishTarget()
224 #warning NEED SOME NEW WAY TO UNLOAD THE POOL
227 removeInstalledResolvables();
232 //------------------------------------------------------------------------
235 /** \todo Remove workflow from target, lot's of it could be done here,
236 * and target used for transact. */
237 ZYppCommitResult ZYppImpl::commit( const ZYppCommitPolicy & policy_r )
239 if ( getenv("ZYPP_TESTSUITE_FAKE_ARCH") )
241 ZYPP_THROW( Exception("ZYPP_TESTSUITE_FAKE_ARCH set. Commit not allowed and disabled.") );
244 MIL << "Attempt to commit (" << policy_r << ")" << endl;
246 ZYPP_THROW( Exception("Target not initialized.") );
248 ZYppCommitResult res = _target->_pimpl->commit( pool(), policy_r );
250 if (! policy_r.dryRun() ) {
251 // Tag target data invalid, so they are reloaded on the next call to
252 // target->resolvables(). Actually the target should do this without
255 #warning NEED SOME NEW WAY TO INDICATE NEDD OF TARGET RELOAD
257 removeInstalledResolvables();
258 if ( policy_r.syncPoolAfterCommit() )
260 // reload new status from target
261 addResolvables( _target->resolvables(), true );
266 MIL << "Commit (" << policy_r << ") returned: "
271 void ZYppImpl::installSrcPackage( const SrcPackage_constPtr & srcPackage_r )
274 ZYPP_THROW( Exception("Target not initialized.") );
275 _target->_pimpl->installSrcPackage( srcPackage_r );
278 //------------------------------------------------------------------------
282 void ZYppImpl::setRequestedLocales( const LocaleSet & locales_r )
284 #warning REIMPLEMENT WITHOUT LANGUAGE RESOLVABLE
286 ResPool mpool( ResPool::instance() );
287 // assert all requested are available
288 for ( LocaleSet::const_iterator it = locales_r.begin();
289 it != locales_r.end(); ++it )
291 NameKindProxy select( nameKindProxy<Language>( mpool, it->code() ) );
292 if ( select.installedEmpty() && select.availableEmpty() )
293 _pool.insert( Language::availableInstance( *it ) );
297 for ( ResPool::byKind_iterator it = mpool.byKindBegin<Language>();
298 it != mpool.byKindEnd<Language>(); ++it )
300 NameKindProxy select( nameKindProxy<Language>( mpool, (*it)->name() ) );
301 if ( locales_r.find( Locale( (*it)->name() ) ) != locales_r.end() )
303 // Language is requested
304 if ( select.installedEmpty() )
306 if ( select.availableEmpty() )
308 // no item ==> provide available to install
309 _pool.insert( Language::availableInstance( Locale((*it)->name()) ) );
310 select = nameKindProxy<Language>( mpool, (*it)->name() );
312 // available only ==> to install
313 select.availableBegin()->status().setTransactValue( ResStatus::TRANSACT, ResStatus::USER );
317 // installed ==> keep it
318 select.installedBegin()->status().setTransactValue( ResStatus::KEEP_STATE, ResStatus::USER );
319 if ( ! select.availableEmpty() )
321 // both items ==> keep
322 select.availableBegin()->status().resetTransact( ResStatus::USER );
328 // Language is NOT requested
329 if ( ! select.installedEmpty() )
330 select.installedBegin()->status().setTransactValue( ResStatus::TRANSACT, ResStatus::USER );
331 if ( ! select.availableEmpty() )
332 select.availableBegin()->status().resetTransact( ResStatus::USER );
339 ZYppImpl::LocaleSet ZYppImpl::getAvailableLocales() const
342 #warning REIMPLEMENT WITHOUT LANGUAGE RESOLVABLE
344 ResPool mpool( ResPool::instance() );
345 for ( ResPool::byKind_iterator it = mpool.byKindBegin<Language>();
346 it != mpool.byKindEnd<Language>(); ++it )
348 if ( (*it).status().isUninstalled() ) // available!
349 ret.insert( Locale( (*it)->name() ) );
356 ZYppImpl::LocaleSet ZYppImpl::getRequestedLocales() const
359 #warning REIMPLEMENT WITHOUT LANGUAGE RESOLVABLE
361 ResPool mpool( ResPool::instance() );
362 for ( ResPool::byKind_iterator it = mpool.byKindBegin<Language>();
363 it != mpool.byKindEnd<Language>(); ++it )
365 NameKindProxy select( nameKindProxy<Language>( mpool, (*it)->name() ) );
366 if ( ! select.installedEmpty()
367 && select.installedBegin()->status().getTransactValue() != ResStatus::TRANSACT )
368 ret.insert( Locale( (*it)->name() ) );
369 else if ( ! select.availableEmpty()
370 && select.availableBegin()->status().getTransactValue() == ResStatus::TRANSACT )
371 ret.insert( Locale( (*it)->name() ) );
377 void ZYppImpl::availableLocale( const Locale & locale_r )
379 #warning REIMPLEMENT WITHOUT LANGUAGE RESOLVABLE
381 _pool.insert( Language::availableInstance( locale_r ) );
385 //------------------------------------------------------------------------
388 void ZYppImpl::setArchitecture( const Arch & arch )
390 _architecture = arch;
393 //------------------------------------------------------------------------
396 Pathname ZYppImpl::homePath() const
397 { return _home_path.empty() ? Pathname("/var/lib/zypp") : _home_path; }
399 void ZYppImpl::setHomePath( const Pathname & path )
400 { _home_path = path; }
402 Pathname ZYppImpl::tmpPath() const
404 static TmpDir zypp_tmp_dir( TmpPath::defaultLocation(), "zypp." );
405 return zypp_tmp_dir.path();
408 int ZYppImpl::applyLocks()
410 Pathname locksrcPath( "/etc/zypp/locks" );
413 Target_Ptr trg( target() );
415 locksrcPath = trg->root() / locksrcPath;
419 // noop: Someone decided to let target() throw if the ptr is NULL ;(
423 PathInfo locksrc( locksrcPath );
424 if ( locksrc.isFile() )
426 MIL << "Reading locks from '" << locksrcPath << "'" << endl;
427 num = zypp::locks::readLocks( pool(), locksrcPath );
428 MIL << num << " items locked." << endl;
432 MIL << "No file '" << locksrcPath << "' to read locks from" << endl;
436 /******************************************************************
438 ** FUNCTION NAME : operator<<
439 ** FUNCTION TYPE : std::ostream &
441 std::ostream & operator<<( std::ostream & str, const ZYppImpl & obj )
443 return str << "ZYppImpl";
446 /////////////////////////////////////////////////////////////////
447 } // namespace zypp_detail
448 ///////////////////////////////////////////////////////////////////
449 /////////////////////////////////////////////////////////////////
451 ///////////////////////////////////////////////////////////////////