Mailinglist Archive: zypp-devel (115 mails)
| < Previous | Next > |
Re: [zypp-devel] [PATCH] repo media handling and verifiers for review
- From: "Duncan Mac-Vicar P." <dmacvicar@xxxxxxx>
- Date: Tue, 24 Jul 2007 00:55:01 +0200
- Message-id: <200707240055.01844.dmacvicar@xxxxxxx>
sorry, I sent the reversed patch, here is the real patch
diff --git a/zypp/RepoInfo.cc b/zypp/RepoInfo.cc
index 3771e8d..f57d44d 100644
--- a/zypp/RepoInfo.cc
+++ b/zypp/RepoInfo.cc
@@ -54,6 +54,7 @@ namespace zypp
std::string alias;
std::string name;
Pathname filepath;
+ Pathname metadatapath;
public:
private:
@@ -167,6 +168,12 @@ namespace zypp
_pimpl->filepath = filepath;
return *this;
}
+
+ RepoInfo & RepoInfo::setMetadataPath( const Pathname &path )
+ {
+ _pimpl->metadatapath = path;
+ return *this;
+ }
tribool RepoInfo::enabled() const
{ return _pimpl->enabled; }
@@ -186,6 +193,9 @@ namespace zypp
Pathname RepoInfo::filepath() const
{ return _pimpl->filepath; }
+ Pathname RepoInfo::metadataPath() const
+ { return _pimpl->metadatapath; }
+
repo::RepoType RepoInfo::type() const
{ return _pimpl->type; }
diff --git a/zypp/RepoInfo.h b/zypp/RepoInfo.h
index 5956e86..0afdf29 100644
--- a/zypp/RepoInfo.h
+++ b/zypp/RepoInfo.h
@@ -174,6 +174,14 @@ namespace zypp
* infos created in memory.
*/
Pathname filepath() const;
+
+ /**
+ * \short Path where this repo metadata was read from
+ *
+ * \note could be an empty pathname for repo
+ * infos created in memory.
+ */
+ Pathname metadataPath() const;
/**
* \short Whether to check or not this repository with gpg
@@ -260,6 +268,16 @@ namespace zypp
* \param path File path
*/
RepoInfo & setFilepath( const Pathname &filename );
+
+ /**
+ * \short set the path where the local metadata is stored
+ *
+ * The path to the metadata of this repository
+ * was defined, or empty if nowhere.
+ *
+ * \param path directory path
+ */
+ RepoInfo & setMetadataPath( const Pathname &path );
/**
* \short Whether to check or not this repository with gpg
diff --git a/zypp/RepoManager.cc b/zypp/RepoManager.cc
index 70c48c4..b06d962 100644
--- a/zypp/RepoManager.cc
+++ b/zypp/RepoManager.cc
@@ -253,7 +253,18 @@ namespace zypp
MIL << endl;
if ( PathInfo(_pimpl->options.knownReposPath).isExist() )
- return repositories_in_dir(_pimpl->options.knownReposPath);
+ {
+ RepoInfoList repos = repositories_in_dir(_pimpl->options.knownReposPath);
+ for ( RepoInfoList::iterator it = repos.begin();
+ it != repos.end();
+ ++it )
+ {
+ // set the metadata path for the repo
+ Pathname metadata_path = rawcache_path_for_repoinfo(_pimpl->options, (*it));
+ (*it).setMetadataPath(metadata_path);
+ }
+ return repos;
+ }
else
return std::list<RepoInfo>();
@@ -833,8 +844,7 @@ namespace zypp
{
ZYPP_THROW(RepoException("Can't delete " + todelete.filepath().asString()));
}
- MIL << todelete.alias() << " sucessfully deleted." << endl;
- return;
+ MIL << todelete.alias() << " sucessfully deleted." << endl;
}
else
{
@@ -858,17 +868,19 @@ namespace zypp
if ( (*fit).alias() != todelete.alias() )
(*fit).dumpRepoOn(file);
}
+ }
- cache::CacheStore store(_pimpl->options.repoCachePath);
-
- if ( store.isCached( todelete.alias() ) ) {
- MIL << "repository was cached. cleaning cache" << endl;
- store.cleanRepository(todelete.alias());
- }
+ // now delete it from cache
+ cache::CacheStore store(_pimpl->options.repoCachePath);
- MIL << todelete.alias() << " sucessfully deleted." << endl;
- return;
+ if ( store.isCached( todelete.alias() ) ) {
+ MIL << "repository was cached. cleaning cache" << endl;
+ store.cleanRepository(todelete.alias());
+ store.commit();
}
+
+ MIL << todelete.alias() << " sucessfully deleted." << endl;
+ return;
} // else filepath is empty
}
diff --git a/zypp/repo/PackageProvider.cc b/zypp/repo/PackageProvider.cc
index b935892..633518f 100644
--- a/zypp/repo/PackageProvider.cc
+++ b/zypp/repo/PackageProvider.cc
@@ -71,13 +71,15 @@ namespace zypp
/////////////////////////////////////////////////////////////////
} // namespace source
///////////////////////////////////////////////////////////////////
- PackageProvider::PackageProvider( const Package::constPtr & package,
+ PackageProvider::PackageProvider( RepoMediaAccess &access,
+ const Package::constPtr & package,
const DeltaCandidates & deltas,
const PackageProviderPolicy & policy_r )
: _policy( policy_r )
, _package( package )
, _implPtr( detail::ImplConnect::resimpl( _package ) )
, _deltas(deltas)
+ , _access(access)
{}
PackageProvider::~PackageProvider()
@@ -186,8 +188,7 @@ namespace zypp
ProvideFilePolicy policy;
policy.progressCB( bind( &PackageProvider::progressPackageDownload, this, _1 ) );
policy.failOnChecksumErrorCB( bind( &PackageProvider::failOnChecksumError, this ) );
-
- return repo::provideFile( _package->repository(), loc, policy );
+ return _access.provideFile( _package->repository(), loc, policy );
}
ManagedFile PackageProvider::tryDelta( const DeltaRpm & delta_r ) const
@@ -206,7 +207,7 @@ namespace zypp
{
ProvideFilePolicy policy;
policy.progressCB( bind( &PackageProvider::progressDeltaDownload, this, _1 ) );
- delta = repo::provideFile( _package->repository(), delta_r.location(), policy );
+ delta = _access.provideFile( _package->repository(), delta_r.location(), policy );
}
catch ( const Exception & excpt )
{
@@ -257,7 +258,7 @@ namespace zypp
{
ProvideFilePolicy policy;
policy.progressCB( bind( &PackageProvider::progressPatchDownload, this, _1 ) );
- patch = repo::provideFile( _package->repository(), patch_r.location(), policy );
+ patch = _access.provideFile( _package->repository(), patch_r.location(), policy );
}
catch ( const Exception & excpt )
{
diff --git a/zypp/repo/PackageProvider.h b/zypp/repo/PackageProvider.h
index 14265f2..28b5e07 100644
--- a/zypp/repo/PackageProvider.h
+++ b/zypp/repo/PackageProvider.h
@@ -20,7 +20,7 @@
#include "zypp/Repository.h"
#include "zypp/Package.h"
#include "zypp/ManagedFile.h"
-
+#include "zypp/repo/RepoProvideFile.h"
#include "zypp/repo/DeltaCandidates.h"
///////////////////////////////////////////////////////////////////
@@ -74,7 +74,8 @@ namespace zypp
public:
/** Ctor taking the Package to provide. */
- PackageProvider( const Package::constPtr & package,
+ PackageProvider( RepoMediaAccess &access,
+ const Package::constPtr & package,
const DeltaCandidates & deltas,
const PackageProviderPolicy & policy_r = PackageProviderPolicy() );
~PackageProvider();
@@ -107,6 +108,7 @@ namespace zypp
mutable bool _retry;
mutable shared_ptr<Report> _report;
DeltaCandidates _deltas;
+ RepoMediaAccess &_access;
};
///////////////////////////////////////////////////////////////////
diff --git a/zypp/repo/RepoProvideFile.cc b/zypp/repo/RepoProvideFile.cc
index 3e22b25..df6163c 100644
--- a/zypp/repo/RepoProvideFile.cc
+++ b/zypp/repo/RepoProvideFile.cc
@@ -16,9 +16,13 @@
#include "zypp/base/Gettext.h"
#include "zypp/base/Logger.h"
+#include "zypp/base/String.h"
#include "zypp/repo/RepoProvideFile.h"
#include "zypp/ZYppCallbacks.h"
#include "zypp/MediaSetAccess.h"
+#include "zypp/ZConfig.h"
+#include "zypp/repo/SUSEMediaVerifier.h"
+#include "zypp/repo/RepoException.h"
using std::endl;
using std::set;
@@ -46,10 +50,10 @@ namespace zypp
*/
struct DownloadFileReportHack : public callback::ReceiveReport<repo::RepoReport>
{
- virtual bool progress( int value )
+ virtual bool progress( const ProgressData &progress )
{
if ( _redirect )
- return _redirect( value );
+ return _redirect( progress.val() );
return true;
}
function<bool ( int )> _redirect;
@@ -63,6 +67,126 @@ namespace zypp
const OnMediaLocation & loc_r,
const ProvideFilePolicy & policy_r )
{
+ RepoMediaAccess access;
+ return access.provideFile(repo_r, loc_r, policy_r );
+ }
+
+ class RepoMediaAccess::Impl
+ {
+ public:
+ Impl()
+ {}
+
+ ~Impl()
+ {
+ std::map<Url, shared_ptr<MediaSetAccess> >::iterator it;
+ for ( it = _medias.begin();
+ it != _medias.end();
+ ++it )
+ {
+ it->second->release();
+ }
+ }
+
+ shared_ptr<MediaSetAccess> mediaAccessForUrl( const Url &url )
+ {
+ std::map<Url, shared_ptr<MediaSetAccess> >::const_iterator it;
+ it = _medias.find(url);
+ shared_ptr<MediaSetAccess> media;
+ if ( it != _medias.end() )
+ {
+ media = it->second;
+ }
+ else
+ {
+ media.reset( new MediaSetAccess(url) );
+ _medias[url] = media;
+ }
+ return media;
+ }
+
+ void setVerifierForRepo( Repository repo, shared_ptr<MediaSetAccess> media )
+ {
+ RepoInfo info = repo.info();
+ // set a verifier if the repository has it
+ Pathname mediafile = info.metadataPath() + "/media.1/media";
+ if ( ! mediafile.empty() )
+ {
+ if ( PathInfo(mediafile).isExist() )
+ {
+ std::map<shared_ptr<MediaSetAccess>, Repository>::const_iterator it;
+ it = _verifier.find(media);
+ if ( it != _verifier.end() )
+ {
+ if ( it->second == repo )
+ {
+ // this media is already using this repo verifier
+ return;
+ }
+ }
+
+ std::ifstream str(mediafile.asString().c_str());
+ std::string vendor;
+ std::string mediaid;
+ std::string buffer;
+ if ( str )
+ {
+ getline(str, vendor);
+ getline(str, mediaid);
+ getline(str, buffer);
+
+ unsigned media_nr = str::strtonum<unsigned>(buffer);
+ MIL << "Repository '" << info.alias() << "' has " << media_nr << " medias"<< endl;
+
+ for ( int i=1; i <= media_nr; ++i )
+ {
+ media::MediaVerifierRef verifier( new repo::SUSEMediaVerifier(vendor,
+ mediaid,
+ media_nr));
+
+ media->setVerifier( i, verifier);
+ }
+ _verifier[media] = repo;
+ }
+ else
+ {
+ ZYPP_THROW(RepoMetadataException(info));
+ }
+ }
+ else
+ {
+ WAR << "No media verifier for repo '" << info.alias() << endl;
+ }
+ }
+ else
+ {
+ MIL << "Unknown metadata path for repo '" << info.alias() << "'. Can't set media verifier."<< endl;
+ }
+ }
+
+ std::map<shared_ptr<MediaSetAccess>, Repository> _verifier;
+ std::map<Url, shared_ptr<MediaSetAccess> > _medias;
+ };
+
+
+
+ RepoMediaAccess::RepoMediaAccess()
+ : _impl( new Impl() )
+ {
+
+ }
+
+ RepoMediaAccess::~RepoMediaAccess()
+ {
+
+ }
+
+
+
+ ManagedFile RepoMediaAccess::provideFile( Repository repo_r,
+ const OnMediaLocation & loc_r,
+ const ProvideFilePolicy & policy_r )
+ {
MIL << "provideFile " << loc_r << endl;
// Arrange DownloadFileReportHack to recieve the source::DownloadFileReport
// and redirect download progress triggers to call the ProvideFilePolicy
@@ -77,7 +201,7 @@ namespace zypp
set<Url> urls = info.baseUrls();
if ( urls.empty() )
ZYPP_THROW(Exception(_("No url in repository.")));
-
+
for ( RepoInfo::urls_const_iterator it = urls.begin();
it != urls.end();
++it )
@@ -85,10 +209,12 @@ namespace zypp
url = *it;
try
{
+ MIL << "Providing file of repo '" << info.alias()
+ << "' from " << url << endl;
+ shared_ptr<MediaSetAccess> access = _impl->mediaAccessForUrl(url);
+ _impl->setVerifierForRepo(repo_r, access);
- MediaSetAccess access(url);
-
- ManagedFile ret( access.provideFile(loc_r) );
+ ManagedFile ret( access->provideFile(loc_r) );
std::string scheme( url.getScheme() );
if ( scheme == "http" || scheme == "https" || scheme == "ftp" )
@@ -136,7 +262,10 @@ namespace zypp
}
} // iteration over urls
- ZYPP_THROW(Exception(_("No more urls in repository.")));
+ ZYPP_THROW(Exception(str::form(_("Can't provide file %s from repository %s"),
+ loc_r.filename().c_str(),
+ info.alias().c_str() ) ) );
+
return ManagedFile(); // not reached
}
diff --git a/zypp/repo/RepoProvideFile.h b/zypp/repo/RepoProvideFile.h
index b5d838c..f5a0bbb 100644
--- a/zypp/repo/RepoProvideFile.h
+++ b/zypp/repo/RepoProvideFile.h
@@ -14,6 +14,7 @@
#include <iosfwd>
+#include "zypp/base/PtrTypes.h"
#include "zypp/base/Function.h"
#include "zypp/base/Functional.h"
#include "zypp/Repository.h"
@@ -46,6 +47,39 @@ namespace zypp
const OnMediaLocation & loc_r,
const ProvideFilePolicy & policy_r = ProvideFilePolicy() );
+ /**
+ * \short Provides files from different repos
+ *
+ * Class that allows to get files from repositories
+ * It handles automatically setting media verifiers if the
+ * repo is cached, and reuses media set access opened for
+ * repositories during its scope, so you can provide
+ * files from different repositories in different order
+ * without opening and closing medias all the time
+ */
+ class RepoMediaAccess
+ {
+ public:
+ RepoMediaAccess();
+ ~RepoMediaAccess();
+
+ /** Provide a file from a Repository.
+ * Let \a source_r provide the file described by \a loc_r. In case
+ * \a loc_r contains a checksum, the file is verified. \a policy_r
+ * provides callback hooks for download progress reporting and behaviour
+ * on failed checksum verification.
+ *
+ * \throws Exception
+ */
+ ManagedFile provideFile( Repository repo_r,
+ const OnMediaLocation & loc_r,
+ const ProvideFilePolicy & policy_r = ProvideFilePolicy() );
+ private:
+ class Impl;
+ RW_pointer<Impl> _impl;
+
+ };
+
/////////////////////////////////////////////////////////////////
} // namespace repo
///////////////////////////////////////////////////////////////////
diff --git a/zypp/repo/SUSEMediaVerifier.cc b/zypp/repo/SUSEMediaVerifier.cc
index 3b84c3f..1a91de6 100644
--- a/zypp/repo/SUSEMediaVerifier.cc
+++ b/zypp/repo/SUSEMediaVerifier.cc
@@ -25,7 +25,8 @@ SUSEMediaVerifier::SUSEMediaVerifier(const std::string & vendor_r,
, _media_nr(media_nr)
{}
-SUSEMediaVerifier::SUSEMediaVerifier( const Pathname &path_r )
+SUSEMediaVerifier::SUSEMediaVerifier( int media_nr, const Pathname &path_r )
+ : _media_nr(media_nr)
{
std::ifstream str(path_r.asString().c_str());
std::string vendor;
diff --git a/zypp/repo/SUSEMediaVerifier.h b/zypp/repo/SUSEMediaVerifier.h
index f778c68..b415c33 100644
--- a/zypp/repo/SUSEMediaVerifier.h
+++ b/zypp/repo/SUSEMediaVerifier.h
@@ -40,8 +40,10 @@ namespace zypp
/**
* \short creates a verifier from a media file
+ *
+ * \param path_r Path to media.1/media kind file
*/
- SUSEMediaVerifier( const Pathname &path_r );
+ SUSEMediaVerifier( int media_nr, const Pathname &path_r );
/**
* \short Check if it is the desider media
diff --git a/zypp/target/TargetImpl.cc b/zypp/target/TargetImpl.cc
index 7c50143..9f8ba72 100644
--- a/zypp/target/TargetImpl.cc
+++ b/zypp/target/TargetImpl.cc
@@ -229,8 +229,10 @@ namespace zypp
struct RepoProvidePackage
{
ResPool _pool;
- RepoProvidePackage( ResPool pool_r )
- : _pool(pool_r)
+ repo::RepoMediaAccess &_access;
+
+ RepoProvidePackage( repo::RepoMediaAccess &access, ResPool pool_r )
+ : _pool(pool_r), _access(access)
{
}
@@ -256,7 +258,7 @@ namespace zypp
}
repo::DeltaCandidates deltas(repos);
- repo::PackageProvider pkgProvider( p, deltas, packageProviderPolicy );
+ repo::PackageProvider pkgProvider( _access, p, deltas, packageProviderPolicy );
return pkgProvider.providePackage();
}
};
@@ -487,7 +489,7 @@ namespace zypp
const ResPool & pool_r )
{
TargetImpl::PoolItemList remaining;
-
+ repo::RepoMediaAccess access;
MIL << "TargetImpl::commit(<list>" << policy_r << ")" << endl;
bool abort = false;
@@ -495,7 +497,7 @@ namespace zypp
// remember the last used source (if any)
Repository lastUsedRepo;
- RepoProvidePackage repoProvidePackage(pool_r);
+ RepoProvidePackage repoProvidePackage( access, pool_r);
// prepare the package cache.
CommitPackageCache packageCache( items_r.begin(), items_r.end(),
root() / "tmp", repoProvidePackage );
| < Previous | Next > |