libzypp 17.32.2
MediaNetwork.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
13#include <iostream>
14#include <list>
15#include <chrono>
16
17#include <zypp/base/Logger.h>
18#include <zypp/base/String.h>
19#include <zypp/base/Gettext.h>
20
21#include <zypp-core/base/Regex.h>
22#include <zypp-core/fs/TmpPath.h>
23#include <zypp-core/zyppng/base/EventDispatcher>
24#include <zypp-core/zyppng/base/EventLoop>
25#include <zypp-core/zyppng/base/private/threaddata_p.h>
26
27#include <zypp-curl/ng/network/Downloader>
28#include <zypp-curl/ng/network/NetworkRequestDispatcher>
29#include <zypp-curl/ng/network/DownloadSpec>
30
31#include <zypp-media/MediaConfig>
33#include <zypp-media/auth/CredentialManager>
34
35#include <zypp/Target.h>
36#include <zypp/ZConfig.h>
37
38
39using std::endl;
40
41namespace internal {
42
43
44 constexpr std::string_view MEDIACACHE_REGEX("^\\/media\\.[1-9][0-9]*\\/media$");
45
47
48 using clock = std::chrono::steady_clock;
49
50 std::optional<clock::time_point> _timeStart;
51 std::optional<clock::time_point> _timeLast;
52
53 double _dnlTotal = 0.0;
54 double _dnlLast = 0.0;
55 double _dnlNow = 0.0;
56
57 int _dnlPercent= 0;
58
59 double _drateTotal= 0.0;
60 double _drateLast = 0.0;
61
62 void updateStats( double dltotal = 0.0, double dlnow = 0.0 )
63 {
64 clock::time_point now = clock::now();
65
66 if ( !_timeStart )
67 _timeStart = _timeLast = now;
68
69 // If called without args (0.0), recompute based on the last values seen
70 if ( dltotal && dltotal != _dnlTotal )
72
73 if ( dlnow && dlnow != _dnlNow ) {
74 _dnlNow = dlnow;
75 }
76
77 // percentage:
78 if ( _dnlTotal )
79 _dnlPercent = int(_dnlNow * 100 / _dnlTotal);
80
81 // download rates:
82 _drateTotal = _dnlNow / std::max( std::chrono::duration_cast<std::chrono::seconds>(now - *_timeStart).count(), int64_t(1) );
83
84 if ( _timeLast < now )
85 {
86 _drateLast = (_dnlNow - _dnlLast) / int( std::chrono::duration_cast<std::chrono::seconds>(now - *_timeLast).count() );
87 // start new period
88 _timeLast = now;
90 }
91 else if ( _timeStart == _timeLast )
93 }
94 };
95
96
97 // All media handler instances share the same EventDispatcher and Downloader
98 // This is released at application shutdown.
99 struct SharedData {
100
101 SharedData(const SharedData &) = delete;
102 SharedData(SharedData &&) = delete;
103 SharedData &operator=(const SharedData &) = delete;
105
107 MIL << "Releasing internal::SharedData for MediaNetwork." << std::endl;
108 }
109
110 static std::shared_ptr<SharedData> instance () {
111 static std::shared_ptr<SharedData> data = std::shared_ptr<SharedData>( new SharedData() );
112 return data;
113 }
114
115 static const zypp::str::regex &mediaRegex () {
116 static zypp::str::regex reg( MEDIACACHE_REGEX.data() );
117 return reg;
118 }
119
120 // we need to keep a reference
121 zyppng::EventDispatcherRef _dispatcher;
122 zyppng::DownloaderRef _downloader;
123
125
126 MediaFileCacheEntry( zypp::ManagedFile &&file ) : _file( std::move(file) ) { }
127
128 std::chrono::steady_clock::time_point _creationTime = std::chrono::steady_clock::now();
130 };
131
132 auto findInCache( const std::string &mediaCacheKey ) {
133 auto i = _mediaCacheEntries.find( mediaCacheKey );
134 if ( i != _mediaCacheEntries.end() ) {
135 auto age = std::chrono::steady_clock::now() - i->second._creationTime;
136 if ( age > std::chrono::minutes( 30 ) ) {
137 MIL << "Found cached media file, but it's older than 30 mins, requesting a new one" << std::endl;
138 _mediaCacheEntries.erase(i);
139 } else {
140 return i;
141 }
142 }
143 return _mediaCacheEntries.end();
144 }
145
147 std::unordered_map<std::string, MediaFileCacheEntry> _mediaCacheEntries;
148
149 private:
151 MIL << "Initializing internal::SharedData for MediaNetwork" << std::endl;
152 _dispatcher = zyppng::ThreadData::current().ensureDispatcher();
153 _downloader = std::make_shared<zyppng::Downloader>();
154 _downloader->requestDispatcher()->setMaximumConcurrentConnections( zypp::MediaConfig::instance().download_max_concurrent_connections() );
155 }
156 };
157
158}
159
160using namespace internal;
161using namespace zypp::base;
162
163namespace zypp {
164
165 namespace media {
166
170 "/", // urlpath at attachpoint
171 true ) // does_download
172 {
173 MIL << "MediaNetwork::MediaNetwork(" << url_r << ", " << attach_point_hint_r << ")" << endl;
174
175 // make sure there is a event loop and downloader instance
177
178 if( !attachPoint().empty())
179 {
181 Pathname apath(attachPoint() + "XXXXXX");
182 char *atemp = ::strdup( apath.asString().c_str());
183 char *atest = NULL;
184 if( !ainfo.isDir() || !ainfo.userMayRWX() ||
185 atemp == NULL || (atest=::mkdtemp(atemp)) == NULL)
186 {
187 WAR << "attach point " << ainfo.path()
188 << " is not useable for " << url_r.getScheme() << endl;
189 setAttachPoint("", true);
190 }
191 else if( atest != NULL)
192 ::rmdir(atest);
193
194 if( atemp != NULL)
195 ::free(atemp);
196 }
197 }
198
199 void MediaNetwork::attachTo (bool next)
200 {
201 if ( next )
203
204 if ( !_url.isValid() )
206
207 // use networkdispatcher check if the scheme is supported
208 if ( !_shared->_downloader->requestDispatcher()->supportsProtocol( _url ) ) {
209 std::string msg("Unsupported protocol '");
210 msg += _url.getScheme();
211 msg += "'";
213 }
214
216 {
218 }
219
221
223 setMediaSource(media);
224 }
225
226 bool
228 {
229 return MediaHandler::checkAttachPoint( apoint, true, true);
230 }
231
235
236 void MediaNetwork::releaseFrom( const std::string & ejectDev )
237 {
238 disconnect();
239 }
240
242 {
243 bool retry = true;
244 unsigned internalTry = 0;
245 static constexpr unsigned maxInternalTry = 3;
246
247 while ( retry ) {
248 retry = false;
249 auto ev = zyppng::EventLoop::create();
250 std::vector<zyppng::connection> signalConnections;
251 OnScopeExit deferred([&](){
252 while( signalConnections.size() ) {
253 signalConnections.back().disconnect();
254 signalConnections.pop_back();
255 }
256 });
257
258 zyppng::DownloadRef dl = _shared->_downloader->downloadFile( spec );
259 std::optional<internal::ProgressTracker> progTracker;
260
261 const auto &startedSlot = [&]( zyppng::Download &req ){
262 if ( !report) return;
263 (*report)->start( spec.url(), spec.targetPath());
264 };
265
266 const auto &aliveSlot = [&]( zyppng::Download &req, off_t dlNow ){
267 if ( !report || !progTracker )
268 return;
269 progTracker->updateStats( 0.0, dlNow );
270 if ( !(*report)->progress( progTracker->_dnlPercent, spec.url(), progTracker-> _drateTotal, progTracker->_drateLast ) )
271 req.cancel();
272 };
273
274 const auto &progressSlot = [&]( zyppng::Download &req, off_t dlTotal, off_t dlNow ) {
275 if ( !report || !progTracker )
276 return;
277
278 progTracker->updateStats( dlTotal, dlNow );
279 if ( !(*report)->progress( progTracker->_dnlPercent, spec.url(), progTracker-> _drateTotal, progTracker->_drateLast ) )
280 req.cancel();
281 };
282
283 const auto &finishedSlot = [&]( zyppng::Download & ){
284 ev->quit();
285 };
286
287 bool firstTry = true;
288 const auto &authRequiredSlot = [&]( zyppng::Download &req, zyppng::NetworkAuthData &auth, const std::string &availAuth ){
289
293
294 // get stored credentials
295 AuthData_Ptr cmcred = cm.getCred(_url);
296 if ( cmcred && auth.lastDatabaseUpdate() < cmcred->lastDatabaseUpdate() ) {
298 DBG << "got stored credentials:" << endl << *credentials << endl;
299
300 } else {
301 // if not found, ask user
305
306 // preset the username if present in current url
307 if (!_url.getUsername().empty() && firstTry)
308 curlcred->setUsername(_url.getUsername());
309 // if CM has found some credentials, preset the username from there
310 else if (cmcred)
311 curlcred->setUsername(cmcred->username());
312
313 // indicate we have no good credentials from CM
314 cmcred.reset();
315
316 std::string prompt_msg = str::Format(_("Authentication required for '%s'")) % _url.asString();
317
318 // set available authentication types from the signal
319 // might be needed in prompt
320 curlcred->setAuthType( availAuth );
321
322 // ask user
323 if (auth_report->prompt(_url, prompt_msg, *curlcred))
324 {
325 DBG << "callback answer: retry" << endl
326 << "CurlAuthData: " << *curlcred << endl;
327
328 if (curlcred->valid())
329 {
331 // if (credentials->username() != _url.getUsername())
332 // _url.setUsername(credentials->username());
340 }
341 }
342 else
343 {
344 DBG << "callback answer: cancel" << endl;
345 }
346 }
347
348 if ( !credentials ) {
350 return;
351 }
352
353 auth = *credentials;
354 if (!cmcred) {
355 credentials->setUrl(_url);
356 cm.addCred(*credentials);
357 cm.save();
358 }
359 };
360
361 signalConnections.insert( signalConnections.end(), {
362 dl->connectFunc( &zyppng::Download::sigStarted, startedSlot),
363 dl->connectFunc( &zyppng::Download::sigFinished, finishedSlot ),
364 dl->connectFunc( &zyppng::Download::sigAuthRequired, authRequiredSlot )
365 });
366
367 if ( report ) {
369 signalConnections.insert( signalConnections.end(), {
370 dl->connectFunc( &zyppng::Download::sigAlive, aliveSlot ),
371 dl->connectFunc( &zyppng::Download::sigProgress, progressSlot ),
372 });
373 }
374
375 dl->start();
376 ev->run();
377
378 std::for_each( signalConnections.begin(), signalConnections.end(), []( auto &conn ) { conn.disconnect(); });
379
380 if ( dl->hasError() ) {
382 std::exception_ptr excp;
383 const auto &error = dl->lastRequestError();
384 switch ( error.type() ) {
394 excp = ZYPP_EXCPT_PTR( zypp::media::MediaCurlException( spec.url(), error.toString(), error.nativeErrorString() ) );
395 break;
396 }
399 break;
400 }
403 break;
404 }
407 break;
408 }
410 excp = ZYPP_EXCPT_PTR( zypp::media::MediaTimeoutException( spec.url(), error.toString() ) );
411 break;
412 }
414 excp = ZYPP_EXCPT_PTR( zypp::media::MediaForbiddenException( spec.url(), error.toString() ) );
415 break;
416 }
419
420 //@BUG using getPathName() can result in wrong error messages
422 break;
423 }
427 excp = ZYPP_EXCPT_PTR( zypp::media::MediaUnauthorizedException( spec.url(), error.toString(), error.nativeErrorString(), "" ) );
428 break;
429 }
431 // should never happen
432 DBG << "BUG: Download error flag is set , but Error code is NoError" << std::endl;
433 break;
436 ++internalTry;
437 if ( internalTry < maxInternalTry ) {
438 retry = true;
439 // just report (NO_ERROR); no interactive request to the user
440 (*report)->problem( spec.url(), media::DownloadProgressReport::NO_ERROR, error.toString()+" "+_("Will try again..."));
441 continue;
442 } else {
443 excp = ZYPP_EXCPT_PTR( zypp::media::MediaCurlException( spec.url(), error.toString(), error.nativeErrorString() ) );
444 }
445
446 break;
447 }
448 }
449
450 if ( excp && !retry ) {
451 if ( report ) (*report)->finish( spec.url(), errCode, error.toString() );
452 std::rethrow_exception( excp );
453 }
454 }
455 }
456 if ( report ) (*report)->finish( spec.url(), zypp::media::DownloadProgressReport::NO_ERROR, "" );
457 }
458
459 void MediaNetwork::getFile( const OnMediaLocation &file ) const
460 {
461 // Use absolute file name to prevent access of files outside of the
462 // hierarchy below the attach point.
463 getFileCopy( file, localPath(file.filename()).absolutename() );
464 }
465
467 {
468 const auto &filename = file.filename();
469 Url fileurl(getFileUrl(filename));
470
471 const bool requestedMediaFile = _shared->mediaRegex().matches( filename.asString() );
472 auto &mediaFileCache = _shared->_mediaCacheEntries;
473 const auto &mediaCacheKey = fileurl.asCompleteString();
474
475 DBG << "FILEURL IS: " << fileurl << std::endl;
476 DBG << "Downloading to: " << targetFilename << std::endl;
477
478 if( assert_dir( targetFilename.dirname() ) ) {
479 DBG << "assert_dir " << targetFilename.dirname() << " failed" << endl;
480 ZYPP_THROW( MediaSystemException(getFileUrl(file.filename()), "System error on " + targetFilename.dirname().asString()) );
481 }
482
483 if ( requestedMediaFile ) {
484 MIL << "Requested " << filename << " trying media cache first" << std::endl;
485
486 auto i = _shared->findInCache( mediaCacheKey );
487 if ( i != mediaFileCache.end() ) {
488 MIL << "Found cached media file, returning a copy to the file" << std::endl;
489 if ( zypp::filesystem::hardlinkCopy( i->second._file, targetFilename ) == 0 )
490 return;
491
492 mediaFileCache.erase(i);
493 MIL << "Failed to copy the requested file, proceeding with download" << std::endl;
494 }
495
496 MIL << "Nothing in the file cache, requesting the file from the server." << std::endl;
497 }
498
500 .setDeltaFile( file.deltafile() )
501 .setHeaderSize( file.headerSize())
504
506
507 try {
508 runRequest( spec, &report );
510 if ( requestedMediaFile ) {
511 MIL << "Media file was not found, remembering in the cache" << std::endl;
513 }
514 std::rethrow_exception( std::current_exception() );
515 }
516
517 // the request was successful
518 if ( requestedMediaFile ) {
519 const auto &cacheFileName = (_shared->_mediaCacheDir.path() / zypp::CheckSum::md5FromString( mediaCacheKey).asString() ).extend(".cache");
522 mediaFileCache.insert_or_assign( mediaCacheKey, internal::SharedData::MediaFileCacheEntry( std::move(file) ) );
523 MIL << "Saved requested media file in media cache for future use" << std::endl;
524 } else {
525 MIL << "Failed to save requested media file in cache, requesting again next time." << std::endl;
526 }
527 }
528 }
529
530 bool MediaNetwork::getDoesFileExist( const Pathname & filename ) const
531 {
532 MIL << "Checking if file " << filename << " does exist" << std::endl;
533 Url fileurl(getFileUrl(filename));
534 const bool requestMediaFile = _shared->mediaRegex().matches( filename.asString() );
535 auto &mediaFileCache = _shared->_mediaCacheEntries;
536 const auto &mediaCacheKey = fileurl.asCompleteString();
537
538 if ( requestMediaFile ) {
539 MIL << "Request for " << filename << " is a media file, trying the cache first" << std::endl;
540 auto i = _shared->findInCache( mediaCacheKey );
541 if ( i != mediaFileCache.end() ) {
542 MIL << "Found a cache entry for requested media file, returning right away" << std::endl;
543 if ( i->second._file->empty() ) {
544 return false;
545 } else {
546 return true;
547 }
548 }
549 }
550
551 bool result = false; //we are pessimists
552 try
553 {
554 const auto &targetFilePath = localPath(filename).absolutename();
555
556 zyppng::DownloadSpec spec = zyppng::DownloadSpec( fileurl, targetFilePath )
557 .setCheckExistsOnly( true )
559
560 runRequest( spec );
561 // if we get to here the request worked.
562 result = true;
563 }
564 catch ( const MediaFileNotFoundException &e ) {
565 // if the file did not exist then we can return false
566 ZYPP_CAUGHT(e);
567 result = false;
568 }
569 // unexpected exception
570 catch (MediaException & excpt_r)
571 {
573 }
574
575 // if the file does not exist remember it right away in our cache
576 if ( !result && requestMediaFile ) {
577 MIL << filename << " does not exist on medium, remembering in the cache" << std::endl;
579 }
580
581 return result;
582 }
583
584 void MediaNetwork::getDir( const Pathname & dirname, bool recurse_r ) const
585 {
587 getDirInfo( content, dirname, /*dots*/false );
588
589 for ( filesystem::DirContent::const_iterator it = content.begin(); it != content.end(); ++it ) {
590 Pathname filename = dirname + it->name;
591 int res = 0;
592
593 switch ( it->type ) {
594 case filesystem::FT_NOT_AVAIL: // old directory.yast contains no typeinfo at all
596 getFile( OnMediaLocation( filename ) );
597 break;
598 case filesystem::FT_DIR: // newer directory.yast contain at least directory info
599 if ( recurse_r ) {
600 getDir( filename, recurse_r );
601 } else {
602 res = assert_dir( localPath( filename ) );
603 if ( res ) {
604 WAR << "Ignore error (" << res << ") on creating local directory '" << localPath( filename ) << "'" << endl;
605 }
606 }
607 break;
608 default:
609 // don't provide devices, sockets, etc.
610 break;
611 }
612 }
613 }
614
615 void MediaNetwork::getDirInfo( std::list<std::string> & retlist,
616 const Pathname & dirname, bool dots ) const
617 {
618 getDirectoryYast( retlist, dirname, dots );
619 }
620
622 const Pathname & dirname, bool dots ) const
623 {
624 getDirectoryYast( retlist, dirname, dots );
625 }
626
627 } // namespace media
628} // namespace zypp
629//
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition AutoDispose.h:95
void reset()
Reset to default Ctor values.
static CheckSum md5FromString(const std::string &input_r)
Definition CheckSum.h:103
static MediaConfig & instance()
Describes a resource file located on a medium.
const ByteCount & downloadSize() const
The size of the resource on the server.
const Pathname & filename() const
The path to the resource on the medium.
const Pathname & deltafile() const
The existing deltafile that can be used to reduce download size ( zchunk or metalink )
const ByteCount & headerSize() const
The size of the header prepending the resource (e.g.
const CheckSum & headerChecksum() const
The checksum of the header prepending the resource (e.g.
Url manipulation class.
Definition Url.h:92
std::string getScheme() const
Returns the scheme name of the URL.
Definition Url.cc:537
std::string asString() const
Returns a default string representation of the Url object.
Definition Url.cc:501
std::string getUsername(EEncoding eflag=zypp::url::E_DECODED) const
Returns the username from the URL authority.
Definition Url.cc:576
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
Definition Url.cc:608
bool isValid() const
Verifies the Url.
Definition Url.cc:493
static ZConfig & instance()
Singleton ctor.
Definition ZConfig.cc:925
Wrapper class for stat/lstat.
Definition PathInfo.h:222
const std::string & asString() const
String representation.
Definition Pathname.h:91
Pathname absolutename() const
Return this path, adding a leading '/' if relative.
Definition Pathname.h:139
Provide a new empty temporary directory and recursively delete it when no longer needed.
Definition TmpPath.h:178
static const Pathname & defaultLocation()
Definition TmpPath.cc:161
Curl HTTP authentication data.
Just inherits Exception to separate media exceptions.
bool isUseableAttachPoint(const Pathname &path, bool mtab=true) const
Ask media manager, if the specified path is already used as attach point or if there are another atta...
virtual bool checkAttachPoint(const Pathname &apoint) const
Verify if the specified directory as attach point (root) as requires by the particular media handler ...
void disconnect()
Use concrete handler to isconnect media.
Pathname createAttachPoint() const
Try to create a default / temporary attach point.
void setMediaSource(const MediaSourceRef &ref)
Set new media source reference.
Pathname localPath(const Pathname &pathname) const
Files provided will be available at 'localPath(filename)'.
const Url _url
Url to handle.
void getDirectoryYast(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const
Retrieve and if available scan dirname/directory.yast.
void setAttachPoint(const Pathname &path, bool temp)
Set a new attach point.
Pathname attachPoint() const
Return the currently used attach point.
Common baseclass for MediaCurl and MediaNetwork.
Url getFileUrl(const Pathname &filename) const
concatenate the attach url and the filename to a complete download url
bool checkAttachPoint(const Pathname &apoint) const override
Verify if the specified directory as attach point (root) as requires by the particular media handler ...
void disconnectFrom() override
void attachTo(bool next=false) override
Call concrete handler to attach the media.
void getDirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const override
Call concrete handler to provide a content list of directory on media via retlist.
void getDir(const Pathname &dirname, bool recurse_r) const override
Call concrete handler to provide directory content (not recursive!) below attach point.
bool getDoesFileExist(const Pathname &filename) const override
void runRequest(const zyppng::DownloadSpec &spec, callback::SendReport< DownloadProgressReport > *report=nullptr) const
MediaNetwork(const Url &url_r, const Pathname &attach_point_hint_r)
void releaseFrom(const std::string &ejectDev) override
Call concrete handler to release the media.
void getFile(const OnMediaLocation &file) const override
Call concrete handler to provide file below attach point.
void getFileCopy(const OnMediaLocation &file, const Pathname &targetFilename) const override
Call concrete handler to provide a file under a different place in the file system (usually not under...
std::shared_ptr<::internal::SharedData > _shared
Media source internally used by MediaManager and MediaHandler.
Definition MediaSource.h:38
Regular expression.
Definition Regex.h:95
DownloadSpec & setDeltaFile(const zypp::Pathname &file)
DownloadSpec & setCheckExistsOnly(bool set=true)
DownloadSpec & setHeaderChecksum(const zypp::CheckSum &sum)
DownloadSpec & setHeaderSize(const zypp::ByteCount &bc)
const zypp::Pathname & targetPath() const
const Url & url() const
DownloadSpec & setTransferSettings(TransferSettings &&set)
zypp::ByteCount expectedFileSize() const
constexpr std::string_view MEDIACACHE_REGEX("^\\/media\\.[1-9][0-9]*\\/media$")
Definition Arch.h:364
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:701
std::list< DirEntry > DirContent
Returned by readdir.
Definition PathInfo.h:519
int hardlinkCopy(const Pathname &oldpath, const Pathname &newpath)
Create newpath as hardlink or copy of oldpath.
Definition PathInfo.cc:884
shared_ptr< AuthData > AuthData_Ptr
Definition authdata.h:81
Easy-to use interface to the ZYPP dependency resolver.
zypp::media::CurlAuthData NetworkAuthData
Definition authdata.h:24
double _drateLast
Download rate in last period.
double _drateTotal
Download rate so far.
void updateStats(double dltotal=0.0, double dlnow=0.0)
double _dnlTotal
Bytes to download or 0 if unknown.
double _dnlLast
Bytes downloaded at period start.
std::chrono::steady_clock clock
double _dnlNow
Bytes downloaded now.
int _dnlPercent
Percent completed or 0 if _dnlTotal is unknown.
std::optional< clock::time_point > _timeStart
Start total stats.
std::optional< clock::time_point > _timeLast
Start last period(~1sec)
std::chrono::steady_clock::time_point _creationTime
MediaFileCacheEntry(zypp::ManagedFile &&file)
SharedData(const SharedData &)=delete
zypp::filesystem::TmpDir _mediaCacheDir
static std::shared_ptr< SharedData > instance()
SharedData & operator=(SharedData &&)=delete
SharedData(SharedData &&)=delete
static const zypp::str::regex & mediaRegex()
std::unordered_map< std::string, MediaFileCacheEntry > _mediaCacheEntries
zyppng::DownloaderRef _downloader
zyppng::EventDispatcherRef _dispatcher
SharedData & operator=(const SharedData &)=delete
auto findInCache(const std::string &mediaCacheKey)
Convenient building of std::string with boost::format.
Definition String.h:253
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition Exception.h:441
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:437
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Definition Exception.h:433
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:429
#define _(MSG)
Definition Gettext.h:37
#define DBG
Definition Logger.h:95
#define MIL
Definition Logger.h:96
#define WAR
Definition Logger.h:97