libzypp: zypp/ng/repomanager.cc Source File

libzypp 17.36.6

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