- Introduce sane probing, with reporting, And decoupled
authorDuncan Mac-Vicar P <dmacvicar@suse.de>
Tue, 22 Aug 2006 20:36:51 +0000 (20:36 +0000)
committerDuncan Mac-Vicar P <dmacvicar@suse.de>
Tue, 22 Aug 2006 20:36:51 +0000 (20:36 +0000)
  of source creation.

zypp/SourceFactory.cc
zypp/SourceFactory.h
zypp/ZYppCallbacks.h
zypp/source/SourceImpl.cc
zypp/source/SourceImpl.h
zypp/source/susetags/SuseTagsImpl.cc
zypp/source/susetags/SuseTagsImpl.h
zypp/source/yum/YUMSourceImpl.cc
zypp/source/yum/YUMSourceImpl.h

index 4673d2e..e1eefeb 100644 (file)
@@ -112,14 +112,13 @@ namespace zypp
     Pathname products_file = Pathname("media.1/products");
 
     try  {
-       media_mgr.provideFile (id, products_file);
-       products_file = media_mgr.localPath (id, products_file);
-       scanProductsFile (products_file, products_r);
+      media_mgr.provideFile (id, products_file);
+      products_file = media_mgr.localPath (id, products_file);
+      scanProductsFile (products_file, products_r);
     }
     catch ( const Exception & excpt ) {
-       ZYPP_CAUGHT(excpt);
-
-       MIL << "No products description found on the Url" << endl;
+      ZYPP_CAUGHT(excpt);
+      MIL << "No products description found on the Url" << endl;
     }
 
     media_mgr.release(id);
@@ -130,14 +129,17 @@ namespace zypp
     return Source_Ref::noSource;  
   }
   
+//   bool SourceFactory::probeSource( const std::string name, boost::function<bool()> prober, callback::SendReport<CreateSourceReport> &report )
+//   {
+//   
+//   }
+  
   Source_Ref SourceFactory::createFrom( const Url & url_r, const Pathname & path_r, const std::string & alias_r, const Pathname & cache_dir_r, bool base_source )
   {
     if (! url_r.isValid())
       ZYPP_THROW( Exception("Empty URL passed to SourceFactory") );
 
-    callback::SendReport<CreateSourceReport> report;
-
-    report->startProbe (url_r);
+    callback::SendReport<ProbeSourceReport> report;
 
 #warning if cache_dir is provided, no need to open the original url
     // open the media
@@ -156,41 +158,88 @@ namespace zypp
     }
 
     bool auto_refresh = media::MediaAccess::canBeVolatile( url_r );
+    
+    report->start(url_r);
+    
+    //////////////////////////////////////////////////////////////////
+    // TRY YUM
+    //////////////////////////////////////////////////////////////////
     try
     {
-      MIL << "Trying the YUM source" << endl;
-      Source_Ref::Impl_Ptr impl( base_source
-          ? Impl::createBaseSourceImpl<yum::YUMSourceImpl>(id, path_r, alias_r, cache_dir_r, auto_refresh)
-        : Impl::createSourceImpl<yum::YUMSourceImpl>(id, path_r, alias_r, cache_dir_r, auto_refresh) );
-      MIL << "Found the YUM source" << endl;
-
-      report->endProbe (url_r);
-
-      return Source_Ref(impl);
+      boost::function<bool()> probe = yum::YUMSourceImpl::Prober( id, path_r );
+      if ( probe() )
+      {
+        report->successProbe(url_r, "YUM");
+        report->finish(url_r, ProbeSourceReport::NO_ERROR, "");
+        try
+        {
+          Source_Ref::Impl_Ptr impl( base_source
+            ? Impl::createBaseSourceImpl<yum::YUMSourceImpl>(id, path_r, alias_r, cache_dir_r, auto_refresh)
+            : Impl::createSourceImpl<yum::YUMSourceImpl>(id, path_r, alias_r, cache_dir_r, auto_refresh) );
+          
+          return Source_Ref(impl);
+        }
+        catch (const Exception & excpt_r)
+        {
+          ZYPP_CAUGHT(excpt_r);
+          MIL << "Not YUM source, trying next type" << endl;
+        }
+      }
+      else
+      {
+        report->failedProbe(url_r, "YUM");
+      }
     }
     catch (const Exception & excpt_r)
     {
-      ZYPP_CAUGHT(excpt_r);
-      MIL << "Not YUM source, trying next type" << endl;
+      report->finish(url_r, ProbeSourceReport::NO_ERROR, "");
     }
