libzypp  16.22.9
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  RepoStatus ret( media.provideFile( repoInfo().path() / "/repodata/repomd.xml" ) );
41  if ( !ret.empty() ) // else: mandatory master index is missing
42  ret = ret && RepoStatus( media.provideOptionalFile( "/media.1/media" ) );
43  // else: mandatory master index is missing -> stay empty
44  return ret;
45 }
46 
47 static OnMediaLocation loc_with_path_prefix( const OnMediaLocation & loc, const Pathname & prefix )
48 {
49  if (prefix.empty() || prefix == "/")
50  return loc;
51 
52  OnMediaLocation loc_with_path(loc);
53  loc_with_path.changeFilename(prefix / loc.filename());
54  return loc_with_path;
55 }
56 
57 // search old repository file file to run the delta algorithm on
58 static Pathname search_deltafile( const Pathname & dir, const Pathname & file )
59 {
60  Pathname deltafile;
61  if (!PathInfo(dir).isDir())
62  return deltafile;
63  string base = file.basename();
64  size_t hypoff = base.find("-");
65  if (hypoff != string::npos)
66  base.replace(0, hypoff + 1, "");
67  size_t basesize = base.size();
68  std::list<Pathname> retlist;
69  if (!filesystem::readdir(retlist, dir, false))
70  {
71  for_( it, retlist.begin(), retlist.end() )
72  {
73  string fn = it->asString();
74  if (fn.size() >= basesize && fn.substr(fn.size() - basesize, basesize) == base)
75  deltafile = *it;
76  }
77  }
78  return deltafile;
79 }
80 
81 bool Downloader::patches_Callback( const OnMediaLocation & loc_r, const string & id_r )
82 {
83  OnMediaLocation loc_with_path(loc_with_path_prefix(loc_r, repoInfo().path()));
84  MIL << id_r << " : " << loc_with_path << endl;
85  this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc_r.filename()));
86  return true;
87 }
88 
89 
90 //bool repomd_Callback2( const OnMediaLocation &loc, const ResourceType &dtype, const std::string &typestr, UserData & userData_r );
91 
93 namespace
94 {
106  struct RepomdFileReaderCallback2
107  {
108  RepomdFileReaderCallback2( const RepomdFileReader::ProcessResource & origCallback_r )
109  : _origCallback( origCallback_r )
110  {
111  addWantedLocale( ZConfig::instance().textLocale() );
112  for ( const Locale & it : ZConfig::instance().repoRefreshLocales() )
113  addWantedLocale( it );
114  }
115 
117  bool repomd_Callback2( const OnMediaLocation & loc_r, const ResourceType & dtype_r, const std::string & typestr_r )
118  {
119  // filter well known resource types
120  if ( dtype_r == ResourceType::OTHER || dtype_r == ResourceType::FILELISTS )
121  return true; // skip it
122 
123  if ( str::endsWith( typestr_r, "_db" ) )
124  return true; // skip sqlitedb
125 
126  // filter custom resource types (by string)
127  if ( dtype_r == ResourceType::NONE )
128  {
129  // susedata.LANG
130  if ( str::hasPrefix( typestr_r, "susedata." ) && ! wantLocale( Locale(typestr_r.c_str()+9) ) )
131  return true; // skip it
132  }
133 
134  // take it
135  return( _origCallback ? _origCallback( loc_r, dtype_r ) : true );
136  }
137 
138  private:
139  bool wantLocale( const Locale & locale_r ) const
140  { return _wantedLocales.count( locale_r ); }
141 
142  void addWantedLocale( Locale locale_r )
143  {
144  while ( locale_r )
145  {
146  _wantedLocales.insert( locale_r );
147  locale_r = locale_r.fallback();
148  }
149  }
150 
151  private:
154 
155  };
156 } // namespace
158 
159 bool Downloader::repomd_Callback( const OnMediaLocation & loc_r, const ResourceType & dtype_r )
160 {
161  // NOTE: Filtering of unwanted files is done in RepomdFileReaderCallback2!
162 
163  // schedule file for download
164  const OnMediaLocation & loc_with_path(loc_with_path_prefix(loc_r, repoInfo().path()));
165  this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc_r.filename()));
166 
167  // We got a patches file we need to read, to add patches listed
168  // there, so we transfer what we have in the queue, and
169  // queue the patches in the patches callback
170  if ( dtype_r == ResourceType::PATCHES )
171  {
172  this->start( _dest_dir, *_media_ptr );
173  // now the patches.xml file must exists
174  PatchesFileReader( _dest_dir + repoInfo().path() + loc_r.filename(),
175  bind( &Downloader::patches_Callback, this, _1, _2));
176  }
177  return true;
178 }
179 
180 void Downloader::download( MediaSetAccess & media, const Pathname & dest_dir, const ProgressData::ReceiverFnc & progressrcv )
181 {
182  downloadMediaInfo( dest_dir, media );
183 
184  Pathname masterIndex( repoInfo().path() / "/repodata/repomd.xml" );
185  defaultDownloadMasterIndex( media, dest_dir, masterIndex );
186 
187  // init the data stored in Downloader itself
188  _media_ptr = (&media);
189  _dest_dir = dest_dir;
190 
191  // init the extended data
192  RepomdFileReaderCallback2 pimpl( bind(&Downloader::repomd_Callback, this, _1, _2) );
193 
194  // setup parser
195  RepomdFileReader( dest_dir / masterIndex,
196  RepomdFileReader::ProcessResource2( bind(&RepomdFileReaderCallback2::repomd_Callback2, &pimpl, _1, _2, _3) ) );
197 
198  // ready, go!
199  start( dest_dir, media );
200 }
201 
202 } // namespace yum
203 } // namespace repo
204 } // namespace zypp
205 
206 
207 
#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:122
function< bool(const OnMediaLocation &, const repo::yum::ResourceType &, const std::string &)> ProcessResource2
Alternate callback also receiving the ResourceType as string.
Pathname provideOptionalFile(const Pathname &file, unsigned media_nr=1)
Provides an optional file from media media_nr.
bool patches_Callback(const OnMediaLocation &loc, const std::string &id)
Definition: Downloader.cc:81
Iterates through a patches.xml file giving on each iteration a OnMediaLocation object with the resour...
void downloadMediaInfo(const Pathname &dest_dir, MediaSetAccess &media, const ProgressData::ReceiverFnc &progressrcv)
Downloads the media info (/media.1) to a local directory.
Definition: Arch.h:344
What is known about a repository.
Definition: RepoInfo.h:71
#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:153
Locale fallback() const
Return the fallback locale for this locale, if no fallback exists the empty Locale::noCode.
Definition: Locale.cc:208
bool repomd_Callback(const OnMediaLocation &loc, const ResourceType &dtype)
Definition: Downloader.cc:159
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:58
bool endsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasSuffix
Definition: String.h:1102
&#39;Language[_Country]&#39; 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:152
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:47
void download(MediaSetAccess &media, const Pathname &dest_dir, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Download metadata to a local directory.
Definition: Downloader.cc:180
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
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
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:1037
std::unordered_set< Locale > LocaleSet
Definition: Locale.h:27
function< bool(const OnMediaLocation &, const repo::yum::ResourceType &)> ProcessResource
Callbacl taking OnMediaLocation and repo::yum::ResourceType.