libzypp  17.23.6
RepoProvideFile.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <fstream>
14 #include <sstream>
15 #include <set>
16 
17 #include <zypp/base/Gettext.h>
18 #include <zypp/base/Logger.h>
19 #include <zypp/base/String.h>
22 #include <zypp/ZYppCallbacks.h>
23 #include <zypp/MediaSetAccess.h>
24 #include <zypp/ZConfig.h>
25 #include <zypp/ZYppFactory.h>
28 
31 #include <zypp/FileChecker.h>
32 #include <zypp/Fetcher.h>
33 
34 using std::endl;
35 using std::set;
36 
38 namespace zypp
39 {
40  namespace repo
42  {
43 
45  //
46  // provideFile
47  //
49 
51  namespace
52  {
53 
59  struct DownloadFileReportHack : public callback::ReceiveReport<media::DownloadProgressReport>
60  {
61  typedef callback::ReceiveReport<ReportType> BaseType;
62  typedef function<bool(int)> RedirectType;
63 
64  DownloadFileReportHack( RedirectType redirect_r )
65  : _oldRec( Distributor::instance().getReceiver() )
66  , _redirect( redirect_r )
67  { connect(); }
68  ~DownloadFileReportHack()
69  { if ( _oldRec ) Distributor::instance().setReceiver( *_oldRec ); else Distributor::instance().noReceiver(); }
70 
71  virtual void start( const Url & file, Pathname localfile )
72  {
73  if ( _oldRec )
74  _oldRec->start( file, localfile );
75  else
76  BaseType::start( file, localfile );
77  }
78 
79  virtual bool progress( int value, const Url & file, double dbps_avg = -1, double dbps_current = -1 )
80  {
81  bool ret = true;
82  if ( _oldRec )
83  ret &= _oldRec->progress( value, file, dbps_avg, dbps_current );
84  if ( _redirect )
85  ret &= _redirect( value );
86  return ret;
87  }
88 
89  virtual Action problem( const Url & file, Error error, const std::string & description )
90  {
91  if ( _oldRec )
92  return _oldRec->problem( file, error, description );
93  return BaseType::problem( file, error, description );
94  }
95  virtual void finish( const Url & file, Error error, const std::string & reason )
96  {
97  if ( _oldRec )
98  _oldRec->finish( file, error, reason );
99  else
100  BaseType::finish( file, error, reason );
101  }
102 
103  private:
104  Receiver * _oldRec;
105  RedirectType _redirect;
106  };
107 
109  } // namespace
111 
113  const OnMediaLocation & loc_r,
114  const ProvideFilePolicy & policy_r )
115  {
116  RepoMediaAccess access;
117  return access.provideFile(repo_r, loc_r, policy_r );
118  }
119 
122  {
123  public:
124  Impl( const ProvideFilePolicy & defaultPolicy_r )
125  : _defaultPolicy( defaultPolicy_r )
126  {}
127 
129  {
130  std::map<Url, shared_ptr<MediaSetAccess> >::iterator it;
131  for ( it = _medias.begin();
132  it != _medias.end();
133  ++it )
134  {
135  it->second->release();
136  }
137  }
138 
146  shared_ptr<MediaSetAccess> mediaAccessForUrl( const Url &url, RepoInfo repo )
147  {
148  std::map<Url, shared_ptr<MediaSetAccess> >::const_iterator it;
149  it = _medias.find(url);
150  shared_ptr<MediaSetAccess> media;
151  if ( it != _medias.end() )
152  {
153  media = it->second;
154  }
155  else
156  {
157  media.reset( new MediaSetAccess(url) );
158  _medias[url] = media;
159  }
160  setVerifierForRepo( repo, media );
161  return media;
162  }
163 
164  private:
165  void setVerifierForRepo( RepoInfo repo, shared_ptr<MediaSetAccess> media )
166  {
167  // Always set the MediaSetAccess label.
168  media->setLabel( repo.name() );
169 
170  // set a verifier if the repository has it
171 
172  Pathname mediafile = repo.metadataPath() + "/media.1/media";
173  if ( ! repo.metadataPath().empty() )
174  {
175  if ( PathInfo(mediafile).isExist() )
176  {
177  std::map<shared_ptr<MediaSetAccess>, RepoInfo>::const_iterator it;
178  it = _verifier.find(media);
179  if ( it != _verifier.end() )
180  {
181  if ( it->second.alias() == repo.alias() )
182  {
183  // this media is already using this repo verifier
184  return;
185  }
186  }
187 
188  std::ifstream str(mediafile.asString().c_str());
189  std::string vendor;
190  std::string mediaid;
191  std::string buffer;
192  if ( str )
193  {
194  getline(str, vendor);
195  getline(str, mediaid);
196  getline(str, buffer);
197 
198  unsigned media_nr = str::strtonum<unsigned>(buffer);
199  MIL << "Repository '" << repo.alias() << "' has " << media_nr << " medias"<< endl;
200 
201  for ( unsigned i=1; i <= media_nr; ++i )
202  {
203  media::MediaVerifierRef verifier( new repo::SUSEMediaVerifier( vendor, mediaid, i ) );
204 
205  media->setVerifier( i, verifier);
206  }
207  _verifier[media] = repo;
208  }
209  else
210  {
212  }
213  }
214  else
215  {
216  WAR << "No media verifier for repo '" << repo.alias() << "' media.1/media does not exist in '" << repo.metadataPath() << "'" << endl;
217  }
218  }
219  else
220  {
221  WAR << "'" << repo.alias() << "' metadata path is empty. Can't set verifier. Probably this repository does not come from RepoManager." << endl;
222  }
223  }
224 
225  private:
226  std::map<shared_ptr<MediaSetAccess>, RepoInfo> _verifier;
227  std::map<Url, shared_ptr<MediaSetAccess> > _medias;
228 
229  public:
231  };
233 
234 
236  : _impl( new Impl( defaultPolicy_r ) )
237  {}
238 
240  {}
241 
243  { _impl->_defaultPolicy = policy_r; }
244 
246  { return _impl->_defaultPolicy; }
247 
249  const OnMediaLocation & loc_rx,
250  const ProvideFilePolicy & policy_r )
251  {
252  const OnMediaLocation locWithPath( OnMediaLocation(loc_rx).prependPath( repo_r.path() ) );
253 
254  MIL << locWithPath << endl;
255  // Arrange DownloadFileReportHack to recieve the source::DownloadFileReport
256  // and redirect download progress triggers to call the ProvideFilePolicy
257  // callback.
258  DownloadFileReportHack dumb( bind( mem_fun_ref( &ProvideFilePolicy::progress ), ref( policy_r ), _1 ) );
259 
260  RepoException repo_excpt(repo_r,
261  str::form(_("Can't provide file '%s' from repository '%s'"),
262  locWithPath.filename().c_str(),
263  repo_r.alias().c_str() ) );
264 
265  if ( repo_r.baseUrlsEmpty() )
266  {
267  repo_excpt.remember(RepoException(_("No url in repository.")));
268  ZYPP_THROW(repo_excpt);
269  }
270 
271  Fetcher fetcher;
272  fetcher.addCachePath( repo_r.packagesPath() );
273  MIL << "Added cache path " << repo_r.packagesPath() << endl;
274 
275  // Test whether download destination is writable, if not
276  // switch into the tmpspace (e.g. bnc#755239, download and
277  // install srpms as user).
278  Pathname destinationDir( repo_r.packagesPath() );
279 
280  PathInfo pi( destinationDir );
281  if ( ! pi.isExist() )
282  {
283  // try to create it...
284  assert_dir( destinationDir );
285  pi();
286  }
287  if ( geteuid() != 0 && ! pi.userMayW() )
288  {
289  WAR << "Destination dir '" << destinationDir << "' is not user writable, using tmp space." << endl;
290  destinationDir = getZYpp()->tmpPath() / destinationDir;
291  assert_dir( destinationDir );
292  fetcher.addCachePath( destinationDir );
293  MIL << "Added cache path " << destinationDir << endl;
294  }
295 
296  // Suppress (interactive) media::MediaChangeReport if we in have multiple basurls (>1)
298 
299  for ( RepoInfo::urls_const_iterator it = repo_r.baseUrlsBegin();
300  it != repo_r.baseUrlsEnd();
301  /* incremented in the loop */ )
302  {
303  Url url( *it );
304  ++it;
305  try
306  {
307  MIL << "Providing file of repo '" << repo_r.alias() << "' from " << url << endl;
308  shared_ptr<MediaSetAccess> access = _impl->mediaAccessForUrl( url, repo_r );
309 
310  fetcher.enqueue( locWithPath, policy_r.fileChecker() );
311  fetcher.start( destinationDir, *access );
312 
313  // reached if no exception has been thrown, so this is the correct file
314  ManagedFile ret( destinationDir + locWithPath.filename() );
315  if ( !repo_r.keepPackages() )
316  {
317  ret.setDispose( filesystem::unlink );
318  }
319 
320  MIL << "provideFile at " << ret << endl;
321  return ret;
322  }
323  catch ( const UserRequestException & excpt )
324  {
325  ZYPP_RETHROW( excpt );
326  }
327  catch ( const FileCheckException & excpt )
328  {
329  ZYPP_RETHROW( excpt );
330  }
331  catch ( const Exception &e )
332  {
333  ZYPP_CAUGHT( e );
334 
335  repo_excpt.remember(e);
336 
337  WAR << "Trying next url" << endl;
338  continue;
339  }
340  } // iteration over urls
341 
342  ZYPP_THROW(repo_excpt);
343  return ManagedFile(); // not reached
344  }
345 
347  } // namespace repo
350 } // namespace zypp
zypp::repo::RepoMediaAccess::Impl::_verifier
std::map< shared_ptr< MediaSetAccess >, RepoInfo > _verifier
Definition: RepoProvideFile.cc:226
zypp::filesystem::assert_dir
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Definition: PathInfo.cc:315
zypp::repo::RepoMediaAccess::~RepoMediaAccess
~RepoMediaAccess()
Definition: RepoProvideFile.cc:239
zypp::filesystem::PathInfo::isExist
bool isExist() const
Return whether valid stat info exists.
Definition: PathInfo.h:281
ZYppFactory.h
zypp::repo::SUSEMediaVerifier
Implementation of the traditional SUSE media verifier.
Definition: SUSEMediaVerifier.h:24
zypp::repo::RepoMediaAccess::Impl::setVerifierForRepo
void setVerifierForRepo(RepoInfo repo, shared_ptr< MediaSetAccess > media)
Definition: RepoProvideFile.cc:165
zypp::Exception
Base class for Exception.
Definition: Exception.h:145
zypp::RepoInfo
What is known about a repository.
Definition: RepoInfo.h:71
zypp::RepoInfo::urls_const_iterator
transform_iterator< repo::RepoVariablesUrlReplacer, url_set::const_iterator > urls_const_iterator
Definition: RepoInfo.h:105
FileChecker.h
zypp::Fetcher::addCachePath
void addCachePath(const Pathname &cache_dir)
adds a directory to the list of directories where to look for cached files
Definition: Fetcher.cc:862
zypp::repo::RepoMediaAccess::Impl::Impl
Impl(const ProvideFilePolicy &defaultPolicy_r)
Definition: RepoProvideFile.cc:124
ZConfig.h
zypp::ManagedFile
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
Definition: ManagedFile.h:27
zypp::repo::RepoMediaAccess::Impl::_medias
std::map< Url, shared_ptr< MediaSetAccess > > _medias
Definition: RepoProvideFile.cc:227
MIL
#define MIL
Definition: Logger.h:79
zypp::FileCheckException
Definition: FileChecker.h:39
zypp::OnMediaLocation
Describes a resource file located on a medium.
Definition: OnMediaLocation.h:38
zypp::repo::RepoMediaAccess::Impl::~Impl
~Impl()
Definition: RepoProvideFile.cc:128
zypp::repo::RepoMetadataException
thrown when it was impossible to use the raw metadata for this repo.
Definition: RepoException.h:155
zypp::RepoInfo::baseUrlsEmpty
bool baseUrlsEmpty() const
whether repository urls are available
Definition: RepoInfo.cc:712
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392
zypp::repo::provideFile
ManagedFile provideFile(RepoInfo repo_r, const OnMediaLocation &loc_r, const ProvideFilePolicy &policy_r)
Provide a file from a Repository.
Definition: RepoProvideFile.cc:112
zypp::repo::RepoMediaAccess::Impl::_defaultPolicy
ProvideFilePolicy _defaultPolicy
Definition: RepoProvideFile.cc:230
zypp::filesystem::unlink
int unlink(const Pathname &path)
Like 'unlink'.
Definition: PathInfo.cc:648
zypp::iostr::getline
std::string getline(std::istream &str)
Read one line from stream.
Definition: IOStream.cc:32
zypp::RepoInfo::packagesPath
Pathname packagesPath() const
Path where this repo packages are cached.
Definition: RepoInfo.cc:652
bool
zypp::RW_pointer
Wrapper for const correct access via Smart pointer types.
Definition: PtrTypes.h:285
zypp::Exception::remember
void remember(const Exception &old_r)
Store an other Exception as history.
Definition: Exception.cc:105
zypp::filesystem::PathInfo
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:220
_redirect
RedirectType _redirect
Definition: RepoProvideFile.cc:105
zypp::repo::RepoMediaAccess::setDefaultPolicy
void setDefaultPolicy(const ProvideFilePolicy &policy_r)
Set a new default ProvideFilePolicy.
Definition: RepoProvideFile.cc:242
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition: Pathname.h:110
zypp::ProvideFilePolicy
Policy for provideFile and RepoMediaAccess.
Definition: ProvideFilePolicy.h:29
zypp::repo::RepoMediaAccess::RepoMediaAccess
RepoMediaAccess(const ProvideFilePolicy &defaultPolicy_r=ProvideFilePolicy())
Ctor taking the default ProvideFilePolicy.
Definition: RepoProvideFile.cc:235
Logger.h
zypp::repo::RepoInfoBase::alias
std::string alias() const
unique identifier for this source.
Definition: RepoInfoBase.cc:111
WAR
#define WAR
Definition: Logger.h:80
RepoProvideFile.h
ZYppCallbacks.h
_
#define _(MSG)
Definition: Gettext.h:37
zypp::repo::RepoMediaAccess::_impl
RW_pointer< Impl > _impl
Definition: RepoProvideFile.h:92
zypp::str::form
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:35
zypp::repo::RepoInfoBase::name
std::string name() const
Repository name.
Definition: RepoInfoBase.cc:117
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
zypp::RepoInfo::baseUrlsBegin
urls_const_iterator baseUrlsBegin() const
iterator that points at begin of repository urls
Definition: RepoInfo.cc:703
zypp::repo::RepoMediaAccess::provideFile
ManagedFile provideFile(RepoInfo repo_r, const OnMediaLocation &loc_r, const ProvideFilePolicy &policy_r)
Provide a file from a Repository.
Definition: RepoProvideFile.cc:248
zypp::repo::RepoMediaAccess::Impl::mediaAccessForUrl
shared_ptr< MediaSetAccess > mediaAccessForUrl(const Url &url, RepoInfo repo)
Provide a MediaSetAccess for url with label and verifyer adjusted.
Definition: RepoProvideFile.cc:146
zypp::OnMediaLocation::filename
const Pathname & filename() const
The path to the resource on the medium.
Definition: OnMediaLocation.cc:85
zypp::repo::RepoMediaAccess::Impl
Definition: RepoProvideFile.cc:121
zypp::ProvideFilePolicy::progress
bool progress(int value) const
Evaluate callback.
Definition: ProvideFilePolicy.cc:28
zypp::Fetcher::start
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
zypp::media::ScopedDisableMediaChangeReport
Temporarily disable MediaChangeReport Sometimes helpful to suppress interactive messages connected to...
Definition: ZYppCallbacks.h:345
UserRequestException.h
zypp::repo::RepoMediaAccess
Provides files from different repos.
Definition: RepoProvideFile.h:60
Gettext.h
ZYPP_RETHROW
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition: Exception.h:400
zypp::AutoDispose
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:92
_oldRec
Receiver * _oldRec
Definition: RepoProvideFile.cc:104
zypp::RepoInfo::metadataPath
Pathname metadataPath() const
Path where this repo metadata was read from.
Definition: RepoInfo.cc:649
zypp::filesystem::Pathname::empty
bool empty() const
Test for an empty path.
Definition: Pathname.h:114
String.h
zypp::filesystem::Pathname
Pathname.
Definition: Pathname.h:44
SUSEMediaVerifier.h
verifier
MediaVerifierRef verifier
Definition: MediaManager.cc:104
zypp::Fetcher::enqueue
void enqueue(const OnMediaLocation &resource, const FileChecker &checker=FileChecker())
Enqueue a object for transferal, they will not be transferred until start() is called.
Definition: Fetcher.cc:857
zypp::repo::RepoException
Exception for repository handling.
Definition: RepoException.h:37
zypp::MediaSetAccess
Media access layer responsible for handling files distributed on a set of media with media change and...
Definition: MediaSetAccess.h:80
str
String related utilities and Regular expression matching.
zypp::RepoInfo::baseUrlsEnd
urls_const_iterator baseUrlsEnd() const
iterator that points at end of repository urls
Definition: RepoInfo.cc:706
ZYPP_CAUGHT
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:396
MediaSetAccess.h
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition: Pathname.h:91
url
Url url
Definition: MediaCurl.cc:66
Fetcher.h
RepoException.h
zypp::Url
Url manipulation class.
Definition: Url.h:87
zypp::ProvideFilePolicy::fileChecker
ProvideFilePolicy & fileChecker(FileChecker fileChecker_r)
Add a FileCecker passed down to the Fetcher.
Definition: ProvideFilePolicy.h:44
zypp::UserRequestException
Base for exceptions caused by explicit user request.
Definition: UserRequestException.h:64
zypp::repo::RepoMediaAccess::defaultPolicy
const ProvideFilePolicy & defaultPolicy() const
Get the current default ProvideFilePolicy.
Definition: RepoProvideFile.cc:245
zypp::RepoInfo::keepPackages
bool keepPackages() const
Whether packages downloaded from this repository will be kept in local cache.
Definition: RepoInfo.cc:646
zypp::RepoInfo::path
Pathname path() const
Repository path.
Definition: RepoInfo.cc:691
zypp::RepoInfo::baseUrlsSize
urls_size_type baseUrlsSize() const
number of repository urls
Definition: RepoInfo.cc:709
zypp::Fetcher
This class allows to retrieve a group of files in a confortable way, providing some smartness that do...
Definition: Fetcher.h:105