backup implementing smart refresh, addding and deletion of repos
authorDuncan Mac-Vicar P <dmacvicar@suse.de>
Mon, 18 Jun 2007 16:05:43 +0000 (16:05 +0000)
committerDuncan Mac-Vicar P <dmacvicar@suse.de>
Mon, 18 Jun 2007 16:05:43 +0000 (16:05 +0000)
12 files changed:
zypp/RepoManager.cc
zypp/RepoManager.h
zypp/RepoStatus.cc
zypp/RepoStatus.h
zypp/cache/CacheStore.cc
zypp/parser/IniDict.cc
zypp/parser/IniDict.h
zypp/parser/RepoFileReader.cc
zypp/repo/susetags/Downloader.cc
zypp/repo/susetags/Downloader.h
zypp/repo/yum/Downloader.cc
zypp/repo/yum/Downloader.h

index d121ebd..7b0fd87 100644 (file)
@@ -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
+    
   }
   
   ////////////////////////////////////////////////////////////////////////////
index 9056482..9512a4c 100644 (file)
@@ -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:
index 3d54d6d..6d77fcc 100644 (file)
@@ -12,7 +12,7 @@
 #include <iostream>
 //#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;
index a4faffe..87c6b9c 100644 (file)
@@ -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();
 
index 2a6999d..a5d55bc 100644 (file)
@@ -717,8 +717,8 @@ RecordId CacheStore::lookupOrAppendFile( const Pathname &path )
 }
 
 void CacheStore::updateRepository( const RecordId &id,
-                    const string &checksum,
-                    const Date &timestamp )
+                                   const string &checksum,
+                                   const Date &timestamp )
 {
   _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) );
index 8e83671..44ad08d 100644 (file)
@@ -91,7 +91,19 @@ namespace zypp
     {
       return make_map_key_end( _dict );
     }
+    
+    void IniDict::insertEntry( const std::string &section,
+                               const std::string &key,
+                               const std::string &value )
+    {
+      consume( section, key, value );
+    }
       
+    void IniDict::deleteSection( const std::string &section )
+    {
+      _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;
     }
 
index 1c7b1d1..1e87f57 100644 (file)
@@ -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 &section,
+                        const std::string &key,
+                        const std::string &value );
+      
+      /**
+       * \short add an entry
+       * \param section
+       * \param key
+       * \param value
+       */
+      void deleteSection( const std::string &section );
+
     public:
 
       /** Called when a section is found. */
       virtual void consume( const std::string &section );
       /** Called when a key value is found. */
-      virtual void consume( const std::string &section, const std::string &key, const std::string &value );
+      virtual void consume( const std::string &section,
+                            const std::string &key,
+                            const std::string &value );
 
     private:
       SectionSet _dict;
-      
       /**
        * empty map used to simulate
        * iteration in non existant
index 3a59ec4..92a4266 100644 (file)
@@ -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())
index 80b1af9..6a7fbf6 100644 (file)
@@ -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 )
 {
index 707e46f..07f4289 100644 (file)
@@ -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;
index fd89098..1b9d6fa 100644 (file)
@@ -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;
index 5d89350..23184e3 100644 (file)
@@ -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 );