+
+    //////////////////////////////////////////////////////////////////
+    // TRY YAST
+    //////////////////////////////////////////////////////////////////
     try
     {
-      MIL << "Trying the SUSE tags source" << endl;
-      Source_Ref::Impl_Ptr impl( base_source
-          ? Impl::createBaseSourceImpl<susetags::SuseTagsImpl>(id, path_r, alias_r, cache_dir_r, auto_refresh)
-        : Impl::createSourceImpl<susetags::SuseTagsImpl>(id, path_r, alias_r, cache_dir_r, auto_refresh) );
-      MIL << "Found the SUSE tags source" << endl;
-
-      report->endProbe (url_r);
-
-      return Source_Ref(impl);
+      boost::function<bool()> probe = susetags::SuseTagsImpl::Prober( id, path_r );
+      if ( probe() )
+      {
+        report->successProbe(url_r, "YaST");
+        report->finish(url_r, ProbeSourceReport::NO_ERROR, "");
+        try
+        {
+          Source_Ref::Impl_Ptr impl( base_source
+              ? Impl::createBaseSourceImpl<susetags::SuseTagsImpl>(id, path_r, alias_r, cache_dir_r, auto_refresh)
+            : Impl::createSourceImpl<susetags::SuseTagsImpl>(id, path_r, alias_r, cache_dir_r, auto_refresh) );
+          return Source_Ref(impl);
+        }
+        catch (const Exception & excpt_r)
+        {
+          ZYPP_CAUGHT(excpt_r);
+          MIL << "Not YUM source, trying next type" << endl;
+        }
+      }
+      else
+      {
+        report->failedProbe(url_r, "YaST");
+      }
     }
     catch (const Exception & excpt_r)
     {
-      ZYPP_CAUGHT(excpt_r);
-      MIL << "Not SUSE tags source, trying next type" << endl;
-    }
-
+      report->finish(url_r, ProbeSourceReport::NO_ERROR, "");
+    } 
+    
+    //////////////////////////////////////////////////////////////////
+    // TRY PLAINDIR
+    //////////////////////////////////////////////////////////////////
+    //FIXME disabled
+    report->finish(url_r, ProbeSourceReport::INVALID, "Unknown source type");
+    ZYPP_THROW( Exception("Unknown source type for " + url_r.asString() ) );
+    
+    
+    return Source_Ref(); // not reached!!
+    
     try
     {
       if ( ! ( ( url_r.getScheme() == "file") || ( url_r.getScheme() == "dir ") ) )
@@ -200,7 +249,7 @@ namespace zypp
             ? Impl::createBaseSourceImpl<plaindir::PlaindirImpl>(id, path_r, alias_r, cache_dir_r, auto_refresh)
           : Impl::createSourceImpl<plaindir::PlaindirImpl>(id, path_r, alias_r, cache_dir_r, auto_refresh) );
         MIL << "Using the Plaindir source" << endl;
-        report->endProbe (url_r);
+        //report->endProbe (url_r);
         return Source_Ref(impl);
       }
       else
@@ -209,12 +258,10 @@ namespace zypp
       }
     }
     catch (const Exception & excpt_r)
-      {
+    {
             ZYPP_CAUGHT(excpt_r);
             MIL << "Not Plaindir source, trying next type" << endl;
-      }
-
-    report->endProbe (url_r);
+    }
 
     ERR << "No next type of source" << endl;
     ZYPP_THROW(Exception("Cannot create the installation source"));
