libzypp  15.28.6
Downloader.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
9 
10 #include <fstream>
11 #include "zypp/base/String.h"
12 #include "zypp/base/LogTools.h"
13 #include "zypp/base/Function.h"
14 #include "zypp/ZConfig.h"
15 
18 #include "Downloader.h"
21 #include "zypp/parser/xml/Reader.h"
22 
23 using namespace std;
24 using namespace zypp::xml;
25 using namespace zypp::parser::yum;
26 
27 namespace zypp
28 {
29 namespace repo
30 {
31 namespace yum
32 {
33 
34 Downloader::Downloader( const RepoInfo &repoinfo , const Pathname &delta_dir)
35  : repo::Downloader(repoinfo), _delta_dir(delta_dir), _media_ptr(0L)
36 {}
37 
39 {
40  Pathname repomd = media.provideFile( repoInfo().path() + "/repodata/repomd.xml");
41  return RepoStatus(repomd);
42 }
43 
44 static OnMediaLocation loc_with_path_prefix( const OnMediaLocation & loc, const Pathname & prefix )
45 {
46  if (prefix.empty() || prefix == "/")
47  return loc;
48 
49  OnMediaLocation loc_with_path(loc);
50  loc_with_path.changeFilename(prefix / loc.filename());
51  return loc_with_path;
52 }
53 
54 // search old repository file file to run the delta algorithm on
55 static Pathname search_deltafile( const Pathname & dir, const Pathname & file )
56 {
57  Pathname deltafile;
58  if (!PathInfo(dir).isDir())
59  return deltafile;
60  string base = file.basename();
61  size_t hypoff = base.find("-");
62  if (hypoff != string::npos)
63  base.replace(0, hypoff + 1, "");
64  size_t basesize = base.size();
65  std::list<Pathname> retlist;
66  if (!filesystem::readdir(retlist, dir, false))
67  {
68  for_( it, retlist.begin(), retlist.end() )
69  {
70  string fn = it->asString();
71  if (fn.size() >= basesize && fn.substr(fn.size() - basesize, basesize) == base)
72  deltafile = *it;
73  }
74  }
75  return deltafile;
76 }
77 
78 bool Downloader::patches_Callback( const OnMediaLocation & loc_r, const string & id_r )
79 {
80  OnMediaLocation loc_with_path(loc_with_path_prefix(loc_r, repoInfo().path()));
81  MIL << id_r << " : " << loc_with_path << endl;
82  this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc_r.filename()));
83  return true;
84 }
85 
86 
87 //bool repomd_Callback2( const OnMediaLocation &loc, const ResourceType &dtype, const std::string &typestr, UserData & userData_r );
88 
90 namespace
91 {
103  struct RepomdFileReaderCallback2
104  {
105  RepomdFileReaderCallback2( const RepomdFileReader::ProcessResource & origCallback_r )
106  : _origCallback( origCallback_r )
107  {
108  addWantedLocale( ZConfig::instance().textLocale() );
109  for ( const Locale & it : ZConfig::instance().repoRefreshLocales() )
110  addWantedLocale( it );
111  }
112 
114  bool repomd_Callback2( const OnMediaLocation & loc_r, const ResourceType & dtype_r, const std::string & typestr_r )
115  {
116  // filter well known resource types
117  if ( dtype_r == ResourceType::OTHER || dtype_r == ResourceType::FILELISTS )
118  return true; // skip it
119 
120  // filter custom resource types (by string)
121  if ( dtype_r == ResourceType::NONE )
122  {
123  // susedata.LANG
124  if ( str::hasPrefix( typestr_r, "susedata." ) && ! wantLocale( Locale(typestr_r.c_str()+9) ) )
125  return true; // skip it
126  }
127 
128  // take it
129  return( _origCallback ? _origCallback( loc_r, dtype_r ) : true );
130  }
131 
132  private:
133  bool wantLocale( const Locale & locale_r ) const
134  { return _wantedLocales.count( locale_r ); }
135 
136  void addWantedLocale( Locale locale_r )
137  {
138  while ( locale_r )
139  {
140  _wantedLocales.insert( locale_r );
141  locale_r = locale_r.fallback();
142  }
143  }
144 
145  private:
148 
149  };
150 } // namespace
152 
153 bool Downloader::repomd_Callback( const OnMediaLocation & loc_r, const ResourceType & dtype_r )
154 {
155  // NOTE: Filtering of unwanted files is done in RepomdFileReaderCallback2!
156 
157  // schedule file for download
158  const OnMediaLocation & loc_with_path(loc_with_path_prefix(loc_r, repoInfo().path()));
159  this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc_r.filename()));
160 
161  // We got a patches file we need to read, to add patches listed
162  // there, so we transfer what we have in the queue, and
163  // queue the patches in the patches callback
164  if ( dtype_r == ResourceType::PATCHES )
165  {
166  this->start( _dest_dir, *_media_ptr );
167  // now the patches.xml file must exists
168  PatchesFileReader( _dest_dir + repoInfo().path() + loc_r.filename(),
169  bind( &Downloader::patches_Callback, this, _1, _2));
170  }
171  return true;
172 }
173 
174 void Downloader::download( MediaSetAccess & media, const Pathname & dest_dir, const ProgressData::ReceiverFnc & progressrcv )
175 {
176  Pathname masterIndex( repoInfo().path() / "/repodata/repomd.xml" );
177  defaultDownloadMasterIndex( media, dest_dir, masterIndex );
178 
179  // init the data stored in Downloader itself
180  _media_ptr = (&media);
181  _dest_dir = dest_dir;
182 
183  // init the extended data
184  RepomdFileReaderCallback2 pimpl( bind(&Downloader::repomd_Callback, this, _1, _2) );
185 
186  // setup parser
187  RepomdFileReader( dest_dir / masterIndex,
188  RepomdFileReader::ProcessResource2( bind(&RepomdFileReaderCallback2::repomd_Callback2, &pimpl, _1, _2, _3) ) );
189 
190  // ready, go!
191  start( dest_dir, media );
192 }
193 
194 } // namespace yum
195 } // namespace repo
196 } // namespace zypp
197 
198 
199 
#define MIL
Definition: Logger.h:64
void defaultDownloadMasterIndex(MediaSetAccess &media_r, const Pathname &destdir_r, const Pathname &masterIndex_r)
Common workflow downloading a (signed) master index file.
Definition: Downloader.cc:49
static const ResourceType PATCHES
Definition: ResourceType.h:35
RepoStatus status(MediaSetAccess &media)
Status of the remote repository.
Definition: Downloader.cc:38
static const ResourceType OTHER
Definition: ResourceType.h:32
Describes a path on a certain media amongs as the information required to download it...
static ZConfig & instance()
Singleton ctor.
Definition: Resolver.cc:125
function< bool(const OnMediaLocation &, const repo::yum::ResourceType &, const std::string &)> ProcessResource2
Alternate callback also receiving the ResourceType as string.
bool patches_Callback(const OnMediaLocation &loc, const std::string &id)
Definition: Downloader.cc:78
Iterates through a patches.xml file giving on each iteration a OnMediaLocation object with the resour...
What is known about a repository.
Definition: RepoInfo.h:72
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
MediaSetAccess * _media_ptr
Definition: Downloader.h:80
const RepoInfo & repoInfo() const
Definition: Downloader.h:58
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
Definition: ProgressData.h:139
static const ResourceType NONE
Definition: ResourceType.h:29
void enqueueDigested(const OnMediaLocation &resource, const FileChecker &checker=FileChecker(), const Pathname &deltafile=Pathname())
Enqueue a object for transferal, they will not be transferred until start() is called.
Definition: Fetcher.cc:831
LocaleSet _wantedLocales
Locales do download.
Definition: Downloader.cc:147
bool repomd_Callback(const OnMediaLocation &loc, const ResourceType &dtype)
Definition: Downloader.cc:153
Interface of patches.xml file reader.
void start(const Pathname &dest_dir, MediaSetAccess &media, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
start the transfer to a destination directory dest_dir You have to provde a media set access media to...
Definition: Fetcher.cc:872
static Pathname search_deltafile(const Pathname &dir, const Pathname &file)
Definition: Downloader.cc:55
'Language[_Country]' codes.
Definition: Locale.h:49
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Definition: PathInfo.cc:598
Reads through a repomd.xml file and collects type, location, checksum and other data about metadata f...
RepomdFileReader::ProcessResource _origCallback
Original Downloader callback.
Definition: Downloader.cc:146
const Pathname & filename() const
The path to the resource relatve to the url and path.
static OnMediaLocation loc_with_path_prefix(const OnMediaLocation &loc, const Pathname &prefix)
Definition: Downloader.cc:44
void download(MediaSetAccess &media, const Pathname &dest_dir, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Download metadata to a local directory.
Definition: Downloader.cc:174
OnMediaLocation & changeFilename(const Pathname &val_r)
Individual manipulation of filename (prefer setLocation).
Interface of repomd.xml file reader.
Track changing files or directories.
Definition: RepoStatus.h:38
static const ResourceType FILELISTS
Definition: ResourceType.h:33
function< void(const Pathname &file)> FileChecker
Functor signature used to check files.
Definition: FileChecker.h:28
Downloader for YUM (rpm-nmd) repositories Encapsulates all the knowledge of which files have to be do...
Definition: Downloader.h:41
Pathname provideFile(const OnMediaLocation &resource, ProvideFileOptions options=PROVIDE_DEFAULT, const Pathname &deltafile=Pathname())
Provides a file from a media location.
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition: String.h:1036
std::unordered_set< Locale > LocaleSet
Definition: Locale.h:27
Media access layer responsible for handling files distributed on a set of media with media change and...
function< bool(const OnMediaLocation &, const repo::yum::ResourceType &)> ProcessResource
Callbacl taking OnMediaLocation and repo::yum::ResourceType.