libzypp 17.31.23
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"
19#include <zypp-core/fs/PathInfo.h>
20
21using namespace std::literals;
22
23namespace zyppng {
24
25 static constexpr std::string_view DEFAULT_MEDIA_VERIFIER("SuseMediaV1");
26
27 expected<ProvideRequestRef> ProvideRequest::create(ProvideItem &owner, const std::vector<zypp::Url> &urls, const std::string &id, ProvideMediaSpec &spec )
28 {
29 if ( urls.empty() )
30 return expected<ProvideRequestRef>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("List of URLs can not be empty") ) );
31
32 auto m = ProvideMessage::createAttach( ProvideQueue::InvalidId, urls.front(), 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, urls, std::move(m))) );
46 }
47
48 expected<ProvideRequestRef> ProvideRequest::create( ProvideItem &owner, const std::vector<zypp::Url> &urls, ProvideFileSpec &spec )
49 {
50 if ( urls.empty() )
51 return expected<ProvideRequestRef>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("List of URLs can not be empty") ) );
52
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, urls, std::move(m)) ) );
73 }
74
75 expected<ProvideRequestRef> ProvideRequest::createDetach( const zypp::Url &url )
76 {
78 return expected<ProvideRequestRef>::success( ProvideRequestRef( new ProvideRequest( nullptr, { url }, std::move(m) ) ) );
79 }
80
82
84 : Base( *new ProvideItemPrivate( parent, *this ) )
85 { }
86
88 { }
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;
136
137 std::chrono::steady_clock::time_point ProvideItem::finishedTime() const {
138 return d_func()->_itemFinished;
139 }
140
142 {
143 Z_D();
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 do we need to merge this with the mirrorlist we got from the user?
239 // or does a mirrorlist from d.o.o invalidate that?
240
241 std::vector<zypp::Url> urls;
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 urls.push_back ( newUrl );
249 } catch ( ... ) {
250 if ( i->isString() )
251 WAR << "Received invalid URL from worker: " << i->asString() << " ignoring!" << std::endl;
252 else
253 WAR << "Received invalid value for newUrl from worker ignoring!" << std::endl;
254 }
255 }
256
257 if ( urls.size () == 0 ) {
258 cancelWithError( ZYPP_EXCPT_PTR ( zypp::media::MediaException("No mirrors left to redirect to.")) );
259 return;
260 }
261
262 MIL << "Found usable nr of mirrors: " << urls.size () << std::endl;
263 finishedReq->setUrls( urls );
264
265 // disable metalink
266 finishedReq->provideMessage().setValue( ProvideMsgFields::MetalinkEnabled, false );
267
268 if ( log ) log->requestDone( *this, msg.requestId() );
269
270 if ( !enqueueRequest( finishedReq ) ) {
271 cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
272 }
273
274 MIL << "End of mirrorlist handling"<< std::endl;
275 return;
276
277 } else if ( code >= ProvideMessage::Code::FirstClientErrCode && code <= ProvideMessage::Code::LastSrvErrCode ) {
278
279 // remove the old request
280 _runningReq.reset();
281
282 std::exception_ptr errPtr;
283 try {
284 const auto reqUrl = finishedReq->activeUrl().value();
285 const auto reason = msg.value( ErrMsgFields::Reason ).asString();
286 switch ( code ) {
287 case ProvideMessage::Code::BadRequest:
288 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException (zypp::str::Str() << "Bad request for URL: " << reqUrl << " " << reason ) );
289 break;
290 case ProvideMessage::Code::PeerCertificateInvalid:
291 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException(zypp::str::Str() << "PeerCertificateInvalid Error for URL: " << reqUrl << " " << reason) );
292 break;
293 case ProvideMessage::Code::ConnectionFailed:
294 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException(zypp::str::Str() << "ConnectionFailed Error for URL: " << reqUrl << " " << reason ) );
295 break;
296 case ProvideMessage::Code::ExpectedSizeExceeded: {
297
298 std::optional<int64_t> filesize;
299 finishedReq->provideMessage ().forEachVal( [&]( const std::string &key, const auto &val ){
300 if ( key == ProvideMsgFields::ExpectedFilesize && val.valid() )
301 filesize = val.asInt64();
302 return true;
303 });
304
305 if ( !filesize ) {
306 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "ExceededExpectedSize Error for URL: " << reqUrl << " " << reason ) );
307 } else {
308 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaFileSizeExceededException(reqUrl, *filesize ) );
309 }
310 break;
311 }
312 case ProvideMessage::Code::Cancelled:
313 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "Request was cancelled: " << reqUrl << " " << reason ) );
314 break;
315 case ProvideMessage::Code::InvalidChecksum:
316 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "InvalidChecksum Error for URL: " << reqUrl << " " << reason ) );
317 break;
318 case ProvideMessage::Code::Timeout:
320 break;
321 case ProvideMessage::Code::NotFound:
323 break;
324 case ProvideMessage::Code::Forbidden:
325 case ProvideMessage::Code::Unauthorized: {
326
327 const auto &hintVal = msg.value( "authHint"sv );
328 std::string hint;
329 if ( hintVal.valid() && hintVal.isString() ) {
330 hint = hintVal.asString();
331 }
332
333 //@TODO retry here with timestamp from cred store check
334 // we let the request fail after it checked the store
335
337 reqUrl, reason, "", hint
338 ));
339 break;
340
341 }
342 case ProvideMessage::Code::MountFailed:
343 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "MountFailed Error for URL: " << reqUrl << " " << reason ) );
344 break;
345 case ProvideMessage::Code::Jammed:
347 break;
348 case ProvideMessage::Code::MediaChangeSkip:
349 errPtr = ZYPP_EXCPT_PTR( zypp::SkipRequestException ( zypp::str::Str() << "User-requested skipping for URL: " << reqUrl << " " << reason ) );
350 break;
351 case ProvideMessage::Code::MediaChangeAbort:
352 errPtr = ZYPP_EXCPT_PTR( zypp::AbortRequestException( zypp::str::Str() <<"Aborting requested by user for URL: " << reqUrl << " " << reason ) );
353 break;
354 case ProvideMessage::Code::InternalError:
355 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "WorkerSpecific Error for URL: " << reqUrl << " " << reason ) );
356 break;
357 case ProvideMessage::Code::NotAFile:
359 break;
360 case ProvideMessage::Code::MediumNotDesired:
362 break;
363 default:
364 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "Unknown Error for URL: " << reqUrl << " " << reason ) );
365 break;
366 }
367 } catch (...) {
368 errPtr = ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "Invalid error message received for URL: " << *finishedReq->activeUrl() << " code: " << code ) );
369 }
370
371 if ( log ) log->requestFailed( *this, msg.requestId(), errPtr );
372 // finish the request
373 cancelWithError( errPtr );
374 return;
375 }
376
377 // if we reach here we don't know how to handle the message
378 _runningReq.reset();
379 cancelWithError( ZYPP_EXCPT_PTR (zypp::media::MediaException("Unhandled message received for ProvideFileItem")) );
380 }
381
382 void ProvideItem::finishReq(ProvideQueue *, ProvideRequestRef finishedReq , const std::exception_ptr excpt)
383 {
384 if ( finishedReq != _runningReq ) {
385 WAR << "Received event for unknown request, ignoring" << std::endl;
386 return;
387 }
388
389 if ( _runningReq ) {
390 auto log = provider().log();
391 if ( log ) log->requestFailed( *this, finishedReq->provideMessage().requestId(), excpt );
392 }
393
394 _runningReq.reset();
395 cancelWithError(excpt);
396 }
397
398 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 )
399 {
400
401 if ( req != _runningReq ) {
402 WAR << "Received authenticationRequired for unknown request, rejecting" << std::endl;
403 return expected<zypp::media::AuthData>::error( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unknown request in authenticationRequired, this is a bug.") ) );
404 }
405
406 try {
407 zypp::media::CredentialManager mgr ( provider().credManagerOptions() );
408
409 MIL << "Looking for existing auth data for " << effectiveUrl << "more recent then " << lastTimestamp << std::endl;
410
411 auto credPtr = mgr.getCred( effectiveUrl );
412 if ( credPtr && credPtr->lastDatabaseUpdate() > lastTimestamp ) {
413 MIL << "Found existing auth data for " << effectiveUrl << "ts: " << credPtr->lastDatabaseUpdate() << std::endl;
414 return expected<zypp::media::AuthData>::success( *credPtr );
415 }
416
417 if ( credPtr ) MIL << "Found existing auth data for " << effectiveUrl << "but too old ts: " << credPtr->lastDatabaseUpdate() << std::endl;
418
419 std::string username;
420 if ( auto i = extraFields.find( std::string(AuthDataRequestMsgFields::LastUser) ); i != extraFields.end() ) {
421 username = i->second;
422 }
423
424
425 MIL << "NO Auth data found, asking user. Last tried username was: " << username << std::endl;
426
427 auto userAuth = provider()._sigAuthRequired.emit( effectiveUrl, username, extraFields );
428 if ( !userAuth || !userAuth->valid() ) {
429 MIL << "User rejected to give auth" << std::endl;
430 return expected<zypp::media::AuthData>::error( ZYPP_EXCPT_PTR( zypp::media::MediaException("No auth given by user." ) ) );
431 }
432
433 mgr.addCred( *userAuth );
434 mgr.save();
435
436 // rather ugly, but update the timestamp to the last mtime of the cred database our URL belongs to
437 // otherwise we'd need to reload the cred database
438 userAuth->setLastDatabaseUpdate( mgr.timestampForCredDatabase( effectiveUrl ) );
439
440 return expected<zypp::media::AuthData>::success(*userAuth);
441 } catch ( const zypp::Exception &e ) {
442 ZYPP_CAUGHT(e);
443 return expected<zypp::media::AuthData>::error( std::current_exception() );
444 }
445 }
446
447 bool ProvideItem::enqueueRequest( ProvideRequestRef request )
448 {
449 // base item just supports one running request at a time
450 if ( _runningReq )
451 return ( _runningReq == request );
452
453 _runningReq = request;
454 return d_func()->_parent.queueRequest( request );
455 }
456
457 void ProvideItem::updateState( const State newState )
458 {
459 Z_D();
460 if ( d->_itemState != newState ) {
461
462 bool started = ( d->_itemState == Uninitialized && ( newState != Finished ));
463 auto log = provider().log();
464
465 const auto oldState = d->_itemState;
466 d->_itemState = newState;
467 d->_sigStateChanged( *this, oldState, d->_itemState );
468
469 if ( started ) {
470 d->_itemStarted = std::chrono::steady_clock::now();
471 pulse();
472 if ( log ) log->itemStart( *this );
473 }
474
475 if ( newState == Finished ) {
476 d->_itemFinished = std::chrono::steady_clock::now();
477 pulse();
478 if ( log) log->itemDone( *this );
479 d->_parent.dequeueItem(this);
480 }
481 // CAREFUL, 'this' might be invalid from here on
482 }
483 }
484
486 {
487 if ( state() == Finished || state() == Finalizing )
488 return;
489
490 MIL << "Item Cleanup due to released Promise in state:" << state() << std::endl;
492 }
493
495 {
496 return d_func()->_itemState;
497 }
498
499 void ProvideRequest::setCurrentQueue( ProvideQueueRef ref )
500 {
501 _myQueue = ref;
502 }
503
505 {
506 return _myQueue.lock();
507 }
508
509 const std::optional<zypp::Url> ProvideRequest::activeUrl() const
510 {
512 switch ( this->_message.code () ) {
513 case ProvideMessage::Code::Attach:
515 break;
516 case ProvideMessage::Code::Detach:
518 break;
519 case ProvideMessage::Code::Provide:
521 break;
522 default:
523 // should never happen because we guard the constructor
524 throw std::logic_error("Invalid message type in ProvideRequest");
525 }
526 if ( !url.valid() ) {
527 return {};
528 }
529
530 try {
531 auto u = zypp::Url( url.asString() );
532 return u;
533 } catch ( const zypp::Exception &e ) {
534 ZYPP_CAUGHT(e);
535 }
536
537 return {};
538 }
539
541
542 switch ( this->_message.code () ) {
543 case ProvideMessage::Code::Attach:
545 break;
546 case ProvideMessage::Code::Detach:
548 break;
549 case ProvideMessage::Code::Provide:
551 break;
552 default:
553 // should never happen because we guard the constructor
554 throw std::logic_error("Invalid message type in ProvideRequest");
555 }
556 }
557
558 ProvideFileItem::ProvideFileItem(const std::vector<zypp::Url> &urls, const ProvideFileSpec &request, ProvidePrivate &parent)
559 : ProvideItem( parent )
560 , _mirrorList ( urls )
561 , _initialSpec ( request )
562 { }
563
564 ProvideFileItemRef ProvideFileItem::create(const std::vector<zypp::Url> &urls, const ProvideFileSpec &request, ProvidePrivate &parent )
565 {
566 return ProvideFileItemRef( new ProvideFileItem( urls, request, parent ) );
567 }
568
570 {
571 if ( state() != Uninitialized || _runningReq ) {
572 WAR << "Double init of ProvideFileItem!" << std::endl;
573 return;
574 }
575
576 auto req = ProvideRequest::create( *this, _mirrorList, _initialSpec );
577 if ( !req ){
578 cancelWithError( req.error() );
579 return ;
580 }
581
582 if ( enqueueRequest( *req ) ) {
585 } else {
586 cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
587 return ;
588 }
589 }
590
592 {
593 if ( !_promiseCreated ) {
594 _promiseCreated = true;
595 auto promiseRef = std::make_shared<ProvidePromise<ProvideRes>>( shared_this<ProvideItem>() );
596 _promise = promiseRef;
597 return promiseRef;
598 }
599 return _promise.lock();
600 }
601
603 {
604 _handleRef = std::move(hdl);
605 }
606
608 {
609 return _handleRef;
610 }
611
612 void ProvideFileItem::informalMessage ( ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg )
613 {
614 if ( req != _runningReq ) {
615 WAR << "Received event for unknown request, ignoring" << std::endl;
616 return;
617 }
618
619 if ( msg.code() == ProvideMessage::Code::ProvideStarted ) {
620 MIL << "Provide File Request: "<< req->url() << " was started" << std::endl;
621 auto log = provider().log();
622
623 auto locPath = msg.value( ProvideStartedMsgFields::LocalFilename, std::string() ).asString();
624 if ( !locPath.empty() )
625 _targetFile = zypp::Pathname(locPath);
626
627 locPath = msg.value( ProvideStartedMsgFields::StagingFilename, std::string() ).asString();
628 if ( !locPath.empty() )
629 _stagingFile = zypp::Pathname(locPath);
630
631 if ( log ) {
632 auto effUrl = req->activeUrl().value_or( zypp::Url() );
633 try {
635 } catch( const zypp::Exception &e ) {
636 ZYPP_CAUGHT(e);
637 }
638
639 AnyMap m;
640 m["spec"] = _initialSpec;
641 if ( log ) log->requestStart( *this, msg.requestId(), effUrl, m );
643 }
644 }
645 }
646
647 void zyppng::ProvideFileItem::ProvideFileItem::finishReq( zyppng::ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg )
648 {
649 if ( finishedReq != _runningReq ) {
650 WAR << "Received event for unknown request, ignoring" << std::endl;
651 return;
652 }
653
654 if ( msg.code () == ProvideMessage::Code::ProvideFinished ) {
655
656 auto log = provider().log();
657 if ( log ) {
658 AnyMap m;
659 m["spec"] = _initialSpec;
660 if ( log ) log->requestDone( *this, msg.requestId(), m );
661 }
662
663 MIL << "Request was successfully finished!" << std::endl;
664 // request is def done
665 _runningReq.reset();
666
667 try {
668
669 const auto locFilename = msg.value( ProvideFinishedMsgFields::LocalFilename ).asString();
670 const auto cacheHit = msg.value( ProvideFinishedMsgFields::CacheHit ).asBool();
671 const auto &wConf = queue.workerConfig();
672
673 const bool doesDownload = wConf.worker_type() == ProvideQueue::Config::Downloading;
674 const bool fileNeedsCleanup = doesDownload || ( wConf.worker_type() == ProvideQueue::Config::CPUBound && wConf.cfg_flags() & ProvideQueue::Config::FileArtifacts );
675
676 std::optional<zypp::ManagedFile> resFile;
677
678 if ( doesDownload ) {
679
680 resFile = provider().addToFileCache ( locFilename );
681 if ( !resFile ) {
682 if ( cacheHit ) {
683 MIL << "CACHE MISS, file " << locFilename << " was already removed, queueing again" << std::endl;
684 cacheMiss ( finishedReq );
685 finishedReq->clearForRestart();
686 enqueueRequest( finishedReq );
687 return;
688 } else {
689 // if we reach here it seems that a new file, that was not in cache before, vanished between
690 // providing it and receiving the finished message.
691 // unlikely this can happen but better be safe than sorry
692 cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("File vanished between downloading and adding it to cache.")) );
693 return;
694 }
695 }
696
697 } else {
698 resFile = zypp::ManagedFile( zypp::filesystem::Pathname(locFilename) );
699 if ( fileNeedsCleanup )
700 resFile->setDispose( zypp::filesystem::unlink );
701 else
702 resFile->resetDispose();
703 }
704
705 _targetFile = locFilename;
706
707 // keep the media handle around as long as the file is used by the code
708 auto resObj = std::make_shared<ProvideResourceData>();
709 resObj->_mediaHandle = this->_handleRef;
710 resObj->_myFile = *resFile;
711 resObj->_resourceUrl = *(finishedReq->activeUrl());
712 resObj->_responseHeaders = msg.headers();
713
714 auto p = promise();
715 if ( p ) {
716 try {
717 p->setReady( expected<ProvideRes>::success( ProvideRes( resObj )) );
718 } catch( const zypp::Exception &e ) {
719 ZYPP_CAUGHT(e);
720 }
721 }
722
723 updateState( Finished );
724
725 } catch ( const zypp::Exception &e ) {
726 ZYPP_CAUGHT(e);
727 cancelWithError( std::current_exception() );
728 } catch ( ...) {
729 cancelWithError( std::current_exception() );
730 }
731
732 } else {
733 ProvideItem::finishReq ( queue, finishedReq, msg );
734 }
735 }
736
737
738 void zyppng::ProvideFileItem::cancelWithError( std::exception_ptr error )
739 {
740 if ( _runningReq ) {
741 auto weakThis = weak_from_this ();
742 provider().dequeueRequest ( _runningReq, error );
743 if ( weakThis.expired () )
744 return;
745 }
746
747 // if we reach this place for some reason finishReq was not called, lets clean up manually
748 _runningReq.reset();
749 auto p = promise();
750 if ( p ) {
751 try {
752 p->setReady( expected<ProvideRes>::error( error ) );
753 } catch( const zypp::Exception &e ) {
754 ZYPP_CAUGHT(e);
755 }
756 }
757 updateState( Finished );
758 }
759
760 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 )
761 {
762 zypp::Url urlToUse = effectiveUrl;
763 if ( _handleRef.isValid() ) {
764 // 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
765 // i guess there were never password protected repositories that have different credentials on the redirection targets
766 auto &attachedMedia = provider().attachedMediaInfos();
767 auto i = std::find_if( attachedMedia.begin(), attachedMedia.end(), [&]( const auto &m ) { return m._name == _handleRef.handle(); } );
768 if ( i == attachedMedia.end() )
769 return expected<zypp::media::AuthData>::error( ZYPP_EXCPT_PTR( zypp::media::MediaException("Attachment handle vanished during request.") ) );
770
771 urlToUse = i->_attachedUrl;
772 }
773 return ProvideItem::authenticationRequired( queue, req, urlToUse, lastTimestamp, extraFields );
774 }
775
777 {
778 zypp::ByteCount providedByNow;
779
780 bool checkStaging = false;
781 if ( !_targetFile.empty() ) {
783 if ( inf.isExist() && inf.isFile() )
784 providedByNow = zypp::ByteCount( inf.size() );
785 else
786 checkStaging = true;
787 }
788
789 if ( checkStaging && !_stagingFile.empty() ) {
791 if ( inf.isExist() && inf.isFile() )
792 providedByNow = zypp::ByteCount( inf.size() );
793 }
794
795 auto baseStats = ProvideItem::makeStats();
796 baseStats._bytesExpected = bytesExpected();
797 baseStats._bytesProvided = providedByNow;
798 return baseStats;
799 }
800
802 {
804 }
805
806 AttachMediaItem::AttachMediaItem( const std::vector<zypp::Url> &urls, const ProvideMediaSpec &request, ProvidePrivate &parent )
807 : ProvideItem ( parent )
808 , _mirrorList ( urls )
809 , _initialSpec ( request )
810 { }
811
813 {
814 MIL << "Killing the AttachMediaItem" << std::endl;
815 }
816
818 {
819 if ( !_promiseCreated ) {
820 _promiseCreated = true;
821 auto promiseRef = std::make_shared<ProvidePromise<Provide::MediaHandle>>( shared_this<ProvideItem>() );
822 _promise = promiseRef;
823 return promiseRef;
824 }
825 return _promise.lock();
826 }
827
829 {
830 if ( state() != Uninitialized ) {
831 WAR << "Double init of AttachMediaItem!" << std::endl;
832 return;
833 }
835
836 if ( _mirrorList.empty() ) {
837 cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("No usable mirrors in mirrorlist.")) );
838 return;
839 }
840
841 // shortcut to the provider instance
842 auto &prov= provider();
843
844 // sanitize the mirrors to contain only URLs that have same worker types
845 std::vector<zypp::Url> usableMirrs;
846 std::optional<ProvideQueue::Config> scheme;
847
848 for ( auto mirrIt = _mirrorList.begin() ; mirrIt != _mirrorList.end(); mirrIt++ ) {
849 const auto &s = prov.schemeConfig( prov.effectiveScheme( mirrIt->getScheme() ) );
850 if ( !s ) {
851 WAR << "URL: " << *mirrIt << " is not supported, ignoring!" << std::endl;
852 continue;
853 }
854 if ( !scheme ) {
855 scheme = *s;
856 usableMirrs.push_back ( *mirrIt );
857 } else {
858 if ( scheme->worker_type () == s->worker_type () ) {
859 usableMirrs.push_back( *mirrIt );
860 } else {
861 WAR << "URL: " << *mirrIt << " has different worker type than the primary URL: "<< usableMirrs.front() <<", ignoring!" << std::endl;
862 }
863 }
864 }
865
866 // save the sanitized mirrors
867 _mirrorList = usableMirrs;
868
869 if ( !scheme || _mirrorList.empty() ) {
870 auto prom = promise();
871 if ( prom ) {
872 try {
873 prom->setReady( expected<Provide::MediaHandle>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("No valid mirrors available") )) );
874 } catch( const zypp::Exception &e ) {
875 ZYPP_CAUGHT(e);
876 }
877 }
879 return;
880 }
881
882 // first check if there is a already attached medium we can use as well
883 auto &attachedMedia = prov.attachedMediaInfos ();
884
885 for ( auto &medium : attachedMedia ) {
886 if ( medium.isSameMedium ( _mirrorList, _initialSpec ) ) {
887 finishWithSuccess ( medium );
888 return;
889 }
890 }
891
892 for ( auto &otherItem : prov.items() ) {
893 auto attachIt = std::dynamic_pointer_cast<AttachMediaItem>(otherItem);
894 if ( !attachIt // not the right type
895 || attachIt.get() == this // do not attach to ourselves
896 || attachIt->state () == Uninitialized // item was not initialized
897 || attachIt->state () == Finalizing // item cleaning up
898 || attachIt->state () == Finished ) // item done
899 continue;
900
901 // does this Item attach the same medium?
902 const auto sameMedium = attachIt->_initialSpec.isSameMedium( _initialSpec);
903 if ( zypp::indeterminate(sameMedium) ) {
904 // check the primary URLs ( should we do a full list compare? )
905 if ( attachIt->_mirrorList.front() != _mirrorList.front() )
906 continue;
907 }
908 else if ( !(bool)sameMedium )
909 continue;
910
911 MIL << "Found item providing the same medium, attaching to finished signal and waiting for it to be finished" << std::endl;
912
913 // it does, connect to its ready signal and just wait
915 return;
916 }
917
918 _workerType = scheme->worker_type();
919
920 switch( _workerType ) {
921 case ProvideQueue::Config::Downloading: {
922
923 // if the media file is empty in the spec we can not do anything
924 // simply pretend attach worked
925 if( _initialSpec.mediaFile().empty() ) {
926 finishWithSuccess( prov.addMedium( _workerType, _mirrorList.front(), _initialSpec ) );
927 return;
928 }
929
930 // prepare the verifier with the data
931 auto smvDataLocal = MediaDataVerifier::createVerifier("SuseMediaV1");
932 if ( !smvDataLocal ) {
933 cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, no verifier instance was returned.")) );
934 return;
935 }
936
937 if ( !smvDataLocal->load( _initialSpec.mediaFile() ) ) {
938 cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, unable to load local verify data.")) );
939 return;
940 }
941
942 _verifier = smvDataLocal;
943
944 std::vector<zypp::Url> urls;
945 urls.reserve( _mirrorList.size () );
946
947 for ( zypp::Url url : _mirrorList ) {
948 url.appendPathName ( ( zypp::str::Format("/media.%d/media") % _initialSpec.medianr() ).asString() );
949 urls.push_back(url);
950 }
951
952 // for downloading schemes we ask for the /media.x/media file and check the data manually
953 ProvideFileSpec spec;
955
956 // disable metalink
957 spec.customHeaders().set( std::string(NETWORK_METALINK_ENABLED), false );
958
959 auto req = ProvideRequest::create( *this, urls, spec );
960 if ( !req ) {
961 cancelWithError( req.error() );
962 return;
963 }
964 if ( !enqueueRequest( *req ) ) {
965 cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
966 return;
967 }
969 break;
970 }
971 case ProvideQueue::Config::VolatileMount:
972 case ProvideQueue::Config::SimpleMount: {
973
974 const auto &newId = provider().nextMediaId();
975 auto req = ProvideRequest::create( *this, _mirrorList, newId, _initialSpec );
976 if ( !req ) {
977 cancelWithError( req.error() );
978 return;
979 }
980 if ( !enqueueRequest( *req ) ) {
981 ERR << "Failed to queue request" << std::endl;
982 cancelWithError( ZYPP_EXCPT_PTR(zypp::media::MediaException("Failed to queue request")) );
983 return;
984 }
985 break;
986 }
987 default: {
988 auto prom = promise();
989 if ( prom ) {
990 try {
991 prom->setReady( expected<Provide::MediaHandle>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("URL scheme does not support attaching.") )) );
992 } catch( const zypp::Exception &e ) {
993 ZYPP_CAUGHT(e);
994 }
995 }
997 return;
998 }
999 }
1000 }
1001
1003 {
1004
1006
1007 // aquire a ref to keep the medium around until we notified all dependant attach operations
1008 // currently not really required because only the next schedule run will clean up attached medias
1009 // but in case that ever changes the code is safe already
1010 medium.ref();
1011 zypp::OnScopeExit autoUnref([&]{
1012 medium.unref();
1013 });
1014
1015 auto prom = promise();
1016 try {
1017 if ( prom ) {
1018 // the ref for the result we are giving out
1019 medium.ref();
1020 try {
1021 prom->setReady( expected<Provide::MediaHandle>::success( Provide::MediaHandle( *static_cast<Provide*>( provider().z_func() ), medium._name) ) );
1022 } catch( const zypp::Exception &e ) {
1023 ZYPP_CAUGHT(e);
1024 }
1025 }
1026 } catch ( const std::exception &e ) {
1027 ERR << "WTF " << e.what () << std::endl;
1028 } catch ( ... ) {
1029 ERR << "WTF " << std::endl;
1030 }
1031
1032 // tell others as well
1033 _sigReady.emit( zyppng::expected<AttachedMediaInfo *>::success(&medium) );
1034
1035 prom->isReady ();
1036
1037 MIL << "Before setFinished" << std::endl;
1039 return;
1040 }
1041
1042 void AttachMediaItem::cancelWithError( std::exception_ptr error )
1043 {
1044 MIL << "Cancelling Item with error" << std::endl;
1046
1047 // tell children
1048 _sigReady.emit( expected<AttachedMediaInfo *>::error(error) );
1049
1050 if ( _runningReq ) {
1051 // we might get deleted when calling dequeueRequest
1052 auto weakThis = weak_from_this ();
1053 provider().dequeueRequest ( _runningReq, error );
1054 if ( weakThis.expired () )
1055 return;
1056 }
1057
1058 // if we reach this place we had no runningReq, clean up manually
1059 _runningReq.reset();
1060 _masterItemConn.disconnect();
1061
1062 auto p = promise();
1063 if ( p ) {
1064 try {
1065 p->setReady( expected<zyppng::Provide::MediaHandle>::error( error ) );
1066 } catch( const zypp::Exception &e ) {
1067 ZYPP_CAUGHT(e);
1068 }
1069 }
1071 }
1072
1073 void AttachMediaItem::onMasterItemReady( const zyppng::expected<AttachedMediaInfo *> &result )
1074 {
1075
1076 _masterItemConn.disconnect();
1077
1078 if ( result ) {
1079 AttachedMediaInfo &medium = *result.get();
1080 finishWithSuccess(medium);
1081 } else {
1082 try {
1083 std::rethrow_exception ( result.error() );
1084 } catch ( const zypp::media::MediaRequestCancelledException & e) {
1085 // in case a item was cancelled, we revert to Pending state and trigger the scheduler.
1086 // This will make sure that all our sibilings that also depend on the master
1087 // can revert to pending state and we only get one new master in the next schedule run
1088 MIL_PRV << "Master item was cancelled, reverting to Uninitialized state and waiting for scheduler to run again" << std::endl;
1091
1092 } catch ( ... ) {
1093 cancelWithError( std::current_exception() );
1094 }
1095 }
1096 }
1097
1098 AttachMediaItemRef AttachMediaItem::create( const std::vector<zypp::Url> &urls, const ProvideMediaSpec &request, ProvidePrivate &parent )
1099 {
1100 return AttachMediaItemRef( new AttachMediaItem(urls, request, parent) );
1101 }
1102
1103 SignalProxy<void (const zyppng::expected<AttachedMediaInfo *> &)> AttachMediaItem::sigReady()
1104 {
1105 return _sigReady;
1106 }
1107
1108 void AttachMediaItem::finishReq ( ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg )
1109 {
1110 if ( finishedReq != _runningReq ) {
1111 WAR << "Received event for unknown request, ignoring" << std::endl;
1112 return;
1113 }
1114
1115 if( _workerType == ProvideQueue::Config::Downloading ) {
1116 // success
1117 if ( msg.code() == ProvideMessage::Code::ProvideFinished ) {
1118
1120
1121 zypp::Url baseUrl = *finishedReq->activeUrl();
1122 // remove /media.n/media
1123 baseUrl.setPathName( zypp::Pathname(baseUrl.getPathName()).dirname().dirname() );
1124
1125 // we got the file, lets parse it
1126 auto smvDataRemote = MediaDataVerifier::createVerifier("SuseMediaV1");
1127 if ( !smvDataRemote ) {
1128 return cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, no verifier instance was returned.")) );
1129 }
1130
1131 if ( !smvDataRemote->load( msg.value( ProvideFinishedMsgFields::LocalFilename ).asString() ) ) {
1132 return cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, unable to load remote verify data.")) );
1133 }
1134
1135 // check if we got a valid media file
1136 if ( !smvDataRemote->valid () ) {
1137 return cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaException("Unable to verify the medium, unable to load local verify data.")) );
1138 }
1139
1140 // check if the received file matches with the one we have in the spec
1141 if (! _verifier->matches( smvDataRemote ) ) {
1142 DBG << "expect: " << _verifier << " medium " << _initialSpec.medianr() << std::endl;
1143 DBG << "remote: " << smvDataRemote << std::endl;
1144 return cancelWithError( ZYPP_EXCPT_PTR( zypp::media::MediaNotDesiredException( *finishedReq->activeUrl() ) ) );
1145 }
1146
1147 // all good, register the medium and tell all child items
1148 _runningReq.reset();
1149 return finishWithSuccess( provider().addMedium( _workerType, baseUrl, _initialSpec ) );
1150
1151 } else if ( msg.code() == ProvideMessage::Code::NotFound ) {
1152
1153 // simple downloading attachment we need to check the media file contents
1154 // in case of a error we might tolerate a file not found error in certain situations
1155 if ( _verifier->totalMedia () == 1 ) {
1156 // relaxed , tolerate a vanished media file
1157 _runningReq.reset();
1158 return finishWithSuccess( provider().addMedium( _workerType, _mirrorList.front(), _initialSpec) );
1159 } else {
1160 return ProvideItem::finishReq ( queue, finishedReq, msg );
1161 }
1162 } else {
1163 return ProvideItem::finishReq ( queue, finishedReq, msg );
1164 }
1165 } else {
1166 // real device attach
1167 if ( msg.code() == ProvideMessage::Code::AttachFinished ) {
1168 _runningReq.reset();
1169 return finishWithSuccess( provider().addMedium( _workerType
1170 , queue.weak_this<ProvideQueue>()
1171 , finishedReq->provideMessage().value( AttachMsgFields::AttachId ).asString()
1172 , *finishedReq->activeUrl()
1173 , _initialSpec ) );
1174 }
1175 }
1176
1177 // unhandled message , let the base impl do it
1178 return ProvideItem::finishReq ( queue, finishedReq, msg );
1179 }
1180
1181 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 )
1182 {
1183 zypp::Url baseUrl = effectiveUrl;
1184 if( _workerType == ProvideQueue::Config::Downloading ) {
1185 // remove /media.n/media
1186 baseUrl.setPathName( zypp::Pathname(baseUrl.getPathName()).dirname().dirname() );
1187 }
1188 return ProvideItem::authenticationRequired( queue, req, baseUrl, lastTimestamp, extraFields );
1189 }
1190
1191}
Store and operate with byte count.
Definition: ByteCount.h:31
Base class for Exception.
Definition: Exception.h:146
Url manipulation class.
Definition: Url.h:92
std::string asCompleteString() const
Returns a complete string representation of the Url object.
Definition: Url.cc:505
std::string asString() const
Returns a default string representation of the Url object.
Definition: Url.cc:497
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
Definition: Url.cc:604
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
Definition: Url.cc:764
Wrapper class for stat/lstat.
Definition: PathInfo.h:221
bool isExist() const
Return whether valid stat info exists.
Definition: PathInfo.h:281
Pathname dirname() const
Return all but the last component od this path.
Definition: Pathname.h:124
const std::string & asString() const
String representation.
Definition: Pathname.h:91
bool empty() const
Test for an empty path.
Definition: Pathname.h:114
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.
void initialize() override
Definition: provideitem.cc:828
Signal< void(const zyppng::expected< AttachedMediaInfo * > &)> _sigReady
void finishReq(ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg) override
ProvidePromiseRef< Provide::MediaHandle > promise()
Definition: provideitem.cc:817
SignalProxy< void(const zyppng::expected< AttachedMediaInfo * > &) > sigReady()
MediaDataVerifierRef _verifier
ProvidePromiseWeakRef< Provide::MediaHandle > _promise
AttachMediaItem(const std::vector< zypp::Url > &urls, const ProvideMediaSpec &request, ProvidePrivate &parent)
Definition: provideitem.cc:806
ProvideQueue::Config::WorkerType _workerType
ProvideMediaSpec _initialSpec
void finishWithSuccess(AttachedMediaInfo &medium)
static AttachMediaItemRef create(const std::vector< zypp::Url > &urls, const ProvideMediaSpec &request, ProvidePrivate &parent)
std::vector< zypp::Url > _mirrorList
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)
void set(const std::string &key, const 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
Definition: provideitem.cc:760
zypp::Pathname _stagingFile
void cancelWithError(std::exception_ptr error) override
Definition: provideitem.cc:738
zypp::ByteCount bytesExpected() const override
Definition: provideitem.cc:801
void setMediaRef(Provide::MediaHandle &&hdl)
Definition: provideitem.cc:602
Provide::MediaHandle & mediaRef()
Definition: provideitem.cc:607
Provide::MediaHandle _handleRef
void initialize() override
Definition: provideitem.cc:569
static ProvideFileItemRef create(const std::vector< zypp::Url > &urls, const ProvideFileSpec &request, ProvidePrivate &parent)
Definition: provideitem.cc:564
ProvideFileItem(const std::vector< zypp::Url > &urls, const ProvideFileSpec &request, ProvidePrivate &parent)
Definition: provideitem.cc:558
ProvideFileSpec _initialSpec
ProvidePromiseRef< ProvideRes > promise()
Definition: provideitem.cc:591
std::vector< zypp::Url > _mirrorList
zypp::ByteCount _expectedBytes
zypp::Pathname _targetFile
ItemStats makeStats() override
Definition: provideitem.cc:776
void informalMessage(ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg) override
Definition: provideitem.cc:612
ProvidePromiseWeakRef< ProvideRes > _promise
HeaderValueMap & customHeaders()
Definition: providespec.cc:246
const zypp::Pathname & destFilenameHint() const
Definition: providespec.cc:186
const zypp::ByteCount & downloadSize() const
The size of the resource on the server.
Definition: providespec.cc:204
const zypp::Pathname & deltafile() const
The existing deltafile that can be used to reduce download size ( zchunk or metalink )
Definition: providespec.cc:240
bool checkExistsOnly() const
Definition: providespec.cc:192
bool safeRedirectTo(ProvideRequestRef startedReq, const zypp::Url &url)
Definition: provideitem.cc:95
virtual std::chrono::steady_clock::time_point startTime() const
Definition: provideitem.cc:132
virtual void cacheMiss(ProvideRequestRef req)
Definition: provideitem.cc:180
ProvideItem(ProvidePrivate &parent)
Definition: provideitem.cc:83
ProvidePrivate & provider()
Definition: provideitem.cc:90
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)
Definition: provideitem.cc:398
virtual ItemStats makeStats()
Definition: provideitem.cc:159
virtual bool canRedirectTo(ProvideRequestRef startedReq, const zypp::Url &url)
Definition: provideitem.cc:110
virtual std::chrono::steady_clock::time_point finishedTime() const
Definition: provideitem.cc:137
virtual zypp::ByteCount bytesExpected() const
Definition: provideitem.cc:154
ProvideRequestRef _runningReq
Definition: provideitem.h:189
void redirectTo(ProvideRequestRef startedReq, const zypp::Url &url)
Definition: provideitem.cc:104
State state() const
Definition: provideitem.cc:494
virtual void informalMessage(ProvideQueue &, ProvideRequestRef req, const ProvideMessage &msg)
Definition: provideitem.cc:167
const std::optional< ItemStats > & previousStats() const
Definition: provideitem.cc:127
virtual void released()
Definition: provideitem.cc:485
virtual void finishReq(ProvideQueue &queue, ProvideRequestRef finishedReq, const ProvideMessage &msg)
Definition: provideitem.cc:190
virtual void cancelWithError(std::exception_ptr error)=0
const std::optional< ItemStats > & currentStats() const
Definition: provideitem.cc:122
void updateState(const State newState)
Definition: provideitem.cc:457
virtual bool enqueueRequest(ProvideRequestRef request)
Definition: provideitem.cc:447
HeaderValueMap & customHeaders()
Definition: providespec.cc:122
unsigned medianr() const
Definition: providespec.cc:104
zypp::Pathname mediaFile() const
Definition: providespec.cc:113
const std::string & label() const
Definition: providespec.cc:95
HeaderValueMap headers() const
std::vector< FieldVal > values(const std::string_view &str) const
FieldVal value(const std::string_view &str, const FieldVal &defaultVal=FieldVal()) const
void setValue(const std::string &name, const FieldVal &value)
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:808
std::string nextMediaId() const
Definition: provide.cc:771
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:105
std::vector< AttachedMediaInfo > & attachedMediaInfos()
Definition: provide.cc:707
void schedule(ScheduleReason reason)
Definition: provide.cc:38
ProvideStatusRef log()
Definition: provide_p.h:98
const Config & workerConfig() const
static constexpr uint32_t InvalidId
void setActiveUrl(const zypp::Url &urlToUse)
Definition: provideitem.cc:540
ProvideQueueWeakRef _myQueue
Definition: provideitem_p.h:87
const std::vector< zypp::Url > & urls() const
Definition: provideitem_p.h:62
static expected< ProvideRequestRef > createDetach(const zypp::Url &url)
Definition: provideitem.cc:75
static expected< ProvideRequestRef > create(ProvideItem &owner, const std::vector< zypp::Url > &urls, const std::string &id, ProvideMediaSpec &spec)
Definition: provideitem.cc:27
ProvideMessage _message
Definition: provideitem_p.h:83
zypp::Url url() const
Definition: provideitem_p.h:66
void setCurrentQueue(ProvideQueueRef ref)
Definition: provideitem.cc:499
ProvideItem * owner()
Definition: provideitem_p.h:45
ProvideQueueRef currentQueue()
Definition: provideitem.cc:504
const std::optional< zypp::Url > activeUrl() const
Definition: provideitem.cc:509
int unlink(const Pathname &path)
Like 'unlink'.
Definition: PathInfo.cc:700
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
Definition: ManagedFile.h:27
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")
std::unordered_map< std::string, boost::any > AnyMap
Definition: provide.h:41
constexpr std::string_view NETWORK_METALINK_ENABLED("zypp-nw-metalink-enabled")
std::shared_ptr< ProvidePromise< T > > ProvidePromiseRef
Definition: providefwd_p.h:31
static constexpr std::string_view DEFAULT_MEDIA_VERIFIER("SuseMediaV1")
ZYPP_IMPL_PRIVATE(Provide)
#define MIL_PRV
Definition: providedbg_p.h:35
Convenient building of std::string with boost::format.
Definition: String.h:253
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:212
std::chrono::steady_clock::time_point _pulseTime
Definition: provideitem.h:46
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:436
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Definition: Exception.h:432
#define DBG
Definition: Logger.h:95
#define MIL
Definition: Logger.h:96
#define ERR
Definition: Logger.h:98
#define WAR
Definition: Logger.h:97