index 4a57067..735cdb2 100644 (file)
@@ -30,6 +30,10 @@ using namespace boost;
 namespace zypp
 { /////////////////////////////////////////////////////////////////
 
+  template<class T>
+  bool probeSource( media::MediaAccessId media_id );
+  
+  
   ///////////////////////////////////////////////////////////////////
   //
   //   CLASS NAME : SourceFactory
@@ -94,8 +98,8 @@ namespace zypp
      * \throw Exception or MediaException on fail
      */
     void listProducts( const Url & url_r, ProductSet & products_r );
-
   private:
+//     bool probeSource( const std::string name, boost::function<bool()> prober, callback::SendReport<CreateSourceReport> &report );
     void scanProductsFile( const Pathname & file_r, ProductSet & pset_r ) const;
   };
   ///////////////////////////////////////////////////////////////////
index cc04c42..f8fd303 100644 (file)
@@ -184,7 +184,7 @@ namespace zypp
       ) {}
     };
 
-    // progress for creating a source (download and parsing)
+    // DEPRECATED
     struct CreateSourceReport : public callback::ReportBase
     {
       enum Action {
@@ -193,14 +193,14 @@ namespace zypp
       };
 
       enum Error {
-       NO_ERROR,
+        NO_ERROR,
         NOT_FOUND,     // the requested Url was not found
-       IO,             // IO error
-       INVALID         // th source is invalid
+        IO,            // IO error
+        INVALID                // th source is invalid
       };
 
       virtual void startData(
-       Url source_url
+        Url source_url
       ) {}
 
       virtual void startProbe(Url url) {}
@@ -212,17 +212,77 @@ namespace zypp
 
       virtual Action problem(
         Url url
-       , Error error
-       , std::string description
+          , Error error
+          , std::string description
       ) { return ABORT; }
 
       virtual void finishData(
         Url url
         , Error error
-       , std::string reason
+        , std::string reason
       ) {}
     };
 
+    // progress for probing a source
+    struct ProbeSourceReport : public callback::ReportBase
+    {
+      enum Action {
+        ABORT,  // abort and return error
+        RETRY  // retry
+      };
+
+      enum Error {
+        NO_ERROR,
+        NOT_FOUND,     // the requested Url was not found
+        IO,            // IO error
+        INVALID                // th source is invalid
+      };
+
+      virtual void start(const Url &url) {}
+      virtual void failedProbe( const Url &url, const std::string &type ) {}
+      virtual void successProbe( const Url &url, const std::string &type ) {}
+      virtual void finish(const Url &url, Error error, std::string reason ) {}
+
+      virtual bool progress(const Url &url, int value)
+      { return true; }
+
+      virtual Action problem( const Url &url, Error error, std::string description ) { return ABORT; }
+    };
+    
+    // progress for refreshing a source data
+    struct SourceProcessReport : public callback::ReportBase
+    {
+      enum Action {
+        ABORT,  // abort and return error
+        RETRY, // retry
+        IGNORE  // skip refresh, ignore failed refresh
+      };
+
+      enum Error {
+        NO_ERROR,
+        NOT_FOUND,     // the requested Url was not found
+        IO,            // IO error
+        INVALID                // th source is invalid
+      };
+      
+      virtual void start( Source_Ref source ) {}
+      virtual bool progress(int value, Source_Ref source)
+      { return true; }
+
+      virtual Action problem(
+          Source_Ref source
+          , Error error
+          , std::string description )
+      { return ABORT; }
+
+      virtual void finish(
+          Source_Ref source
+          , Error error
+          , std::string reason )
+      {}
+    };
+    
+    
     /////////////////////////////////////////////////////////////////
   } // namespace source
   ///////////////////////////////////////////////////////////////////
@@ -236,25 +296,25 @@ namespace zypp
       enum Action {
         ABORT,  // abort and return error
         RETRY, // retry
-       IGNORE, // ignore this media in future, not available anymore
-       IGNORE_ID,      // ignore wrong medium id
-       CHANGE_URL,     // change media URL
-       EJECT           // eject the medium
+        IGNORE, // ignore this media in future, not available anymore
+        IGNORE_ID,     // ignore wrong medium id
+        CHANGE_URL,    // change media URL
+        EJECT          // eject the medium
       };
 
       enum Error {
-       NO_ERROR,
+        NO_ERROR,
         NOT_FOUND,  // the medie not found at all
         IO,    // error accessing the media
-       INVALID, // media is broken
-       WRONG   // wrong media, need a different one
+        INVALID, // media is broken
+        WRONG  // wrong media, need a different one
       };
 
       virtual Action requestMedia(
         const Source_Ref source
-       , unsigned mediumNr
-       , Error error
-       , std::string description
+        , unsigned mediumNr
+        , Error error
+        , std::string description
       ) { return ABORT; }
     };
 
