libzypp 17.37.17
provideitem.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
9
12#include "private/provide_p.h"
15#include "provide-configvars.h"
16#include <zypp-media/MediaException>
17#include <zypp-core/base/UserRequestException>
18#include "mediaverifier.h"
20
21using namespace std::literals;
22
23namespace zyppng {
24
25 static constexpr std::string_view DEFAULT_MEDIA_VERIFIER("SuseMediaV1");
26
28 {
29 if ( !origin.isValid () )
30 return expected<ProvideRequestRef>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("Origin config must be valid") ) );
31
32 auto m = ProvideMessage::createAttach( ProvideQueue::InvalidId, origin.authority().url(), id, spec.label() );
33 if ( !spec.mediaFile().empty() ) {
34 m.setValue( AttachMsgFields::VerifyType, std::string(DEFAULT_MEDIA_VERIFIER.data()) );
35 m.setValue( AttachMsgFields::VerifyData, spec.mediaFile().asString() );
36 m.setValue( AttachMsgFields::MediaNr, int32_t(spec.medianr()) );
37 }
38
39 const auto &cHeaders = spec.customHeaders();
40 for ( auto i = cHeaders.beginList (); i != cHeaders.endList(); i++) {
41 for ( const auto &val : i->second )
42 m.addValue( i->first, val );
43 }
44
45 return expected<ProvideRequestRef>::success( ProvideRequestRef( new ProvideRequest(&owner, origin, std::move(m))) );
46 }
47
49 {
50 if ( !origin.isValid () )
51 return expected<ProvideRequestRef>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("Origin config must be valid") ) );
52
53 auto m = ProvideMessage::createProvide ( ProvideQueue::InvalidId, origin.authority().url() );
54 const auto &destFile = spec.destFilenameHint();
55 const auto &deltaFile = spec.deltafile();
56 const int64_t fSize = spec.downloadSize();;
57
58 if ( !destFile.empty() )
59 m.setValue( ProvideMsgFields::Filename, destFile.asString() );
60 if ( !deltaFile.empty() )
61 m.setValue( ProvideMsgFields::DeltaFile, deltaFile.asString() );
62 if ( fSize )
63 m.setValue( ProvideMsgFields::ExpectedFilesize, fSize );
65
66 const auto &cHeaders = spec.customHeaders();
67 for ( auto i = cHeaders.beginList (); i != cHeaders.endList(); i++) {
68 for ( const auto &val : i->second )
69 m.addValue( i->first, val );
70 }
71
72 return expected<ProvideRequestRef>::success( ProvideRequestRef( new ProvideRequest(&owner, origin, std::move(m)) ) );
73 }
74
76 {
78 return expected<ProvideRequestRef>::success( ProvideRequestRef( new ProvideRequest( nullptr, { url }, std::move(m) ) ) );
79 }
80
82
86
89
91 {
92 return d_func()->_parent;
93 }
94
95 bool ProvideItem::safeRedirectTo( ProvideRequestRef startedReq, const zypp::Url &url )
96 {
97 if ( !canRedirectTo( startedReq, url ) )
98 return false;
99
100 redirectTo( startedReq, url );
101 return true;
102 }
103
104 void ProvideItem::redirectTo( ProvideRequestRef startedReq, const zypp::Url &url )
105 {
106 //@TODO strip irrelevant stuff from URL
107 startedReq->_pastRedirects.push_back ( url );
108 }
109
110 bool ProvideItem::canRedirectTo( ProvideRequestRef startedReq, const zypp::Url &url )
111 {
112 // make sure there is no redirect loop
113 if ( !startedReq->_pastRedirects.size() )
114 return true;
115
116 if ( std::find( startedReq->_pastRedirects.begin(), startedReq->_pastRedirects.end(), url ) != startedReq->_pastRedirects.end() )
117 return false;
118
119 return true;
120 }
121
122 const std::optional<ProvideItem::ItemStats> &ProvideItem::currentStats() const
123 {
124 return d_func()->_currStats;
125 }
126
127 const std::optional<ProvideItem::ItemStats> &ProvideItem::previousStats() const
128 {
129 return d_func()->_prevStats;
130 }
131
132 std::chrono::steady_clock::time_point ProvideItem::startTime() const
133 {
134 return d_func()->_itemStarted;
135 }
136
137 std::chrono::steady_clock::time_point ProvideItem::finishedTime() const {
138 return d_func()->_itemFinished;
139 }
140
142 {
144 if ( d->_currStats )
145 d->_prevStats = d->_currStats;
146
147 d->_currStats = makeStats();
148
149 // once the item is finished the pulse time is always the finish time
150 if ( d->_itemState == Finished )
151 d->_currStats->_pulseTime = d->_itemFinished;
152 }
153
155 {
156 return 0;
157 }
158
160 {
161 return ItemStats {
162 ._pulseTime = std::chrono::steady_clock::now(),
163 ._runningRequests = _runningReq ? (uint)1 : (uint)0
164 };
165 }
166
167 void ProvideItem::informalMessage ( ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg )
168 {
169 if ( req != _runningReq ) {
170 WAR << "Received event for unknown request, ignoring" << std::endl;
171 return;
172 }
173
174 if ( msg.code() == ProvideMessage::Code::ProvideStarted ) {
175 MIL << "Request: "<< req->url() << " was started" << std::endl;
176 }
177
178 }
179
180 void ProvideItem::cacheMiss( ProvideRequestRef req )
181 {
182 if ( req != _runningReq ) {
183 WAR << "Received event for unknown request, ignoring" << std::endl;
184 return;
185 }
186
187 MIL << "Request: "<< req->url() << " CACHE MISS, request will be restarted by queue." << std::endl;
188 }
189
190 void ProvideItem::finishReq(ProvideQueue &, ProvideRequestRef finishedReq, const ProvideMessage &msg )
191 {
192 if ( finishedReq != _runningReq ) {
193 WAR << "Received event for unknown request, ignoring" << std::endl;
194 return;
195 }
196
197 auto log = provider().log();
198
199 // explicitely handled codes
200 const auto code = msg.code();
201 if ( code == ProvideMessage::Code::Redirect ) {
202
203 // remove the old request
204 _runningReq.reset();
205
206 try {
207
208 MIL << "Request finished with redirect." << std::endl;
209
211 if ( !safeRedirectTo( finishedReq, newUrl ) ) {
213 return;
214 }
215
216 MIL << "Request redirected to: " << newUrl << std::endl;
217
218 if ( log ) log->requestRedirect( *this, msg.requestId(), newUrl );
219
220 finishedReq->setUrl( newUrl );
221
222 if ( !enqueueRequest( finishedReq ) ) {
223 cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
224 }
225 } catch ( ... ) {
226 cancelWithError( std::current_exception() );
227 return;
228 }
229 return;
230
231 } else if ( code == ProvideMessage::Code::Metalink ) {
232
233 // remove the old request
234 _runningReq.reset();
235
236 MIL << "Request finished with mirrorlist from server." << std::endl;
237
238 //@TODO get rid of metalink inside the provider and handle it just in legacy mode:
239 // code requests the metalist in RepoInfo and the provider already gets a clean MirroredOrigin config
240
241 zypp::MirroredOrigin newOrigin;
242 const auto &mirrors = msg.values( MetalinkRedirectMsgFields::NewUrl );
243 for( auto i = mirrors.cbegin(); i != mirrors.cend(); i++ ) {
244 try {
245 zypp::Url newUrl( i->asString() );
246 if ( !canRedirectTo( finishedReq, newUrl ) )
247 continue;
248 if ( !newOrigin.isValid () )
249 newOrigin.setAuthority (newUrl);
250 else
251 newOrigin.addMirror(newUrl);
252 } catch ( ... ) {
253 if ( i->isString() )
254 WAR << "Received invalid URL from worker: " << i->asString() << " ignoring!" << std::endl;
255 else
256 WAR << "Received invalid value for newUrl from worker ignoring!" << std::endl;
257 }
258 }
259
260 if ( newOrigin.endpointCount() == 0 ) {
261 cancelWithError( ZYPP_EXCPT_PTR ( zypp::media::MediaException("No mirrors left to redirect to.")) );
262 return;
263 }
264
265 MIL << "Found usable nr of mirrors: " << newOrigin.endpointCount() << std::endl;
266 finishedReq->setOrigin( std::move(newOrigin) );
267
268 // disable metalink
269 finishedReq->provideMessage().setValue( ProvideMsgFields::MetalinkEnabled, false );
270
271 if ( log ) log->requestDone( *this, msg.requestId() );
272
273 if ( !enqueueRequest( finishedReq ) ) {
274 cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
275 }
276
277 MIL << "End of mirrorlist handling"<< std::endl;
278 return;
279
280 } else if ( code >= ProvideMessage::Code::FirstClientErrCode && code <= ProvideMessage::Code::LastSrvErrCode ) {
281
282 // remove the old request
283 _runningReq.reset();
284
285 std::exception_ptr errPtr;
286 try {
287 const auto reqUrl = finishedReq->activeUrl().value();
288 const auto reason = msg.value( ErrMsgFields::Reason ).asString();
289 switch ( code ) {
290 case ProvideMessage::Code::BadRequest:
291 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException (zypp::str::Str() << "Bad request for URL: " << reqUrl << " " << reason ) );
292 break;
293 case ProvideMessage::Code::PeerCertificateInvalid:
294 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException(zypp::str::Str() << "PeerCertificateInvalid Error for URL: " << reqUrl << " " << reason) );
295 break;
296 case ProvideMessage::Code::ConnectionFailed:
297 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException(zypp::str::Str() << "ConnectionFailed Error for URL: " << reqUrl << " " << reason ) );
298 break;
299 case ProvideMessage::Code::ExpectedSizeExceeded: {
300
301 std::optional<int64_t> filesize;
302 const auto &hdrs = finishedReq->provideMessage ().headers ();
303 if ( hdrs.contains( ProvideMsgFields::ExpectedFilesize ) ) {
304 const auto &val = hdrs.value ( ProvideMsgFields::ExpectedFilesize );
305 if ( val.valid() )
306 filesize = val.asInt64();
307 }
308
309 if ( !filesize ) {
310 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "ExceededExpectedSize Error for URL: " << reqUrl << " " << reason ) );
311 } else {
312 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaFileSizeExceededException(reqUrl, *filesize ) );
313 }
314 break;
315 }
316 case ProvideMessage::Code::Cancelled:
317 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "Request was cancelled: " << reqUrl << " " << reason ) );
318 break;
319 case ProvideMessage::Code::InvalidChecksum:
320 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "InvalidChecksum Error for URL: " << reqUrl << " " << reason ) );
321 break;
322 case ProvideMessage::Code::Timeout:
324 break;
325 case ProvideMessage::Code::NotFound:
327 break;
328 case ProvideMessage::Code::Forbidden:
329 case ProvideMessage::Code::Unauthorized: {
330
331 const auto &hintVal = msg.value( "authHint"sv );
332 std::string hint;
333 if ( hintVal.valid() && hintVal.isString() ) {
334 hint = hintVal.asString();
335 }
336
337 //@TODO retry here with timestamp from cred store check
338 // we let the request fail after it checked the store
339
341 reqUrl, reason, "", hint
342 ));
343 break;
344
345 }
346 case ProvideMessage::Code::MountFailed:
347 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "MountFailed Error for URL: " << reqUrl << " " << reason ) );
348 break;
349 case ProvideMessage::Code::Jammed:
351 break;
352 case ProvideMessage::Code::MediaChangeSkip:
353 errPtr = ZYPP_EXCPT_PTR( zypp::SkipRequestException ( zypp::str::Str() << "User-requested skipping for URL: " << reqUrl << " " << reason ) );
354 break;
355 case ProvideMessage::Code::MediaChangeAbort:
356 errPtr = ZYPP_EXCPT_PTR( zypp::AbortRequestException( zypp::str::Str() <<"Aborting requested by user for URL: " << reqUrl << " " << reason ) );
357 break;
358 case ProvideMessage::Code::InternalError:
359 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "WorkerSpecific Error for URL: " << reqUrl << " " << reason ) );
360 break;
361 case ProvideMessage::Code::NotAFile:
363 break;
364 case ProvideMessage::Code::MediumNotDesired:
366 break;
367 default:
368 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "Unknown Error for URL: " << reqUrl << " " << reason ) );
369 break;
370 }
371 } catch (...) {
372 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "Invalid error message received for URL: " << *finishedReq->activeUrl() << " code: " << code ) );
373 }
374
375 if ( log ) log->requestFailed( *this, msg.requestId(), errPtr );
376 // finish the request
377 cancelWithError( errPtr );
378 return;
379 }
380
381 // if we reach here we don't know how to handle the message
382 _runningReq.reset();
383 cancelWithError( ZYPP_EXCPT_PTR (zypp::media::MediaException("Unhandled message received for ProvideFileItem")) );
384 }
385
386 void ProvideItem::finishReq(ProvideQueue *, ProvideRequestRef finishedReq , const std::exception_ptr excpt)
387 {
388 if ( finishedReq != _runningReq ) {
389 WAR << "Received event for unknown request, ignoring" << std::endl;
390 return;
391 }
392
393 if ( _runningReq ) {
394 auto log = provider().log();
395 if ( log ) log->requestFailed( *this, finishedReq->provideMessage().requestId(), excpt );
396 }
397
398 _runningReq.reset();
399 cancelWithError(excpt);
400 }
401
402 expected<zypp::media::AuthData> ProvideItem::authenticationRequired ( ProvideQueue &queue, ProvideRequestRef req, const zypp::Url &effectiveUrl, int64_t lastTimestamp, const std::map<std::string, std::string> &extraFields )
403 {
404
405 if ( req != _runningReq ) {
406 WAR << "Received authenticationRequired for unknown request, rejecting" << std::endl;
407 return expected<zypp::media::AuthData>::error( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unknown request in authenticationRequired, this is a bug.") ) );
408 }
409
410 try {
411 zypp::media::CredentialManager mgr ( provider().credManagerOptions() );
412
413 MIL << "Looking for existing auth data for " << effectiveUrl << "more recent then " << lastTimestamp << std::endl;
414
415 auto credPtr = mgr.getCred( effectiveUrl );
416 if ( credPtr && credPtr->lastDatabaseUpdate() > lastTimestamp ) {
417 MIL << "Found existing auth data for " << effectiveUrl << "ts: " << credPtr->lastDatabaseUpdate() << std::endl;
419 }
420
421 if ( credPtr ) MIL << "Found existing auth data for " << effectiveUrl << "but too old ts: " << credPtr->lastDatabaseUpdate() << std::endl;
422
423 std::string username;
424 if ( auto i = extraFields.find( std::string(AuthDataRequestMsgFields::LastUser) ); i != extraFields.end() ) {
425 username = i->second;
426 }
427
428
429 MIL << "NO Auth data found, asking user. Last tried username was: " << username << std::endl;
430
431 auto userAuth = provider()._sigAuthRequired.emit( effectiveUrl, username, extraFields );
432 if ( !userAuth || !userAuth->valid() ) {
433 MIL << "User rejected to give auth" << std::endl;
435 }
436
437 mgr.addCred( *userAuth );
438 mgr.save();
439
440 // rather ugly, but update the timestamp to the last mtime of the cred database our URL belongs to
441 // otherwise we'd need to reload the cred database
442 userAuth->setLastDatabaseUpdate( mgr.timestampForCredDatabase( effectiveUrl ) );
443
445 } catch ( const zypp::Exception &e ) {
446 ZYPP_CAUGHT(e);
448 }
449 }
450
451 bool ProvideItem::enqueueRequest( ProvideRequestRef request )
452 {
453 // base item just supports one running request at a time
454 if ( _runningReq )
455 return ( _runningReq == request );
456
457 _runningReq = request;
458 return d_func()->_parent.queueRequest( request );
459 }
460
461 void ProvideItem::updateState( const State newState )
462 {
463 Z_D();
464 if ( d->_itemState != newState ) {
465
466 bool started = ( d->_itemState == Uninitialized && ( newState != Finished ));
467 auto log = provider().log();
468
469 const auto oldState = d->_itemState;
470 d->_itemState = newState;
471 d->_sigStateChanged( *this, oldState, d->_itemState );
472
473 if ( started ) {
474 d->_itemStarted = std::chrono::steady_clock::now();
475 pulse();
476 if ( log ) log->itemStart( *this );
477 }
478
479 if ( newState == Finished ) {
480 d->_itemFinished = std::chrono::steady_clock::now();
481 pulse();
482 if ( log) log->itemDone( *this );
483 d->_parent.dequeueItem(this);
484 }
485 // CAREFUL, 'this' might be invalid from here on
486 }
487 }
488
490 {
491 if ( state() == Finished || state() == Finalizing )
492 return;
493
494 MIL << "Item Cleanup due to released Promise in state:" << state() << std::endl;
496 }
497
499 {
500 return d_func()->_itemState;
501 }
502
503 void ProvideRequest::setCurrentQueue( ProvideQueueRef ref )
504 {
505 _myQueue = ref;
506 }
507
509 {
510 return _myQueue.lock();
511 }
512
513 const std::optional<zypp::Url> ProvideRequest::activeUrl() const
514 {
516 switch ( this->_message.code () ) {
517 case ProvideMessage::Code::Attach:
519 break;
520 case ProvideMessage::Code::Detach:
522 break;
523 case ProvideMessage::Code::Prov:
525 break;
526 default:
527 // should never happen because we guard the constructor
528 throw std::logic_error("Invalid message type in ProvideRequest");
529 }
530 if ( !url.valid() ) {
531 return {};
532 }
533
534 try {
535 auto u = zypp::Url( url.asString() );
536 return u;
537 } catch ( const zypp::Exception &e ) {
538 ZYPP_CAUGHT(e);
539 }
540
541 return {};
542 }
543
545
546 switch ( this->_message.code () ) {
547 case ProvideMessage::Code::Attach:
548 this->_message.setValue( AttachMsgFields::Url, urlToUse.asCompleteString() );
549 break;
550 case ProvideMessage::Code::Detach:
551 this->_message.setValue( DetachMsgFields::Url, urlToUse.asCompleteString() );
552 break;
553 case ProvideMessage::Code::Prov:
554 this->_message.setValue( ProvideMsgFields::Url, urlToUse.asCompleteString() );
555 break;
556 default:
557 // should never happen because we guard the constructor
558 throw std::logic_error("Invalid message type in ProvideRequest");
559 }
560 }
561
564 , _origin ( std::move(origin) )
565 , _initialSpec ( request )
566 { }
567
569 {
570 return ProvideFileItemRef( new ProvideFileItem( std::move(origin), request, parent ) );
571 }
572
574 {
575 if ( state() != Uninitialized || _runningReq ) {
576 WAR << "Double init of ProvideFileItem!" << std::endl;
577 return;
578 }
579
580 auto req = ProvideRequest::create( *this, _origin, _initialSpec );
581 if ( !req ){
582 cancelWithError( req.error() );
583 return ;
584 }
585
586 if ( enqueueRequest( *req ) ) {
587 _expectedBytes = _initialSpec.downloadSize();
589 } else {
590 cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
591 return ;
592 }
593 }
594
596 {
597 if ( !_promiseCreated ) {
598 _promiseCreated = true;
599 auto promiseRef = std::make_shared<ProvidePromise<ProvideRes>>( shared_this<ProvideItem>() );
600 _promise = promiseRef;
601 return promiseRef;
602 }
603 return _promise.lock();
604 }
605
607 {
608 _handleRef = std::move(hdl);
609 }
610
615
616 void ProvideFileItem::informalMessage ( ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg )
617 {
618 if ( req != _runningReq ) {
619 WAR << "Received event for unknown request, ignoring" << std::endl;
620 return;
621 }
622
623 if ( msg.code() == ProvideMessage::Code::ProvideStarted ) {
624 MIL << "Provide File Request: "<< req->url() << " was started" << std::endl;
625 auto log = provider().log();
626
627 auto locPath = msg.value( ProvideStartedMsgFields::LocalFilename, std::string() ).asString();
628 if ( !locPath.empty() )
629 _targetFile = zypp::Pathname(locPath);
630
631 locPath = msg.value( ProvideStartedMsgFields::StagingFilename, std::string() ).asString();
632 if ( !locPath.empty() )
633 _stagingFile = zypp::Pathname(locPath);
634
635 if ( log ) {
636 auto effUrl = req->activeUrl().value_or( zypp::Url() );
637 try {
639 } catch( const zypp::Exception &e ) {
640 ZYPP_CAUGHT(e);
641 }
642
643 AnyMap m;
644 m["spec"] = _initialSpec;
645 if ( log ) log->requestStart( *this, msg.requestId(), effUrl, m );
647 }
648 }
649 }
650
651 void zyppng::ProvideFileItem::ProvideFileItem::finishReq( zyppng::ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg )
652 {
653 if ( finishedReq != _runningReq ) {
654 WAR << "Received event for unknown request, ignoring" << std::endl;
655 return;
656 }
657
658 if ( msg.code () == ProvideMessage::Code::ProvideFinished ) {
659
660 auto log = provider().log();
661 if ( log ) {
662 AnyMap m;
663 m["spec"] = _initialSpec;
664 if ( log ) log->requestDone( *this, msg.requestId(), m );
665 }
666
667 MIL << "Request was successfully finished!" << std::endl;
668 // request is def done
669 _runningReq.reset();
670
671 std::optional<zypp::ManagedFile> resFile;
672
673 try {
674 const auto locFilename = msg.value( ProvideFinishedMsgFields::LocalFilename ).asString();
675 const auto cacheHit = msg.value( ProvideFinishedMsgFields::CacheHit ).asBool();
676 const auto &wConf = queue.workerConfig();
677
678 const bool checkExistsOnly = _initialSpec.checkExistsOnly();
679 const bool doesDownload = wConf.worker_type() == ProvideQueue::Config::Downloading;
680 const bool fileNeedsCleanup = doesDownload || ( wConf.worker_type() == ProvideQueue::Config::CPUBound && wConf.cfg_flags() & ProvideQueue::Config::FileArtifacts );
681
682 if ( doesDownload && !checkExistsOnly ) {
683
684 resFile = provider().addToFileCache ( locFilename );
685 if ( !resFile ) {
686 if ( cacheHit ) {
687 MIL << "CACHE MISS, file " << locFilename << " was already removed, queueing again" << std::endl;
688 cacheMiss ( finishedReq );
689 finishedReq->clearForRestart();
690 enqueueRequest( finishedReq );
691 return;
692 } else {
693 // if we reach here it seems that a new file, that was not in cache before, vanished between
694 // providing it and receiving the finished message.
695 // unlikely this can happen but better be safe than sorry
696 cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("File vanished between downloading and adding it to cache.")) );
697 return;
698 }
699 }
700
701 } else {
702 resFile = zypp::ManagedFile( zypp::filesystem::Pathname(locFilename) );
703 if ( fileNeedsCleanup && !checkExistsOnly )
704 resFile->setDispose( zypp::filesystem::unlink );
705 else
706 resFile->resetDispose();
707 }
708
709 _targetFile = locFilename;
710
711 } catch ( const zypp::Exception &e ) {
712 ZYPP_CAUGHT(e);
713 cancelWithError( std::current_exception() );
714 } catch ( const std::exception &e ) {
715 ZYPP_CAUGHT(e);
716 cancelWithError( std::current_exception() );
717 } catch ( ...) {
718 cancelWithError( std::current_exception() );
719 }
720
721 // keep the media handle around as long as the file is used by the code
722 auto resObj = std::make_shared<ProvideResourceData>();
723 resObj->_mediaHandle = this->_handleRef;
724 resObj->_myFile = *resFile;
725 resObj->_resourceUrl = *(finishedReq->activeUrl());
726 resObj->_responseHeaders = msg.headers();
727
728 // if there is a exception escaping the pipeline we need to rethrow it after cleaning up
729 std::exception_ptr excpt;
730 auto p = promise();
731 if ( p ) {
732 try {
733 p->setReady( expected<ProvideRes>::success( ProvideRes( resObj )) );
734 } catch( const zypp::Exception &e ) {
735 ERR << "Caught unhandled pipline exception:" << e << std::endl;
736 ZYPP_CAUGHT(e);
737 excpt = std::current_exception ();
738 } catch ( const std::exception &e ) {
739 ERR << "Caught unhandled pipline exception:" << e.what() << std::endl;
740 ZYPP_CAUGHT(e);
741 excpt = std::current_exception ();
742 } catch ( ...) {
743 ERR << "Caught unhandled unknown exception:" << std::endl;
744 excpt = std::current_exception ();
745 }
746 }
747
748 updateState( Finished );
749
750 if ( excpt ) {
751 ERR << "Rethrowing pipeline exception, this is a BUG!" << std::endl;
752 std::rethrow_exception ( excpt );
753 }
754
755 } else {
756 // on errors we could recover from if we have mirrors we try to redirect
757 switch( msg.code() ) {
759 case NotFound:
760 case ConnectionFailed:
761 //case Timeout:
762 case InvalidChecksum: {
763 auto log = provider().log();
764 MIL << "Request failed trying to recover." << std::endl;
765
766 bool canRedirect = false;
767 for ( const auto &ep : _origin ) {
768 if ( canRedirectTo ( finishedReq, ep.url() ) ) {
769 canRedirect = true;
770 break;
771 }
772 }
773
774 if ( canRedirect ) {
775 MIL << "Trying to recover by redirecting to a mirror" << std::endl;
776 if ( enqueueRequest( finishedReq ) )
777 return;
778 }
779
780 MIL << "No mirror found or no mirror usable, giving up" << std::endl;
781 break;
782 }
783 default:
784 //all other codes handled by default code
785 break;
786 }
787 ProvideItem::finishReq ( queue, finishedReq, msg );
788 }
789 }
790
791
792 void zyppng::ProvideFileItem::cancelWithError( std::exception_ptr error )
793 {
794 if ( _runningReq ) {
795 auto weakThis = weak_from_this ();
796 provider().dequeueRequest ( _runningReq, error );
797 if ( weakThis.expired () )
798 return;
799 }
800
801 // if we reach this place for some reason finishReq was not called, lets clean up manually
802 _runningReq.reset();
803 auto p = promise();
804 if ( p ) {
805 try {
806 p->setReady( expected<ProvideRes>::error( error ) );
807 } catch( const zypp::Exception &e ) {
808 ZYPP_CAUGHT(e);
809 }
810 }
812 }
813
814 expected<zypp::media::AuthData> ProvideFileItem::authenticationRequired ( ProvideQueue &queue, ProvideRequestRef req, const zypp::Url &effectiveUrl, int64_t lastTimestamp, const std::map<std::string, std::string> &extraFields )
815 {
816 zypp::Url urlToUse = effectiveUrl;
817 if ( _handleRef.isValid() ) {
818 // if we have a attached medium this overrules the URL we are going to ask the user about... this is how the old media backend did handle this
819 // i guess there were never password protected repositories that have different credentials on the redirection targets
820 auto &attachedMedia = provider().attachedMediaInfos();
821 if ( std::find( attachedMedia.begin(), attachedMedia.end(), _handleRef.mediaInfo() ) == attachedMedia.end() )
822 return expected<zypp::media::AuthData>::error( ZYPP_EXCPT_PTR( zypp::media::MediaException("Attachment handle vanished during request.") ) );
823 urlToUse = _handleRef.mediaInfo()->attachedUrl();
824 }
825 return ProvideItem::authenticationRequired( queue, req, urlToUse, lastTimestamp, extraFields );
826 }
827
829 {
830 zypp::ByteCount providedByNow;
831
832 bool checkStaging = false;
833 if ( !_targetFile.empty() ) {
835 if ( inf.isExist() && inf.isFile() )
836 providedByNow = zypp::ByteCount( inf.size() );
837 else
838 checkStaging = true;
839 }
840
841 if ( checkStaging && !_stagingFile.empty() ) {
843 if ( inf.isExist() && inf.isFile() )
844 providedByNow = zypp::ByteCount( inf.size() );
845 }
846
847 auto baseStats = ProvideItem::makeStats();
848 baseStats._bytesExpected = bytesExpected();
849 baseStats._bytesProvided = providedByNow;
850 return baseStats;
851 }
852
854 {
855 return (_initialSpec.checkExistsOnly() ? zypp::ByteCount(0) : _expectedBytes);
856 }
857
859 : ProvideItem ( parent )
860 , _origin ( origin )
861 , _initialSpec ( request )
862 { }
863
865 {
866 MIL << "Killing the AttachMediaItem" << std::endl;
867 }
868
870 {
871 if ( !_promiseCreated ) {
872 _promiseCreated = true;
873 auto promiseRef = std::make_shared<ProvidePromise<Provide::MediaHandle>>( shared_this<ProvideItem>() );
874 _promise = promiseRef;
875 return promiseRef;
876 }
877 return _promise.lock();
878 }
879
881 {
882 if ( state() != Uninitialized ) {
883 WAR << "Double init of AttachMediaItem!" << std::endl;
884 return;
885 }
887
888 if ( !_origin.isValid() ) {
889 cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("No usable origin config.")) );
890 return;
891 }
892
893 // shortcut to the provider instance
894 auto &prov= provider();
895
896 // authority mandates the scheme
897 expected<ProvideQueue::Config> scheme = prov.schemeConfig( prov.effectiveScheme( _origin.authority().scheme() ) );
898
899 if ( !scheme || !_origin.isValid() ) {
900 auto prom = promise();
901 if ( prom ) {
902 try {
903 if ( !scheme )
904 prom->setReady( expected<Provide::MediaHandle>::error( scheme.error() ) );
905 else
906 prom->setReady( expected<Provide::MediaHandle>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("No valid mirrors available") )) );
907 } catch( const zypp::Exception &e ) {
908 ZYPP_CAUGHT(e);
909 }
910 }
912 return;
913 }
914
915 // first check if there is a already attached medium we can use as well
916 auto &attachedMedia = prov.attachedMediaInfos ();
917
918 // @TODO should we extend the mirrors here if some are not in the mirror list?
919 for ( auto &medium : attachedMedia ) {
920 if ( medium->isSameMedium ( _origin, _initialSpec ) ) {
921 finishWithSuccess ( medium );
922 return;
923 }
924 }
925
926 for ( auto &otherItem : prov.items() ) {
927 auto attachIt = std::dynamic_pointer_cast<AttachMediaItem>(otherItem);
928 if ( !attachIt // not the right type
929 || attachIt.get() == this // do not attach to ourselves
930 || attachIt->state () == Uninitialized // item was not initialized
931 || attachIt->state () == Finalizing // item cleaning up
932 || attachIt->state () == Finished ) // item done
933 continue;
934
935 // does this Item attach the same medium?
936 const bool sameMedium = AttachedMediaInfo::isSameMedium( attachIt->_origin, attachIt->_initialSpec, _origin, _initialSpec );
937 if ( !sameMedium )
938 continue;
939
940 MIL << "Found item providing the same medium, attaching to finished signal and waiting for it to be finished" << std::endl;
941
942 // it does, connect to its ready signal and just wait
944 return;
945 }
946
947 _workerType = scheme->worker_type();
948
949 switch( _workerType ) {
951
952 // if the media file is empty in the spec we can not do anything
953 // simply pretend attach worked
954 if( _initialSpec.mediaFile().empty() ) {
956 return;
957 }
958
959 // prepare the verifier with the data
960 auto smvDataLocal = MediaDataVerifier::createVerifier("SuseMediaV1");
961 if ( !smvDataLocal ) {
962 cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, no verifier instance was returned.")) );
963 return;
964 }
965
966 if ( !smvDataLocal->load( _initialSpec.mediaFile() ) ) {
967 cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, unable to load local verify data.")) );
968 return;
969 }
970
971 _verifier = smvDataLocal;
972
973 zypp::MirroredOrigin fileOrigin = _origin;
974 for ( auto &ep : fileOrigin ) {
975 ep.url().appendPathName ( ( zypp::str::Format("/media.%d/media") % _initialSpec.medianr() ).asString() );
976 }
977
978 // for downloading schemes we ask for the /media.x/media file and check the data manually
979 ProvideFileSpec spec;
980 spec.customHeaders() = _initialSpec.customHeaders();
981
982 // disable metalink
983 spec.customHeaders().set( std::string(NETWORK_METALINK_ENABLED), false );
984
985 auto req = ProvideRequest::create( *this, fileOrigin, spec );
986 if ( !req ) {
987 cancelWithError( req.error() );
988 return;
989 }
990 if ( !enqueueRequest( *req ) ) {
991 cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
992 return;
993 }
995 break;
996 }
999
1000 const auto &newId = provider().nextMediaId();
1001 auto req = ProvideRequest::create( *this, _origin, newId, _initialSpec );
1002 if ( !req ) {
1003 cancelWithError( req.error() );
1004 return;
1005 }
1006 if ( !enqueueRequest( *req ) ) {
1007 ERR << "Failed to queue request" << std::endl;
1008 cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
1009 return;
1010 }
1011 break;
1012 }
1013 default: {
1014 auto prom = promise();
1015 if ( prom ) {
1016 try {
1017 prom->setReady( expected<Provide::MediaHandle>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("URL scheme does not support attaching.") )) );
1018 } catch( const zypp::Exception &e ) {
1019 ZYPP_CAUGHT(e);
1020 }
1021 }
1023 return;
1024 }
1025 }
1026 }
1027
1028 void AttachMediaItem::finishWithSuccess( AttachedMediaInfo_Ptr medium )
1029 {
1030
1032
1033 auto prom = promise();
1034 try {
1035 if ( prom ) {
1036 try {
1037 prom->setReady( expected<Provide::MediaHandle>::success( Provide::MediaHandle( *static_cast<Provide*>( provider().z_func() ), medium ) ) );
1038 } catch( const zypp::Exception &e ) {
1039 ZYPP_CAUGHT(e);
1040 }
1041 }
1042 } catch ( const std::exception &e ) {
1043 ERR << "WTF " << e.what () << std::endl;
1044 } catch ( ... ) {
1045 ERR << "WTF " << std::endl;
1046 }
1047
1048 // tell others as well
1050
1051 prom->isReady ();
1052
1053 MIL << "Before setFinished" << std::endl;
1055 return;
1056 }
1057
1058 void AttachMediaItem::cancelWithError( std::exception_ptr error )
1059 {
1060 MIL << "Cancelling Item with error" << std::endl;
1062
1063 // tell children
1065
1066 if ( _runningReq ) {
1067 // we might get deleted when calling dequeueRequest
1068 auto weakThis = weak_from_this ();
1069 provider().dequeueRequest ( _runningReq, error );
1070 if ( weakThis.expired () )
1071 return;
1072 }
1073
1074 // if we reach this place we had no runningReq, clean up manually
1075 _runningReq.reset();
1076 _masterItemConn.disconnect();
1077
1078 auto p = promise();
1079 if ( p ) {
1080 try {
1081 p->setReady( expected<zyppng::Provide::MediaHandle>::error( error ) );
1082 } catch( const zypp::Exception &e ) {
1083 ZYPP_CAUGHT(e);
1084 }
1085 }
1087 }
1088
1090 {
1091
1092 _masterItemConn.disconnect();
1093
1094 if ( result ) {
1095 finishWithSuccess( AttachedMediaInfo_Ptr(result.get()) );
1096 } else {
1097 try {
1098 std::rethrow_exception ( result.error() );
1099 } catch ( const zypp::media::MediaRequestCancelledException & e) {
1100 // in case a item was cancelled, we revert to Pending state and trigger the scheduler.
1101 // This will make sure that all our sibilings that also depend on the master
1102 // can revert to pending state and we only get one new master in the next schedule run
1103 MIL_PRV << "Master item was cancelled, reverting to Uninitialized state and waiting for scheduler to run again" << std::endl;
1106
1107 } catch ( ... ) {
1108 cancelWithError( std::current_exception() );
1109 }
1110 }
1111 }
1112
1113 AttachMediaItemRef AttachMediaItem::create( const zypp::MirroredOrigin &origin, const ProvideMediaSpec &request, ProvidePrivate &parent )
1114 {
1115 return AttachMediaItemRef( new AttachMediaItem(origin, request, parent) );
1116 }
1117
1122
1123 void AttachMediaItem::finishReq ( ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg )
1124 {
1125 if ( finishedReq != _runningReq ) {
1126 WAR << "Received event for unknown request, ignoring" << std::endl;
1127 return;
1128 }
1129
1131 // success
1132 if ( msg.code() == ProvideMessage::Code::ProvideFinished ) {
1133
1135
1136 zypp::Url baseUrl = *finishedReq->activeUrl();
1137 // remove /media.n/media
1138 baseUrl.setPathName( zypp::Pathname(baseUrl.getPathName()).dirname().dirname() );
1139
1140 // we got the file, lets parse it
1141 auto smvDataRemote = MediaDataVerifier::createVerifier("SuseMediaV1");
1142 if ( !smvDataRemote ) {
1143 return cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, no verifier instance was returned.")) );
1144 }
1145
1146 if ( !smvDataRemote->load( msg.value( ProvideFinishedMsgFields::LocalFilename ).asString() ) ) {
1147 return cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, unable to load remote verify data.")) );
1148 }
1149
1150 // check if we got a valid media file
1151 if ( !smvDataRemote->valid () ) {
1152 return cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, unable to load local verify data.")) );
1153 }
1154
1155 // check if the received file matches with the one we have in the spec
1156 if (! _verifier->matches( smvDataRemote ) ) {
1157 DBG << "expect: " << _verifier << " medium " << _initialSpec.medianr() << std::endl;
1158 DBG << "remote: " << smvDataRemote << std::endl;
1159 return cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaNotDesiredException( *finishedReq->activeUrl() ) ) );
1160 }
1161
1162 // all good, register the medium and tell all child items
1163 _runningReq.reset();
1164
1166
1167 } else if ( msg.code() == ProvideMessage::Code::NotFound ) {
1168
1169 // simple downloading attachment we need to check the media file contents
1170 // in case of a error we might tolerate a file not found error in certain situations
1171 if ( _verifier->totalMedia () == 1 ) {
1172 // relaxed , tolerate a vanished media file
1173 _runningReq.reset();
1174
1176 }
1177 }
1178 } else {
1179 // real device attach
1180 if ( msg.code() == ProvideMessage::Code::AttachFinished ) {
1181
1182 std::optional<zypp::Pathname> mntPoint;
1184 if ( mountPtVal.valid() && mountPtVal.isString() ) {
1185 mntPoint = zypp::Pathname(mountPtVal.asString());
1186 }
1187
1188 _runningReq.reset();
1190 finishedReq->provideMessage().value( AttachMsgFields::AttachId ).asString()
1191 , queue.weak_this<ProvideQueue>()
1192 , _workerType
1193 , zypp::MirroredOrigin(*finishedReq->activeUrl()) // no mirrors
1194 , _initialSpec
1195 , mntPoint ) ) );
1196 }
1197 }
1198
1199 // unhandled message , let the base impl do it
1200 return ProvideItem::finishReq ( queue, finishedReq, msg );
1201 }
1202
1203 expected<zypp::media::AuthData> AttachMediaItem::authenticationRequired ( ProvideQueue &queue, ProvideRequestRef req, const zypp::Url &effectiveUrl, int64_t lastTimestamp, const std::map<std::string, std::string> &extraFields )
1204 {
1205 zypp::Url baseUrl = effectiveUrl;
1207 // remove /media.n/media
1208 baseUrl.setPathName( zypp::Pathname(baseUrl.getPathName()).dirname().dirname() );
1209 }
1210 return ProvideItem::authenticationRequired( queue, req, baseUrl, lastTimestamp, extraFields );
1211 }
1212
1213}
Store and operate with byte count.
Definition ByteCount.h:32
Base class for Exception.
Definition Exception.h:153
Manages a data source characterized by an authoritative URL and a list of mirror URLs.
void setAuthority(OriginEndpoint newAuthority)
bool addMirror(OriginEndpoint newMirror)
Url manipulation class.
Definition Url.h:93
std::string asCompleteString() const
Returns a complete string representation of the Url object.
Definition Url.cc:523
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
Definition Url.cc:622
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
Definition Url.cc:782
Wrapper class for stat/lstat.
Definition PathInfo.h:226
bool isExist() const
Return whether valid stat info exists.
Definition PathInfo.h:286
Pathname dirname() const
Return all but the last component od this path.
Definition Pathname.h:126
const std::string & asString() const
String representation.
Definition Pathname.h:93
bool empty() const
Test for an empty path.
Definition Pathname.h:116
void save()
Saves any unsaved credentials added via addUserCred() or addGlobalCred() methods.
time_t timestampForCredDatabase(const zypp::Url &url)
AuthData_Ptr getCred(const Url &url)
Get credentials for the specified url.
void addCred(const AuthData &cred)
Add new credentials with user callbacks.
Just inherits Exception to separate media exceptions.
static AttachMediaItemRef create(const zypp::MirroredOrigin &origin, const ProvideMediaSpec &request, ProvidePrivate &parent)
AttachMediaItem(const zypp::MirroredOrigin &origin, const ProvideMediaSpec &request, ProvidePrivate &parent)
void initialize() override
Signal< void(const zyppng::expected< AttachedMediaInfo * > &)> _sigReady
void finishReq(ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg) override
ProvidePromiseRef< Provide::MediaHandle > promise()
SignalProxy< void(const zyppng::expected< AttachedMediaInfo * > &) > sigReady()
void finishWithSuccess(AttachedMediaInfo_Ptr medium)
MediaDataVerifierRef _verifier
ProvidePromiseWeakRef< Provide::MediaHandle > _promise
ProvideQueue::Config::WorkerType _workerType
ProvideMediaSpec _initialSpec
zypp::MirroredOrigin _origin
void cancelWithError(std::exception_ptr error) override
expected< zypp::media::AuthData > authenticationRequired(ProvideQueue &queue, ProvideRequestRef req, const zypp::Url &effectiveUrl, int64_t lastTimestamp, const std::map< std::string, std::string > &extraFields) override
void onMasterItemReady(const zyppng::expected< AttachedMediaInfo * > &result)
bool isSameMedium(const zypp::MirroredOrigin &origin, const ProvideMediaSpec &spec)
std::shared_ptr< T > shared_this() const
Definition base.h:113
WeakPtr parent() const
Definition base.cc:26
static auto connect(typename internal::MemberFunction< SenderFunc >::ClassType &s, SenderFunc &&sFun, typename internal::MemberFunction< ReceiverFunc >::ClassType &recv, ReceiverFunc &&rFunc)
Definition base.h:142
std::weak_ptr< T > weak_this() const
Definition base.h:123
void set(const std::string &key, Value val)
const std::string & asString() const
static MediaDataVerifierRef createVerifier(const std::string &verifierType)
expected< zypp::media::AuthData > authenticationRequired(ProvideQueue &queue, ProvideRequestRef req, const zypp::Url &effectiveUrl, int64_t lastTimestamp, const std::map< std::string, std::string > &extraFields) override
ProvideFileItem(zypp::MirroredOrigin origin, const ProvideFileSpec &request, ProvidePrivate &parent)
zypp::Pathname _stagingFile
void cancelWithError(std::exception_ptr error) override
zypp::ByteCount bytesExpected() const override
void setMediaRef(Provide::MediaHandle &&hdl)
Provide::MediaHandle & mediaRef()
Provide::MediaHandle _handleRef
void initialize() override
zypp::MirroredOrigin _origin
ProvideFileSpec _initialSpec
static ProvideFileItemRef create(zypp::MirroredOrigin origin, const ProvideFileSpec &request, ProvidePrivate &parent)
ProvidePromiseRef< ProvideRes > promise()
zypp::ByteCount _expectedBytes
zypp::Pathname _targetFile
ItemStats makeStats() override
void informalMessage(ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg) override
ProvidePromiseWeakRef< ProvideRes > _promise
HeaderValueMap & customHeaders()
const zypp::Pathname & destFilenameHint() const
const zypp::ByteCount & downloadSize() const
The size of the resource on the server.
const zypp::Pathname & deltafile() const
The existing deltafile that can be used to reduce download size ( zchunk or metalink )
bool checkExistsOnly() const
bool safeRedirectTo(ProvideRequestRef startedReq, const zypp::Url &url)
virtual std::chrono::steady_clock::time_point startTime() const
virtual void cacheMiss(ProvideRequestRef req)
ProvideItem(ProvidePrivate &parent)
ProvidePrivate & provider()
virtual expected< zypp::media::AuthData > authenticationRequired(ProvideQueue &queue, ProvideRequestRef req, const zypp::Url &effectiveUrl, int64_t lastTimestamp, const std::map< std::string, std::string > &extraFields)
virtual ItemStats makeStats()
friend class Provide
Definition provideitem.h:31
virtual bool canRedirectTo(ProvideRequestRef startedReq, const zypp::Url &url)
virtual std::chrono::steady_clock::time_point finishedTime() const
virtual zypp::ByteCount bytesExpected() const
ProvideRequestRef _runningReq
void redirectTo(ProvideRequestRef startedReq, const zypp::Url &url)
State state() const
virtual void informalMessage(ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg)
const std::optional< ItemStats > & previousStats() const
friend class ProvidePrivate
Definition provideitem.h:32
virtual void released()
virtual void finishReq(ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg)
virtual void cancelWithError(std::exception_ptr error)=0
const std::optional< ItemStats > & currentStats() const
void updateState(const State newState)
friend class ProvideQueue
Definition provideitem.h:33
virtual bool enqueueRequest(ProvideRequestRef request)
HeaderValueMap & customHeaders()
unsigned medianr() const
zypp::Pathname mediaFile() const
const std::string & label() const
const HeaderValueMap & headers() const
FieldVal value(const std::string_view &str, const FieldVal &defaultVal=FieldVal()) const
const std::vector< ProvideMessage::FieldVal > & values(const std::string_view &str) const
static ProvideMessage createProvide(const uint32_t reqId, const zypp::Url &url, const std::optional< std::string > &filename={}, const std::optional< std::string > &deltaFile={}, const std::optional< int64_t > &expFilesize={}, bool checkExistOnly=false)
static ProvideMessage createDetach(const uint32_t reqId, const zypp::Url &attachUrl)
static ProvideMessage createAttach(const uint32_t reqId, const zypp::Url &url, const std::string attachId, const std::string &label, const std::optional< std::string > &verifyType={}, const std::optional< std::string > &verifyData={}, const std::optional< int32_t > &mediaNr={})
bool dequeueRequest(ProvideRequestRef req, std::exception_ptr error)
Definition provide.cc:832
std::string nextMediaId() const
Definition provide.cc:798
Signal< std::optional< zypp::media::AuthData >(const zypp::Url &reqUrl, const std::string &triedUsername, const std::map< std::string, std::string > &extraValues) > _sigAuthRequired
Definition provide_p.h:97
std::vector< AttachedMediaInfo_Ptr > & attachedMediaInfos()
Definition provide.cc:734
void schedule(ScheduleReason reason)
Definition provide.cc:38
ProvideStatusRef log()
Definition provide_p.h:90
const Config & workerConfig() const
static constexpr uint32_t InvalidId
void setActiveUrl(const zypp::Url &urlToUse)
ProvideQueueWeakRef _myQueue
static expected< ProvideRequestRef > createDetach(const zypp::Url &url)
ProvideMessage _message
zypp::Url url() const
void setCurrentQueue(ProvideQueueRef ref)
ProvideItem * owner()
ProvideQueueRef currentQueue()
const zypp::MirroredOrigin & origin() const
const std::optional< zypp::Url > activeUrl() const
Returns the currenty active URL as set by the scheduler.
static expected< ProvideRequestRef > create(ProvideItem &owner, const zypp::MirroredOrigin &origin, const std::string &id, ProvideMediaSpec &spec)
ProvideRequest(ProvideItem *owner, zypp::MirroredOrigin origin, ProvideMessage &&msg)
A ProvideRes object is a reference counted ownership of a resource in the cache provided by a Provide...
Definition provideres.h:36
ProvideMediaHandle MediaHandle
Definition provide.h:124
WorkerType worker_type() const
static expected success(ConsParams &&...params)
Definition expected.h:115
static expected error(ConsParams &&...params)
Definition expected.h:126
Definition Arch.h:364
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:705
Url details namespace.
Definition UrlBase.cc:58
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
Definition ManagedFile.h:27
intrusive_ptr< T > make_intrusive(Args &&... __args)
Definition PtrTypes.h:103
constexpr std::string_view LocalMountPoint("local_mountpoint")
constexpr std::string_view AttachId("attach_id")
constexpr std::string_view VerifyData("verify_data")
constexpr std::string_view VerifyType("verify_type")
constexpr std::string_view MediaNr("media_nr")
constexpr std::string_view Url("url")
constexpr std::string_view LastUser("username")
constexpr std::string_view Url("url")
constexpr std::string_view Reason("reason")
constexpr std::string_view NewUrl("new_url")
constexpr std::string_view LocalFilename("local_filename")
constexpr std::string_view CacheHit("cacheHit")
constexpr std::string_view Url("url")
constexpr std::string_view MetalinkEnabled("metalink_enabled")
constexpr std::string_view ExpectedFilesize("expected_filesize")
constexpr std::string_view DeltaFile("delta_file")
constexpr std::string_view CheckExistOnly("check_existance_only")
constexpr std::string_view Filename("filename")
constexpr std::string_view StagingFilename("staging_filename")
constexpr std::string_view Url("url")
constexpr std::string_view LocalFilename("local_filename")
constexpr std::string_view NewUrl("new_url")
constexpr std::string_view NETWORK_METALINK_ENABLED("zypp-nw-metalink-enabled")
@ PeerCertificateInvalid
static constexpr std::string_view DEFAULT_MEDIA_VERIFIER("SuseMediaV1")
std::shared_ptr< ProvidePromise< T > > ProvidePromiseRef
std::unordered_map< std::string, boost::any > AnyMap
Definition provide.h:48
#define MIL_PRV
Convenient building of std::string with boost::format.
Definition String.h:254
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition String.h:213
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:475
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Definition Exception.h:463
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
Definition Exception.h:471
#define DBG
Definition Logger.h:99
#define MIL
Definition Logger.h:100
#define ERR
Definition Logger.h:102
#define WAR
Definition Logger.h:101
#define ZYPP_IMPL_PRIVATE(Class)
Definition zyppglobal.h:92
#define Z_D()
Definition zyppglobal.h:105