From 3f0cdb730268710b47633e1e06fe6caeda60fe2e Mon Sep 17 00:00:00 2001 From: Duncan Mac-Vicar P Date: Mon, 18 Jun 2007 16:05:43 +0000 Subject: [PATCH] backup implementing smart refresh, addding and deletion of repos --- zypp/RepoManager.cc | 86 ++++++++++++++++++++++++++++++++++++++-- zypp/RepoManager.h | 15 ++++++- zypp/RepoStatus.cc | 9 ++++- zypp/RepoStatus.h | 9 +++++ zypp/cache/CacheStore.cc | 6 +-- zypp/parser/IniDict.cc | 25 ++++++++++++ zypp/parser/IniDict.h | 26 ++++++++++-- zypp/parser/RepoFileReader.cc | 2 +- zypp/repo/susetags/Downloader.cc | 7 ++++ zypp/repo/susetags/Downloader.h | 5 +++ zypp/repo/yum/Downloader.cc | 6 +++ zypp/repo/yum/Downloader.h | 6 +++ 12 files changed, 188 insertions(+), 14 deletions(-) diff --git a/zypp/RepoManager.cc b/zypp/RepoManager.cc index d121ebd..7b0fd87 100644 --- a/zypp/RepoManager.cc +++ b/zypp/RepoManager.cc @@ -253,12 +253,52 @@ namespace zypp //////////////////////////////////////////////////////////////////////////// + RepoStatus RepoManager::rawMetadataStatus( const RepoInfo &info ) + { + Pathname rawpath = rawcache_path_for_repoinfo( _pimpl->options, info ); + RepoType repokind = info.type(); + switch ( repokind.toEnum() ) + { + case RepoType::NONE_e: + // unknown, probe the local metadata + repokind = probe(Url(rawpath.asString())); + break; + default: + break; + } + + switch ( repokind.toEnum() ) + { + case RepoType::RPMMD_e : + { + return RepoStatus( rawpath + "/repodata/repomd.xml"); + } + break; + case RepoType::YAST2_e : + { + return RepoStatus( rawpath + "/content"); + } + break; + default: + ZYPP_THROW(RepoUnknownTypeException()); + } + } + + RepoStatus RepoManager::cacheStatus( const RepoInfo &info ) + { + return RepoStatus(); + } + + void RepoManager::refreshMetadata( const RepoInfo &info, + RepoRefreshPolicy policy, const ProgressData::ReceiverFnc & progress ) { assert_alias(info); assert_urls(info); + RepoStatus oldstatus; + RepoStatus newstatus; // try urls one by one for ( RepoInfo::urls_const_iterator it = info.baseUrlsBegin(); it != info.baseUrlsEnd(); ++it ) { @@ -278,19 +318,51 @@ namespace zypp break; } + Pathname rawpath = rawcache_path_for_repoinfo( _pimpl->options, info ); + oldstatus = rawMetadataStatus(info); + switch ( repokind.toEnum() ) { case RepoType::RPMMD_e : { yum::Downloader downloader( url, "/" ); - downloader.download(tmpdir.path()); + + RepoStatus newstatus = downloader.status(); + bool refresh = false; + if ( oldstatus.checksum() == newstatus.checksum() ) + { + MIL << "repo has not changed" << endl; + if ( policy == RefreshForced ) + { + MIL << "refresh set to forced" << endl; + refresh = true; + } + } + + if ( refresh ) + downloader.download(tmpdir.path()); + // no error } break; case RepoType::YAST2_e : { susetags::Downloader downloader( url, "/" ); - downloader.download(tmpdir.path()); + + RepoStatus newstatus = downloader.status(); + bool refresh = false; + if ( oldstatus.checksum() == newstatus.checksum() ) + { + MIL << "repo has not changed" << endl; + if ( policy == RefreshForced ) + { + MIL << "refresh set to forced" << endl; + refresh = true; + } + } + + if ( refresh ) + downloader.download(tmpdir.path()); // no error } break; @@ -300,7 +372,6 @@ namespace zypp // ok we have the metadata, now exchange // the contents - Pathname rawpath = rawcache_path_for_repoinfo(_pimpl->options, info); TmpDir oldmetadata; filesystem::assert_dir(rawpath); filesystem::rename( rawpath, oldmetadata.path() ); @@ -322,6 +393,7 @@ namespace zypp //////////////////////////////////////////////////////////////////////////// void RepoManager::buildCache( const RepoInfo &info, + CacheBuildPolicy policy, const ProgressData::ReceiverFnc & progress ) { assert_alias(info); @@ -372,6 +444,9 @@ namespace zypp ZYPP_THROW(RepoUnknownTypeException()); } + // update timestamp and checksum + //store.updateRepository(id, ) + MIL << "Commit cache.." << endl; store.commit(); } @@ -476,8 +551,11 @@ namespace zypp int counter = 1; while ( PathInfo(_pimpl->options.knownReposPath + filename).isExist() ) { - filename = Pathname( filename.asString() ); + filename = Pathname( filename.asString() + "_" + str::numstring(counter)); + counter++; } + // now we have a filename that does not exists + } //////////////////////////////////////////////////////////////////////////// diff --git a/zypp/RepoManager.h b/zypp/RepoManager.h index 9056482..9512a4c 100644 --- a/zypp/RepoManager.h +++ b/zypp/RepoManager.h @@ -24,6 +24,7 @@ #include "zypp/RepoInfo.h" #include "zypp/repo/RepoException.h" #include "zypp/repo/RepoType.h" +#include "zypp/RepoStatus.h" #include "zypp/ProgressData.h" /////////////////////////////////////////////////////////////////// @@ -75,10 +76,16 @@ namespace zypp enum RepoRefreshPolicy { - RefreshIfChanged, + RefreshIfNeeded, RefreshForced }; + enum CacheBuildPolicy + { + BuildIfNeeded, + BuildForced + }; + enum RepoAddPolicy { }; @@ -107,6 +114,7 @@ namespace zypp * \throws Exception on unknown error. */ void refreshMetadata( const RepoInfo &info, + RepoRefreshPolicy policy = RefreshIfNeeded, const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() ); /** @@ -134,6 +142,7 @@ namespace zypp * \throws Exception on unknown error. */ void buildCache( const RepoInfo &info, + CacheBuildPolicy policy = BuildIfNeeded, const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() ); /** @@ -205,6 +214,10 @@ namespace zypp void removeRepository( const std::string & alias, const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() ); + RepoStatus rawMetadataStatus( const RepoInfo &info ); + RepoStatus cacheStatus( const RepoInfo &info ); + + public: private: diff --git a/zypp/RepoStatus.cc b/zypp/RepoStatus.cc index 3d54d6d..6d77fcc 100644 --- a/zypp/RepoStatus.cc +++ b/zypp/RepoStatus.cc @@ -12,7 +12,7 @@ #include //#include "zypp/base/Logger.h" #include "zypp/RepoStatus.h" - +#include "zypp/PathInfo.h" using namespace std; @@ -66,7 +66,7 @@ namespace zypp // METHOD TYPE : Ctor // RepoStatus::RepoStatus() - : _pimpl( Impl::nullimpl() ) + : _pimpl( new Impl() ) {} /////////////////////////////////////////////////////////////////// @@ -77,6 +77,11 @@ namespace zypp RepoStatus::~RepoStatus() {} + RepoStatus::RepoStatus( const Pathname &path ) + { + _pimpl->checksum = filesystem::sha1sum(path); + } + RepoStatus & RepoStatus::setChecksum( const string &checksum ) { _pimpl->checksum = checksum; diff --git a/zypp/RepoStatus.h b/zypp/RepoStatus.h index a4faffe..87c6b9c 100644 --- a/zypp/RepoStatus.h +++ b/zypp/RepoStatus.h @@ -73,6 +73,15 @@ namespace zypp public: /** Default ctor */ RepoStatus(); + + /** + * \short Status from a single file + * As most repository state is represented + * by the status of the index file, you can + * construct the status from a file. + */ + RepoStatus( const Pathname &file ); + /** Dtor */ ~RepoStatus(); diff --git a/zypp/cache/CacheStore.cc b/zypp/cache/CacheStore.cc index 2a6999d..a5d55bc 100644 --- a/zypp/cache/CacheStore.cc +++ b/zypp/cache/CacheStore.cc @@ -717,8 +717,8 @@ RecordId CacheStore::lookupOrAppendFile( const Pathname &path ) } void CacheStore::updateRepository( const RecordId &id, - const string &checksum, - const Date ×tamp ) + const string &checksum, + const Date ×tamp ) { _pimpl->update_repository_cmd->bind(":repository_id", id); _pimpl->update_repository_cmd->bind(":checksum", checksum); @@ -782,7 +782,7 @@ RepoStatus CacheStore::repositoryStatus( const data::RecordId &id ) { sqlite3_reader reader = cmd.executereader(); RepoStatus status; - while ( reader.read() ) + if ( reader.read() ) { status.setChecksum( reader.getstring(2) ); status.setTimestamp( reader.getstring(3) ); diff --git a/zypp/parser/IniDict.cc b/zypp/parser/IniDict.cc index 8e83671..44ad08d 100644 --- a/zypp/parser/IniDict.cc +++ b/zypp/parser/IniDict.cc @@ -91,7 +91,19 @@ namespace zypp { return make_map_key_end( _dict ); } + + void IniDict::insertEntry( const std::string §ion, + const std::string &key, + const std::string &value ) + { + consume( section, key, value ); + } + void IniDict::deleteSection( const std::string §ion ) + { + _dict.erase(section); + } + /****************************************************************** ** ** FUNCTION NAME : operator<< @@ -99,6 +111,19 @@ namespace zypp */ std::ostream & operator<<( std::ostream & str, const IniDict & obj ) { + for ( IniDict::section_const_iterator si = obj.sectionsBegin(); + si != obj.sectionsEnd(); + ++si ) + { + str << "[" << *si << "]" << endl; + for ( IniDict::entry_const_iterator ei = obj.entriesBegin(*si); + ei != obj.entriesEnd(*si); + ++ei ) + { + str << ei->first << " = " << ei->second << endl; + } + str << endl; + } return str; } diff --git a/zypp/parser/IniDict.h b/zypp/parser/IniDict.h index 1c7b1d1..1e87f57 100644 --- a/zypp/parser/IniDict.h +++ b/zypp/parser/IniDict.h @@ -85,21 +85,41 @@ namespace zypp * Creates a dictionary from a InputStream * containing a ini structured file */ - IniDict( const InputStream &is, const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc() ); + IniDict( const InputStream &is, + const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc() ); /** Dtor */ ~IniDict(); + /** + * \short add an entry + * \param section + * \param key + * \param value + */ + void insertEntry( const std::string §ion, + const std::string &key, + const std::string &value ); + + /** + * \short add an entry + * \param section + * \param key + * \param value + */ + void deleteSection( const std::string §ion ); + public: /** Called when a section is found. */ virtual void consume( const std::string §ion ); /** Called when a key value is found. */ - virtual void consume( const std::string §ion, const std::string &key, const std::string &value ); + virtual void consume( const std::string §ion, + const std::string &key, + const std::string &value ); private: SectionSet _dict; - /** * empty map used to simulate * iteration in non existant diff --git a/zypp/parser/RepoFileReader.cc b/zypp/parser/RepoFileReader.cc index 3a59ec4..92a4266 100644 --- a/zypp/parser/RepoFileReader.cc +++ b/zypp/parser/RepoFileReader.cc @@ -61,7 +61,7 @@ namespace zypp else if ( it->first == "type" ) info.setType(repo::RepoType(it->second)); } - + info.setFilepath(file); // add it to the list. callback(info); //if (!progress.tick()) diff --git a/zypp/repo/susetags/Downloader.cc b/zypp/repo/susetags/Downloader.cc index 80b1af9..6a7fbf6 100644 --- a/zypp/repo/susetags/Downloader.cc +++ b/zypp/repo/susetags/Downloader.cc @@ -23,6 +23,13 @@ Downloader::Downloader( const Url &url, const Pathname &path ) } +RepoStatus Downloader::status() +{ + MediaSetAccess media(_url, _path); + Pathname content = media.provideFile("/content"); + return RepoStatus(content); +} + void Downloader::download( const Pathname &dest_dir, const ProgressData::ReceiverFnc & progress ) { diff --git a/zypp/repo/susetags/Downloader.h b/zypp/repo/susetags/Downloader.h index 707e46f..07f4289 100644 --- a/zypp/repo/susetags/Downloader.h +++ b/zypp/repo/susetags/Downloader.h @@ -13,6 +13,7 @@ #include "zypp/Url.h" #include "zypp/Pathname.h" #include "zypp/ProgressData.h" +#include "zypp/RepoStatus.h" namespace zypp { @@ -27,6 +28,10 @@ namespace zypp Downloader( const Url &url, const Pathname &path ); void download( const Pathname &dest_dir, const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc() ); + /** + * \short Status of the remote repository + */ + RepoStatus status(); private: Url _url; Pathname _path; diff --git a/zypp/repo/yum/Downloader.cc b/zypp/repo/yum/Downloader.cc index fd89098..1b9d6fa 100644 --- a/zypp/repo/yum/Downloader.cc +++ b/zypp/repo/yum/Downloader.cc @@ -35,6 +35,12 @@ Downloader::Downloader( const Url &url, const Pathname &path ) { } +RepoStatus Downloader::status() +{ + Pathname repomd = _media.provideFile("/repodata/repomd.xml"); + return RepoStatus(repomd); +} + bool Downloader::patches_Callback( const OnMediaLocation &loc, const string &id ) { MIL << id << " : " << loc << endl; diff --git a/zypp/repo/yum/Downloader.h b/zypp/repo/yum/Downloader.h index 5d89350..23184e3 100644 --- a/zypp/repo/yum/Downloader.h +++ b/zypp/repo/yum/Downloader.h @@ -18,6 +18,7 @@ #include "zypp/parser/xml/Reader.h" #include "zypp/repo/yum/ResourceType.h" #include "zypp/ProgressData.h" +#include "zypp/RepoStatus.h" namespace zypp { @@ -48,6 +49,11 @@ namespace zypp void download( const Pathname &dest_dir, const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc() ); + /** + * \short Status of the remote repository + */ + RepoStatus status(); + protected: bool repomd_Callback( const OnMediaLocation &loc, const ResourceType &dtype ); bool patches_Callback( const OnMediaLocation &loc, const std::string &id ); -- 2.7.4