libzypp 17.36.7

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>
20#include <utility>
21#include <zypp-core/base/UserRequestException>
22#include <zypp/repo/RepoProvideFile.h>
23#include <zypp/ZYppCallbacks.h>
24#include <zypp/MediaSetAccess.h>
25#include <zypp/ZConfig.h>
26#include <zypp/ZYppFactory.h>
27#include <zypp/repo/SUSEMediaVerifier.h>
28#include <zypp/repo/RepoException.h>
29
30#include <zypp/repo/SUSEMediaVerifier.h>
31#include <zypp/repo/RepoException.h>
32#include <zypp/FileChecker.h>
33#include <zypp/Fetcher.h>
34
35 using std::endl;
36 using std::set;
37
39 namespace zypp
40{
42 namespace repo
43 {
44
46 //
47 // provideFile
48 //
50
52 namespace
53 {
54
60 struct DownloadFileReportHack : public callback::ReceiveReport<media::DownloadProgressReport>
61 {
62 using BaseType = callback::ReceiveReport<ReportType>;
63 using RedirectType = function<bool (int)>;
64
65 DownloadFileReportHack(RedirectType &&redirect_r)
66 : _oldRec(Distributor::instance().getReceiver()),
67 _redirect(std::move(redirect_r)) {
68 connect();
69 }
70
71 DownloadFileReportHack(const DownloadFileReportHack &) = delete;
72 DownloadFileReportHack(DownloadFileReportHack &&) = delete;
73 DownloadFileReportHack &operator=(const DownloadFileReportHack &) = delete;
74 DownloadFileReportHack &operator=(DownloadFileReportHack &&) = delete;
75
76 ~DownloadFileReportHack() override
77 { if ( _oldRec ) Distributor::instance().setReceiver( *_oldRec ); else Distributor::instance().noReceiver(); }
78
79 void start( const Url & file, Pathname localfile ) override
80 {
81 if ( _oldRec )
82 _oldRec->start( file, localfile );
83 else
84 BaseType::start( file, localfile );
85 }
86
87 bool progress( int value, const Url & file, double dbps_avg = -1, double dbps_current = -1 ) override
88 {
89 bool ret = true;
90 if ( _oldRec )
91 ret &= _oldRec->progress( value, file, dbps_avg, dbps_current );
92 if ( _redirect )
93 ret &= _redirect( value );
94 return ret;
95 }
96
97 Action problem( const Url & file, Error error, const std::string & description ) override
98 {
99 if ( _oldRec )
100 return _oldRec->problem( file, error, description );
101 return BaseType::problem( file, error, description );
102 }
103 void finish( const Url & file, Error error, const std::string & reason ) override
104 {
105 if ( _oldRec )
106 _oldRec->finish( file, error, reason );
107 else
108 BaseType::finish( file, error, reason );
109 }
110
111 private:
112 Receiver * _oldRec;
113 RedirectType _redirect;
114 };
115
117 } // namespace
119
120 ManagedFile provideFile( RepoInfo repo_r,
121 const OnMediaLocation & loc_r,
122 const ProvideFilePolicy & policy_r )
123 {
124 RepoMediaAccess access;
125 return access.provideFile(std::move(repo_r), loc_r, policy_r );
126 }
127
129 class RepoMediaAccess::Impl
130 {
131 public:
132 Impl(ProvideFilePolicy &&defaultPolicy_r)
133 : _defaultPolicy(std::move(defaultPolicy_r)) {}
134
135 Impl(const Impl &) = delete;
136 Impl(Impl &&) = delete;
137 Impl &operator=(const Impl &) = delete;
138 Impl &operator=(Impl &&) = delete;
139
140 ~Impl()
141 {
142 std::map<Url, shared_ptr<MediaSetAccess> >::iterator it;
143 for ( it = _medias.begin();
144 it != _medias.end();
145 ++it )
146 {
147 it->second->release();
148 }
149 }
150
158 shared_ptr<MediaSetAccess> mediaAccessForUrl( const Url &url, RepoInfo repo )
159 {
160 std::map<Url, shared_ptr<MediaSetAccess> >::const_iterator it;
161 it = _medias.find(url);
162 shared_ptr<MediaSetAccess> media;
163 if ( it != _medias.end() )
164 {
165 media = it->second;
166 }
167 else
168 {
169 media.reset( new MediaSetAccess(url) );
170 _medias[url] = media;
171 }
172 setVerifierForRepo( std::move(repo), media );
173 return media;
174 }
175
176 private:
177 void setVerifierForRepo( const RepoInfo& repo, const shared_ptr<MediaSetAccess>& media )
178 {
179 // Always set the MediaSetAccess label.
180 media->setLabel( repo.name() );
181
182 // set a verifier if the repository has it
183
184 Pathname mediafile = repo.metadataPath() + "/media.1/media";
185 if ( ! repo.metadataPath().empty() )
186 {
187 if ( PathInfo(mediafile).isExist() )
188 {
189 std::map<shared_ptr<MediaSetAccess>, RepoInfo>::const_iterator it;
190 it = _verifier.find(media);
191 if ( it != _verifier.end() )
192 {
193 if ( it->second.alias() == repo.alias() )
194 {
195 // this media is already using this repo verifier
196 return;
197 }
198 }
199
200 SUSEMediaVerifier lverifier { mediafile };
201 if ( lverifier ) {
202 DBG << "Verifier for repo '" << repo.alias() << "':" << lverifier << endl;
203 for ( media::MediaNr i = 1; i <= lverifier.totalMedia(); ++i ) {
204 media::MediaVerifierRef verifier( new repo::SUSEMediaVerifier( lverifier, i ) );
205 media->setVerifier( i, verifier);
206 }
207 _verifier[media] = repo;
208 }
209 else {
210 WAR << "Invalid verifier for repo '" << repo.alias() << "' in '" << repo.metadataPath() << "': " << lverifier << endl;
211 }
212 }
213 else
214 {
215 DBG << "No media verifier for repo '" << repo.alias() << "' media.1/media does not exist in '" << repo.metadataPath() << "'" << endl;
216 }
217 }
218 else
219 {
220 WAR << "'" << repo.alias() << "' metadata path is empty. Can't set verifier. Probably this repository does not come from RepoManager." << endl;
221 }
222 }
223
224 private:
225 std::map<shared_ptr<MediaSetAccess>, RepoInfo> _verifier;
226 std::map<Url, shared_ptr<MediaSetAccess> > _medias;
227
228 public:
229 ProvideFilePolicy _defaultPolicy;
230 };
231
232
233
234 RepoMediaAccess::RepoMediaAccess( ProvideFilePolicy defaultPolicy_r )
235 : _impl( new Impl( std::move(defaultPolicy_r) ) )
236 {}
237
238 RepoMediaAccess::~RepoMediaAccess()
239 {}
240
241 void RepoMediaAccess::setDefaultPolicy( const ProvideFilePolicy & policy_r )
242 { _impl->_defaultPolicy = policy_r; }
243
244 const ProvideFilePolicy & RepoMediaAccess::defaultPolicy() const
245 { return _impl->_defaultPolicy; }
246
247 ManagedFile RepoMediaAccess::provideFile( const RepoInfo& repo_r,
248 const OnMediaLocation & loc_rx,
249 const ProvideFilePolicy & policy_r )
250 {
251 const OnMediaLocation locWithPath( OnMediaLocation(loc_rx).prependPath( repo_r.path() ) );
252
253 MIL << locWithPath << endl;
254 // Arrange DownloadFileReportHack to recieve the source::DownloadFileReport
255 // and redirect download progress triggers to call the ProvideFilePolicy
256 // callback.
257 DownloadFileReportHack dumb( std::bind( std::mem_fn(&ProvideFilePolicy::progress), std::ref(policy_r), _1 ) );
258
259 RepoException repo_excpt(repo_r,
260 str::form(_("Can't provide file '%s' from repository '%s'"),
261 locWithPath.filename().c_str(),
262 repo_r.alias().c_str() ) );
263
264 if ( repo_r.baseUrlsEmpty() )
265 {
266 repo_excpt.remember(RepoException(_("No url in repository.")));
267 ZYPP_THROW(repo_excpt);
268 }
269
270 Fetcher fetcher;
271 fetcher.addCachePath( repo_r.packagesPath() );
272 MIL << "Added cache path " << repo_r.packagesPath() << endl;
273 fetcher.addCachePath( repo_r.predownloadPath(), Fetcher::CleanFiles );
274 MIL << "Added cache path " << repo_r.predownloadPath() << endl;
275
276 // Test whether download destination is writable, if not
277 // switch into the tmpspace (e.g. bnc#755239, download and
278 // install srpms as user).
279 Pathname destinationDir( repo_r.packagesPath() );
280
281 PathInfo pi( destinationDir );
282 if ( ! pi.isExist() )
283 {
284 // try to create it...
285 assert_dir( destinationDir );
286 pi();
287 }
288 if ( geteuid() != 0 && ! pi.userMayW() )
289 {
290 WAR << "Destination dir '" << destinationDir << "' is not user writable, using tmp space." << endl;
291 destinationDir = getZYpp()->tmpPath() / destinationDir;
292 assert_dir( destinationDir );
293 fetcher.addCachePath( destinationDir );
294 MIL << "Added cache path " << destinationDir << endl;
295 }
296
297 // Suppress (interactive) media::MediaChangeReport if we in have multiple basurls (>1)
298 media::ScopedDisableMediaChangeReport guard( repo_r.baseUrlsSize() > 1 );
299
300 for ( RepoInfo::urls_const_iterator it = repo_r.baseUrlsBegin();
301 it != repo_r.baseUrlsEnd();
302 /* incremented in the loop */ )
303 {
304 Url url( *it );
305 ++it;
306 try
307 {
308 MIL << "Providing file of repo '" << repo_r.alias() << "' from " << url << endl;
309 shared_ptr<MediaSetAccess> access = _impl->mediaAccessForUrl( url, repo_r );
310
311 fetcher.enqueue( locWithPath, policy_r.fileChecker() );
312 fetcher.start( destinationDir, *access );
313
314 // reached if no exception has been thrown, so this is the correct file
315 ManagedFile ret( destinationDir + locWithPath.filename() );
316 if ( !repo_r.keepPackages() )
317 {
318 ret.setDispose( filesystem::unlink );
319 }
320
321 MIL << "provideFile at " << ret << endl;
322 return ret;
323 }
324 catch ( const UserRequestException & excpt )
325 {
326 ZYPP_RETHROW( excpt );
327 }
328 catch ( const FileCheckException & excpt )
329 {
330 ZYPP_RETHROW( excpt );
331 }
332 catch ( const Exception &e )
333 {
334 ZYPP_CAUGHT( e );
335
336 repo_excpt.remember(e);
337
338 WAR << "Trying next url" << endl;
339 continue;
340 }
341 } // iteration over urls
342
343 ZYPP_THROW(repo_excpt);
344 return ManagedFile(); // not reached
345 }
346
348 } // namespace repo
351} // namespace zypp
Fetcher.h
FileChecker.h
MediaSetAccess.h
RepoException.h
RepoProvideFile.h
SUSEMediaVerifier.h
ZConfig.h
ZYppCallbacks.h
ZYppFactory.h
shared_ptr
zypp::AutoDispose::setDispose
void setDispose(const Dispose &dispose_r)
Set a new dispose function.
Definition AutoDispose.h:167
zypp::Exception
Base class for Exception.
Definition Exception.h:147
zypp::Exception::remember
void remember(const Exception &old_r)
Store an other Exception as history.
Definition Exception.cc:141
zypp::Fetcher
This class allows to retrieve a group of files in a confortable way, providing some smartness that do...
Definition Fetcher.h:104
zypp::Fetcher::CleanFiles
@ CleanFiles
Definition Fetcher.h:307
zypp::Fetcher::start
void start(const Pathname &dest_dir, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
start the transfer to a destination directory dest_dir The media has to be provides with setMediaSetA...
Definition Fetcher.cc:927
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:901
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:907
zypp::FileCheckException
Definition filecheckexception.h:18
zypp::MediaSetAccess
Media access layer responsible for handling files distributed on a set of media with media change and...
Definition MediaSetAccess.h:81
zypp::OnMediaLocation
Describes a resource file located on a medium.
Definition onmedialocation.h:37
zypp::OnMediaLocation::filename
const Pathname & filename() const
The path to the resource on the medium.
Definition onmedialocation.cc:88
zypp::ProvideFilePolicy
Policy for provideFile and RepoMediaAccess.
Definition ProvideFilePolicy.h:31
zypp::ProvideFilePolicy::fileChecker
ProvideFilePolicy & fileChecker(FileChecker fileChecker_r)
Add a FileCecker passed down to the Fetcher.
Definition ProvideFilePolicy.h:45
zypp::ProvideFilePolicy::progress
bool progress(int value) const
Evaluate callback.
Definition ProvideFilePolicy.cc:28
zypp::RepoInfo
What is known about a repository.
Definition RepoInfo.h:72
zypp::RepoInfo::baseUrlsEmpty
bool baseUrlsEmpty() const
whether repository urls are available
Definition RepoInfo.cc:678
zypp::RepoInfo::predownloadPath
Pathname predownloadPath() const
Path where this repo packages are predownloaded.
Definition RepoInfo.cc:597
zypp::RepoInfo::urls_const_iterator
transform_iterator< repo::RepoVariablesUrlReplacer, url_set::const_iterator > urls_const_iterator
Definition RepoInfo.h:110
zypp::RepoInfo::baseUrlsSize
urls_size_type baseUrlsSize() const
number of repository urls
Definition RepoInfo.cc:675
zypp::RepoInfo::keepPackages
bool keepPackages() const
Whether packages downloaded from this repository will be kept in local cache.
Definition RepoInfo.cc:609
zypp::RepoInfo::baseUrlsEnd
urls_const_iterator baseUrlsEnd() const
iterator that points at end of repository urls
Definition RepoInfo.cc:672
zypp::RepoInfo::path
Pathname path() const
Repository path.
Definition RepoInfo.cc:657
zypp::RepoInfo::baseUrlsBegin
urls_const_iterator baseUrlsBegin() const
iterator that points at begin of repository urls
Definition RepoInfo.cc:669
zypp::RepoInfo::packagesPath
Pathname packagesPath() const
Path where this repo packages are cached.
Definition RepoInfo.cc:618
zypp::Url
Url manipulation class.
Definition Url.h:93
zypp::UserRequestException
Base for exceptions caused by explicit user request.
Definition userrequestexception.h:65
zypp::ZYppFactory::getZYpp
ZYpp::Ptr getZYpp()
Convenience to get the Pointer to the ZYpp instance.
Definition ZYppFactory.h:77
zypp::filesystem::PathInfo
Wrapper class for stat/lstat.
Definition PathInfo.h:226
zypp::filesystem::PathInfo::userMayW
bool userMayW() const
Definition PathInfo.h:354
zypp::filesystem::PathInfo::isExist
bool isExist() const
Return whether valid stat info exists.
Definition PathInfo.h:286
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:47
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition Pathname.h:112
zypp::repo::RepoException
Exception for repository handling.
Definition RepoException.h:38
zypp::repo::RepoInfoBase::alias
std::string alias() const
unique identifier for this source.
Definition RepoInfoBase.cc:104
zypp::repo::RepoMediaAccess::Impl
Definition RepoProvideFile.cc:130
zypp::repo::RepoMediaAccess::Impl::_verifier
std::map< shared_ptr< MediaSetAccess >, RepoInfo > _verifier
Definition RepoProvideFile.cc:225
zypp::repo::RepoMediaAccess::Impl::_defaultPolicy
ProvideFilePolicy _defaultPolicy
Definition RepoProvideFile.cc:229
zypp::repo::RepoMediaAccess::Impl::~Impl
~Impl()
Definition RepoProvideFile.cc:140
zypp::repo::RepoMediaAccess::Impl::Impl
Impl(const Impl &)=delete
zypp::repo::RepoMediaAccess::Impl::operator=
Impl & operator=(Impl &&)=delete
zypp::repo::RepoMediaAccess::Impl::Impl
Impl(ProvideFilePolicy &&defaultPolicy_r)
Definition RepoProvideFile.cc:132
zypp::repo::RepoMediaAccess::Impl::_medias
std::map< Url, shared_ptr< MediaSetAccess > > _medias
Definition RepoProvideFile.cc:226
zypp::repo::RepoMediaAccess::Impl::Impl
Impl(Impl &&)=delete
zypp::repo::RepoMediaAccess::Impl::setVerifierForRepo
void setVerifierForRepo(const RepoInfo &repo, const shared_ptr< MediaSetAccess > &media)
Definition RepoProvideFile.cc:177
zypp::repo::RepoMediaAccess::Impl::operator=
Impl & operator=(const Impl &)=delete
zypp::repo::RepoMediaAccess::Impl::mediaAccessForUrl
shared_ptr< MediaSetAccess > mediaAccessForUrl(const Url &url, RepoInfo repo)
Provide a MediaSetAccess for url with label and verifier adjusted.
Definition RepoProvideFile.cc:158
zypp::repo::RepoMediaAccess
Provides files from different repos.
Definition RepoProvideFile.h:62
zypp::repo::RepoMediaAccess::setDefaultPolicy
void setDefaultPolicy(const ProvideFilePolicy &policy_r)
Set a new default ProvideFilePolicy.
Definition RepoProvideFile.cc:241
zypp::repo::RepoMediaAccess::_impl
RW_pointer< Impl > _impl
Definition RepoProvideFile.h:94
zypp::repo::RepoMediaAccess::~RepoMediaAccess
~RepoMediaAccess()
Definition RepoProvideFile.cc:238
zypp::repo::RepoMediaAccess::RepoMediaAccess
RepoMediaAccess(ProvideFilePolicy defaultPolicy_r=ProvideFilePolicy())
Ctor taking the default ProvideFilePolicy.
Definition RepoProvideFile.cc:234
zypp::repo::RepoMediaAccess::defaultPolicy
const ProvideFilePolicy & defaultPolicy() const
Get the current default ProvideFilePolicy.
Definition RepoProvideFile.cc:244
zypp::repo::RepoMediaAccess::provideFile
ManagedFile provideFile(const RepoInfo &repo_r, const OnMediaLocation &loc_r, const ProvideFilePolicy &policy_r)
Provide a file from a Repository.
Definition RepoProvideFile.cc:247
zypp::repo::SUSEMediaVerifier
Implementation of the traditional SUSE media verifier.
Definition SUSEMediaVerifier.h:28
std
Definition Arch.h:364
zypp::filesystem::unlink
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:705
zypp::media
Definition MediaCD.cc:47
zypp::media::MediaNr
unsigned int MediaNr
Definition MediaManager.h:32
zypp::media::MediaVerifierRef
zypp::RW_pointer< MediaVerifierBase > MediaVerifierRef
A shared reference to the MediaVerifier implementation.
Definition MediaManager.h:107
zypp::repo
Definition DeltaCandidates.cc:30
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:120
zypp::sat::operator=
SolvableSpec & operator=(const SolvableSpec &)=default
zypp::str::form
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition String.cc:37
zypp::url
Url details namespace.
Definition UrlBase.cc:58
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition Application.cc:20
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::media::ScopedDisableMediaChangeReport
Temporarily disable MediaChangeReport Sometimes helpful to suppress interactive messages connected to...
Definition ZYppCallbacks.h:354
ZYPP_RETHROW
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition Exception.h:444
ZYPP_CAUGHT
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:440
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:424
_
#define _(MSG)
Definition Gettext.h:39
DBG
#define DBG
Definition Logger.h:99
MIL
#define MIL
Definition Logger.h:100
WAR
#define WAR
Definition Logger.h:101
Gettext.h
Interface to gettext.
Logger.h
String.h