TargetImpl.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include <sstream>
00014 #include <string>
00015 #include <list>
00016 #include <set>
00017 
00018 #include "zypp/base/Logger.h"
00019 #include "zypp/base/Exception.h"
00020 #include "zypp/base/Iterator.h"
00021 #include "zypp/base/Gettext.h"
00022 #include "zypp/base/UserRequestException.h"
00023 
00024 #include "zypp/PoolItem.h"
00025 #include "zypp/Resolvable.h"
00026 #include "zypp/ResObject.h"
00027 #include "zypp/Package.h"
00028 #include "zypp/SrcPackage.h"
00029 #include "zypp/Pattern.h"
00030 #include "zypp/Selection.h"
00031 #include "zypp/Script.h"
00032 #include "zypp/Message.h"
00033 #include "zypp/Url.h"
00034 
00035 #include "zypp/CapMatchHelper.h"
00036 #include "zypp/ResFilters.h"
00037 #include "zypp/target/CommitLog.h"
00038 #include "zypp/target/TargetImpl.h"
00039 #include "zypp/target/TargetCallbackReceiver.h"
00040 #include "zypp/target/rpm/librpmDb.h"
00041 #include "zypp/target/CommitPackageCache.h"
00042 
00043 #include "zypp/pool/GetResolvablesToInsDel.h"
00044 #include "zypp/solver/detail/Helper.h"
00045 
00046 #include "zypp/repo/DeltaCandidates.h"
00047 #include "zypp/repo/PackageProvider.h"
00048 #include "zypp/repo/ScriptProvider.h"
00049 #include "zypp/repo/SrcPackageProvider.h"
00050 
00051 using namespace std;
00052 using namespace zypp;
00053 using namespace zypp::resfilter;
00054 using zypp::solver::detail::Helper;
00055 
00057 namespace zypp
00058 { 
00059 
00060   namespace target
00061   { 
00062 
00064     namespace
00065     { 
00066       void ExecuteScriptHelper( repo::RepoMediaAccess & access_r,
00067                                 Script::constPtr script_r,
00068                                 bool do_r )
00069       {
00070         MIL << "Execute script " << script_r << endl;
00071         if ( ! script_r )
00072         {
00073           INT << "NULL Script passed." << endl;
00074           return;
00075         }
00076 
00077         repo::ScriptProvider prov( access_r );
00078         ManagedFile localfile = prov.provideScript( script_r, do_r );
00079 
00080         if ( localfile->empty() )
00081         {
00082           DBG << "No " << (do_r?"do":"undo") << " script for " << script_r << endl;
00083           return; // success
00084         }
00085 
00086         // Go...
00087         callback::SendReport<ScriptResolvableReport> report;
00088         report->start( script_r, localfile,
00089                        (do_r ? ScriptResolvableReport::DO
00090                         : ScriptResolvableReport::UNDO ) );
00091 
00092         PathInfo pi( localfile );
00093         if ( ! pi.isFile() )
00094         {
00095           std::ostringstream err;
00096           err << "Script is not a file: " << pi.fileType() << " " << localfile;
00097           report->problem( err.str() );
00098           ZYPP_THROW(Exception(err.str()));
00099         }
00100 
00101         filesystem::chmod( localfile, S_IRUSR|S_IXUSR );        // "r-x------"
00102         ExternalProgram prog( localfile->asString(), ExternalProgram::Stderr_To_Stdout, false, -1, true );
00103         for ( std::string output = prog.receiveLine(); output.length(); output = prog.receiveLine() )
00104         {
00105           if ( ! report->progress( ScriptResolvableReport::OUTPUT, output ) )
00106             {
00107               WAR << "User request to abort script." << endl;
00108               prog.kill(); // the rest is handled by exit code evaluation.
00109             }
00110         }
00111 
00112         int exitCode = prog.close();
00113         if ( exitCode != 0 )
00114         {
00115           std::ostringstream err;
00116           err << "Script failed with exit code " << exitCode;
00117           report->problem( err.str() );
00118           ZYPP_THROW(Exception(err.str()));
00119         }
00120 
00121         report->finish();
00122         return;
00123       }
00124 
00125       inline void ExecuteDoScript( repo::RepoMediaAccess & access_r, const Script::constPtr & script_r )
00126       {
00127         ExecuteScriptHelper( access_r, script_r, true );
00128       }
00129 
00130       inline void ExecuteUndoScript( repo::RepoMediaAccess & access_r, const Script::constPtr & script_r )
00131       {
00132         ExecuteScriptHelper( access_r, script_r, false );
00133       }
00135     } // namespace
00137 
00139     namespace
00140     { 
00141 
00143       struct StorageRemoveObsoleted
00144       {
00145         StorageRemoveObsoleted( storage::PersistentStorage & storage_r,
00146                                 const PoolItem & byPoolitem_r )
00147         : _storage( storage_r )
00148         , _byPoolitem( byPoolitem_r )
00149         {}
00150 
00151         bool operator()( const PoolItem & poolitem_r ) const
00152         {
00153           if ( ! poolitem_r.status().isInstalled() )
00154             return true;
00155 
00156           if ( isKind<Package>(poolitem_r.resolvable()) )
00157             {
00158               ERR << "Ignore unsupported Package/non-Package obsolete: "
00159                   << _byPoolitem << " obsoletes " << poolitem_r << endl;
00160               return true;
00161             }
00162 
00163           try
00164             {
00165               _storage.deleteObject( poolitem_r.resolvable() );
00166                MIL<< "Obsoleted: " << poolitem_r << " (by " << _byPoolitem << ")" << endl;
00167             }
00168           catch ( Exception & excpt_r )
00169             {
00170               ZYPP_CAUGHT( excpt_r );
00171               WAR << "Failed obsolete: " << poolitem_r << " (by " << _byPoolitem << ")" << endl;
00172             }
00173 
00174           return true;
00175         }
00176 
00177       private:
00178         storage::PersistentStorage & _storage;
00179         const PoolItem               _byPoolitem;
00180       };
00181 
00187       void obsoleteMatchesFromStorage( storage::PersistentStorage & storage_r,
00188                                        const ResPool & pool_r,
00189                                        const PoolItem & byPoolitem_r )
00190       {
00191         forEachPoolItemMatchedBy( pool_r, byPoolitem_r, Dep::OBSOLETES,
00192                                   OncePerPoolItem( StorageRemoveObsoleted( storage_r,
00193                                                                            byPoolitem_r ) ) );
00194       }
00195 
00197     } // namespace
00199 
00201     struct QueryInstalledEditionHelper
00202     {
00203       bool operator()( const std::string & name_r,
00204                        const Edition &     ed_r,
00205                        const Arch &        arch_r ) const
00206       {
00207         rpm::librpmDb::db_const_iterator it;
00208         for ( it.findByName( name_r ); *it; ++it )
00209           {
00210             if ( arch_r == it->tag_arch()
00211                  && ( ed_r == Edition::noedition || ed_r == it->tag_edition() ) )
00212               {
00213                 return true;
00214               }
00215           }
00216         return false;
00217       }
00218     };
00219 
00225     struct RepoProvidePackage
00226     {
00227       ResPool _pool;
00228       repo::RepoMediaAccess &_access;
00229 
00230       RepoProvidePackage( repo::RepoMediaAccess &access, ResPool pool_r )
00231         : _pool(pool_r), _access(access)
00232       {
00233 
00234       }
00235 
00236       ManagedFile operator()( const PoolItem & pi )
00237       {
00238         // Redirect PackageProvider queries for installed editions
00239         // (in case of patch/delta rpm processing) to rpmDb.
00240         repo::PackageProviderPolicy packageProviderPolicy;
00241         packageProviderPolicy.queryInstalledCB( QueryInstalledEditionHelper() );
00242 
00243         Package::constPtr p = asKind<Package>(pi.resolvable());
00244 
00245 
00246         // Build a repository list for repos
00247         // contributing to the pool
00248         std::list<Repository> repos( _pool.knownRepositoriesBegin(), _pool.knownRepositoriesEnd() );
00249         repo::DeltaCandidates deltas(repos);
00250         repo::PackageProvider pkgProvider( _access, p, deltas, packageProviderPolicy );
00251         return pkgProvider.providePackage();
00252       }
00253     };
00255 
00256     IMPL_PTR_TYPE(TargetImpl);
00257 
00258     TargetImpl_Ptr TargetImpl::_nullimpl;
00259 
00261     TargetImpl_Ptr TargetImpl::nullimpl()
00262     {
00263       if (_nullimpl == 0)
00264         _nullimpl = new TargetImpl;
00265       return _nullimpl;
00266     }
00267 
00269     //
00270     //  METHOD NAME : TargetImpl::TargetImpl
00271     //  METHOD TYPE : Ctor
00272     //
00273     TargetImpl::TargetImpl(const Pathname & root_r)
00274     : _root(root_r), _storage_enabled(false)
00275     {
00276       _rpm.initDatabase(root_r);
00277       MIL << "Initialized target on " << _root << endl;
00278     }
00279 
00281     //
00282     //  METHOD NAME : TargetImpl::~TargetImpl
00283     //  METHOD TYPE : Dtor
00284     //
00285     TargetImpl::~TargetImpl()
00286     {
00287       _rpm.closeDatabase();
00288       MIL << "Targets closed" << endl;
00289     }
00290 
00291     bool TargetImpl::isStorageEnabled() const
00292     {
00293       return _storage_enabled;
00294     }
00295 
00296 
00297     void TargetImpl::enableStorage(const Pathname &root_r)
00298     {
00299       _storage.init(root_r);
00300       _storage_enabled = true;
00301     }
00302 
00303     Pathname TargetImpl::root() const
00304     {
00305       return _root;
00306     }
00307 
00308     void TargetImpl::loadKindResolvables( const Resolvable::Kind kind )
00309     {
00310       // if this kind is already loaded, return
00311       if ( _resstore_loaded[kind] )
00312         return;
00313 
00314       if ( kind == ResTraits<zypp::Package>::kind )
00315       {
00316         std::list<Package::Ptr> packages = _rpm.getPackages();
00317         for (std::list<Package::Ptr>::const_iterator it = packages.begin();
00318              it != packages.end();
00319              it++)
00320         {
00321           _store.insert(*it);
00322         }
00323         _resstore_loaded[kind] = true;
00324       }
00325       else
00326       {
00327         if ( isStorageEnabled() )
00328         {
00329           // resolvables stored in the zypp storage database
00330           std::list<ResObject::Ptr> resolvables = _storage.storedObjects(kind);
00331           for (std::list<ResObject::Ptr>::iterator it = resolvables.begin();
00332                it != resolvables.end();
00333                it++)
00334           {
00335             _store.insert(*it);
00336           }
00337         }
00338         else
00339         {
00340           WAR << "storage target not enabled" << std::endl;
00341         }
00342         _resstore_loaded[kind] = true;
00343       } // end switch
00344     }
00345 
00346     ResStore::resfilter_const_iterator TargetImpl::byKindBegin( const ResObject::Kind & kind_r ) const
00347     {
00348       TargetImpl *ptr = const_cast<TargetImpl *>(this);
00349       ptr->loadKindResolvables(kind_r);
00350       resfilter::ResFilter filter = ByKind(kind_r);
00351       return make_filter_iterator( filter, _store.begin(), _store.end() );
00352     }
00353 
00354     ResStore::resfilter_const_iterator TargetImpl::byKindEnd( const ResObject::Kind & kind_r  ) const
00355     {
00356       TargetImpl *ptr = const_cast<TargetImpl *>(this);
00357       ptr->loadKindResolvables(kind_r);
00358       resfilter::ResFilter filter = ByKind(kind_r);
00359       return make_filter_iterator( filter, _store.end(), _store.end() );
00360     }
00361 
00362     const ResStore & TargetImpl::resolvables()
00363     {
00364       loadKindResolvables( ResTraits<zypp::Patch>::kind );
00365       loadKindResolvables( ResTraits<zypp::Selection>::kind );
00366       loadKindResolvables( ResTraits<zypp::Pattern>::kind );
00367       loadKindResolvables( ResTraits<zypp::Product>::kind );
00368       loadKindResolvables( ResTraits<zypp::Language>::kind );
00369       loadKindResolvables( ResTraits<zypp::Package>::kind );
00370       return _store;
00371     }
00372 
00373     void TargetImpl::reset()
00374     {
00375       // make this smarter later
00376       _store.clear();
00377       _resstore_loaded[ResTraits<zypp::Patch>::kind] = false;
00378       _resstore_loaded[ResTraits<zypp::Selection>::kind] = false;
00379       _resstore_loaded[ResTraits<zypp::Pattern>::kind] = false;
00380       _resstore_loaded[ResTraits<zypp::Product>::kind] = false;
00381       _resstore_loaded[ResTraits<zypp::Language>::kind] = false;
00382       _resstore_loaded[ResTraits<zypp::Package>::kind] = false;
00383     }
00384 
00385     ZYppCommitResult TargetImpl::commit( ResPool pool_r, const ZYppCommitPolicy & policy_rX )
00386     {
00387       // ----------------------------------------------------------------- //
00388       // Fake outstanding YCP fix: Honour restriction to media 1
00389       // at installation, but install all remaining packages if post-boot.
00390       ZYppCommitPolicy policy_r( policy_rX );
00391       if ( policy_r.restrictToMedia() > 1 )
00392         policy_r.allMedia();
00393       // ----------------------------------------------------------------- //
00394 
00395       MIL << "TargetImpl::commit(<pool>, " << policy_r << ")" << endl;
00396       ZYppCommitResult result;
00397 
00398       TargetImpl::PoolItemList to_uninstall;
00399       TargetImpl::PoolItemList to_install;
00400       TargetImpl::PoolItemList to_srcinstall;
00401       {
00402 
00403         pool::GetResolvablesToInsDel
00404         collect( pool_r, policy_r.restrictToMedia() ? pool::GetResolvablesToInsDel::ORDER_BY_MEDIANR
00405                  : pool::GetResolvablesToInsDel::ORDER_BY_SOURCE );
00406         MIL << "GetResolvablesToInsDel: " << endl << collect << endl;
00407         to_uninstall.swap( collect._toDelete );
00408         to_install.swap( collect._toInstall );
00409         to_srcinstall.swap( collect._toSrcinstall );
00410       }
00411 
00412       if ( policy_r.restrictToMedia() )
00413       {
00414         MIL << "Restrict to media number " << policy_r.restrictToMedia() << endl;
00415       }
00416 
00417       commit (to_uninstall, policy_r, pool_r );
00418 
00419       if (policy_r.restrictToMedia() == 0)
00420       {                 // commit all
00421         result._remaining = commit( to_install, policy_r, pool_r );
00422         result._srcremaining = commit( to_srcinstall, policy_r, pool_r );
00423       }
00424       else
00425       {
00426         TargetImpl::PoolItemList current_install;
00427         TargetImpl::PoolItemList current_srcinstall;
00428 
00429         // Collect until the 1st package from an unwanted media occurs.
00430         // Further collection could violate install order.
00431         bool hitUnwantedMedia = false;
00432         for (TargetImpl::PoolItemList::iterator it = to_install.begin(); it != to_install.end(); ++it)
00433         {
00434           ResObject::constPtr res( it->resolvable() );
00435 
00436           if ( hitUnwantedMedia
00437                || ( res->mediaNr() && res->mediaNr() != policy_r.restrictToMedia() ) )
00438           {
00439             hitUnwantedMedia = true;
00440             result._remaining.push_back( *it );
00441           }
00442           else
00443           {
00444             current_install.push_back( *it );
00445           }
00446         }
00447 
00448         TargetImpl::PoolItemList bad = commit( current_install, policy_r, pool_r );
00449         result._remaining.insert(result._remaining.end(), bad.begin(), bad.end());
00450 
00451         for (TargetImpl::PoolItemList::iterator it = to_srcinstall.begin(); it != to_srcinstall.end(); ++it)
00452         {
00453           Resolvable::constPtr res( it->resolvable() );
00454           Package::constPtr pkg( asKind<Package>(res) );
00455           if (pkg && policy_r.restrictToMedia() != pkg->mediaNr()) // check medianr for packages only
00456           {
00457             XXX << "Package " << *pkg << ", wrong media " << pkg->mediaNr() << endl;
00458             result._srcremaining.push_back( *it );
00459           }
00460           else
00461           {
00462             current_srcinstall.push_back( *it );
00463           }
00464         }
00465         bad = commit( current_srcinstall, policy_r, pool_r );
00466         result._srcremaining.insert(result._srcremaining.end(), bad.begin(), bad.end());
00467       }
00468 
00469 
00470       result._result = (to_install.size() - result._remaining.size());
00471       MIL << "TargetImpl::commit(<pool>, " << policy_r << ") returns: " << result << endl;
00472       return result;
00473     }
00474 
00475 
00476     TargetImpl::PoolItemList
00477     TargetImpl::commit( const TargetImpl::PoolItemList & items_r,
00478                         const ZYppCommitPolicy & policy_r,
00479                         const ResPool & pool_r )
00480     {
00481       TargetImpl::PoolItemList remaining;
00482       repo::RepoMediaAccess access;
00483       MIL << "TargetImpl::commit(<list>" << policy_r << ")" << endl;
00484 
00485       bool abort = false;
00486 
00487       // remember the last used source (if any)
00488       Repository lastUsedRepo;
00489 
00490       RepoProvidePackage repoProvidePackage( access, pool_r);
00491       // prepare the package cache.
00492       CommitPackageCache packageCache( items_r.begin(), items_r.end(),
00493                                        root() / "tmp", repoProvidePackage );
00494 
00495       for (TargetImpl::PoolItemList::const_iterator it = items_r.begin(); it != items_r.end(); it++)
00496       {
00497         if (isKind<Package>(it->resolvable()))
00498         {
00499           Package::constPtr p = asKind<Package>(it->resolvable());
00500           if (it->status().isToBeInstalled())
00501           {
00502             ManagedFile localfile;
00503             try
00504             {
00505               localfile = packageCache.get( it );
00506             }
00507             catch ( const SkipRequestException &e )
00508             {
00509               ZYPP_CAUGHT( e );
00510               WAR << "Skipping package " << p << " in commit" << endl;
00511               continue;
00512             }
00513 
00514             lastUsedRepo = p->repository();                     // remember the package source
00515 
00516 #warning Exception handling
00517             // create a installation progress report proxy
00518             RpmInstallPackageReceiver progress( it->resolvable() );
00519             progress.connect();
00520             bool success = true;
00521             unsigned flags = 0;
00522             // Why force and nodeps?
00523             //
00524             // Because zypp builds the transaction and the resolver asserts that
00525             // everything is fine.
00526             // We use rpm just to unpack and register the package in the database.
00527             // We do this step by step, so rpm is not aware of the bigger context.
00528             // So we turn off rpms internal checks, because we do it inside zypp.
00529             flags |= rpm::RpmDb::RPMINST_NODEPS;
00530             flags |= rpm::RpmDb::RPMINST_FORCE;
00531             //
00532             if (p->installOnly()) flags |= rpm::RpmDb::RPMINST_NOUPGRADE;
00533             if (policy_r.dryRun()) flags |= rpm::RpmDb::RPMINST_TEST;
00534             if (policy_r.rpmNoSignature()) flags |= rpm::RpmDb::RPMINST_NOSIGNATURE;
00535 
00536             try
00537             {
00538               progress.tryLevel( target::rpm::InstallResolvableReport::RPM_NODEPS_FORCE );
00539               rpm().installPackage( localfile, flags );
00540 
00541               if ( progress.aborted() )
00542               {
00543                 WAR << "commit aborted by the user" << endl;
00544                 progress.disconnect();
00545                 success = false;
00546                 abort = true;
00547                 break;
00548               }
00549             }
00550             catch (Exception & excpt_r)
00551             {
00552               ZYPP_CAUGHT(excpt_r);
00553               if ( policy_r.dryRun() )
00554               {
00555                 WAR << "dry run failed" << endl;
00556                 progress.disconnect();
00557                 break;
00558               }
00559               // else
00560               WAR << "Install failed" << endl;
00561               remaining.push_back( *it );
00562               success = false;
00563             }
00564 
00565             if ( success && !policy_r.dryRun() )
00566             {
00567               it->status().resetTransact( ResStatus::USER );
00568             }
00569             progress.disconnect();
00570           }
00571           else
00572           {
00573             bool success = true;
00574 
00575             RpmRemovePackageReceiver progress( it->resolvable() );
00576             progress.connect();
00577             unsigned flags = rpm::RpmDb::RPMINST_NODEPS;
00578             if (policy_r.dryRun()) flags |= rpm::RpmDb::RPMINST_TEST;
00579             try
00580             {
00581               rpm().removePackage( p, flags );
00582             }
00583             catch (Exception & excpt_r)
00584             {
00585               WAR << "removal of " << p << " failed";
00586               success = false;
00587               ZYPP_CAUGHT( excpt_r );
00588             }
00589             if (success
00590                 && !policy_r.dryRun())
00591             {
00592               it->status().resetTransact( ResStatus::USER );
00593             }
00594             progress.disconnect();
00595           }
00596         }
00597         else if (!policy_r.dryRun()) // other resolvables (non-Package)
00598         {
00599           if ( isStorageEnabled() )
00600           {
00601             if (it->status().isToBeInstalled())
00602             {
00603               // Process OBSOLETES and remove them from store.
00604               obsoleteMatchesFromStorage( _storage, pool_r, *it );
00605 
00606               bool success = false;
00607               try
00608               {
00609                 if (isKind<Message>(it->resolvable()))
00610                 {
00611                   Message::constPtr m = dynamic_pointer_cast<const Message>(it->resolvable());
00612                   std::string text = m->text().asString();
00613 
00614                   callback::SendReport<target::MessageResolvableReport> report;
00615 
00616                   report->show( m );
00617 
00618                   MIL << "Displaying the text '" << text << "'" << endl;
00619                 }
00620                 else if (isKind<Script>(it->resolvable()))
00621                 {
00622                   ExecuteDoScript( access, asKind<Script>(it->resolvable()) );
00623                 }
00624                 else if (!isKind<Atom>(it->resolvable()))       // atoms are re-created from the patch data, no need to save them
00625                 {
00626                   // #160792 do not just add, also remove older versions
00627                   if (true) // !installOnly - only on Package?!
00628                   {
00629                     // this would delete the same item over and over
00630                     //for (PoolItem_Ref old = Helper::findInstalledItem (pool_r, *it); old; )
00631 #warning REMOVE ALL OLD VERSIONS AND NOT JUST ONE
00632                     PoolItem_Ref old = Helper::findInstalledItem (pool_r, *it);
00633                     if (old)
00634                     {
00635                       _storage.deleteObject(old.resolvable());
00636                     }
00637                   }
00638                   _storage.storeObject(it->resolvable());
00639                 }
00640                 success = true;
00641               }
00642               catch (Exception & excpt_r)
00643               {
00644                 ZYPP_CAUGHT(excpt_r);
00645                 WAR << "Install of Resolvable from storage failed" << endl;
00646               }
00647               if (success)
00648                 it->status().resetTransact( ResStatus::USER );
00649             }
00650             else
00651             {                                   // isToBeUninstalled
00652               bool success = false;
00653               try
00654               {
00655                 if (isKind<Atom>(it->resolvable()))
00656                 {
00657                   DBG << "Uninstalling atom - no-op" << endl;
00658                 }
00659                 else if (isKind<Message>(it->resolvable()))
00660                 {
00661                   DBG << "Uninstalling message - no-op" << endl;
00662                 }
00663                 else if (isKind<Script>(it->resolvable()))
00664                 {
00665                   ExecuteUndoScript( access, asKind<Script>(it->resolvable()) );
00666                 }
00667                 else
00668                 {
00669                   _storage.deleteObject(it->resolvable());
00670                 }
00671                 success = true;
00672               }
00673               catch (Exception & excpt_r)
00674               {
00675                 ZYPP_CAUGHT(excpt_r);
00676                 WAR << "Uninstall of Resolvable from storage failed" << endl;
00677               }
00678               if (success)
00679                 it->status().resetTransact( ResStatus::USER );
00680             }
00681           }
00682           else
00683           {
00684             WAR << "storage target disabled" << std::endl;
00685           }
00686 
00687         }  // other resolvables
00688 
00689       } // for
00690 
00691       // we're done with the commit, release the source media
00692       //   In the case of a single media, end of commit means we don't need _this_
00693       //   media any more.
00694       //   In the case of 'commit any media', end of commit means we're completely
00695       //   done and don't need the source's media anyways.
00696 
00697       if (lastUsedRepo)
00698       {         // if a source was used
00699         //lastUsedRepo.release();       //  release their medias
00700       }
00701 
00702       if ( abort )
00703         ZYPP_THROW( TargetAbortedException( N_("Installation has been aborted as directed.") ) );
00704 
00705       return remaining;
00706     }
00707 
00708     rpm::RpmDb & TargetImpl::rpm()
00709     {
00710       return _rpm;
00711     }
00712 
00713     bool TargetImpl::providesFile (const std::string & path_str, const std::string & name_str) const
00714     {
00715       return _rpm.hasFile(path_str, name_str);
00716     }
00717 
00720     ResObject::constPtr TargetImpl::whoOwnsFile (const std::string & path_str) const
00721     {
00722       string name = _rpm.whoOwnsFile (path_str);
00723       if (name.empty())
00724         return NULL;
00725 
00726       for (ResStore::const_iterator it = _store.begin(); it != _store.end(); ++it)
00727       {
00728         if ((*it)->name() == name)
00729         {
00730           return *it;
00731         }
00732       }
00733       return NULL;
00734     }
00735 
00737     bool TargetImpl::setInstallationLogfile(const Pathname & path_r)
00738     {
00739       CommitLog::setFname(path_r);
00740       return true;
00741     }
00742 
00743     Date TargetImpl::timestamp() const
00744     {
00745       Date ts_rpm;
00746       Date ts_store;
00747 
00748       ts_rpm = _rpm.timestamp();
00749 
00750       if ( isStorageEnabled() )
00751         ts_store = _storage.timestamp();
00752 
00753       if ( ts_rpm > ts_store )
00754       {
00755         return ts_rpm;
00756       }
00757       else if (ts_rpm < ts_store)
00758       {
00759         return ts_store;
00760       }
00761       else
00762       {
00763         // they are the same
00764         if ( ts_rpm != 0 )
00765           return ts_rpm;
00766         else
00767           return Date::now();
00768       }
00769     }
00770 
00771     void TargetImpl::installSrcPackage( const SrcPackage_constPtr & srcPackage_r )
00772     {
00773       // provide on local disk
00774       repo::RepoMediaAccess access_r;
00775       repo::SrcPackageProvider prov( access_r );
00776       ManagedFile localfile = prov.provideSrcPackage( srcPackage_r );
00777       // install it
00778       rpm().installPackage ( localfile );
00779     }
00780 
00782   } // namespace target
00785 } // namespace zypp

Generated on Tue Sep 25 19:23:10 2007 for libzypp by  doxygen 1.5.3