@@ -264,13 +324,13 @@ namespace zypp
         enum Action {
           ABORT,  // abort and return error
           RETRY,       // retry
-         IGNORE        // ignore the failure
+          IGNORE       // ignore the failure
         };
 
         enum Error {
-         NO_ERROR,
+          NO_ERROR,
           NOT_FOUND,   // the requested Url was not found
-         IO            // IO error
+          IO           // IO error
         };
 
         virtual void start( Url file, Pathname localfile ) {}
index fbef11b..76675e8 100644 (file)
@@ -140,15 +140,17 @@ namespace zypp
       _base_source = base_source;
       _autorefresh = auto_refresh;
       
+      callback::SendReport<source::CreateSourceReport> report;
+      
       try
-        {
-          factoryInit();
-        }
+      {
+        factoryInit();
+      }
       catch ( Exception & excpt )
-        {
-          _store.clear();
-          ZYPP_RETHROW( excpt );
-        }
+      {
+        _store.clear();
+        ZYPP_RETHROW( excpt );
+      }
     }
 
     ///////////////////////////////////////////////////////////////////
index bc874c4..e03a541 100644 (file)
@@ -36,6 +36,30 @@ namespace zypp
   { /////////////////////////////////////////////////////////////////
 
     DEFINE_PTR_TYPE(SourceImpl);
+    
+    /** Base class for Source prober.
+     *
+     * Source probe implementations get a attached media id
+     * and return a bool, wether the source is a source
+     * of this type
+     */
+    class SourceProber
+    {
+      public:
+        SourceProber( media::MediaAccessId media_id, const Pathname &path )
+          : _media_id(media_id), _path(path)
+        {}
+        
+        virtual ~SourceProber()
+        {}
+        
+        virtual bool operator()() = 0;
+
+      protected:
+        media::MediaAccessId _media_id;
+        Pathname _path;
+    };
+    
     ///////////////////////////////////////////////////////////////////
     //
     // CLASS NAME : SourceImpl
index 3297052..d2e7930 100644 (file)
@@ -42,6 +42,23 @@ namespace zypp
     namespace susetags
     { /////////////////////////////////////////////////////////////////
       
+      bool SuseTagsProber::operator()()
+      {
+        MIL << "Probing for YaST source..." << std::endl;
+        bool result = false;
+        media::MediaManager mm;
+        result = mm.doesFileExist(_media_id, _path + Pathname("/content"));
+
+        if ( result )
+        {
+          MIL << "YaST source detected..." << std::endl;
+          return true;
+        }
+        
+         MIL << "Not a YaST source..." << std::endl;
+         return false;
+      }
+      
       ///////////////////////////////////////////////////////////////////
       //
       //       METHOD NAME : SuseTagsImpl::SuseTagsImpl
index 7eb7a40..fb24be4 100644 (file)
@@ -35,6 +35,21 @@ namespace zypp
     namespace susetags
     { /////////////////////////////////////////////////////////////////
 
+      /**
+       * Functor to probe
+       */
+      class SuseTagsProber : public SourceProber
+      {
+        public:
+          SuseTagsProber( media::MediaAccessId media_id, const Pathname &path ) : SourceProber( media_id, path )
+          {}
+        
+          virtual ~SuseTagsProber()
+          {}
+        
+          virtual bool operator()();
+      };
+      
       struct SuseTagsPackageImplData
       {
         SuseTagsPackageImplData()
@@ -57,6 +72,7 @@ namespace zypp
       class SuseTagsImpl : public SourceImpl
       {
       public:
+        typedef source::susetags::SuseTagsProber Prober;
         typedef intrusive_ptr<SuseTagsImpl>       Ptr;
         typedef intrusive_ptr<const SuseTagsImpl> constPtr;
 
index c050a70..f2764c1 100644 (file)
@@ -54,6 +54,23 @@ namespace zypp
   { /////////////////////////////////////////////////////////////////
     namespace yum
     {
+      
+      bool YUMProber::operator()()
+      {
+        MIL << "Probing for YUM source..." << std::endl;
+        bool result = false;
+        media::MediaManager mm;
+        result = mm.doesFileExist(_media_id, _path + Pathname("/repodata/repomd.xml"));
+        if ( result )
+        {
+          MIL << "YUM source detected..." << std::endl;
+          return true;
+        }
+          
+        MIL << "Not a YUM source..." << std::endl;
+        return false;
+      }
+      
       ///////////////////////////////////////////////////////////////////
       //
       //        CLASS NAME : YUMSourceImpl
@@ -196,35 +213,35 @@ namespace zypp
 
       void YUMSourceImpl::factoryInit()
       {
-        resetMediaVerifier();
-
-        bool cache = cacheExists();
-        if ( cache )
-        {
-          DBG << "Cached metadata found in [" << _cache_dir << "]." << endl;
-          if ( autorefresh() )
-            storeMetadata(_cache_dir);
-        }
-        else
-        {
-          if ( _cache_dir.empty() || !PathInfo(_cache_dir).isExist() )
+          resetMediaVerifier();
+  
+          bool cache = cacheExists();
+          if ( cache )
           {
-            DBG << "Cache dir not set. Downloading to temp dir: " << tmpMetadataDir() << std::endl;
-            // as we have no local dir set we use a tmp one, but we use a member variable because
-            // it cant go out of scope while the source exists.
-            saveMetadataTo(tmpMetadataDir());
+            DBG << "Cached metadata found in [" << _cache_dir << "]." << endl;
+            if ( autorefresh() )
+              storeMetadata(_cache_dir);
           }
           else
           {
-            DBG << "Cached metadata not found in [" << _cache_dir << "]. Will download." << std::endl;
-            saveMetadataTo(_cache_dir);
+            if ( _cache_dir.empty() || !PathInfo(_cache_dir).isExist() )
+            {
+              DBG << "Cache dir not set. Downloading to temp dir: " << tmpMetadataDir() << std::endl;
+              // as we have no local dir set we use a tmp one, but we use a member variable because
+              // it cant go out of scope while the source exists.
+              saveMetadataTo(tmpMetadataDir());
+            }
+            else
+            {
+              DBG << "Cached metadata not found in [" << _cache_dir << "]. Will download." << std::endl;
+              saveMetadataTo(_cache_dir);
+            }
           }
-        }
-
-        MIL << "YUM source initialized." << std::endl;
-        MIL << "   Url      : " << url() << std::endl;
-        MIL << "   Path     : " << path() << std::endl;
-        MIL << "   Metadata : " << metadataRoot() << (_cache_dir.empty() ? " [TMP]" : " [CACHE]") << std::endl;
+  
+          MIL << "YUM source initialized." << std::endl;
+          MIL << "   Url      : " << url() << std::endl;
+          MIL << "   Path     : " << path() << std::endl;
+          MIL << "   Metadata : " << metadataRoot() << (_cache_dir.empty() ? " [TMP]" : " [CACHE]") << std::endl;
       }
 
       void YUMSourceImpl::checkMetadataChecksums() const
index f66b12f..6ff0e96 100644 (file)
@@ -38,6 +38,22 @@ namespace zypp
     { //////////////////////////////////////////////////////////////
 
       /**
+       * Functor to probe
+       */
+      class YUMProber : public SourceProber
+      {
+      public:
+        YUMProber( media::MediaAccessId media_id, const Pathname &path ) : SourceProber( media_id, path )
+        {}
+        
+        virtual ~YUMProber()
+        {}
+        
+        virtual bool operator()();
+
+      };
+      
+      /**
        * class representing a YUM collection of metadata
        */
       
@@ -51,6 +67,8 @@ namespace zypp
       {
       public:
         
+        typedef source::yum::YUMProber     Prober;
+        
         /** Default Ctor.
          * Just initilizes data members. Metadata retrieval
          * is delayed untill \ref factoryInit.