5#include <zypp-core/zyppng/io/IODevice>
6#include <zypp-core/Url.h>
7#include <zypp-core/base/DtorReset>
8#include <zypp-core/fs/PathInfo.h>
9#include <zypp-media/MediaException>
10#include <zypp-media/FileCheckException>
11#include <zypp-media/CDTools>
23 , _workDir(
std::move(workDir) )
24 , _workerPath( constants::DEFAULT_PROVIDE_WORKER_PATH.data() )
32 MIL <<
"Provider workdir is: " <<
_workDir << std::endl;
41 std::string_view reasonStr;
44 reasonStr =
"ProvideStart";
47 reasonStr =
"QueueIdle";
50 reasonStr =
"EnqueueItem";
53 reasonStr =
"EnqueueReq";
56 reasonStr =
"FinishReq";
59 reasonStr =
"RestartAttach";
62 DBG <<
"Triggering the schedule timer (" << reasonStr <<
")" << std::endl;
76 DBG_PRV <<
"Scheduling triggered during scheduling, returning immediately." << std::endl;
81#ifdef _SC_NPROCESSORS_ONLN
82 sysconf(_SC_NPROCESSORS_ONLN) * 2;
88 constexpr auto findLaziestWorker = [](
const auto &workerQueues,
const auto &idleNames ) {
89 auto candidate = workerQueues.end();
93 for (
const auto &name : idleNames ) {
94 auto thisElem = workerQueues.find(name);
95 if ( thisElem == workerQueues.end() )
98 const auto idleS = thisElem->second->idleSince();
100 && ( candidate == workerQueues.end() || *idleS < candidateIdleSince ) ) {
101 candidateIdleSince = *idleS;
102 candidate = thisElem;
106 if ( candidate != workerQueues.end() )
107 MIL_PRV <<
"Found idle worker:" << candidate->first <<
" idle since: " << candidateIdleSince.time_since_epoch().count() << std::endl;
115 if ( iMedia->_refCount > 0 ) {
116 MIL_PRV <<
"Not releasing media " << iMedia->_name <<
" refcount is not zero" << std::endl;
120 if ( iMedia->_workerType == ProvideQueue::Config::Downloading ) {
122 if ( std::chrono::steady_clock::now() - iMedia->_idleSince >= std::chrono::hours(1) ) {
123 MIL <<
"Detaching medium " << iMedia->_name <<
" for baseUrl " << iMedia->_attachedUrl << std::endl;
127 MIL_PRV <<
"Not releasing media " << iMedia->_name <<
" downloading worker and not timed out yet." << std::endl;
131 auto bQueue = iMedia->_backingQueue.lock();
138 MIL <<
"Detaching medium " << iMedia->_name <<
" for baseUrl " << iMedia->_attachedUrl << std::endl;
139 bQueue->enqueue ( *req );
143 ERR <<
"Could not send detach request, creating the request failed" << std::endl;
146 ERR <<
"Could not send detach request since no backing queue was defined" << std::endl;
155 const auto schedStart = std::chrono::steady_clock::now();
156 MIL_PRV <<
"Start scheduling" << std::endl;
159 const auto dur = std::chrono::steady_clock::now() - schedStart;
160 MIL_PRV <<
"Exit scheduling after:" << std::chrono::duration_cast<std::chrono::milliseconds>( dur ).count () << std::endl;
164 for (
auto it =
_items.begin (); it !=
_items.end(); ) {
180 for(
auto queueIter =
_queues.begin(); queueIter !=
_queues.end(); queueIter ++ ) {
182 const auto &scheme = queueIter->_schemeName;
183 auto &queue = queueIter->_requests;
190 MIL_PRV <<
"Start scheduling for scheme:" << scheme <<
" queue size is: " << queue.size() << std::endl;
194 ERR <<
"Scheme: " << scheme <<
" failed to return a valid configuration." << std::endl;
196 while( queue.size() ) {
197 auto item = std::move( queue.front() );
207 const auto &config = configOpt.get();
208 const auto isSingleInstance = ( (config.cfg_flags() & ProvideQueue::Config::SingleInstance) == ProvideQueue::Config::SingleInstance );
209 if ( config.worker_type() == ProvideQueue::Config::Downloading && !isSingleInstance ) {
211 for(
auto i = queue.begin (); i != queue.end(); ) {
215 while ( i != queue.end() && !(*i) ) {
219 if ( i == queue.end() )
222 ProvideRequestRef item = *i;
226 if( item->code() == ProvideMessage::Code::Attach || item->code() == ProvideMessage::Code::Detach ) {
229 item->owner()->finishReq(
nullptr, item,
ZYPP_EXCPT_PTR(
zypp::Exception(
"Downloading Queues do not support ProvideMessage::Code::Attach requests") ) );
233 MIL_PRV <<
"Trying to schedule request: " << item->urls().front() << std::endl;
236 int existingTypeWorkers = 0;
239 int existingConnections = 0;
242 std::vector< std::pair<zypp::Url, ProvideQueue*> > possibleHostWorkers;
245 std::vector<std::string> idleWorkers;
248 std::vector<zypp::Url> mirrsWithoutWorker;
249 for (
const auto &url : item->urls() ) {
252 MIL <<
"Mirror URL " << url <<
" is incompatible with current scheme: " << scheme <<
", ignoring." << std::endl;
256 if( item->owner()->canRedirectTo( item, url ) )
257 mirrsWithoutWorker.push_back( url );
259 MIL_PRV <<
"URL was rejected" << url << std::endl;
264 if( mirrsWithoutWorker.size() == 0 ) {
265 MIL <<
"Request has NO usable URLs" << std::endl;
274 if ( ProvideQueue::Config::Downloading != workerQueue->workerConfig().worker_type() )
277 existingTypeWorkers ++;
278 existingConnections += workerQueue->activeRequests();
280 if ( workerQueue->isIdle() )
286 for (
auto i = mirrsWithoutWorker.begin (); i != mirrsWithoutWorker.end(); ) {
288 if ( u.getHost() == workerQueue->hostname() ) {
290 possibleHostWorkers.push_back( {u, workerQueue.get()} );
291 i = mirrsWithoutWorker.erase( i );
300 MIL <<
"Current stats: " << std::endl;
301 MIL <<
"Existing type workers: " << existingTypeWorkers << std::endl;
302 MIL <<
"Existing active connections: " << existingConnections << std::endl;
303 MIL <<
"Possible host workers: "<< possibleHostWorkers.size() << std::endl;
304 MIL <<
"Mirrors without worker: " << mirrsWithoutWorker.size() << std::endl;
309 MIL_PRV <<
"Reached maximum nr of connections, break" << std::endl;
316 && mirrsWithoutWorker.size() ) {
318 MIL_PRV <<
"Free worker slots and available mirror URLs, starting a new worker" << std::endl;
322 for(
const auto &url : mirrsWithoutWorker ) {
325 if ( !item->owner()->safeRedirectTo ( item, url ) )
328 ProvideQueueRef q = std::make_shared<ProvideQueue>( *
this );
329 if ( !q->startup( scheme,
_workDir / scheme / url.getHost(), url.getHost() ) ) {
333 MIL_PRV <<
"Started worker for " << url.getHost() <<
" enqueing request" << std::endl;
335 item->setActiveUrl(url);
352 if ( possibleHostWorkers.size() ) {
354 MIL_PRV <<
"No free worker slots, looking for the best existing worker" << std::endl;
356 while( possibleHostWorkers.size () ) {
357 std::vector< std::pair<zypp::Url, ProvideQueue *> >::iterator candidate = possibleHostWorkers.begin();
358 for (
auto i = candidate+1; i != possibleHostWorkers.end(); i++ ) {
359 if ( i->second->activeRequests () < candidate->second->activeRequests () )
363 if ( !item->owner()->safeRedirectTo( item, candidate->first ) ) {
364 possibleHostWorkers.erase( candidate );
368 MIL_PRV <<
"Using existing worker " << candidate->first.getHost() <<
" to download request" << std::endl;
371 item->setActiveUrl( candidate->first );
372 candidate->second->enqueue( item );
384 if ( idleWorkers.size() && mirrsWithoutWorker.size() ) {
386 MIL_PRV <<
"No free worker slots, no slots in existing queues, trying to decomission idle queues." << std::endl;
388 auto candidate = findLaziestWorker(
_workerQueues, idleWorkers );
397 for(
const auto &url : mirrsWithoutWorker ) {
399 if ( !item->owner()->safeRedirectTo ( item, url ) )
402 ProvideQueueRef q = std::make_shared<ProvideQueue>( *
this );
403 if ( !q->startup( scheme,
_workDir / scheme / url.getHost(), url.getHost() ) ) {
407 MIL_PRV <<
"Replaced worker for " << url.getHost() <<
", enqueing request" << std::endl;
409 item->setActiveUrl(url);
426 MIL_PRV <<
"End of line, deferring request for next try." << std::endl;
430 }
else if ( config.worker_type() == ProvideQueue::Config::CPUBound && !isSingleInstance ) {
432 for(
auto i = queue.begin (); i != queue.end(); ) {
436 while ( i != queue.end() && !(*i) ) {
440 if ( i == queue.end() )
444 ProvideRequestRef item = *i;
448 if( item->code() == ProvideMessage::Code::Attach || item->code() == ProvideMessage::Code::Detach ) {
450 if ( item->owner () )
451 item->owner()->finishReq(
nullptr, item,
ZYPP_EXCPT_PTR(
zypp::Exception(
"CPU bound Queues do not support ProvideAttachSpecRef requests") ) );
455 MIL_PRV <<
"Trying to schedule request: " << item->urls().front() << std::endl;
458 int existingTypeWorkers = 0;
459 int existingSchemeWorkers = 0;
462 std::vector< ProvideQueue* > possibleWorkers;
465 std::vector<std::string> idleWorkers;
471 for (
const auto &tmpurl : item->urls() ) {
473 MIL <<
"Mirror URL " << tmpurl <<
" is incompatible with current scheme: " << scheme <<
", ignoring." << std::endl;
482 MIL <<
"Request has NO usable URLs" << std::endl;
491 if ( ProvideQueue::Config::CPUBound != workerQueue->workerConfig().worker_type() )
496 existingTypeWorkers ++;
498 existingSchemeWorkers++;
499 if ( workerQueue->canScheduleMore() )
500 possibleWorkers.push_back(workerQueue.get());
503 if ( workerQueue->isIdle() )
508 MIL <<
"Current stats: " << std::endl;
509 MIL <<
"Existing type workers: " << existingTypeWorkers << std::endl;
510 MIL <<
"Possible CPU workers: "<< possibleWorkers.size() << std::endl;
514 if ( possibleWorkers.size() ) {
516 for (
auto &w : possibleWorkers ) {
518 MIL_PRV <<
"Using existing idle worker to provide request" << std::endl;
520 item->owner()->redirectTo ( item, url );
521 item->setActiveUrl( url );
533 if ( existingTypeWorkers < cpuLimit ) {
535 MIL_PRV <<
"Free CPU slots, starting a new worker" << std::endl;
538 item->owner()->redirectTo ( item, url );
540 ProvideQueueRef q = std::make_shared<ProvideQueue>( *
this );
541 if ( q->startup( scheme,
_workDir / scheme ) ) {
543 item->setActiveUrl(url);
560 if ( possibleWorkers.size() ) {
561 MIL_PRV <<
"No free CPU slots, looking for the best existing worker" << std::endl;
563 if( possibleWorkers.size () ) {
564 std::vector<ProvideQueue *>::iterator candidate = possibleWorkers.begin();
565 for (
auto i = candidate+1; i != possibleWorkers.end(); i++ ) {
566 if ( (*i)->activeRequests () < (*candidate)->activeRequests () )
571 item->owner()->redirectTo ( item, url );
573 MIL_PRV <<
"Using existing worker to provide request" << std::endl;
574 item->setActiveUrl( url );
575 (*candidate)->enqueue( item );
583 if ( idleWorkers.size() ) {
585 MIL_PRV <<
"No free CPU slots, no slots in existing queues, trying to decomission idle queues." << std::endl;
587 auto candidate = findLaziestWorker(
_workerQueues, idleWorkers );
593 item->owner()->redirectTo ( item, url );
595 ProvideQueueRef q = std::make_shared<ProvideQueue>( *
this );
596 if ( q->startup( scheme,
_workDir / scheme ) ) {
598 MIL_PRV <<
"Replaced worker, enqueing request" << std::endl;
600 item->setActiveUrl(url);
616 MIL_PRV <<
"No idle workers and no free CPU spots, wait for the next schedule run" << std::endl;
621 MIL_PRV <<
"End of line, deferring request for next try." << std::endl;
628 for(
auto i = queue.begin (); i != queue.end(); ) {
632 while ( i != queue.end() && !(*i) ) {
636 if ( i == queue.end() )
640 ProvideRequestRef item = *i;
641 MIL_PRV <<
"Trying to schedule request: " << item->urls().front() << std::endl;
646 for (
const auto &tmpurl : item->urls() ) {
648 MIL <<
"Mirror URL " << tmpurl <<
" is incompatible with current scheme: " << scheme <<
", ignoring." << std::endl;
657 MIL <<
"Request has NO usable URLs" << std::endl;
667 ProvideQueueRef q = std::make_shared<ProvideQueue>( *
this );
668 if ( !q->startup( scheme,
_workDir / scheme ) ) {
669 ERR <<
"Worker startup failed!" << std::endl;
678 MIL_PRV <<
"Started worker, enqueing request" << std::endl;
682 MIL_PRV <<
"Found worker, enqueing request" << std::endl;
687 item->owner()->redirectTo ( item, url );
689 item->setActiveUrl(url);
697 std::list<ProvideItemRef> &ProvidePrivate::items()
704 return _credManagerOptions;
707 std::vector<AttachedMediaInfo> &ProvidePrivate::attachedMediaInfos()
709 return _attachedMediaInfos;
712 expected<ProvideQueue::Config> ProvidePrivate::schemeConfig(
const std::string &scheme )
714 if (
auto i = _schemeConfigs.find( scheme ); i != _schemeConfigs.end() ) {
715 return expected<ProvideQueue::Config>::success(i->second);
719 if ( !q.
startup( scheme, _workDir / scheme ) ) {
722 auto newItem = _schemeConfigs.insert( std::make_pair( scheme, q.
workerConfig() ));
723 return expected<ProvideQueue::Config>::success(newItem.first->second);
729 const auto &key = downloadedFile.
asString();
732 _fileCache.erase ( key );
739 i.first->second._deathTimer.reset();
740 return i.first->second._file;
744 return i.first->second._file;
749 const auto &key = downloadedFile.
asString();
750 return (_fileCache.count(key) > 0);
753 void ProvidePrivate::queueItem ( ProvideItemRef item )
755 _items.push_back( item );
756 schedule( ProvidePrivate::EnqueueItem );
761 auto elem = std::find_if( _items.begin(), _items.end(), [item](
const auto &i){ return i.get() == item; } );
762 if ( elem != _items.end() ) {
763 if ( _isScheduling ) {
771 std::string ProvidePrivate::nextMediaId()
const
779 auto str = nextMediaId();
780 MIL_PRV <<
"Generated new ID for media attachment: " <<
str << std::endl;
781 _attachedMediaInfos.push_back(
AttachedMediaInfo{ std::move(
str), {}, workerType, baseUrl, spec } );
782 return _attachedMediaInfos.back();
787 MIL_PRV <<
"New media attachment with id: " <<
id << std::endl;
788 _attachedMediaInfos.push_back(
AttachedMediaInfo{ id, backingQueue, workerType, baseUrl, spec } );
789 return _attachedMediaInfos.back();
792 bool ProvidePrivate::queueRequest ( ProvideRequestRef req )
794 const auto &schemeName = effectiveScheme( req->url().getScheme() );
795 auto existingQ = std::find_if( _queues.begin (), _queues.end(), [&schemeName](
const auto &qItem) {
796 return (qItem._schemeName == schemeName);
798 if ( existingQ != _queues.end() ) {
799 existingQ->_requests.push_back(req);
804 schedule( ProvidePrivate::EnqueueReq );
808 bool ProvidePrivate::dequeueRequest(ProvideRequestRef req , std::exception_ptr error)
810 auto queue = req->currentQueue ();
812 queue->cancel( req.get(), error );
816 for (
auto &q : _queues ) {
817 auto elem = std::find( q._requests.begin(), q._requests.end(), req );
818 if ( elem != q._requests.end() ) {
819 q._requests.erase(elem);
822 req->owner()->finishReq(
nullptr, req, error );
837 for (
const auto &v : _workerQueues ) {
838 if ( v.second.get() == &q )
844 bool ProvidePrivate::isRunning()
const
849 std::string ProvidePrivate::effectiveScheme(
const std::string &scheme)
const
852 if (
auto it = _workerAlias.find ( ss ); it != _workerAlias.end () ) {
858 void ProvidePrivate::onPulseTimeout( Timer & )
860 DBG_PRV <<
"Pulse timeout" << std::endl;
862 auto now = std::chrono::steady_clock::now();
864 if ( _log ) _log->pulse();
867 for (
auto i = _fileCache.begin (); i != _fileCache.end(); ) {
868 auto &cacheItem = i->second;
869 if ( cacheItem._file.unique() ) {
870 if ( cacheItem._deathTimer ) {
871 if ( now - *cacheItem._deathTimer < std::chrono::seconds(20) ) {
872 MIL <<
"Releasing file " << *i->second._file <<
" from cache, death timeout." << std::endl;
873 i = _fileCache.erase(i);
878 cacheItem._deathTimer = std::chrono::steady_clock::now();
886 void ProvidePrivate::onQueueIdle()
888 if ( !_items.empty() )
890 for (
auto &[k,q] : _workerQueues ) {
901 if ( item.
state() == ProvideItem::Finished ) {
903 auto i = std::find( _items.begin(), _items.end(), itemRef );
904 if ( i == _items.end() ) {
905 ERR <<
"State of unknown Item changed, ignoring" << std::endl;
913 if ( _items.empty() )
917 uint32_t ProvidePrivate::nextRequestId()
920 return ++_nextRequestId;
926 : _parent( parent.weak_this<
Provide>() )
930 auto p = _parent.lock();
if (p) p->releaseMedia(_hdlName);
937 ProvideMediaHandle::ProvideMediaHandle(
Provide &parent,
const std::string &hdl )
943 return _ref->_parent.lock();
948 return (
_ref.get() !=
nullptr );
953 return _ref->_hdlName;
965 return ProvideRef(
new Provide(workDir) );
970 return attachMedia ( std::vector<zypp::Url>{url}, request );
977 if ( urls.empty() ) {
982 std::vector<zypp::Url> usableMirrs;
983 std::optional<ProvideQueue::Config> scheme;
985 for (
auto mirrIt = urls.begin() ; mirrIt != urls.end(); mirrIt++ ) {
986 const auto &s = d->schemeConfig( d->effectiveScheme( mirrIt->getScheme() ) );
988 WAR <<
"URL: " << *mirrIt <<
" is not supported, ignoring!" << std::endl;
993 usableMirrs.push_back ( *mirrIt );
995 if ( scheme->worker_type () == s->worker_type () ) {
996 usableMirrs.push_back( *mirrIt );
998 WAR <<
"URL: " << *mirrIt <<
" has different worker type than the primary URL: "<< usableMirrs.front() <<
", ignoring!" << std::endl;
1003 if ( !scheme || usableMirrs.empty() ) {
1008 auto &attachedMedia = d->attachedMediaInfos ();
1009 for (
auto &medium : attachedMedia ) {
1010 if ( medium.isSameMedium ( usableMirrs, request ) ) {
1012 return makeReadyResult( expected<Provide::MediaHandle>::success(
Provide::MediaHandle( *
this, medium._name) ) );
1018 return op->promise();
1025 if ( mediaRef.empty() )
1028 const auto i = std::find_if( d->_attachedMediaInfos.begin(), d->_attachedMediaInfos.end(), [&](
const auto &info ){ return info._name == mediaRef;} );
1029 if ( i == d->_attachedMediaInfos.end() ) {
1030 ERR <<
"Unknown media attach handle" << std::endl;
1043 return op->promise();
1048 return provide( std::vector<zypp::Url>{ url }, request );
1054 const auto i = std::find_if( d->_attachedMediaInfos.begin(), d->_attachedMediaInfos.end(), [&](
const auto &info ){ return info._name == attachHandle.handle();} );
1055 if ( i == d->_attachedMediaInfos.end() ) {
1064 if ( i->_workerType == ProvideQueue::Config::SimpleMount || i->_workerType == ProvideQueue::Config::VolatileMount ) {
1079 return op->promise();
1084 using namespace zyppng::operators;
1090 if ( chksumRes.headers().contains(algorithm) )
1091 return expected<std::string>::success( chksumRes.headers().value(algorithm).asString() );
1099 using namespace zyppng::operators;
1105 return expected<zypp::ManagedFile>::success( copyRes.asManagedFile() );
1113 d->_isRunning =
true;
1114 d->_pulseTimer->start( 5000 );
1116 if ( d->_log ) d->_log->provideStart();
1121 d_func()->_workerPath = path;
1126 if ( !queueRef.empty() ) {
1134 d_func()->_log = tracker;
1139 return d_func()->_workDir;
1145 return d->_credManagerOptions;
1150 d_func()->_credManagerOptions = opt;
1155 return d_func()->_sigIdle;
1160 return d_func()->_sigMediaChange;
1163 SignalProxy< std::optional<zypp::media::AuthData> (
const zypp::Url &reqUrl,
const std::string &triedUsername,
const std::map<std::string, std::string> &extraValues ) >
Provide::sigAuthRequired()
1165 return d_func()->_sigAuthRequired;
1171 : _provider( parent )
1185 if ( sTime > sTime.min() && fTime >= sTime ) {
1186 auto duration = std::chrono::duration_cast<std::chrono::seconds>( item.
finishedTime() - item.
startTime() );
1187 if ( duration.count() )
1196 MIL <<
"Item failed" << std::endl;
1215 for (
const auto &i : prov->d_func()->items() ) {
1229 const auto &
stats = i->currentStats();
1230 const auto & prevStats = i->previousStats();
1231 if ( !
stats || !prevStats ) {
1232 ERR <<
"Bug! Stats should be initialized by now" << std::endl;
1240 tmpPartialBytes +=
stats->_bytesProvided;
1247 const auto now = std::chrono::steady_clock::now();
1248 const auto sinceLast = std::chrono::duration_cast<std::chrono::seconds>( now -
_stats.
_lastPulseTime );
1249 const auto lastFinB = lastPartialBytes + lastFinishedBytes;
1252 const auto diff = currFinB - lastFinB;
1256 if ( sinceLast >= std::chrono::seconds(1) )
1260 if ( sinceStart.count() ) {
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
reference value() const
Reference to the Tp object.
Store and operate with byte count.
Assign a vaiable a certain value when going out of scope.
Base class for Exception.
std::string getScheme() const
Returns the scheme name of the URL.
void setAuthority(const std::string &authority)
Set the authority component in the URL.
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
bool isValid() const
Verifies the Url.
void appendPathName(const Pathname &path_r, EEncoding eflag_r=zypp::url::E_DECODED)
Extend the path name.
void setScheme(const std::string &scheme)
Set the scheme name in the URL.
Wrapper class for stat/lstat.
const std::string & asString() const
String representation.
bool empty() const
Test for an empty path.
Pathname realpath() const
Returns this path as the absolute canonical pathname.
static ProvideFileItemRef create(const std::vector< zypp::Url > &urls, const ProvideFileSpec &request, ProvidePrivate &parent)
virtual std::chrono::steady_clock::time_point startTime() const
virtual std::chrono::steady_clock::time_point finishedTime() const
const std::optional< ItemStats > & currentStats() const
const std::string queueName(ProvideQueue &q) const
std::string effectiveScheme(const std::string &scheme) const
std::vector< AttachedMediaInfo > _attachedMediaInfos
std::list< ProvideItemRef > _items
ProvidePrivate(zypp::Pathname &&workDir, Provide &pub)
Timer::Ptr _scheduleTrigger
std::unordered_map< std::string, ProvideQueueRef > _workerQueues
void onPulseTimeout(Timer &)
std::deque< QueueItem > _queues
void schedule(ScheduleReason reason)
expected< ProvideQueue::Config > schemeConfig(const std::string &scheme)
std::chrono::time_point< std::chrono::steady_clock > TimePoint
bool startup(const std::string &workerScheme, const zypp::Pathname &workDir, const std::string &hostname="")
const Config & workerConfig() const
void enqueue(ProvideRequestRef request)
static expected< ProvideRequestRef > createDetach(const zypp::Url &url)
A ProvideRes object is a reference counted ownership of a resource in the cache provided by a Provide...
virtual void provideStart()
const Stats & stats() const
ProvideStatus(ProvideRef parent)
virtual void itemFailed(ProvideItem &item)
virtual void itemDone(ProvideItem &item)
AsyncOpRef< expected< ProvideRes > > provide(const std::vector< zypp::Url > &urls, const ProvideFileSpec &request)
const zypp::media::CredManagerOptions & credManangerOptions() const
SignalProxy< std::optional< zypp::media::AuthData >(const zypp::Url &reqUrl, const std::string &triedUsername, const std::map< std::string, std::string > &extraValues) > sigAuthRequired()
static ProvideRef create(const zypp::Pathname &workDir="")
AsyncOpRef< expected< MediaHandle > > attachMedia(const std::vector< zypp::Url > &urls, const ProvideMediaSpec &request)
void setWorkerPath(const zypp::Pathname &path)
SignalProxy< void()> sigIdle()
void setCredManagerOptions(const zypp::media::CredManagerOptions &opt)
Provide(const zypp::Pathname &workDir)
void setStatusTracker(ProvideStatusRef tracker)
bool ejectDevice(const std::string &queueRef, const std::string &device)
AsyncOpRef< expected< std::string > > checksumForFile(const zypp::Pathname &p, const std::string &algorithm)
AsyncOpRef< expected< zypp::ManagedFile > > copyFile(const zypp::Pathname &source, const zypp::Pathname &target)
SignalProxy< MediaChangeAction(const std::string &queueRef, const std::string &label, const int32_t mediaNr, const std::vector< std::string > &devices, const std::optional< std::string > &desc)> sigMediaChangeRequested()
std::optional< Action > MediaChangeAction
const zypp::Pathname & providerWorkdir() const
ProvideMediaHandle MediaHandle
void releaseMedia(const std::string &mediaRef)
String related utilities and Regular expression matching.
int unlink(const Pathname &path)
Like 'unlink'.
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
std::string stripSuffix(const C_Str &str_r, const C_Str &suffix_r)
Strip a suffix_r from str_r and return the resulting string.
Easy-to use interface to the ZYPP dependency resolver.
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
constexpr auto DEFAULT_ACTIVE_CONN_PER_HOST
constexpr auto DEFAULT_ACTIVE_CONN
constexpr auto DEFAULT_MAX_DYNAMIC_WORKERS
constexpr std::string_view ATTACHED_MEDIA_SUFFIX
bool provideDebugEnabled()
ZYPP_IMPL_PRIVATE(Provide)
zypp::ByteCount _partialBytes
zypp::ByteCount _perSecondSinceLastPulse
zypp::ByteCount _perSecond
zypp::ByteCount _expectedBytes
std::chrono::steady_clock::time_point _startTime
zypp::ByteCount _finishedBytes
std::chrono::steady_clock::time_point _lastPulseTime
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
#define L_ENV_CONSTR_DEFINE_FUNC(ENV)