libzypp  16.22.5
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  // filter custom resource types (by string)
124  if ( dtype_r == ResourceType::NONE )
125  {
126  // susedata.LANG
127  if ( str::hasPrefix( typestr_r, "susedata." ) && ! wantLocale( Locale(typestr_r.c_str()+9) ) )
128  return true; // skip it
129  }
130 
131  // take it
132  return( _origCallback ? _origCallback( loc_r, dtype_r ) : true );
133  }
134 
135  private:
136  bool wantLocale( const Locale & locale_r ) const
137  { return _wantedLocales.count( locale_r ); }
138 
139  void addWantedLocale( Locale locale_r )
140  {
141  while ( locale_r )
142  {
143  _wantedLocales.insert( locale_r );
144  locale_r = locale_r.fallback();
145  }
146  }
147 
148  private:
151 
152  };
153 } // namespace
155 
156 bool Downloader::repomd_Callback( const OnMediaLocation & loc_r, const ResourceType & dtype_r )
157 {
158  // NOTE: Filtering of unwanted files is done in RepomdFileReaderCallback2!
159 
160  // schedule file for download
161  const OnMediaLocation & loc_with_path(loc_with_path_prefix(loc_r, repoInfo().path()));
162  this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc_r.filename()));
163 
164  // We got a patches file we need to read, to add patches listed
165  // there, so we transfer what we have in the queue, and
166  // queue the patches in the patches callback
167  if ( dtype_r == ResourceType::PATCHES )
168  {
169  this->start( _dest_dir, *_media_ptr );
170  // now the patches.xml file must exists
171  PatchesFileReader( _dest_dir + repoInfo().path() + loc_r.filename(),
172  bind( &Downloader::patches_Callback, this, _1, _2));
173  }
174  return true;
175 }
176 
177 void Downloader::download( MediaSetAccess & media, const Pathname & dest_dir, const ProgressData::ReceiverFnc & progressrcv )
178 {
179  downloadMediaInfo( dest_dir, media );
180 
181  Pathname masterIndex( repoInfo().path() / "/repodata/repomd.xml" );
182  defaultDownloadMasterIndex( media, dest_dir, masterIndex );
183 
184  // init the data stored in Downloader itself
185  _media_ptr = (&media);
186  _dest_dir = dest_dir;
187 
188  // init the extended data
189  RepomdFileReaderCallback2 pimpl( bind(&Downloader::repomd_Callback, this, _1, _2) );
190 
191  // setup parser
192  RepomdFileReader( dest_dir / masterIndex,
193  RepomdFileReader::ProcessResource2( bind(&RepomdFileReaderCallback2::repomd_Callback2, &pimpl, _1, _2, _3) ) );
194 
195  // ready, go!
196  start( dest_dir, media );
197 }
198 
199 } // namespace yum
200 } // namespace repo
201 } // namespace zypp
202 
203 
204 
#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.
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:150
bool repomd_Callback(const OnMediaLocation &loc, const ResourceType &dtype)
Definition: Downloader.cc:156
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
'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:149
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:177
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:1037
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.