libzypp 17.38.15

repomanager.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
9
10#include "repomanager.h"
11#include "zypp-core/ExternalProgram.h"
12
13#include <solv/solvversion.h>
14
15#include <zypp-core/AutoDispose.h>
16#include <zypp-core/base/Regex.h>
17#include <zypp-core/fs/PathInfo.h>
18#include <zypp-core/ng/pipelines/MTry>
19#include <zypp-core/ng/pipelines/Transform>
20#include <zypp-core/ng/pipelines/wait.h>
21#include <zypp-core/ng/ui/ProgressObserver>
22#include <zypp-media/ng/providespec.h>
23#include <zypp/HistoryLog.h>
24#include <zypp/ZConfig.h>
25#include <zypp/ZYppCallbacks.h>
26#include <zypp-core/base/LogTools.h>
27#include <zypp/parser/RepoFileReader.h>
28#include <zypp/parser/ServiceFileReader.h>
29#include <zypp/sat/Pool.h>
30#include <zypp/zypp_detail/urlcredentialextractor_p.h>
31#include <zypp/repo/ServiceType.h>
32#include <zypp/repo/PluginServices.h>
33
34#include <zypp/ng/reporthelper.h>
35#include <zypp/ng/repo/refresh.h>
36#include <zypp/ng/repo/workflows/repomanagerwf.h>
37#include <zypp/ng/repo/workflows/serviceswf.h>
38
39#include <fstream>
40#include <utility>
41
42#undef ZYPP_BASE_LOGGER_LOGGROUP
43#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::repomanager"
44
45 namespace zypp::zypp_readonly_hack {
46 bool IGotIt(); // in readonly-mode
47}
48
49
50 namespace zyppng
51{
52 namespace env
53 {
55 inline bool ZYPP_PLUGIN_APPDATA_FORCE_COLLECT()
56 {
57 const char * env = getenv("ZYPP_PLUGIN_APPDATA_FORCE_COLLECT");
58 return( env && zypp::str::strToBool( env, true ) );
59 }
60 } // namespace env
61
62 namespace {
68 inline void cleanupNonRepoMetadataFolders( const zypp::Pathname & cachePath_r,
69 const zypp::Pathname & defaultCachePath_r,
70 const std::list<std::string> & repoEscAliases_r )
71 {
72 if ( cachePath_r != defaultCachePath_r )
73 return;
74
75 std::list<std::string> entries;
76 if ( zypp::filesystem::readdir( entries, cachePath_r, false ) == 0 )
77 {
78 entries.sort();
79 std::set<std::string> oldfiles;
80 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
81 std::inserter( oldfiles, oldfiles.end() ) );
82
83 // bsc#1178966: Files or symlinks here have been created by the user
84 // for whatever purpose. It's our cache, so we purge them now before
85 // they may later conflict with directories we need.
86 zypp::PathInfo pi;
87 for ( const std::string & old : oldfiles )
88 {
89 if ( old == zypp::Repository::systemRepoAlias() ) // don't remove the @System solv file
90 continue;
91 pi( cachePath_r/old );
92 if ( pi.isDir() )
93 zypp::filesystem::recursive_rmdir( pi.path() );
94 else
95 zypp::filesystem::unlink( pi.path() );
96 }
97 }
98 }
99 } // namespace
100
101 std::ostream & operator<<( std::ostream & str, zypp::RepoManagerFlags::RawMetadataRefreshPolicy obj )
102 {
103 switch ( obj ) {
104#define OUTS(V) case zypp::RepoManagerFlags::V: str << #V; break
105 OUTS( RefreshIfNeeded );
106 OUTS( RefreshForced );
107 OUTS( RefreshIfNeededIgnoreDelay );
108#undef OUTS
109 }
110 return str;
111 }
112
113 std::ostream & operator<<( std::ostream & str, zypp::RepoManagerFlags::RefreshCheckStatus obj )
114 {
115 switch ( obj ) {
116#define OUTS(V) case zypp::RepoManagerFlags::V: str << #V; break
117 OUTS( REFRESH_NEEDED );
118 OUTS( REPO_UP_TO_DATE );
119 OUTS( REPO_CHECK_DELAYED );
120#undef OUTS
121 }
122 return str;
123 }
124
125 std::ostream & operator<<( std::ostream & str, zypp::RepoManagerFlags::CacheBuildPolicy obj )
126 {
127 switch ( obj ) {
128#define OUTS(V) case zypp::RepoManagerFlags::V: str << #V; break
129 OUTS( BuildIfNeeded );
130 OUTS( BuildForced );
131#undef OUTS
132 }
133 return str;
134 }
135
136
137 std::string filenameFromAlias(const std::string &alias_r, const std::string &stem_r)
138 {
139 std::string filename( alias_r );
140 // replace slashes with underscores
141 zypp::str::replaceAll( filename, "/", "_" );
142
143 filename = zypp::Pathname(filename).extend("."+stem_r).asString();
144 MIL << "generating filename for " << stem_r << " [" << alias_r << "] : '" << filename << "'" << std::endl;
145 return filename;
146 }
147
148 bool RepoCollector::collect(const RepoInfo &repo)
149 {
150 // skip repositories meant for other distros than specified
151 if (!targetDistro.empty()
152 && !repo.targetDistribution().empty()
153 && repo.targetDistribution() != targetDistro)
154 {
155 MIL
156 << "Skipping repository meant for '" << repo.targetDistribution()
157 << "' distribution (current distro is '"
158 << targetDistro << "')." << std::endl;
159
160 return true;
161 }
162
163 repos.push_back(repo);
164 return true;
165 }
166
167 expected<std::list<RepoInfo>> repositories_in_file(const zypp::Pathname &file)
168 {
169 try {
170 MIL << "repo file: " << file << std::endl;
171 RepoCollector collector;
172 zypp::parser::RepoFileReader parser( file, std::bind( &RepoCollector::collect, &collector, std::placeholders::_1 ) );
173 return expected<std::list<RepoInfo>>::success( std::move(collector.repos) );
174 } catch ( ... ) {
175 return expected<std::list<RepoInfo>>::error( ZYPP_FWD_CURRENT_EXCPT() );
176 }
177 }
178
188 template <typename ZContextRef>
189 std::list<RepoInfo> repositories_in_dir( ZContextRef zyppContext, const zypp::Pathname &dir )
190 {
191 MIL << "directory " << dir << std::endl;
192 std::list<RepoInfo> repos;
193 bool nonroot( geteuid() != 0 );
194 if ( nonroot && ! zypp::PathInfo(dir).userMayRX() )
195 {
196 JobReportHelper(zyppContext).warning( zypp::str::Format(_("Cannot read repo directory '%1%': Permission denied")) % dir );
197 }
198 else
199 {
200 std::list<zypp::Pathname> entries;
201 if ( zypp::filesystem::readdir( entries, dir, false ) != 0 )
202 {
203 // TranslatorExplanation '%s' is a pathname
204 ZYPP_THROW(zypp::Exception(zypp::str::form(_("Failed to read directory '%s'"), dir.c_str())));
205 }
206
207 zypp::str::regex allowedRepoExt("^\\.repo(_[0-9]+)?$");
208 for ( std::list<zypp::Pathname>::const_iterator it = entries.begin(); it != entries.end(); ++it )
209 {
210 if ( zypp::str::regex_match(it->extension(), allowedRepoExt) )
211 {
212 if ( nonroot && ! zypp::PathInfo(*it).userMayR() )
213 {
214 JobReportHelper(zyppContext).warning( zypp::str::Format(_("Cannot read repo file '%1%': Permission denied")) % *it );
215 }
216 else
217 {
218 const std::list<RepoInfo> tmp( repositories_in_file( *it ).unwrap() );
219 repos.insert( repos.end(), tmp.begin(), tmp.end() );
220 }
221 }
222 }
223 }
224 return repos;
225 }
226
227 expected<void> assert_urls(const RepoInfo &info)
228 {
229 if ( info.repoOriginsEmpty() )
230 return expected<void>::error( ZYPP_EXCPT_PTR ( zypp::repo::RepoNoUrlException( info ) ) );
231 return expected<void>::success();
232 }
233
234 bool autoPruneInDir(const zypp::Pathname &path_r)
235 { return not zypp::PathInfo(path_r/".no_auto_prune").isExist(); }
236
237
238 RepoManager::RepoManager( ZYPP_PRIVATE_CONSTR_ARG, ContextRef zyppCtx, RepoManagerOptions opt )
239 : _zyppContext( std::move(zyppCtx) )
240 , _options( std::move(opt) )
241 , _pluginRepoverification( _options.pluginsPath / "repoverification",
242 _options.rootDir)
243 {
244
245 }
246
247 RepoManager::~RepoManager()
248 {
249 // trigger appdata refresh if some repos change
250 if ( ( _reposDirty || env::ZYPP_PLUGIN_APPDATA_FORCE_COLLECT() )
251 && geteuid() == 0 && ( _options.rootDir.empty() || _options.rootDir == "/" ) )
252 {
253 try {
254 std::list<zypp::Pathname> entries;
255 zypp::filesystem::readdir( entries, _options.pluginsPath/"appdata", false );
256 if ( ! entries.empty() )
257 {
258 zypp::ExternalProgram::Arguments cmd;
259 cmd.push_back( "<" ); // discard stdin
260 cmd.push_back( ">" ); // discard stdout
261 cmd.push_back( "PROGRAM" ); // [2] - fix index below if changing!
262 for ( const auto & rinfo : repos() )
263 {
264 if ( ! rinfo.enabled() )
265 continue;
266 cmd.push_back( "-R" );
267 cmd.push_back( rinfo.alias() );
268 cmd.push_back( "-t" );
269 cmd.push_back( rinfo.type().asString() );
270 cmd.push_back( "-p" );
271 cmd.push_back( (rinfo.metadataPath()/rinfo.path()).asString() ); // bsc#1197684: path to the repodata/ directory inside the cache
272 }
273
274 for_( it, entries.begin(), entries.end() )
275 {
276 zypp::PathInfo pi( *it );
277 //DBG << "/tmp/xx ->" << pi << endl;
278 if ( pi.isFile() && pi.userMayRX() )
279 {
280 // trigger plugin
281 cmd[2] = pi.asString(); // [2] - PROGRAM
282 zypp::ExternalProgram prog( cmd, zypp::ExternalProgram::Stderr_To_Stdout );
283 }
284 }
285 }
286 }
287 catch (...) {} // no throw in dtor
288 }
289 }
290
291
292 expected<void> RepoManager::initialize()
293 {
294 using namespace zyppng::operators;
295 return
296 init_knownServices()
297 | and_then( [this](){ return init_knownRepositories(); } );
298 }
299
300
301 const RepoManagerOptions &RepoManager::options() const
302 {
303 return _options;
304 }
305
306
307 expected<RepoStatus> RepoManager::metadataStatus(const RepoInfo & info , const RepoManagerOptions &options)
308 {
309 try {
310 using namespace zyppng::operators;
311
312 // ATTENTION when making this pipeline async
313 // consider moving it into a workflow object
314 // this var is caputured by ref to modify it from
315 // inside the pipeline, which would break.
316 zypp::Pathname mediarootpath;
317
318 return rawcache_path_for_repoinfo( options, info )
319 | and_then( [&]( zypp::Pathname mrPath ) {
320 mediarootpath = std::move(mrPath);
321 return rawproductdata_path_for_repoinfo( options, info );
322 })
323 | and_then( [&]( zypp::Pathname productdatapath ) {
324 zypp::repo::RepoType repokind = info.type();
325 // If unknown, probe the local metadata
326 if ( repokind == zypp::repo::RepoType::NONE )
327 repokind = probeCache( productdatapath );
328
329 // NOTE: The calling code expects an empty RepoStatus being returned
330 // if the metadata cache is empty. So additional components like the
331 // RepoInfos status are joined after the switch IFF the status is not
332 // empty.huhu
333 RepoStatus status;
334 switch ( repokind.toEnum() )
335 {
336 case zypp::repo::RepoType::RPMMD_e :
337 status = RepoStatus( productdatapath/"repodata/repomd.xml");
338 if ( info.requireStatusWithMediaFile() )
339 status = status && RepoStatus( mediarootpath/"media.1/media" );
340 break;
341
342 case zypp::repo::RepoType::YAST2_e :
343 status = RepoStatus( productdatapath/"content" ) && RepoStatus( mediarootpath/"media.1/media" );
344 break;
345
346 case zypp::repo::RepoType::RPMPLAINDIR_e :
347 // Dir status at last refresh. Plaindir uses the cookiefile as pseudo metadata index file.
348 // It gets touched if the refresh check finds the data being up-to-date. That's why we use
349 // the files mtime as timestamp (like the RepoStatus ctor in the other cases above).
350 status = RepoStatus::fromCookieFileUseMtime( productdatapath/"cookie" );
351 break;
352
353 case zypp::repo::RepoType::NONE_e :
354 // Return default RepoStatus in case of RepoType::NONE
355 // indicating it should be created?
356 // ZYPP_THROW(RepoUnknownTypeException());
357 break;
358 }
359
360 if ( ! status.empty() )
361 status = status && RepoStatus( info );
362
363 return expected<RepoStatus>::success(status);
364 });
365 } catch (...) {
366 return expected<RepoStatus>::error( ZYPP_FWD_CURRENT_EXCPT() );
367 }
368 }
369
370
371 expected<RepoStatus> RepoManager::metadataStatus(const RepoInfo &info) const
372 {
373 return metadataStatus( info, _options );
374 }
375
376
377 expected<void> RepoManager::cleanMetadata(const RepoInfo &info, ProgressObserverRef myProgress )
378 {
379 try {
380
381 ProgressObserver::setup( myProgress, _("Cleaning metadata"), 100 );
382 ProgressObserver::start( myProgress );
383 zypp::filesystem::recursive_rmdir( _zyppContext->config().geoipCachePath() );
384 ProgressObserver::setCurrent ( myProgress, 50 );
385 zypp::filesystem::recursive_rmdir( rawcache_path_for_repoinfo(_options, info).unwrap() );
386 ProgressObserver::finish ( myProgress );
387
388 } catch ( ... ) {
389 ProgressObserver::finish ( myProgress, ProgressObserver::Error );
390 return expected<void>::error( ZYPP_FWD_CURRENT_EXCPT() );
391 }
392 return expected<void>::success();
393 }
394
395
396 expected<void> RepoManager::cleanPackages(const RepoInfo &info, ProgressObserverRef myProgress, bool isAutoClean )
397 {
398 try {
399 ProgressObserver::setup( myProgress, _("Cleaning packages"), 100 );
400 ProgressObserver::start( myProgress );
401
402 // bsc#1204956: Tweak to prevent auto pruning package caches
403 zypp::Pathname rpc { packagescache_path_for_repoinfo(_options, info).unwrap() };
404 if ( not isAutoClean || autoPruneInDir( rpc.dirname() ) )
405 zypp::filesystem::recursive_rmdir( rpc );
406
407 ProgressObserver::finish ( myProgress );
408
409 } catch (...) {
410 ProgressObserver::finish ( myProgress, ProgressObserver::Error );
411 return expected<void>::error( ZYPP_FWD_CURRENT_EXCPT() );
412 }
413
414 return expected<void>::success();
415 }
416
422
423 zypp::repo::RepoType RepoManager::probeCache( const zypp::Pathname & path_r )
424 {
425 MIL << "going to probe the cached repo at " << path_r << std::endl;
426
427 zypp::repo::RepoType ret = zypp::repo::RepoType::NONE;
428
429 if ( zypp::PathInfo(path_r/"/repodata/repomd.xml").isFile() )
430 { ret = zypp::repo::RepoType::RPMMD; }
431 else if ( zypp::PathInfo(path_r/"/content").isFile() )
432 { ret = zypp::repo::RepoType::YAST2; }
433 else if ( zypp::PathInfo(path_r/"/cookie").isFile() )
434 { ret = zypp::repo::RepoType::RPMPLAINDIR; }
435
436 MIL << "Probed cached type " << ret << " at " << path_r << std::endl;
437 return ret;
438 }
439
440
441 expected<void> RepoManager::cleanCacheDirGarbage( ProgressObserverRef myProgress )
442 {
443 try {
444 MIL << "Going to clean up garbage in cache dirs" << std::endl;
445
446 std::list<zypp::Pathname> cachedirs;
447 cachedirs.push_back(_options.repoRawCachePath);
448 cachedirs.push_back(_options.repoPackagesCachePath);
449 cachedirs.push_back(_options.repoSolvCachePath);
450
451 ProgressObserver::setup( myProgress, _("Cleaning up cache dirs"), cachedirs.size() );
452 ProgressObserver::start( myProgress );
453
454 for( const auto &dir : cachedirs )
455 {
456 // increase progress on end of every iteration
457 zypp_defer {
458 ProgressObserver::increase( myProgress );
459 };
460
461 if ( zypp::PathInfo(dir).isExist() )
462 {
463 std::list<zypp::Pathname> entries;
464 if ( zypp::filesystem::readdir( entries, dir, false ) != 0 )
465 // TranslatorExplanation '%s' is a pathname
466 ZYPP_THROW(zypp::Exception(zypp::str::form(_("Failed to read directory '%s'"), dir.c_str())));
467
468 if ( !entries.size() )
469 continue;
470
471 auto dirProgress = ProgressObserver::makeSubTask( myProgress, 1.0, zypp::str::Format( _("Cleaning up directory: %1%") ) % dir, entries.size() );
472 for( const auto &subdir : entries )
473 {
474 // if it does not belong known repo, make it disappear
475 bool found = false;
476 for_( r, repoBegin(), repoEnd() )
477 if ( subdir.basename() == r->escaped_alias() )
478 { found = true; break; }
479
480 if ( ! found && ( zypp::Date::now()-zypp::PathInfo(subdir).mtime() > zypp::Date::day ) )
481 zypp::filesystem::recursive_rmdir( subdir );
482
483 ProgressObserver::increase( dirProgress );
484 }
485 ProgressObserver::finish( dirProgress );
486 }
487 }
488 } catch (...) {
489 // will finish all subprogress children
490 ProgressObserver::finish ( myProgress, ProgressObserver::Error );
491 return expected<void>::error( ZYPP_FWD_CURRENT_EXCPT() );
492 }
493 ProgressObserver::finish ( myProgress );
494 return expected<void>::success();
495 }
496
497
498 expected<void> RepoManager::cleanCache(const RepoInfo &info, ProgressObserverRef myProgress )
499 {
500 try {
501 ProgressObserver::setup( myProgress, _("Cleaning cache"), 100 );
502 ProgressObserver::start( myProgress );
503
504 MIL << "Removing raw metadata cache for " << info.alias() << std::endl;
505 zypp::filesystem::recursive_rmdir(solv_path_for_repoinfo(_options, info).unwrap());
506
507 ProgressObserver::finish( myProgress );
508 return expected<void>::success();
509
510 } catch (...) {
511 // will finish all subprogress children
512 ProgressObserver::finish ( myProgress, ProgressObserver::Error );
513 return expected<void>::error( ZYPP_FWD_CURRENT_EXCPT() );
514 }
515 }
516
517
518 expected<void> RepoManager::loadFromCache( const RepoInfo & info, ProgressObserverRef myProgress )
519 {
520 using namespace zyppng::operators;
521 return zyppng::mtry( [this, info, myProgress](){
522 ProgressObserver::setup( myProgress, _("Loading from cache"), 3 );
523 ProgressObserver::start( myProgress );
524
525 assert_alias(info).unwrap();
526 zypp::Pathname solvfile = solv_path_for_repoinfo(_options, info).unwrap() / "solv";
527
528 if ( ! zypp::PathInfo(solvfile).isExist() )
529 ZYPP_THROW(zypp::repo::RepoNotCachedException(info));
530
531 _zyppContext->satPool().reposErase( info.alias() );
532
533 ProgressObserver::increase ( myProgress );
534
535 zypp::Repository repo = _zyppContext->satPool().addRepoSolv( solvfile, info );
536
537 ProgressObserver::increase ( myProgress );
538
539 // test toolversion in order to rebuild solv file in case
540 // it was written by a different libsolv-tool parser.
541 const std::string & toolversion( zypp::sat::LookupRepoAttr( zypp::sat::SolvAttr::repositoryToolVersion, repo ).begin().asString() );
542 if ( toolversion != LIBSOLV_TOOLVERSION ) {
543 repo.eraseFromPool();
544 ZYPP_THROW(zypp::Exception(zypp::str::Str() << "Solv-file was created by '"<<toolversion<<"'-parser (want "<<LIBSOLV_TOOLVERSION<<")."));
545 }
546 })
547 | or_else( [this, info, myProgress]( std::exception_ptr exp ) {
548 ZYPP_CAUGHT( exp );
549 MIL << "Try to handle exception by rebuilding the solv-file" << std::endl;
550 return cleanCache( info, ProgressObserver::makeSubTask( myProgress ) )
551 | and_then([this, info, myProgress]{
552 return buildCache ( info, zypp::RepoManagerFlags::BuildIfNeeded, ProgressObserver::makeSubTask( myProgress ) );
553 })
554 | and_then( mtry([this, info = info]{
555 _zyppContext->satPool().addRepoSolv( solv_path_for_repoinfo(_options, info).unwrap() / "solv", info );
556 }));
557 })
558 | and_then([myProgress]{
559 ProgressObserver::finish ( myProgress );
560 return expected<void>::success();
561 })
562 | or_else([myProgress]( auto ex ){
563 ProgressObserver::finish ( myProgress, ProgressObserver::Error );
564 return expected<void>::error(ex);
565 })
566 ;
567 }
568
569
570 expected<RepoInfo> RepoManager::addProbedRepository( RepoInfo info, zypp::repo::RepoType probedType )
571 {
572 try {
573 auto tosave = info;
574
575 // assert the directory exists
576 zypp::filesystem::assert_dir(_options.knownReposPath);
577
578 zypp::Pathname repofile = generateNonExistingName(
579 _options.knownReposPath, generateFilename(tosave));
580 // now we have a filename that does not exists
581 MIL << "Saving repo in " << repofile << std::endl;
582
583 std::ofstream file(repofile.c_str());
584 if (!file)
585 {
586 // TranslatorExplanation '%s' is a filename
587 ZYPP_THROW( zypp::Exception(zypp::str::form( _("Can't open file '%s' for writing."), repofile.c_str() )));
588 }
589
590 tosave.dumpAsIniOn(file);
591 tosave.setFilepath(repofile);
592 tosave.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ).unwrap() );
593 tosave.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ).unwrap() );
594 reposManip().insert(tosave);
595
596 // check for credentials in base Urls
597 zypp::UrlCredentialExtractor( _options.rootDir ).collect( tosave.baseUrls() );
598
599 zypp::HistoryLog(_options.rootDir).addRepository(tosave);
600
601 // return the new repoinfo
602 return expected<RepoInfo>::success( tosave );
603
604 } catch (...) {
605 return expected<RepoInfo>::error( ZYPP_FWD_CURRENT_EXCPT() );
606 }
607 }
608
609
610 expected<void> RepoManager::removeRepository( const RepoInfo & info, ProgressObserverRef myProgress )
611 {
612 try {
613 ProgressObserver::setup( myProgress, zypp::str::form(_("Removing repository '%s'"), info.label().c_str()), 1 );
614 ProgressObserver::start( myProgress );
615
616 MIL << "Going to delete repo " << info.alias() << std::endl;
617
618 for( const auto &repo : repos() )
619 {
620 // they can be the same only if the provided is empty, that means
621 // the provided repo has no alias
622 // then skip
623 if ( (!info.alias().empty()) && ( info.alias() != repo.alias() ) )
624 continue;
625
626 // TODO match by url
627
628 // we have a matching repository, now we need to know
629 // where it does come from.
630 RepoInfo todelete = repo;
631 if (todelete.filepath().empty())
632 {
633 ZYPP_THROW(zypp::repo::RepoException( todelete, _("Can't figure out where the repo is stored.") ));
634 }
635 else
636 {
637 // figure how many repos are there in the file:
638 std::list<RepoInfo> filerepos = repositories_in_file(todelete.filepath()).unwrap();
639 if ( filerepos.size() == 0 // bsc#984494: file may have already been deleted
640 ||(filerepos.size() == 1 && filerepos.front().alias() == todelete.alias() ) )
641 {
642 // easy: file does not exist, contains no or only the repo to delete: delete the file
643 int ret = zypp::filesystem::unlink( todelete.filepath() );
644 if ( ! ( ret == 0 || ret == ENOENT ) )
645 {
646 // TranslatorExplanation '%s' is a filename
647 ZYPP_THROW(zypp::repo::RepoException( todelete, zypp::str::form( _("Can't delete '%s'"), todelete.filepath().c_str() )));
648 }
649 MIL << todelete.alias() << " successfully deleted." << std::endl;
650 }
651 else
652 {
653 // there are more repos in the same file
654 // write them back except the deleted one.
655 //TmpFile tmp;
656 //std::ofstream file(tmp.path().c_str());
657
658 // assert the directory exists
659 zypp::filesystem::assert_dir(todelete.filepath().dirname());
660
661 std::ofstream file(todelete.filepath().c_str());
662 if (!file)
663 {
664 // TranslatorExplanation '%s' is a filename
665 ZYPP_THROW( zypp::Exception(zypp::str::form( _("Can't open file '%s' for writing."), todelete.filepath().c_str() )));
666 }
667 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
668 fit != filerepos.end();
669 ++fit )
670 {
671 if ( (*fit).alias() != todelete.alias() )
672 (*fit).dumpAsIniOn(file);
673 }
674 }
675
676 // now delete it from cache
677 if ( isCached(todelete) )
678 cleanCache( todelete, ProgressObserver::makeSubTask( myProgress, 0.2 )).unwrap();
679 // now delete metadata (#301037)
680 cleanMetadata( todelete, ProgressObserver::makeSubTask( myProgress, 0.4 )).unwrap();
681 cleanPackages( todelete, ProgressObserver::makeSubTask( myProgress, 0.4 ), true/*isAutoClean*/ ).unwrap();
682 reposManip().erase(todelete);
683 MIL << todelete.alias() << " successfully deleted." << std::endl;
684 zypp::HistoryLog(_options.rootDir).removeRepository(todelete);
685
686 ProgressObserver::finish(myProgress);
687 return expected<void>::success();
688 } // else filepath is empty
689 }
690 // should not be reached on a sucess workflow
691 ZYPP_THROW(zypp::repo::RepoNotFoundException(info));
692 } catch (...) {
693 ProgressObserver::finish( myProgress, ProgressObserver::Error );
694 return expected<void>::error( std::current_exception () );
695 }
696 }
697
698
699 expected<RepoInfo> RepoManager::modifyRepository( const std::string & alias, const RepoInfo & newinfo_r, ProgressObserverRef myProgress )
700 {
701 try {
702
703 ProgressObserver::setup( myProgress, _("Modifying repository"), 5 );
704 ProgressObserver::start( myProgress );
705
706 RepoInfo toedit = getRepositoryInfo(alias).unwrap();
707 RepoInfo newinfo( newinfo_r ); // need writable copy to upadte housekeeping data
708
709 // check if the new alias already exists when renaming the repo
710 if ( alias != newinfo.alias() && hasRepo( newinfo.alias() ) )
711 {
712 ZYPP_THROW(zypp::repo::RepoAlreadyExistsException(newinfo));
713 }
714
715 if (toedit.filepath().empty())
716 {
717 ZYPP_THROW(zypp::repo::RepoException( toedit, _("Can't figure out where the repo is stored.") ));
718 }
719 else
720 {
721 ProgressObserver::increase( myProgress );
722 // figure how many repos are there in the file:
723 std::list<RepoInfo> filerepos = repositories_in_file(toedit.filepath()).unwrap();
724
725 // there are more repos in the same file
726 // write them back except the deleted one.
727 //TmpFile tmp;
728 //std::ofstream file(tmp.path().c_str());
729
730 // assert the directory exists
731 zypp::filesystem::assert_dir(toedit.filepath().dirname());
732
733 std::ofstream file(toedit.filepath().c_str());
734 if (!file)
735 {
736 // TranslatorExplanation '%s' is a filename
737 ZYPP_THROW( zypp::Exception(zypp::str::form( _("Can't open file '%s' for writing."), toedit.filepath().c_str() )));
738 }
739 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
740 fit != filerepos.end();
741 ++fit )
742 {
743 // if the alias is different, dump the original
744 // if it is the same, dump the provided one
745 if ( (*fit).alias() != toedit.alias() )
746 (*fit).dumpAsIniOn(file);
747 else
748 newinfo.dumpAsIniOn(file);
749 }
750
751 ProgressObserver::increase( myProgress );
752
753 if ( toedit.enabled() && !newinfo.enabled() )
754 {
755 // On the fly remove solv.idx files for bash completion if a repo gets disabled.
756 const zypp::Pathname solvidx = solv_path_for_repoinfo(_options, newinfo).unwrap()/"solv.idx";
757 if ( zypp::PathInfo(solvidx).isExist() )
758 zypp::filesystem::unlink( solvidx );
759 }
760
761 newinfo.setFilepath(toedit.filepath());
762 newinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ).unwrap() );
763 newinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ).unwrap() );
764
765 ProgressObserver::increase( myProgress );
766
767 reposManip().erase(toedit);
768 reposManip().insert(newinfo);
769
770 ProgressObserver::increase( myProgress );
771
772 // check for credentials in Urls
773 zypp::UrlCredentialExtractor( _options.rootDir ).collect( newinfo.baseUrls() );
774 zypp::HistoryLog(_options.rootDir).modifyRepository(toedit, newinfo);
775 MIL << "repo " << alias << " modified" << std::endl;
776
777 ProgressObserver::finish ( myProgress );
778 return expected<RepoInfo>::success( newinfo );
779 }
780
781 } catch ( ... ) {
782 ProgressObserver::finish ( myProgress, ProgressObserver::Error );
783 return expected<RepoInfo>::error( ZYPP_FWD_CURRENT_EXCPT() );
784 }
785 }
786
787
788 expected<RepoInfo> RepoManager::getRepositoryInfo( const std::string & alias )
789 {
790 try {
791 RepoConstIterator it( findAlias( alias, repos() ) );
792 if ( it != repos().end() )
793 return make_expected_success(*it);
794 RepoInfo info;
795 info.setAlias( alias );
796 ZYPP_THROW( zypp::repo::RepoNotFoundException(info) );
797 } catch ( ... ) {
798 return expected<RepoInfo>::error( std::current_exception () );
799 }
800 }
801
802
803
804 expected<RepoInfo> RepoManager::getRepositoryInfo( const zypp::Url & url, const zypp::url::ViewOption & urlview )
805 {
806 try {
807
808 for_( it, repoBegin(), repoEnd() )
809 {
810 for( const auto &origin : it->repoOrigins() )
811 {
812 if ( std::any_of( origin.begin(), origin.end(), [&url, &urlview]( const zypp::OriginEndpoint &ep ){ return (ep.url().asString(urlview) == url.asString(urlview)); }) )
813 return make_expected_success(*it);
814 }
815 }
816 RepoInfo info;
817 info.setBaseUrl( url );
818 ZYPP_THROW( zypp::repo::RepoNotFoundException(info) );
819
820 } catch ( ... ) {
821 return expected<RepoInfo>::error( std::current_exception () );
822 }
823 }
824
825
826 expected<typename RepoManager::RefreshCheckStatus> RepoManager::checkIfToRefreshMetadata(const RepoInfo &info, const zypp::MirroredOrigin &origin, RawMetadataRefreshPolicy policy)
827 {
828 using namespace zyppng::operators;
829 return joinPipeline( _zyppContext,
830 RepoManagerWorkflow::refreshGeoIPData( _zyppContext, info.repoOrigins() )
831 | [this, info](auto) { return zyppng::repo::RefreshContext::create( _zyppContext, info, shared_this<RepoManager>() ); }
832 | and_then( [this, origin, policy]( zyppng::repo::RefreshContextRef &&refCtx ) {
833 refCtx->setPolicy ( static_cast<zyppng::repo::RawMetadataRefreshPolicy>( policy ) );
834
835 return _zyppContext->provider()->prepareMedia( origin, zyppng::ProvideMediaSpec() )
836 | and_then( [ r = std::move(refCtx) ]( auto mediaHandle ) mutable { return zyppng::RepoManagerWorkflow::checkIfToRefreshMetadata ( std::move(r), std::move(mediaHandle), nullptr ); } );
837 })
838 );
839 }
840
841
842 expected<void> RepoManager::refreshMetadata( const RepoInfo &info, RawMetadataRefreshPolicy policy, ProgressObserverRef myProgress )
843 {
844 using namespace zyppng::operators;
845 // helper callback in case the repo type changes on the remote
846 // do NOT capture by reference here, since this is possibly executed async
847 const auto &updateProbedType = [this, info = info]( zypp::repo::RepoType repokind ) {
848 // update probed type only for repos in system
849 for( const auto &repo : repos() ) {
850 if ( info.alias() == repo.alias() )
851 {
852 RepoInfo modifiedrepo = repo;
853 modifiedrepo.setType( repokind );
854 // don't modify .repo in refresh.
855 // modifyRepository( info.alias(), modifiedrepo );
856 break;
857 }
858 }
859 };
860
861 // the list of URLs we want to have geo ip redirects for
862 auto urls = info.baseUrls ();
863 if ( info.mirrorListUrl ().isValid () )
864 urls.push_back ( info.mirrorListUrl () );
865
866 return joinPipeline( _zyppContext,
867 // make sure geoIP data is up 2 date, but ignore errors
868 RepoManagerWorkflow::refreshGeoIPData( _zyppContext, urls )
869 | [this, info = info](auto) { return zyppng::repo::RefreshContext::create( _zyppContext, info, shared_this<RepoManager>()); }
870 | and_then( [policy, myProgress, cb = updateProbedType]( repo::RefreshContextRef refCtx ) {
871 refCtx->setPolicy( static_cast<repo::RawMetadataRefreshPolicy>( policy ) );
872 // in case probe detects a different repokind, update our internal repos
873 refCtx->connectFunc( &repo::RefreshContext::sigProbedTypeChanged, cb );
874
875 return zyppng::RepoManagerWorkflow::refreshMetadata ( std::move(refCtx), myProgress );
876 })
877 | and_then([rMgr = shared_this<RepoManager>()]( repo::RefreshContextRef ctx ) {
878
879 if ( ! isTmpRepo( ctx->repoInfo() ) )
880 rMgr->reposManip(); // remember to trigger appdata refresh
881
882 return expected<void>::success ();
883 }));
884 }
885
886
887 std::vector<std::pair<RepoInfo, expected<void>>> RepoManager::refreshMetadata( std::vector<RepoInfo> infos, RawMetadataRefreshPolicy policy, ProgressObserverRef myProgress )
888 {
889 using namespace zyppng::operators;
890
891 ProgressObserver::setup( myProgress, "Refreshing repositories" , 1 );
892
893 auto r = std::move(infos)
894 | transform( [this, policy, myProgress]( const RepoInfo &info ) {
895
896 auto subProgress = ProgressObserver::makeSubTask( myProgress, 1.0, zypp::str::Str() << _("Refreshing Repository: ") << info.alias(), 3 );
897
898 // helper callback in case the repo type changes on the remote
899 // do NOT capture by reference here, since this is possibly executed async
900 const auto &updateProbedType = [this, info = info]( zypp::repo::RepoType repokind ) {
901 // update probed type only for repos in system
902 for( const auto &repo : repos() ) {
903 if ( info.alias() == repo.alias() )
904 {
905 RepoInfo modifiedrepo = repo;
906 modifiedrepo.setType( repokind );
907 // don't modify .repo in refresh.
908 // modifyRepository( info.alias(), modifiedrepo );
909 break;
910 }
911 }
912 };
913
914 auto sharedThis = shared_this<RepoManager>();
915
916 return
917 // make sure geoIP data is up 2 date, but ignore errors
918 RepoManagerWorkflow::refreshGeoIPData( _zyppContext, info.repoOrigins() )
919 | [sharedThis, info = info](auto) { return zyppng::repo::RefreshContext::create( sharedThis->_zyppContext, info, sharedThis); }
920 | inspect( incProgress( subProgress ) )
921 | and_then( [policy, subProgress, cb = updateProbedType]( repo::RefreshContextRef refCtx ) {
922 refCtx->setPolicy( static_cast<repo::RawMetadataRefreshPolicy>( policy ) );
923 // in case probe detects a different repokind, update our internal repos
924 refCtx->connectFunc( &repo::RefreshContext::sigProbedTypeChanged, cb );
925
926 return zyppng::RepoManagerWorkflow::refreshMetadata ( std::move(refCtx), ProgressObserver::makeSubTask( subProgress ) );
927 })
928 | inspect( incProgress( subProgress ) )
929 | and_then([subProgress]( repo::RefreshContextRef ctx ) {
930
931 if ( ! isTmpRepo( ctx->repoInfo() ) )
932 ctx->repoManager()->reposManip(); // remember to trigger appdata refresh
933
934 return zyppng::RepoManagerWorkflow::buildCache ( std::move(ctx), CacheBuildPolicy::BuildIfNeeded, ProgressObserver::makeSubTask( subProgress ) );
935 })
936 | inspect( incProgress( subProgress ) )
937 | [ info = info, subProgress ]( expected<repo::RefreshContextRef> result ) {
938 if ( result ) {
939 ProgressObserver::finish( subProgress, ProgressObserver::Success );
940 return std::make_pair(info, expected<void>::success() );
941 } else {
942 ProgressObserver::finish( subProgress, ProgressObserver::Error );
943 return std::make_pair(info, expected<void>::error( result.error() ) );
944 }
945 };
946 }
947 | [myProgress]( auto res ) {
948 ProgressObserver::finish( myProgress, ProgressObserver::Success );
949 return res;
950 }
951 );
952
953 return joinPipeline( _zyppContext, r );
954 }
955
962
963 expected<zypp::repo::RepoType> RepoManager::probe(const zypp::MirroredOrigin &origin, const zypp::Pathname &path) const
964 {
965 using namespace zyppng::operators;
966
967 RepoInfo::url_set allUrls;
968 std::transform( origin.begin (), origin.end(), std::back_inserter(allUrls), []( const zypp::OriginEndpoint &ep ){ return ep.url(); } );
969
970 return joinPipeline( _zyppContext,
971 RepoManagerWorkflow::refreshGeoIPData( _zyppContext, allUrls )
972 | [this, origin=origin](auto) { return _zyppContext->provider()->prepareMedia( origin, zyppng::ProvideMediaSpec() ); }
973 | and_then( [this, path = path]( auto mediaHandle ) {
974 return RepoManagerWorkflow::probeRepoType( _zyppContext, std::move(mediaHandle), path );
975 }));
976 }
977
978
979 expected<void> RepoManager::buildCache( const RepoInfo &info, CacheBuildPolicy policy, ProgressObserverRef myProgress )
980 {
981 using namespace zyppng::operators;
982 return joinPipeline( _zyppContext,
983 zyppng::repo::RefreshContext::create( _zyppContext, info, shared_this<RepoManager>() )
984 | and_then( [policy, myProgress]( repo::RefreshContextRef refCtx ) {
985 return zyppng::RepoManagerWorkflow::buildCache ( std::move(refCtx), policy, myProgress );
986 })
987 | and_then([]( auto ){ return expected<void>::success(); })
988 );
989 }
990
991
992 expected<RepoInfo> RepoManager::addRepository(const RepoInfo &info, ProgressObserverRef myProgress, const zypp::TriBool & forcedProbe )
993 {
994 return joinPipeline( _zyppContext, RepoManagerWorkflow::addRepository( shared_this<RepoManager>(), info, std::move(myProgress), forcedProbe ) );
995 }
996
997
998 expected<void> RepoManager::addRepositories(const zypp::Url &url, ProgressObserverRef myProgress)
999 {
1000 using namespace zyppng::operators;
1001 return joinPipeline( _zyppContext, RepoManagerWorkflow::addRepositories( shared_this<RepoManager>(), url, std::move(myProgress)));
1002 }
1003
1004
1005 expected<zypp::repo::ServiceType> RepoManager::probeService( const zypp::Url & url ) const
1006 {
1007 return joinPipeline( _zyppContext, RepoServicesWorkflow::probeServiceType ( _zyppContext, url ) );
1008 }
1009
1010
1011 expected<void> RepoManager::addService( const ServiceInfo & service )
1012 {
1013 try {
1014
1015 assert_alias( service ).unwrap();
1016
1017 // check if service already exists
1018 if ( hasService( service.alias() ) )
1019 ZYPP_THROW( zypp::repo::ServiceAlreadyExistsException( service ) );
1020
1021 // Writable ServiceInfo is needed to save the location
1022 // of the .service file. Finaly insert into the service list.
1023 ServiceInfo toSave( service );
1024 saveService( toSave ).unwrap();
1025 _services.insert( toSave );
1026
1027 // check for credentials in Url
1028 zypp::UrlCredentialExtractor( _options.rootDir ).collect( toSave.url() );
1029
1030 MIL << "added service " << toSave.alias() << std::endl;
1031
1032 } catch ( ... ) {
1033 return expected<void>::error( std::current_exception () );
1034 }
1035
1036 return expected<void>::success();
1037 }
1038
1039
1040 expected<void> RepoManager::refreshService( const std::string &alias, const RefreshServiceOptions &options_r )
1041 {
1042 return joinPipeline ( _zyppContext, RepoServicesWorkflow::refreshService( shared_this<RepoManager>(), getService( alias ), options_r ) );
1043 }
1044
1048
1049 expected<void> RepoManager::refreshServices(const RefreshServiceOptions &options_r)
1050 {
1051 using namespace zyppng::operators;
1052 // copy the set of services since refreshService
1053 // can eventually invalidate the iterator
1054 ServiceSet servicesCopy( serviceBegin(), serviceEnd() );
1055
1056 // convert the set into a vector, transform needs a container with push_back support
1057 std::vector<ServiceInfo> servicesVec;
1058 std::copy( std::make_move_iterator(servicesCopy.begin()), std::make_move_iterator(servicesCopy.end()), std::back_inserter(servicesVec));
1059
1060 return joinPipeline( _zyppContext,
1061 std::move(servicesVec)
1062 | transform( [options_r, this]( ServiceInfo i ){ return RepoServicesWorkflow::refreshService( shared_this<RepoManager>(), i, options_r ); } )
1063 | join()
1064 | collect()
1065 );
1066 }
1067
1069
1070
1071 expected<void> RepoManager::removeService( const std::string & alias )
1072 {
1073 try {
1074 MIL << "Going to delete service " << alias << std::endl;
1075
1076 const ServiceInfo & service = getService( alias );
1077
1078 zypp::Pathname location = service.filepath();
1079 if( location.empty() )
1080 {
1081 ZYPP_THROW(zypp::repo::ServiceException( service, _("Can't figure out where the service is stored.") ));
1082 }
1083
1084 ServiceSet tmpSet;
1085 zypp::parser::ServiceFileReader( location, ServiceCollector(tmpSet) );
1086
1087 // only one service definition in the file
1088 if ( tmpSet.size() == 1 )
1089 {
1090 if ( zypp::filesystem::unlink(location) != 0 )
1091 {
1092 // TranslatorExplanation '%s' is a filename
1093 ZYPP_THROW(zypp::repo::ServiceException( service, zypp::str::form( _("Can't delete '%s'"), location.c_str() ) ));
1094 }
1095 MIL << alias << " successfully deleted." << std::endl;
1096 }
1097 else
1098 {
1099 zypp::filesystem::assert_dir(location.dirname());
1100
1101 std::ofstream file(location.c_str());
1102 if( !file )
1103 {
1104 // TranslatorExplanation '%s' is a filename
1105 ZYPP_THROW( zypp::Exception(zypp::str::form( _("Can't open file '%s' for writing."), location.c_str() )));
1106 }
1107
1108 for_(it, tmpSet.begin(), tmpSet.end())
1109 {
1110 if( it->alias() != alias )
1111 it->dumpAsIniOn(file);
1112 }
1113
1114 MIL << alias << " successfully deleted from file " << location << std::endl;
1115 }
1116
1117 // now remove all repositories added by this service
1118 RepoCollector rcollector;
1119 getRepositoriesInService( alias,
1120 boost::make_function_output_iterator( std::bind( &RepoCollector::collect, &rcollector, std::placeholders::_1 ) ) );
1121 // cannot do this directly in getRepositoriesInService - would invalidate iterators
1122 for_(rit, rcollector.repos.begin(), rcollector.repos.end())
1123 removeRepository(*rit).unwrap();
1124
1125 return expected<void>::success();
1126
1127 } catch ( ... ) {
1128 return expected<void>::error( std::current_exception () );
1129 }
1130 }
1131
1132
1133 expected<void> RepoManager::modifyService( const std::string & oldAlias, const ServiceInfo & newService )
1134 {
1135 try {
1136
1137 MIL << "Going to modify service " << oldAlias << std::endl;
1138
1139 // we need a writable copy to link it to the file where
1140 // it is saved if we modify it
1141 ServiceInfo service(newService);
1142
1143 if ( service.type() == zypp::repo::ServiceType::PLUGIN )
1144 {
1145 ZYPP_THROW(zypp::repo::ServicePluginImmutableException( service ));
1146 }
1147
1148 const ServiceInfo & oldService = getService(oldAlias);
1149
1150 zypp::Pathname location = oldService.filepath();
1151 if( location.empty() )
1152 {
1153 ZYPP_THROW(zypp::repo::ServiceException( oldService, _("Can't figure out where the service is stored.") ));
1154 }
1155
1156 // remember: there may multiple services being defined in one file:
1157 ServiceSet tmpSet;
1158 zypp::parser::ServiceFileReader( location, ServiceCollector(tmpSet) );
1159
1160 zypp::filesystem::assert_dir(location.dirname());
1161 std::ofstream file(location.c_str());
1162 for_(it, tmpSet.begin(), tmpSet.end())
1163 {
1164 if( *it != oldAlias )
1165 it->dumpAsIniOn(file);
1166 }
1167 service.dumpAsIniOn(file);
1168 file.close();
1169 service.setFilepath(location);
1170
1171 _services.erase(oldAlias);
1172 _services.insert(service);
1173 // check for credentials in Urls
1174 zypp::UrlCredentialExtractor( _options.rootDir ).collect( service.url() );
1175
1176
1177 // changed properties affecting also repositories
1178 if ( oldAlias != service.alias() // changed alias
1179 || oldService.enabled() != service.enabled() ) // changed enabled status
1180 {
1181 std::vector<RepoInfo> toModify;
1182 getRepositoriesInService(oldAlias, std::back_inserter(toModify));
1183 for_( it, toModify.begin(), toModify.end() )
1184 {
1185 if ( oldService.enabled() != service.enabled() )
1186 {
1187 if ( service.enabled() )
1188 {
1189 // reset to last refreshs state
1190 const auto & last = service.repoStates().find( it->alias() );
1191 if ( last != service.repoStates().end() )
1192 it->setEnabled( last->second.enabled );
1193 }
1194 else
1195 it->setEnabled( false );
1196 }
1197
1198 if ( oldAlias != service.alias() )
1199 it->setService(service.alias());
1200
1201 modifyRepository(it->alias(), *it).unwrap();
1202 }
1203 }
1204
1205 return expected<void>::success();
1206
1207 } catch ( ... ) {
1208 return expected<void>::error( std::current_exception () );
1209 }
1210
1212 }
1213
1214
1215
1216 expected<void> RepoManager::saveService( ServiceInfo & service ) const
1217 {
1218 try {
1219
1220 zypp::filesystem::assert_dir( _options.knownServicesPath );
1221 zypp::Pathname servfile = generateNonExistingName( _options.knownServicesPath,
1222 generateFilename( service ) );
1223 service.setFilepath( servfile );
1224
1225 MIL << "saving service in " << servfile << std::endl;
1226
1227 std::ofstream file( servfile.c_str() );
1228 if ( !file )
1229 {
1230 // TranslatorExplanation '%s' is a filename
1231 ZYPP_THROW( zypp::Exception(zypp::str::form( _("Can't open file '%s' for writing."), servfile.c_str() )));
1232 }
1233 service.dumpAsIniOn( file );
1234 MIL << "done" << std::endl;
1235
1236 return expected<void>::success();
1237
1238 } catch ( ... ) {
1239 return expected<void>::error( std::current_exception () );
1240 }
1241 }
1242
1258
1259 zypp::Pathname RepoManager::generateNonExistingName( const zypp::Pathname & dir,
1260 const std::string & basefilename ) const
1261 {
1262 std::string final_filename = basefilename;
1263 int counter = 1;
1264 while ( zypp::PathInfo(dir + final_filename).isExist() )
1265 {
1266 final_filename = basefilename + "_" + zypp::str::numstring(counter);
1267 ++counter;
1268 }
1269 return dir + zypp::Pathname(final_filename);
1270 }
1271
1272
1273 expected<void> RepoManager::touchIndexFile(const RepoInfo &info, const RepoManagerOptions &options)
1274 {
1275 try {
1276 zypp::Pathname productdatapath = rawproductdata_path_for_repoinfo( options, info ).unwrap();
1277
1278 zypp::repo::RepoType repokind = info.type();
1279 if ( repokind.toEnum() == zypp::repo::RepoType::NONE_e )
1280 // unknown, probe the local metadata
1281 repokind = probeCache( productdatapath );
1282 // if still unknown, just return
1283 if (repokind == zypp::repo::RepoType::NONE_e)
1284 return expected<void>::success();
1285
1286 zypp::Pathname p;
1287 switch ( repokind.toEnum() )
1288 {
1289 case zypp::repo::RepoType::RPMMD_e :
1290 p = zypp::Pathname(productdatapath + "/repodata/repomd.xml");
1291 break;
1292
1293 case zypp::repo::RepoType::YAST2_e :
1294 p = zypp::Pathname(productdatapath + "/content");
1295 break;
1296
1297 case zypp::repo::RepoType::RPMPLAINDIR_e :
1298 p = zypp::Pathname(productdatapath + "/cookie");
1299 break;
1300
1301 case zypp::repo::RepoType::NONE_e :
1302 default:
1303 break;
1304 }
1305
1306 // touch the file, ignore error (they are logged anyway)
1307 zypp::filesystem::touch(p);
1308 } catch ( ... ) {
1309 return expected<void>::error( ZYPP_FWD_CURRENT_EXCPT() );
1310 }
1311 return expected<void>::success();
1312 }
1313
1314 expected<void> RepoManager::refreshGeoIp( const RepoInfo::url_set &urls )
1315 {
1316 return joinPipeline( _zyppContext, RepoManagerWorkflow::refreshGeoIPData( _zyppContext, urls) );
1317 }
1318
1319 expected<void> RepoManager::touchIndexFile( const RepoInfo & info )
1320 {
1321 return touchIndexFile( info, _options );
1322 }
1323
1324
1325 expected<void> RepoManager::init_knownServices()
1326 {
1327 try {
1328 zypp::Pathname dir = _options.knownServicesPath;
1329 std::list<zypp::Pathname> entries;
1330 if (zypp::PathInfo(dir).isExist())
1331 {
1332 if ( zypp::filesystem::readdir( entries, dir, false ) != 0 )
1333 {
1334 // TranslatorExplanation '%s' is a pathname
1335 ZYPP_THROW(zypp::Exception(zypp::str::form(_("Failed to read directory '%s'"), dir.c_str())));
1336 }
1337
1338 //str::regex allowedServiceExt("^\\.service(_[0-9]+)?$");
1339 for_(it, entries.begin(), entries.end() )
1340 {
1341 zypp::parser::ServiceFileReader(*it, ServiceCollector(_services));
1342 }
1343 }
1344
1345 zypp::repo::PluginServices(_options.pluginsPath/"services", ServiceCollector(_services));
1346
1347 return expected<void>::success();
1348
1349 } catch ( ... ) {
1350 return expected<void>::error( std::current_exception () );
1351 }
1352
1353 }
1354
1355 namespace {
1362 inline void cleanupNonRepoMetadtaFolders( const zypp::Pathname & cachePath_r,
1363 const zypp::Pathname & defaultCachePath_r,
1364 const std::list<std::string> & repoEscAliases_r )
1365 {
1366 if ( zypp::zypp_readonly_hack::IGotIt() )
1367 return;
1368
1369 if ( cachePath_r != defaultCachePath_r )
1370 return;
1371
1372 std::list<std::string> entries;
1373 if ( zypp::filesystem::readdir( entries, cachePath_r, false ) == 0 )
1374 {
1375 entries.sort();
1376 std::set<std::string> oldfiles;
1377 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
1378 std::inserter( oldfiles, oldfiles.end() ) );
1379
1380 // bsc#1178966: Files or symlinks here have been created by the user
1381 // for whatever purpose. It's our cache, so we purge them now before
1382 // they may later conflict with directories we need.
1383 zypp::PathInfo pi;
1384 for ( const std::string & old : oldfiles )
1385 {
1386 if ( old == zypp::Repository::systemRepoAlias() ) // don't remove the @System solv file
1387 continue;
1388 pi( cachePath_r/old );
1389 if ( pi.isDir() )
1390 zypp::filesystem::recursive_rmdir( pi.path() );
1391 else
1392 zypp::filesystem::unlink( pi.path() );
1393 }
1394 }
1395 }
1396 } // namespace
1397
1398
1399 expected<void> RepoManager::init_knownRepositories()
1400 {
1401 try {
1402
1403 MIL << "start construct known repos" << std::endl;
1404
1405 if ( zypp::PathInfo(_options.knownReposPath).isExist() )
1406 {
1407 std::list<std::string> repoEscAliases;
1408 std::list<RepoInfo> orphanedRepos;
1409 for ( RepoInfo & repoInfo : repositories_in_dir( _zyppContext, _options.knownReposPath ) )
1410 {
1411 // set the metadata path for the repo
1412 repoInfo.setMetadataPath( rawcache_path_for_repoinfo(_options, repoInfo).unwrap() );
1413 // set the downloaded packages path for the repo
1414 repoInfo.setPackagesPath( packagescache_path_for_repoinfo(_options, repoInfo).unwrap() );
1415 // remember it
1416 _reposX.insert( repoInfo ); // direct access via _reposX in ctor! no reposManip.
1417
1418 // detect orphaned repos belonging to a deleted service
1419 const std::string & serviceAlias( repoInfo.service() );
1420 if ( ! ( serviceAlias.empty() || hasService( serviceAlias ) ) )
1421 {
1422 WAR << "Schedule orphaned service repo for deletion: " << repoInfo << std::endl;
1423 orphanedRepos.push_back( repoInfo );
1424 continue; // don't remember it in repoEscAliases
1425 }
1426
1427 repoEscAliases.push_back(repoInfo.escaped_alias());
1428 }
1429
1430 // Cleanup orphanded service repos:
1431 if ( ! orphanedRepos.empty() )
1432 {
1433 for ( const auto & repoInfo : orphanedRepos )
1434 {
1435 MIL << "Delete orphaned service repo " << repoInfo.alias() << std::endl;
1436 // translators: Cleanup a repository previously owned by a meanwhile unknown (deleted) service.
1437 // %1% = service name
1438 // %2% = repository name
1439 JobReportHelper(_zyppContext).warning( zypp::str::Format(_("Unknown service '%1%': Removing orphaned service repository '%2%'"))
1440 % repoInfo.service()
1441 % repoInfo.alias() );
1442 try {
1443 removeRepository( repoInfo ).unwrap();
1444 }
1445 catch ( const zypp::Exception & caugth )
1446 {
1447 JobReportHelper(_zyppContext).error( caugth.asUserHistory() );
1448 }
1449 }
1450 }
1451
1452 // bsc#1210740: Don't cleanup if read-only mode was promised.
1453 if ( not zypp::zypp_readonly_hack::IGotIt() ) {
1454 // delete metadata folders without corresponding repo (e.g. old tmp directories)
1455 //
1456 // bnc#891515: Auto-cleanup only zypp.conf default locations. Otherwise
1457 // we'd need somemagic file to identify zypp cache directories. Without this
1458 // we may easily remove user data (zypper --pkg-cache-dir . download ...)
1459 repoEscAliases.sort();
1460 cleanupNonRepoMetadtaFolders( _options.repoRawCachePath,
1461 zypp::Pathname::assertprefix( _options.rootDir, _zyppContext->config().builtinRepoMetadataPath() ),
1462 repoEscAliases );
1463 cleanupNonRepoMetadtaFolders( _options.repoSolvCachePath,
1464 zypp::Pathname::assertprefix( _options.rootDir, _zyppContext->config().builtinRepoSolvfilesPath() ),
1465 repoEscAliases );
1466 // bsc#1204956: Tweak to prevent auto pruning package caches
1467 if ( autoPruneInDir( _options.repoPackagesCachePath ) )
1468 cleanupNonRepoMetadtaFolders( _options.repoPackagesCachePath,
1469 zypp::Pathname::assertprefix( _options.rootDir, _zyppContext->config().builtinRepoPackagesPath() ),
1470 repoEscAliases );
1471 }
1472 }
1473 MIL << "end construct known repos" << std::endl;
1474
1475 return expected<void>::success();
1476
1477 } catch ( ... ) {
1478 return expected<void>::error( std::current_exception () );
1479 }
1480 }
1481} // namespace zyppng
AutoDispose.h
zypp_defer
#define zypp_defer
Definition AutoDispose.h:293
OUTS
#define OUTS(VAL)
for_
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition Easy.h:27
ZYPP_CAUGHT
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:475
ZYPP_EXCPT_PTR
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Definition Exception.h:463
ZYPP_FWD_CURRENT_EXCPT
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
Definition Exception.h:471
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
ExternalProgram.h
_
#define _(MSG)
Definition Gettext.h:39
HistoryLog.h
LogTools.h
MIL
#define MIL
Definition Logger.h:130
WAR
#define WAR
Definition Logger.h:131
PluginServices.h
Pool.h
Regex.h
RepoFileReader.h
ServiceFileReader.h
ServiceType.h
ZConfig.h
ZYppCallbacks.h
zypp::Date::day
static const ValueType day
Definition Date.h:44
zypp::Date::now
static Date now()
Return the current time.
Definition Date.h:78
zypp::Exception
Base class for Exception.
Definition Exception.h:153
zypp::Exception::asUserHistory
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
Definition Exception.cc:140
zypp::ExternalProgram
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
Definition ExternalProgram.h:64
zypp::ExternalProgram::Arguments
std::vector< std::string > Arguments
Definition ExternalProgram.h:68
zypp::ExternalProgram::Stderr_To_Stdout
@ Stderr_To_Stdout
Definition ExternalProgram.h:77
zypp::HistoryLog
Writing the zypp history file.
Definition HistoryLog.h:57
zypp::HistoryLog::modifyRepository
void modifyRepository(const RepoInfo &oldrepo, const RepoInfo &newrepo)
Log certain modifications to a repository.
Definition HistoryLog.cc:312
zypp::HistoryLog::addRepository
void addRepository(const RepoInfo &repo)
Log a newly added repository.
Definition HistoryLog.cc:289
zypp::HistoryLog::removeRepository
void removeRepository(const RepoInfo &repo)
Log recently removed repository.
Definition HistoryLog.cc:301
zypp::MirroredOrigin
Manages a data source characterized by an authoritative URL and a list of mirror URLs.
Definition MirroredOrigin.h:170
zypp::MirroredOrigin::end
endpoint_iterator end()
Definition MirroredOrigin.h:272
zypp::MirroredOrigin::begin
endpoint_iterator begin()
Definition MirroredOrigin.h:265
zypp::OriginEndpoint
Represents a single, configurable network endpoint, combining a URL with specific access settings.
Definition MirroredOrigin.h:41
zypp::Pathname::assertprefix
static Pathname assertprefix(const Pathname &root_r, const Pathname &path_r)
Unless path_r does not already denote a path below root_r, combine them.
Definition Pathname.cc:272
zypp::RepoInfo
What is known about a repository.
Definition RepoInfo.h:72
zypp::RepoInfo::repoOrigins
MirroredOriginSet repoOrigins() const
The repodata origins.
Definition RepoInfo.cc:775
zypp::RepoInfo::type
repo::RepoType type() const
Type of repository,.
Definition RepoInfo.cc:831
zypp::RepoInfo::setBaseUrl
void setBaseUrl(Url url)
Clears current base URL list and adds url.
Definition RepoInfo.cc:762
zypp::RepoInfo::setPackagesPath
void setPackagesPath(const Pathname &path)
set the path where the local packages are stored
Definition RepoInfo.cc:798
zypp::RepoInfo::baseUrls
url_set baseUrls() const
The complete set of repository urls as configured.
Definition RepoInfo.cc:858
zypp::RepoInfo::requireStatusWithMediaFile
bool requireStatusWithMediaFile() const
Returns true if this repository requires the media.1/media file to be included in the metadata status...
Definition RepoInfo.cc:1225
zypp::RepoInfo::mirrorListUrl
Url mirrorListUrl() const
Url of a file which contains a list of repository urls.
Definition RepoInfo.cc:834
zypp::RepoInfo::dumpAsIniOn
std::ostream & dumpAsIniOn(std::ostream &str) const override
Write this RepoInfo object into str in a .repo file format.
Definition RepoInfo.cc:1087
zypp::RepoInfo::setMetadataPath
void setMetadataPath(const Pathname &path)
Set the path where the local metadata is stored.
Definition RepoInfo.cc:795
zypp::RepoInfo::setType
void setType(const repo::RepoType &t)
set the repository type
Definition RepoInfo.cc:788
zypp::RepoInfo::url_set
std::list< Url > url_set
Definition RepoInfo.h:108
zypp::RepoInfo::repoOriginsEmpty
bool repoOriginsEmpty() const
whether repo origins are available
Definition RepoInfo.cc:780
zypp::RepoManager::cleanCacheDirGarbage
void cleanCacheDirGarbage(const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Remove any subdirectories of cache directories which no longer belong to any of known repositories.
Definition RepoManager.cc:174
zypp::RepoManager::cleanMetadata
void cleanMetadata(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Clean local metadata.
Definition RepoManager.cc:149
zypp::RepoManager::~RepoManager
~RepoManager()
Dtor.
Definition RepoManager.cc:86
zypp::RepoManager::addService
void addService(const std::string &alias, const Url &url)
Adds a new service by its alias and URL.
Definition RepoManager.cc:248
zypp::RepoManager::removeService
void removeService(const std::string &alias)
Removes service specified by its name.
Definition RepoManager.cc:254
zypp::RepoManager::probeService
repo::ServiceType probeService(const Url &url) const
Probe the type or the service.
Definition RepoManager.cc:245
zypp::RepoManager::cleanCache
void cleanCache(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
clean local cache
Definition RepoManager.cc:165
zypp::RepoManager::refreshServices
void refreshServices(const RefreshServiceOptions &options_r=RefreshServiceOptions())
Refreshes all enabled services.
Definition RepoManager.cc:260
zypp::RepoManager::addRepository
void addRepository(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Adds a repository to the list of known repositories.
Definition RepoManager.cc:197
zypp::RepoManager::addRepositories
void addRepositories(const Url &url, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Adds repositores from a repo file to the list of known repositories.
Definition RepoManager.cc:200
zypp::RepoManager::refreshMetadata
void refreshMetadata(const RepoInfo &info, RawMetadataRefreshPolicy policy=RefreshIfNeeded, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Refresh local raw cache.
Definition RepoManager.cc:142
zypp::RepoManager::refreshGeoIp
void refreshGeoIp(const RepoInfo::url_set &urls)
Definition RepoManager.cc:272
zypp::RepoManager::refreshService
void refreshService(const std::string &alias, const RefreshServiceOptions &options_r=RefreshServiceOptions())
Refresh specific service.
Definition RepoManager.cc:263
zypp::RepoManager::modifyRepository
void modifyRepository(const std::string &alias, const RepoInfo &newinfo, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Modify repository attributes.
Definition RepoManager.cc:210
zypp::RepoManager::removeRepository
void removeRepository(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Remove the best matching repository from known repos list.
Definition RepoManager.cc:203
zypp::RepoManager::getRepositoryInfo
RepoInfo getRepositoryInfo(const std::string &alias, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Find a matching repository info.
Definition RepoManager.cc:221
zypp::RepoManager::checkIfToRefreshMetadata
RefreshCheckStatus checkIfToRefreshMetadata(const RepoInfo &info, const Url &url, RawMetadataRefreshPolicy policy=RefreshIfNeeded)
Checks whether to refresh metadata for specified repository and url.
Definition RepoManager.cc:133
zypp::RepoManager::buildCache
void buildCache(const RepoInfo &info, CacheBuildPolicy policy=BuildIfNeeded, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Refresh local cache.
Definition RepoManager.cc:158
zypp::RepoManager::RepoManager
RepoManager(RepoManagerOptions options=RepoManagerOptions())
Definition repomanager.cc:238
zypp::RepoManager::loadFromCache
void loadFromCache(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Load resolvables into the pool.
Definition RepoManager.cc:171
zypp::RepoManager::cleanPackages
void cleanPackages(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Clean local package cache.
Definition RepoManager.cc:152
zypp::RepoManager::metadataStatus
RepoStatus metadataStatus(const RepoInfo &info) const
Status of local metadata.
Definition RepoManager.cc:127
zypp::RepoManager::modifyService
void modifyService(const std::string &oldAlias, const ServiceInfo &service)
Modifies service file (rewrites it with new values) and underlying repositories if needed.
Definition RepoManager.cc:269
zypp::RepoManager::probe
repo::RepoType probe(const Url &url, const Pathname &path) const
Probe repo metadata type.
Definition RepoManager.cc:177
zypp::RepoStatus
Track changing files or directories.
Definition RepoStatus.h:41
zypp::RepoStatus::fromCookieFileUseMtime
static RepoStatus fromCookieFileUseMtime(const Pathname &path)
Reads the status from a cookie file but uses the files mtime.
Definition RepoStatus.cc:217
zypp::RepoStatus::empty
bool empty() const
Whether the status is empty (empty checksum).
Definition RepoStatus.cc:234
zypp::RepoStatus::RepoStatus
RepoStatus()
Default ctor.
Definition RepoStatus.cc:172
zypp::Repository
Definition Repository.h:40
zypp::Repository::systemRepoAlias
static const std::string & systemRepoAlias()
Reserved system repository alias @System .
Definition Repository.cc:43
zypp::ServiceInfo
Service data.
Definition ServiceInfo.h:37
zypp::ServiceInfo::type
repo::ServiceType type() const
Service type.
Definition ServiceInfo.cc:111
zypp::ServiceInfo::repoStates
const RepoStates & repoStates() const
Access the remembered repository states.
Definition ServiceInfo.cc:164
zypp::ServiceInfo::url
Url url() const
The service url.
Definition ServiceInfo.cc:102
zypp::ServiceInfo::dumpAsIniOn
std::ostream & dumpAsIniOn(std::ostream &str) const override
Writes ServiceInfo to stream in ".service" format.
Definition ServiceInfo.cc:176
zypp::UrlCredentialExtractor
Extract credentials in Url authority and store them via CredentialManager.
Definition urlcredentialextractor_p.h:44
zypp::UrlCredentialExtractor::collect
bool collect(const Url &url_r)
Remember credentials stored in URL authority leaving the password in url_r.
Definition urlcredentialextractor_p.h:58
zypp::Url
Url manipulation class.
Definition Url.h:93
zypp::Url::isValid
bool isValid() const
Verifies the Url.
Definition Url.cc:516
zypp::filesystem::PathInfo
Wrapper class for stat/lstat.
Definition PathInfo.h:226
zypp::filesystem::PathInfo::userMayR
bool userMayR() const
Definition PathInfo.h:353
zypp::filesystem::PathInfo::userMayRX
bool userMayRX() const
Definition PathInfo.h:358
zypp::filesystem::PathInfo::path
const Pathname & path() const
Return current Pathname.
Definition PathInfo.h:251
zypp::filesystem::PathInfo::isDir
bool isDir() const
Definition PathInfo.h:296
zypp::filesystem::PathInfo::isFile
bool isFile() const
Definition PathInfo.h:295
zypp::filesystem::PathInfo::isExist
bool isExist() const
Return whether valid stat info exists.
Definition PathInfo.h:286
zypp::filesystem::PathInfo::asString
const std::string & asString() const
Return current Pathname as String.
Definition PathInfo.h:253
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:48
zypp::filesystem::Pathname::extend
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
Definition Pathname.h:192
zypp::filesystem::Pathname::dirname
Pathname dirname() const
Return all but the last component od this path.
Definition Pathname.h:133
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition Pathname.h:113
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition Pathname.h:94
zypp::filesystem::Pathname::empty
bool empty() const
Test for an empty path.
Definition Pathname.h:117
zypp::parser::RepoFileReader
Read repository data from a .repo file.
Definition RepoFileReader.h:52
zypp::parser::ServiceFileReader
Read service data from a .service file.
Definition ServiceFileReader.h:44
zypp::repo::RepoAlreadyExistsException
Repository already exists and some unique attribute can't be duplicated.
Definition RepoException.h:130
zypp::repo::RepoException
Exception for repository handling.
Definition RepoException.h:38
zypp::repo::RepoInfoBase::label
std::string label() const
Label for use in messages for the user interface.
Definition RepoInfoBase.cc:126
zypp::repo::RepoInfoBase::setFilepath
void setFilepath(const Pathname &filename)
set the path to the .repo file
Definition RepoInfoBase.cc:101
zypp::repo::RepoInfoBase::setAlias
void setAlias(const std::string &alias)
set the repository alias
Definition RepoInfoBase.cc:95
zypp::repo::RepoInfoBase::filepath
Pathname filepath() const
File where this repo was read from.
Definition RepoInfoBase.cc:133
zypp::repo::RepoInfoBase::enabled
bool enabled() const
If enabled is false, then this repository must be ignored as if does not exists, except when checking...
Definition RepoInfoBase.cc:104
zypp::repo::RepoInfoBase::alias
std::string alias() const
unique identifier for this source.
Definition RepoInfoBase.cc:110
zypp::repo::RepoNoUrlException
thrown when it was impossible to determine one url for this repo.
Definition RepoException.h:79
zypp::repo::RepoNotCachedException
The repository cache is not built yet so you can't create the repostories from the cache.
Definition RepoException.h:66
zypp::repo::RepoNotFoundException
thrown when it was impossible to match a repository
Definition RepoException.h:117
zypp::repo::ServiceAlreadyExistsException
Service already exists and some unique attribute can't be duplicated.
Definition RepoException.h:237
zypp::repo::ServiceException
Base Exception for service handling.
Definition RepoException.h:189
zypp::repo::ServicePluginImmutableException
Service plugin is immutable.
Definition RepoException.h:287
zypp::sat::LookupRepoAttr
Lightweight repository attribute value lookup.
Definition LookupAttr.h:265
zypp::sat::SolvAttr::repositoryToolVersion
static const SolvAttr repositoryToolVersion
Definition SolvAttr.h:193
zypp::str::regex
Regular expression.
Definition Regex.h:95
zyppng::Base::shared_this
std::shared_ptr< T > shared_this() const
Definition base.h:114
zyppng::JobReportHelper
Definition reporthelper.h:131
zyppng::JobReportHelper::JobReportHelper
JobReportHelper(ContextRef r)
Definition reporthelper.h:135
zyppng::JobReportHelper::error
bool error(std::string msg_r, UserData userData_r=UserData())
send error text
Definition reporthelper.cc:216
zyppng::JobReportHelper::warning
bool warning(std::string msg_r, UserData userData_r=UserData())
send warning text
Definition reporthelper.cc:205
zyppng::ProgressObserver::increase
static void increase(ProgressObserverRef progress, double inc=1.0, const std::optional< std::string > &newLabel={})
Definition progressobserver.h:78
zyppng::ProgressObserver::makeSubTask
static ProgressObserverRef makeSubTask(ProgressObserverRef parentProgress, float weight=1.0, const std::string &label=std::string(), int steps=100)
Definition progressobserver.h:62
zyppng::ProgressObserver::setup
static void setup(ProgressObserverRef progress, const std::string &label=std::string(), int steps=100)
Definition progressobserver.h:71
zyppng::ProgressObserver::finish
static void finish(ProgressObserverRef progress, ProgressObserver::FinishResult result=ProgressObserver::Success)
Definition progressobserver.h:94
zyppng::ProgressObserver::setCurrent
void setCurrent(double curr)
Definition progressobserver.cc:258
zyppng::ProgressObserver::Error
@ Error
Definition progressobserver.h:36
zyppng::ProgressObserver::Success
@ Success
Definition progressobserver.h:35
zyppng::ProgressObserver::start
void start()
Definition progressobserver.cc:163
zyppng::ProvideMediaSpec
Definition providespec.h:30
zyppng::RepoManager::cleanPackages
expected< void > cleanPackages(const RepoInfo &info, ProgressObserverRef myProgress=nullptr, bool isAutoClean=false)
Definition repomanager.cc:396
zyppng::RepoManager::removeRepository
expected< void > removeRepository(const RepoInfo &info, ProgressObserverRef myProgress=nullptr)
Definition repomanager.cc:610
zyppng::RepoManager::RepoConstIterator
RepoSet::const_iterator RepoConstIterator
Definition repomanager.h:290
zyppng::RepoManager::isCached
expected< bool > isCached(const RepoInfo &info) const
Definition repomanager.h:340
zyppng::RepoManager::buildCache
expected< void > buildCache(const RepoInfo &info, CacheBuildPolicy policy, ProgressObserverRef myProgress=nullptr)
Definition repomanager.cc:979
zyppng::RepoManager::addProbedRepository
expected< RepoInfo > addProbedRepository(RepoInfo info, zypp::repo::RepoType probedType)
Definition repomanager.cc:570
zyppng::RepoManager::generateFilename
std::string generateFilename(const RepoInfo &info) const
Definition repomanager.h:477
zyppng::RepoManager::_services
ServiceSet _services
Definition repomanager.h:504
zyppng::RepoManager::_reposX
RepoSet _reposX
Definition repomanager.h:503
zyppng::RepoManager::init_knownServices
expected< void > init_knownServices()
zyppng::RepoManager::getService
ServiceInfo getService(const std::string &alias) const
Definition repomanager.h:417
zyppng::RepoManager::RefreshServiceOptions
zypp::RepoManagerFlags::RefreshServiceOptions RefreshServiceOptions
Definition repomanager.h:256
zyppng::RepoManager::modifyRepository
expected< RepoInfo > modifyRepository(const std::string &alias, const RepoInfo &newinfo_r, ProgressObserverRef myProgress=nullptr)
Definition repomanager.cc:699
zyppng::RepoManager::_reposDirty
zypp::DefaultIntegral< bool, false > _reposDirty
Definition repomanager.h:506
zyppng::RepoManager::metadataStatus
static expected< RepoStatus > metadataStatus(const RepoInfo &info, const RepoManagerOptions &options)
Definition repomanager.cc:307
zyppng::RepoManager::hasRepo
bool hasRepo(const std::string &alias) const
Definition repomanager.h:311
zyppng::RepoManager::saveService
expected< void > saveService(ServiceInfo &service) const
Definition repomanager.cc:1216
zyppng::RepoManager::getRepositoryInfo
expected< RepoInfo > getRepositoryInfo(const std::string &alias)
Definition repomanager.cc:788
zyppng::RepoManager::RawMetadataRefreshPolicy
zypp::RepoManagerFlags::RawMetadataRefreshPolicy RawMetadataRefreshPolicy
Definition repomanager.h:248
zyppng::RepoManager::probeCache
static zypp::repo::RepoType probeCache(const zypp::Pathname &path_r)
Probe Metadata in a local cache directory.
Definition repomanager.cc:423
zyppng::RepoManager::repos
const RepoSet & repos() const
Definition repomanager.h:493
zyppng::RepoManager::serviceBegin
ServiceConstIterator serviceBegin() const
Definition repomanager.h:411
zyppng::RepoManager::generateNonExistingName
zypp::Pathname generateNonExistingName(const zypp::Pathname &dir, const std::string &basefilename) const
zyppng::RepoManager::_zyppContext
ContextRefType _zyppContext
Definition repomanager.h:501
zyppng::RepoManager::getRepositoriesInService
void getRepositoriesInService(const std::string &alias, OutputIterator out) const
Definition repomanager.h:467
zyppng::RepoManager::repoEnd
RepoConstIterator repoEnd() const
Definition repomanager.h:309
zyppng::RepoManager::cleanCache
expected< void > cleanCache(const RepoInfo &info, ProgressObserverRef myProgress=nullptr)
Definition repomanager.cc:498
zyppng::RepoManager::repoBegin
RepoConstIterator repoBegin() const
Definition repomanager.h:308
zyppng::RepoManager::initialize
expected< void > initialize()
Definition repomanager.cc:292
zyppng::RepoManager::ServiceSet
std::set< ServiceInfo > ServiceSet
ServiceInfo typedefs.
Definition repomanager.h:284
zyppng::RepoManager::reposManip
RepoSet & reposManip()
Definition repomanager.h:494
zyppng::RepoManager::_options
RepoManagerOptions _options
Definition repomanager.h:502
zyppng::RepoManager::init_knownRepositories
expected< void > init_knownRepositories()
Definition repomanager.cc:1399
zyppng::RepoManager::cleanMetadata
expected< void > cleanMetadata(const RepoInfo &info, ProgressObserverRef myProgress=nullptr)
Definition repomanager.cc:377
zyppng::RepoManager::serviceEnd
ServiceConstIterator serviceEnd() const
Definition repomanager.h:412
zyppng::RepoManager::hasService
bool hasService(const std::string &alias) const
Definition repomanager.h:414
zyppng::RepoManager::options
const RepoManagerOptions & options() const
Definition repomanager.cc:301
zyppng::RepoManager::CacheBuildPolicy
zypp::RepoManagerFlags::CacheBuildPolicy CacheBuildPolicy
Definition repomanager.h:249
zyppng::ServiceCollector
Functor collecting ServiceInfos into a ServiceSet.
Definition repomanager.h:210
zyppng::expected
Definition expected.h:56
zyppng::expected::unwrap
T & unwrap()
Definition expected.h:236
zyppng::expected::success
static expected success(ConsParams &&...params)
Definition expected.h:178
zyppng::expected::error
static expected error(ConsParams &&...params)
Definition expected.h:189
zyppng::expected::error
E & error()
Definition expected.h:288
zyppng::repo::RefreshContext::sigProbedTypeChanged
SignalProxy< void(zypp::repo::RepoType)> sigProbedTypeChanged()
Definition refresh.cc:157
zyppng::repo::RefreshContext::create
static expected< repo::RefreshContextRef > create(ContextRef zyppContext, zypp::RepoInfo info, RepoManagerRef repoManager)
Definition refresh.cc:31
zypp::TriBool
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
Definition String.h:31
zypp::str::regex_match
bool regex_match(const char *s, smatch &matches, const regex &regex) ZYPP_API
Regular expression matching.
Definition Regex.cc:80
std
Definition ansi.h:855
str
String related utilities and Regular expression matching.
zypp::RepoManagerFlags::RefreshCheckStatus
RefreshCheckStatus
Possibly return state of RepoManager::checkIfToRefreshMetadata function.
Definition RepoManagerFlags.h:47
zypp::RepoManagerFlags::CacheBuildPolicy
CacheBuildPolicy
Definition RepoManagerFlags.h:28
zypp::RepoManagerFlags::BuildIfNeeded
@ BuildIfNeeded
Definition RepoManagerFlags.h:29
zypp::RepoManagerFlags::RawMetadataRefreshPolicy
RawMetadataRefreshPolicy
Definition RepoManagerFlags.h:21
zypp::env
Namespace intended to collect all environment variables we use.
Definition RepoVariables.cc:34
zypp::env::ZYPP_PLUGIN_APPDATA_FORCE_COLLECT
bool ZYPP_PLUGIN_APPDATA_FORCE_COLLECT()
To trigger appdata refresh unconditionally.
Definition repomanager.cc:55
zypp::filesystem::recursive_rmdir
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
Definition PathInfo.cc:431
zypp::filesystem::unlink
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:719
zypp::filesystem::readdir
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Definition PathInfo.cc:624
zypp::filesystem::assert_dir
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Definition PathInfo.cc:338
zypp::filesystem::touch
int touch(const Pathname &path)
Change file's modification and access times.
Definition PathInfo.cc:1256
zypp::parser
Definition HistoryLogReader.cc:30
zypp::str::replaceAll
std::string & replaceAll(std::string &str_r, const std::string &from_r, const std::string &to_r)
Replace all occurrences of from_r with to_r in str_r (inplace).
Definition String.cc:333
zypp::str::numstring
std::string numstring(char n, int w=0)
Definition String.h:290
zypp::str::form
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition String.cc:39
zypp::str::strToBool
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
Definition String.h:500
zypp::url
Url details namespace.
Definition UrlBase.cc:58
zypp::zypp_readonly_hack
Definition repomanager.cc:45
zypp::zypp_readonly_hack::IGotIt
bool IGotIt()
Definition ZYppFactory.cc:92
zypp::asString
std::string asString(const Patch::Category &obj)
relates: Patch::Category string representation.
Definition Patch.cc:122
zypp::operator<<
std::ostream & operator<<(std::ostream &str, const Capabilities &obj)
relates: Capabilities Stream output
Definition Capabilities.cc:65
zyppng::RepoManagerWorkflow::checkIfToRefreshMetadata
MaybeAwaitable< expected< repo::RefreshCheckStatus > > checkIfToRefreshMetadata(repo::RefreshContextRef refCtx, LazyMediaHandle< Provide > medium, ProgressObserverRef progressObserver)
Definition repomanagerwf.cc:344
zyppng::RepoManagerWorkflow::addRepositories
MaybeAwaitable< expected< void > > addRepositories(RepoManagerRef mgr, zypp::Url url, ProgressObserverRef myProgress)
Definition repomanagerwf.cc:1007
zyppng::RepoManagerWorkflow::probeRepoType
MaybeAwaitable< expected< zypp::repo::RepoType > > probeRepoType(ContextRef ctx, Provide::LazyMediaHandle medium, zypp::Pathname path, std::optional< zypp::Pathname > targetPath)
Definition repomanagerwf.cc:195
zyppng::RepoManagerWorkflow::addRepository
MaybeAwaitable< expected< RepoInfo > > addRepository(RepoManagerRef mgr, RepoInfo info, ProgressObserverRef myProgress, const zypp::TriBool &forcedProbe)
Definition repomanagerwf.cc:913
zyppng::RepoManagerWorkflow::refreshMetadata
MaybeAwaitable< expected< repo::RefreshContextRef > > refreshMetadata(repo::RefreshContextRef refCtx, LazyMediaHandle< Provide > medium, ProgressObserverRef progressObserver)
Definition repomanagerwf.cc:444
zyppng::RepoManagerWorkflow::buildCache
MaybeAwaitable< expected< repo::RefreshContextRef > > buildCache(repo::RefreshContextRef refCtx, zypp::RepoManagerFlags::CacheBuildPolicy policy, ProgressObserverRef progressObserver)
Definition repomanagerwf.cc:841
zyppng::RepoManagerWorkflow::refreshGeoIPData
MaybeAwaitable< expected< void > > refreshGeoIPData(ContextRef ctx, RepoInfo::url_set urls)
Definition repomanagerwf.cc:1174
zyppng::RepoServicesWorkflow::refreshService
MaybeAwaitable< expected< void > > refreshService(RepoManagerRef repoMgr, ServiceInfo info, zypp::RepoManagerFlags::RefreshServiceOptions options)
Definition serviceswf.cc:713
zyppng::RepoServicesWorkflow::probeServiceType
MaybeAwaitable< expected< zypp::repo::ServiceType > > probeServiceType(ContextRef ctx, const zypp::Url &url)
Definition serviceswf.cc:231
zyppng::env
Definition repomanager.cc:53
zyppng::operators
Definition expected.h:699
zyppng::operators::incProgress
auto incProgress(ProgressObserverRef progressObserver, double progrIncrease=1.0, std::optional< std::string > newStr={})
Definition progressobserver.h:229
zyppng::operators::join
auto join()
Definition wait.h:34
zyppng::repo
Definition downloader.cc:22
zyppng::repo::RawMetadataRefreshPolicy
zypp::RepoManagerFlags::RawMetadataRefreshPolicy RawMetadataRefreshPolicy
Definition refresh.h:33
zyppng::rpc
Definition stompframestream.h:41
zyppng
Definition MediaNetworkRequestExecutor.h:16
zyppng::isTmpRepo
bool isTmpRepo(const RepoInfo &info_r)
Whether repo is not under RM control and provides its own methadata paths.
Definition repomanager.h:49
zyppng::assert_urls
expected< void > assert_urls(const RepoInfo &info)
Definition repomanager.cc:227
zyppng::repositories_in_dir
std::list< RepoInfo > repositories_in_dir(ZContextRef zyppContext, const zypp::Pathname &dir)
List of RepoInfo's from a directory.
Definition repomanager.cc:189
zyppng::cleanupNonRepoMetadtaFolders
void cleanupNonRepoMetadtaFolders(const zypp::Pathname &cachePath_r, const zypp::Pathname &defaultCachePath_r, const std::list< std::string > &repoEscAliases_r)
Generate a non existing filename in a directory, using a base name.
Definition repomanager.cc:1362
zyppng::filenameFromAlias
std::string filenameFromAlias(const std::string &alias_r, const std::string &stem_r)
Generate a related filename from a repo/service infos alias.
Definition repomanager.cc:137
zyppng::rawcache_path_for_repoinfo
expected< zypp::Pathname > rawcache_path_for_repoinfo(const RepoManagerOptions &opt, const RepoInfo &info)
Calculates the raw cache path for a repository, this is usually /var/cache/zypp/alias.
Definition repomanager.h:166
zyppng::assert_alias
expected< void > assert_alias(const RepoInfo &info)
Definition repomanager.h:52
zyppng::or_else
ResultType or_else(const expected< T, E > &exp, Function &&f)
Definition expected.h:554
zyppng::and_then
ResultType and_then(const expected< T, E > &exp, Function &&f)
Definition expected.h:520
zyppng::transform
auto transform(Container< Msg, CArgs... > &&val, Transformation &&transformation)
Definition transform.h:64
zyppng::solv_path_for_repoinfo
expected< zypp::Pathname > solv_path_for_repoinfo(const RepoManagerOptions &opt, const RepoInfo &info)
Calculates the solv cache path for a repository.
Definition repomanager.h:199
zyppng::repositories_in_file
expected< std::list< RepoInfo > > repositories_in_file(const zypp::Pathname &file)
Reads RepoInfo's from a repo file.
Definition repomanager.cc:167
zyppng::findAlias
Iterator findAlias(const std::string &alias_r, Iterator begin_r, Iterator end_r)
Find alias_r in repo/service container.
Definition repomanager.h:93
zyppng::collect
std::enable_if_t<!std::is_same_v< void, T >, expected< Container< T >, E > > collect(Container< expected< T, E >, CArgs... > &&in)
Definition expected.h:586
zyppng::packagescache_path_for_repoinfo
expected< zypp::Pathname > packagescache_path_for_repoinfo(const RepoManagerOptions &opt, const RepoInfo &info)
Calculates the packages cache path for a repository.
Definition repomanager.h:189
zyppng::joinPipeline
auto joinPipeline(ContextRef ctx, T &&val)
Definition context.h:52
zyppng::rawproductdata_path_for_repoinfo
expected< zypp::Pathname > rawproductdata_path_for_repoinfo(const RepoManagerOptions &opt, const RepoInfo &info)
Calculates the raw product metadata path for a repository, this is inside the raw cache dir,...
Definition repomanager.h:180
zyppng::inspect
expected< T, E > inspect(expected< T, E > exp, Function &&f)
Definition expected.h:616
zyppng::autoPruneInDir
bool autoPruneInDir(const zypp::Pathname &path_r)
bsc#1204956: Tweak to prevent auto pruning package caches.
Definition repomanager.cc:234
zyppng::mtry
auto mtry(F &&f, Args &&...args)
Definition mtry.h:50
providespec.h
refresh.h
repomanager.h
repomanagerwf.h
reporthelper.h
serviceswf.h
zypp::RepoManagerOptions
Repo manager settings.
Definition RepoManagerOptions.h:26
zypp::repo::RepoType
Repository type enumeration.
Definition RepoType.h:29
zypp::repo::RepoType::YAST2
static const RepoType YAST2
Definition RepoType.h:31
zypp::repo::RepoType::RPMMD_e
@ RPMMD_e
Definition RepoType.h:38
zypp::repo::RepoType::NONE_e
@ NONE_e
Definition RepoType.h:37
zypp::repo::RepoType::YAST2_e
@ YAST2_e
Definition RepoType.h:39
zypp::repo::RepoType::RPMPLAINDIR_e
@ RPMPLAINDIR_e
Definition RepoType.h:40
zypp::repo::RepoType::toEnum
Type toEnum() const
Definition RepoType.h:49
zypp::repo::RepoType::RPMMD
static const RepoType RPMMD
Definition RepoType.h:30
zypp::repo::RepoType::NONE
static const RepoType NONE
Definition RepoType.h:33
zypp::repo::RepoType::RPMPLAINDIR
static const RepoType RPMPLAINDIR
Definition RepoType.h:32
zypp::str::Format
Convenient building of std::string with boost::format.
Definition String.h:254
zypp::str::Str
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition String.h:213
zypp::url::ViewOption
Url::asString() view options.
Definition UrlBase.h:41
zyppng::RepoCollector
Simple callback to collect the results.
Definition repomanager.h:129
zyppng::RepoCollector::targetDistro
std::string targetDistro
Definition repomanager.h:140
zyppng::RepoCollector::repos
RepoInfoList repos
Definition repomanager.h:139
zyppng::RepoCollector::collect
bool collect(const RepoInfo &repo)
Definition repomanager.cc:148
urlcredentialextractor_p.h
wait.h
PathInfo.h
ZYPP_PRIVATE_CONSTR_ARG
#define ZYPP_PRIVATE_CONSTR_ARG
Definition zyppglobal.h:153