libzypp 17.37.10

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
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 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 base 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( const auto &origin : it->repoOrigins() )
813 {
814 if ( std::any_of( origin.begin(), origin.end(), [&url, &urlview]( const zypp::OriginEndpoint &ep ){ return (ep.url().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::MirroredOrigin &origin, RawMetadataRefreshPolicy policy)
829 {
830 using namespace zyppng::operators;
831 return joinPipeline( _zyppContext,
832 RepoManagerWorkflow::refreshGeoIPData( _zyppContext, info.repoOrigins() )
833 | [this, info](auto) { return zyppng::repo::RefreshContext<ZyppContextRefType>::create( _zyppContext, info, shared_this<RepoManager<ZyppContextRefType>>() ); }
834 | and_then( [this, origin, policy]( zyppng::repo::RefreshContextRef<ZyppContextRefType> &&refCtx ) {
835 refCtx->setPolicy ( static_cast<zyppng::repo::RawMetadataRefreshPolicy>( policy ) );
836
837 return _zyppContext->provider()->prepareMedia( origin, zyppng::ProvideMediaSpec() )
838 | and_then( [ r = std::move(refCtx) ]( auto mediaHandle ) mutable { return zyppng::RepoManagerWorkflow::checkIfToRefreshMetadata ( std::move(r), std::move(mediaHandle), nullptr ); } );
839 })
840 );
841 }
842
843 template<typename ZyppContextRefType>
844 expected<void> RepoManager<ZyppContextRefType>::refreshMetadata( const RepoInfo &info, RawMetadataRefreshPolicy policy, ProgressObserverRef myProgress )
845 {
846 using namespace zyppng::operators;
847 // helper callback in case the repo type changes on the remote
848 // do NOT capture by reference here, since this is possibly executed async
849 const auto &updateProbedType = [this, info = info]( zypp::repo::RepoType repokind ) {
850 // update probed type only for repos in system
851 for( const auto &repo : repos() ) {
852 if ( info.alias() == repo.alias() )
853 {
854 RepoInfo modifiedrepo = repo;
855 modifiedrepo.setType( repokind );
856 // don't modify .repo in refresh.
857 // modifyRepository( info.alias(), modifiedrepo );
858 break;
859 }
860 }
861 };
862
863 // the list of URLs we want to have geo ip redirects for
864 auto urls = info.baseUrls ();
865 if ( info.mirrorListUrl ().isValid () )
866 urls.push_back ( info.mirrorListUrl () );
867
868 return joinPipeline( _zyppContext,
869 // make sure geoIP data is up 2 date, but ignore errors
870 RepoManagerWorkflow::refreshGeoIPData( _zyppContext, urls )
871 | [this, info = info](auto) { return zyppng::repo::RefreshContext<ZyppContextRefType>::create( _zyppContext, info, shared_this<RepoManager<ZyppContextRefType>>()); }
872 | and_then( [policy, myProgress, cb = updateProbedType]( repo::RefreshContextRef<ZyppContextRefType> refCtx ) {
873 refCtx->setPolicy( static_cast<repo::RawMetadataRefreshPolicy>( policy ) );
874 // in case probe detects a different repokind, update our internal repos
875 refCtx->connectFunc( &repo::RefreshContext<ZyppContextRefType>::sigProbedTypeChanged, cb );
876
877 return zyppng::RepoManagerWorkflow::refreshMetadata ( std::move(refCtx), myProgress );
878 })
879 | and_then([rMgr = shared_this<RepoManager<ZyppContextRefType>>()]( repo::RefreshContextRef<ZyppContextRefType> ctx ) {
880
881 if ( ! isTmpRepo( ctx->repoInfo() ) )
882 rMgr->reposManip(); // remember to trigger appdata refresh
883
884 return expected<void>::success ();
885 }));
886 }
887
888 template<typename ZyppContextRefType>
889 std::vector<std::pair<RepoInfo, expected<void>>> RepoManager<ZyppContextRefType>::refreshMetadata( std::vector<RepoInfo> infos, RawMetadataRefreshPolicy policy, ProgressObserverRef myProgress )
890 {
891 using namespace zyppng::operators;
892
893 ProgressObserver::setup( myProgress, "Refreshing repositories" , 1 );
894
895 auto r = std::move(infos)
896 | transform( [this, policy, myProgress]( const RepoInfo &info ) {
897
898 auto subProgress = ProgressObserver::makeSubTask( myProgress, 1.0, zypp::str::Str() << _("Refreshing Repository: ") << info.alias(), 3 );
899
900 // helper callback in case the repo type changes on the remote
901 // do NOT capture by reference here, since this is possibly executed async
902 const auto &updateProbedType = [this, info = info]( zypp::repo::RepoType repokind ) {
903 // update probed type only for repos in system
904 for( const auto &repo : repos() ) {
905 if ( info.alias() == repo.alias() )
906 {
907 RepoInfo modifiedrepo = repo;
908 modifiedrepo.setType( repokind );
909 // don't modify .repo in refresh.
910 // modifyRepository( info.alias(), modifiedrepo );
911 break;
912 }
913 }
914 };
915
916 auto sharedThis = shared_this<RepoManager<ZyppContextRefType>>();
917
918 return
919 // make sure geoIP data is up 2 date, but ignore errors
920 RepoManagerWorkflow::refreshGeoIPData( _zyppContext, info.repoOrigins() )
921 | [sharedThis, info = info](auto) { return zyppng::repo::RefreshContext<ZyppContextRefType>::create( sharedThis->_zyppContext, info, sharedThis); }
922 | inspect( incProgress( subProgress ) )
923 | and_then( [policy, subProgress, cb = updateProbedType]( repo::RefreshContextRef<ZyppContextRefType> refCtx ) {
924 refCtx->setPolicy( static_cast<repo::RawMetadataRefreshPolicy>( policy ) );
925 // in case probe detects a different repokind, update our internal repos
926 refCtx->connectFunc( &repo::RefreshContext<ZyppContextRefType>::sigProbedTypeChanged, cb );
927
928 return zyppng::RepoManagerWorkflow::refreshMetadata ( std::move(refCtx), ProgressObserver::makeSubTask( subProgress ) );
929 })
930 | inspect( incProgress( subProgress ) )
931 | and_then([subProgress]( repo::RefreshContextRef<ZyppContextRefType> ctx ) {
932
933 if ( ! isTmpRepo( ctx->repoInfo() ) )
934 ctx->repoManager()->reposManip(); // remember to trigger appdata refresh
935
936 return zyppng::RepoManagerWorkflow::buildCache ( std::move(ctx), CacheBuildPolicy::BuildIfNeeded, ProgressObserver::makeSubTask( subProgress ) );
937 })
938 | inspect( incProgress( subProgress ) )
939 | [ info = info, subProgress ]( expected<repo::RefreshContextRef<ZyppContextRefType>> result ) {
940 if ( result ) {
941 ProgressObserver::finish( subProgress, ProgressObserver::Success );
942 return std::make_pair(info, expected<void>::success() );
943 } else {
944 ProgressObserver::finish( subProgress, ProgressObserver::Error );
945 return std::make_pair(info, expected<void>::error( result.error() ) );
946 }
947 };
948 }
949 | [myProgress]( auto res ) {
950 ProgressObserver::finish( myProgress, ProgressObserver::Success );
951 return res;
952 }
953 );
954
955 return joinPipeline( _zyppContext, r );
956 }
957
964 template<typename ZyppContextRefType>
965 expected<zypp::repo::RepoType> RepoManager<ZyppContextRefType>::probe(const zypp::MirroredOrigin &origin, const zypp::Pathname &path) const
966 {
967 using namespace zyppng::operators;
968
969 RepoInfo::url_set allUrls;
970 std::transform( origin.begin (), origin.end(), std::back_inserter(allUrls), []( const zypp::OriginEndpoint &ep ){ return ep.url(); } );
971
972 return joinPipeline( _zyppContext,
973 RepoManagerWorkflow::refreshGeoIPData( _zyppContext, allUrls )
974 | [this, origin=origin](auto) { return _zyppContext->provider()->prepareMedia( origin, zyppng::ProvideMediaSpec() ); }
975 | and_then( [this, path = path]( auto mediaHandle ) {
976 return RepoManagerWorkflow::probeRepoType( _zyppContext, std::move(mediaHandle), path );
977 }));
978 }
979
980 template<typename ZyppContextRefType>
981 expected<void> RepoManager<ZyppContextRefType>::buildCache( const RepoInfo &info, CacheBuildPolicy policy, ProgressObserverRef myProgress )
982 {
983 using namespace zyppng::operators;
984 return joinPipeline( _zyppContext,
985 zyppng::repo::RefreshContext<ZyppContextRefType>::create( _zyppContext, info, shared_this<RepoManager<ZyppContextRefType>>() )
986 | and_then( [policy, myProgress]( repo::RefreshContextRef<ZyppContextRefType> refCtx ) {
987 return zyppng::RepoManagerWorkflow::buildCache ( std::move(refCtx), policy, myProgress );
988 })
989 | and_then([]( auto ){ return expected<void>::success(); })
990 );
991 }
992
993 template<typename ZyppContextRefType>
994 expected<RepoInfo> RepoManager<ZyppContextRefType>::addRepository(const RepoInfo &info, ProgressObserverRef myProgress)
995 {
996 return joinPipeline( _zyppContext, RepoManagerWorkflow::addRepository( shared_this<RepoManager<ZyppContextRefType>>(), info, std::move(myProgress) ) );
997 }
998
999 template<typename ZyppContextRefType>
1000 expected<void> RepoManager<ZyppContextRefType>::addRepositories(const zypp::Url &url, ProgressObserverRef myProgress)
1001 {
1002 using namespace zyppng::operators;
1003 return joinPipeline( _zyppContext, RepoManagerWorkflow::addRepositories( shared_this<RepoManager<ZyppContextRefType>>(), url, std::move(myProgress)));
1004 }
1005
1006 template <typename ZyppContextRefType>
1007 expected<zypp::repo::ServiceType> RepoManager<ZyppContextRefType>::probeService( const zypp::Url & url ) const
1008 {
1009 return joinPipeline( _zyppContext, RepoServicesWorkflow::probeServiceType ( _zyppContext, url ) );
1010 }
1011
1012 template <typename ZyppContextRefType>
1013 expected<void> RepoManager<ZyppContextRefType>::addService( const ServiceInfo & service )
1014 {
1015 try {
1016
1017 assert_alias( service ).unwrap();
1018
1019 // check if service already exists
1020 if ( hasService( service.alias() ) )
1021 ZYPP_THROW( zypp::repo::ServiceAlreadyExistsException( service ) );
1022
1023 // Writable ServiceInfo is needed to save the location
1024 // of the .service file. Finaly insert into the service list.
1025 ServiceInfo toSave( service );
1026 saveService( toSave ).unwrap();
1027 _services.insert( toSave );
1028
1029 // check for credentials in Url
1030 zypp::UrlCredentialExtractor( _options.rootDir ).collect( toSave.url() );
1031
1032 MIL << "added service " << toSave.alias() << std::endl;
1033
1034 } catch ( ... ) {
1035 return expected<void>::error( std::current_exception () );
1036 }
1037
1038 return expected<void>::success();
1039 }
1040
1041 template<typename ZyppContextRefType>
1042 expected<void> RepoManager<ZyppContextRefType>::refreshService( const std::string &alias, const RefreshServiceOptions &options_r )
1043 {
1044 return joinPipeline ( _zyppContext, RepoServicesWorkflow::refreshService( shared_this<RepoManager<ZyppContextRefType>>(), getService( alias ), options_r ) );
1045 }
1046
1050 template<typename ZyppContextRefType>
1051 expected<void> RepoManager<ZyppContextRefType>::refreshServices(const RefreshServiceOptions &options_r)
1052 {
1053 using namespace zyppng::operators;
1054 // copy the set of services since refreshService
1055 // can eventually invalidate the iterator
1056 ServiceSet servicesCopy( serviceBegin(), serviceEnd() );
1057
1058 // convert the set into a vector, transform needs a container with push_back support
1059 std::vector<ServiceInfo> servicesVec;
1060 std::copy( std::make_move_iterator(servicesCopy.begin()), std::make_move_iterator(servicesCopy.end()), std::back_inserter(servicesVec));
1061
1062 return joinPipeline( _zyppContext,
1063 std::move(servicesVec)
1064 | transform( [options_r, this]( ServiceInfo i ){ return RepoServicesWorkflow::refreshService( shared_this<RepoManager<ZyppContextRefType>>(), i, options_r ); } )
1065 | join()
1066 | collect()
1067 );
1068 }
1069
1071
1072 template <typename ZyppContextRefType>
1073 expected<void> RepoManager<ZyppContextRefType>::removeService( const std::string & alias )
1074 {
1075 try {
1076 MIL << "Going to delete service " << alias << std::endl;
1077
1078 const ServiceInfo & service = getService( alias );
1079
1080 zypp::Pathname location = service.filepath();
1081 if( location.empty() )
1082 {
1083 ZYPP_THROW(zypp::repo::ServiceException( service, _("Can't figure out where the service is stored.") ));
1084 }
1085
1086 ServiceSet tmpSet;
1087 zypp::parser::ServiceFileReader( location, ServiceCollector(tmpSet) );
1088
1089 // only one service definition in the file
1090 if ( tmpSet.size() == 1 )
1091 {
1092 if ( zypp::filesystem::unlink(location) != 0 )
1093 {
1094 // TranslatorExplanation '%s' is a filename
1095 ZYPP_THROW(zypp::repo::ServiceException( service, zypp::str::form( _("Can't delete '%s'"), location.c_str() ) ));
1096 }
1097 MIL << alias << " successfully deleted." << std::endl;
1098 }
1099 else
1100 {
1101 zypp::filesystem::assert_dir(location.dirname());
1102
1103 std::ofstream file(location.c_str());
1104 if( !file )
1105 {
1106 // TranslatorExplanation '%s' is a filename
1107 ZYPP_THROW( zypp::Exception(zypp::str::form( _("Can't open file '%s' for writing."), location.c_str() )));
1108 }
1109
1110 for_(it, tmpSet.begin(), tmpSet.end())
1111 {
1112 if( it->alias() != alias )
1113 it->dumpAsIniOn(file);
1114 }
1115
1116 MIL << alias << " successfully deleted from file " << location << std::endl;
1117 }
1118
1119 // now remove all repositories added by this service
1120 RepoCollector rcollector;
1121 getRepositoriesInService( alias,
1122 boost::make_function_output_iterator( std::bind( &RepoCollector::collect, &rcollector, std::placeholders::_1 ) ) );
1123 // cannot do this directly in getRepositoriesInService - would invalidate iterators
1124 for_(rit, rcollector.repos.begin(), rcollector.repos.end())
1125 removeRepository(*rit).unwrap();
1126
1127 return expected<void>::success();
1128
1129 } catch ( ... ) {
1130 return expected<void>::error( std::current_exception () );
1131 }
1132 }
1133
1134 template <typename ZyppContextRefType>
1135 expected<void> RepoManager<ZyppContextRefType>::modifyService( const std::string & oldAlias, const ServiceInfo & newService )
1136 {
1137 try {
1138
1139 MIL << "Going to modify service " << oldAlias << std::endl;
1140
1141 // we need a writable copy to link it to the file where
1142 // it is saved if we modify it
1143 ServiceInfo service(newService);
1144
1145 if ( service.type() == zypp::repo::ServiceType::PLUGIN )
1146 {
1147 ZYPP_THROW(zypp::repo::ServicePluginImmutableException( service ));
1148 }
1149
1150 const ServiceInfo & oldService = getService(oldAlias);
1151
1152 zypp::Pathname location = oldService.filepath();
1153 if( location.empty() )
1154 {
1155 ZYPP_THROW(zypp::repo::ServiceException( oldService, _("Can't figure out where the service is stored.") ));
1156 }
1157
1158 // remember: there may multiple services being defined in one file:
1159 ServiceSet tmpSet;
1160 zypp::parser::ServiceFileReader( location, ServiceCollector(tmpSet) );
1161
1162 zypp::filesystem::assert_dir(location.dirname());
1163 std::ofstream file(location.c_str());
1164 for_(it, tmpSet.begin(), tmpSet.end())
1165 {
1166 if( *it != oldAlias )
1167 it->dumpAsIniOn(file);
1168 }
1169 service.dumpAsIniOn(file);
1170 file.close();
1171 service.setFilepath(location);
1172
1173 _services.erase(oldAlias);
1174 _services.insert(service);
1175 // check for credentials in Urls
1176 zypp::UrlCredentialExtractor( _options.rootDir ).collect( service.url() );
1177
1178
1179 // changed properties affecting also repositories
1180 if ( oldAlias != service.alias() // changed alias
1181 || oldService.enabled() != service.enabled() ) // changed enabled status
1182 {
1183 std::vector<RepoInfo> toModify;
1184 getRepositoriesInService(oldAlias, std::back_inserter(toModify));
1185 for_( it, toModify.begin(), toModify.end() )
1186 {
1187 if ( oldService.enabled() != service.enabled() )
1188 {
1189 if ( service.enabled() )
1190 {
1191 // reset to last refreshs state
1192 const auto & last = service.repoStates().find( it->alias() );
1193 if ( last != service.repoStates().end() )
1194 it->setEnabled( last->second.enabled );
1195 }
1196 else
1197 it->setEnabled( false );
1198 }
1199
1200 if ( oldAlias != service.alias() )
1201 it->setService(service.alias());
1202
1203 modifyRepository(it->alias(), *it).unwrap();
1204 }
1205 }
1206
1207 return expected<void>::success();
1208
1209 } catch ( ... ) {
1210 return expected<void>::error( std::current_exception () );
1211 }
1212
1214 }
1215
1216
1217 template <typename ZyppContextRefType>
1218 expected<void> RepoManager<ZyppContextRefType>::saveService( ServiceInfo & service ) const
1219 {
1220 try {
1221
1222 zypp::filesystem::assert_dir( _options.knownServicesPath );
1223 zypp::Pathname servfile = generateNonExistingName( _options.knownServicesPath,
1224 generateFilename( service ) );
1225 service.setFilepath( servfile );
1226
1227 MIL << "saving service in " << servfile << std::endl;
1228
1229 std::ofstream file( servfile.c_str() );
1230 if ( !file )
1231 {
1232 // TranslatorExplanation '%s' is a filename
1233 ZYPP_THROW( zypp::Exception(zypp::str::form( _("Can't open file '%s' for writing."), servfile.c_str() )));
1234 }
1235 service.dumpAsIniOn( file );
1236 MIL << "done" << std::endl;
1237
1238 return expected<void>::success();
1239
1240 } catch ( ... ) {
1241 return expected<void>::error( std::current_exception () );
1242 }
1243 }
1244
1260 template <typename ZyppContextRefType>
1261 zypp::Pathname RepoManager<ZyppContextRefType>::generateNonExistingName( const zypp::Pathname & dir,
1262 const std::string & basefilename ) const
1263 {
1264 std::string final_filename = basefilename;
1265 int counter = 1;
1266 while ( zypp::PathInfo(dir + final_filename).isExist() )
1267 {
1268 final_filename = basefilename + "_" + zypp::str::numstring(counter);
1269 ++counter;
1270 }
1271 return dir + zypp::Pathname(final_filename);
1272 }
1273
1274 template <typename ZyppContextRefType>
1275 expected<void> RepoManager<ZyppContextRefType>::touchIndexFile(const RepoInfo &info, const RepoManagerOptions &options)
1276 {
1277 try {
1278 zypp::Pathname productdatapath = rawproductdata_path_for_repoinfo( options, info ).unwrap();
1279
1280 zypp::repo::RepoType repokind = info.type();
1281 if ( repokind.toEnum() == zypp::repo::RepoType::NONE_e )
1282 // unknown, probe the local metadata
1283 repokind = probeCache( productdatapath );
1284 // if still unknown, just return
1285 if (repokind == zypp::repo::RepoType::NONE_e)
1286 return expected<void>::success();
1287
1288 zypp::Pathname p;
1289 switch ( repokind.toEnum() )
1290 {
1291 case zypp::repo::RepoType::RPMMD_e :
1292 p = zypp::Pathname(productdatapath + "/repodata/repomd.xml");
1293 break;
1294
1295 case zypp::repo::RepoType::YAST2_e :
1296 p = zypp::Pathname(productdatapath + "/content");
1297 break;
1298
1299 case zypp::repo::RepoType::RPMPLAINDIR_e :
1300 p = zypp::Pathname(productdatapath + "/cookie");
1301 break;
1302
1303 case zypp::repo::RepoType::NONE_e :
1304 default:
1305 break;
1306 }
1307
1308 // touch the file, ignore error (they are logged anyway)
1309 zypp::filesystem::touch(p);
1310 } catch ( ... ) {
1311 return expected<void>::error( ZYPP_FWD_CURRENT_EXCPT() );
1312 }
1313 return expected<void>::success();
1314 }
1315
1316 template<typename ZyppContextRefType>
1317 expected<void> RepoManager<ZyppContextRefType>::refreshGeoIp( const RepoInfo::url_set &urls )
1318 {
1319 return joinPipeline( _zyppContext, RepoManagerWorkflow::refreshGeoIPData( _zyppContext, urls) );
1320 }
1321
1322 template <typename ZyppContextRefType>
1323 expected<void> RepoManager<ZyppContextRefType>::touchIndexFile( const RepoInfo & info )
1324 {
1325 return touchIndexFile( info, _options );
1326 }
1327
1328 template <typename ZyppContextRefType>
1329 expected<void> RepoManager<ZyppContextRefType>::init_knownServices()
1330 {
1331 try {
1332 zypp::Pathname dir = _options.knownServicesPath;
1333 std::list<zypp::Pathname> entries;
1334 if (zypp::PathInfo(dir).isExist())
1335 {
1336 if ( zypp::filesystem::readdir( entries, dir, false ) != 0 )
1337 {
1338 // TranslatorExplanation '%s' is a pathname
1339 ZYPP_THROW(zypp::Exception(zypp::str::form(_("Failed to read directory '%s'"), dir.c_str())));
1340 }
1341
1342 //str::regex allowedServiceExt("^\\.service(_[0-9]+)?$");
1343 for_(it, entries.begin(), entries.end() )
1344 {
1345 zypp::parser::ServiceFileReader(*it, ServiceCollector(_services));
1346 }
1347 }
1348
1349 zypp::repo::PluginServices(_options.pluginsPath/"services", ServiceCollector(_services));
1350
1351 return expected<void>::success();
1352
1353 } catch ( ... ) {
1354 return expected<void>::error( std::current_exception () );
1355 }
1356
1357 }
1358
1359 namespace {
1366 inline void cleanupNonRepoMetadtaFolders( const zypp::Pathname & cachePath_r,
1367 const zypp::Pathname & defaultCachePath_r,
1368 const std::list<std::string> & repoEscAliases_r )
1369 {
1370 if ( zypp::zypp_readonly_hack::IGotIt() )
1371 return;
1372
1373 if ( cachePath_r != defaultCachePath_r )
1374 return;
1375
1376 std::list<std::string> entries;
1377 if ( zypp::filesystem::readdir( entries, cachePath_r, false ) == 0 )
1378 {
1379 entries.sort();
1380 std::set<std::string> oldfiles;
1381 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
1382 std::inserter( oldfiles, oldfiles.end() ) );
1383
1384 // bsc#1178966: Files or symlinks here have been created by the user
1385 // for whatever purpose. It's our cache, so we purge them now before
1386 // they may later conflict with directories we need.
1387 zypp::PathInfo pi;
1388 for ( const std::string & old : oldfiles )
1389 {
1390 if ( old == zypp::Repository::systemRepoAlias() ) // don't remove the @System solv file
1391 continue;
1392 pi( cachePath_r/old );
1393 if ( pi.isDir() )
1394 zypp::filesystem::recursive_rmdir( pi.path() );
1395 else
1396 zypp::filesystem::unlink( pi.path() );
1397 }
1398 }
1399 }
1400 } // namespace
1401
1402 template <typename ZyppContextRefType>
1403 expected<void> RepoManager<ZyppContextRefType>::init_knownRepositories()
1404 {
1405 try {
1406
1407 MIL << "start construct known repos" << std::endl;
1408
1409 if ( zypp::PathInfo(_options.knownReposPath).isExist() )
1410 {
1411 std::list<std::string> repoEscAliases;
1412 std::list<RepoInfo> orphanedRepos;
1413 for ( RepoInfo & repoInfo : repositories_in_dir( _zyppContext, _options.knownReposPath ) )
1414 {
1415 // set the metadata path for the repo
1416 repoInfo.setMetadataPath( rawcache_path_for_repoinfo(_options, repoInfo).unwrap() );
1417 // set the downloaded packages path for the repo
1418 repoInfo.setPackagesPath( packagescache_path_for_repoinfo(_options, repoInfo).unwrap() );
1419 // remember it
1420 _reposX.insert( repoInfo ); // direct access via _reposX in ctor! no reposManip.
1421
1422 // detect orphaned repos belonging to a deleted service
1423 const std::string & serviceAlias( repoInfo.service() );
1424 if ( ! ( serviceAlias.empty() || hasService( serviceAlias ) ) )
1425 {
1426 WAR << "Schedule orphaned service repo for deletion: " << repoInfo << std::endl;
1427 orphanedRepos.push_back( repoInfo );
1428 continue; // don't remember it in repoEscAliases
1429 }
1430
1431 repoEscAliases.push_back(repoInfo.escaped_alias());
1432 }
1433
1434 // Cleanup orphanded service repos:
1435 if ( ! orphanedRepos.empty() )
1436 {
1437 for ( const auto & repoInfo : orphanedRepos )
1438 {
1439 MIL << "Delete orphaned service repo " << repoInfo.alias() << std::endl;
1440 // translators: Cleanup a repository previously owned by a meanwhile unknown (deleted) service.
1441 // %1% = service name
1442 // %2% = repository name
1443 JobReportHelper(_zyppContext).warning( zypp::str::Format(_("Unknown service '%1%': Removing orphaned service repository '%2%'"))
1444 % repoInfo.service()
1445 % repoInfo.alias() );
1446 try {
1447 removeRepository( repoInfo ).unwrap();
1448 }
1449 catch ( const zypp::Exception & caugth )
1450 {
1451 JobReportHelper(_zyppContext).error( caugth.asUserHistory() );
1452 }
1453 }
1454 }
1455
1456 // bsc#1210740: Don't cleanup if read-only mode was promised.
1457 if ( not zypp::zypp_readonly_hack::IGotIt() ) {
1458 // delete metadata folders without corresponding repo (e.g. old tmp directories)
1459 //
1460 // bnc#891515: Auto-cleanup only zypp.conf default locations. Otherwise
1461 // we'd need somemagic file to identify zypp cache directories. Without this
1462 // we may easily remove user data (zypper --pkg-cache-dir . download ...)
1463 repoEscAliases.sort();
1464 cleanupNonRepoMetadtaFolders( _options.repoRawCachePath,
1465 zypp::Pathname::assertprefix( _options.rootDir, _zyppContext->config().builtinRepoMetadataPath() ),
1466 repoEscAliases );
1467 cleanupNonRepoMetadtaFolders( _options.repoSolvCachePath,
1468 zypp::Pathname::assertprefix( _options.rootDir, _zyppContext->config().builtinRepoSolvfilesPath() ),
1469 repoEscAliases );
1470 // bsc#1204956: Tweak to prevent auto pruning package caches
1471 if ( autoPruneInDir( _options.repoPackagesCachePath ) )
1472 cleanupNonRepoMetadtaFolders( _options.repoPackagesCachePath,
1473 zypp::Pathname::assertprefix( _options.rootDir, _zyppContext->config().builtinRepoPackagesPath() ),
1474 repoEscAliases );
1475 }
1476 }
1477 MIL << "end construct known repos" << std::endl;
1478
1479 return expected<void>::success();
1480
1481 } catch ( ... ) {
1482 return expected<void>::error( std::current_exception () );
1483 }
1484 }
1485
1486 // explicitely intantiate the template types we want to work with
1487 template class RepoManager<SyncContextRef>;
1488 template class RepoManager<ContextRef>;
1489} // 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: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:266
zypp::MirroredOrigin::begin
endpoint_iterator begin()
Definition MirroredOrigin.h:259
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)
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::repoOrigins
MirroredOriginSet repoOrigins() const
The repodata origins.
Definition RepoInfo.cc:689
zypp::RepoInfo::type
repo::RepoType type() const
Type of repository,.
Definition RepoInfo.cc:742
zypp::RepoInfo::setBaseUrl
void setBaseUrl(Url url)
Clears current base URL list and adds url.
Definition RepoInfo.cc:676
zypp::RepoInfo::setPackagesPath
void setPackagesPath(const Pathname &path)
set the path where the local packages are stored
Definition RepoInfo.cc:712
zypp::RepoInfo::baseUrls
url_set baseUrls() const
The complete set of repository urls as configured.
Definition RepoInfo.cc:769
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:1123
zypp::RepoInfo::mirrorListUrl
Url mirrorListUrl() const
Url of a file which contains a list of repository urls.
Definition RepoInfo.cc:745
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:995
zypp::RepoInfo::setMetadataPath
void setMetadataPath(const Pathname &path)
Set the path where the local metadata is stored.
Definition RepoInfo.cc:709
zypp::RepoInfo::setType
void setType(const repo::RepoType &t)
set the repository type
Definition RepoInfo.cc:702
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:694
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:172
zypp::RepoManager::cleanMetadata
void cleanMetadata(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Clean local metadata.
Definition RepoManager.cc:147
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:243
zypp::RepoManager::removeService
void removeService(const std::string &alias)
Removes service specified by its name.
Definition RepoManager.cc:249
zypp::RepoManager::probeService
repo::ServiceType probeService(const Url &url) const
Probe the type or the service.
Definition RepoManager.cc:240
zypp::RepoManager::cleanCache
void cleanCache(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
clean local cache
Definition RepoManager.cc:163
zypp::RepoManager::refreshServices
void refreshServices(const RefreshServiceOptions &options_r=RefreshServiceOptions())
Refreshes all enabled services.
Definition RepoManager.cc:255
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:181
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:195
zypp::RepoManager::refreshMetadata
void refreshMetadata(const RepoInfo &info, RawMetadataRefreshPolicy policy=RefreshIfNeeded, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Refresh local raw cache.
Definition RepoManager.cc:140
zypp::RepoManager::refreshGeoIp
void refreshGeoIp(const RepoInfo::url_set &urls)
Definition RepoManager.cc:267
zypp::RepoManager::refreshService
void refreshService(const std::string &alias, const RefreshServiceOptions &options_r=RefreshServiceOptions())
Refresh specific service.
Definition RepoManager.cc:258
zypp::RepoManager::modifyRepository
void modifyRepository(const std::string &alias, const RepoInfo &newinfo, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Modify repository attributes.
Definition RepoManager.cc:205
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:198
zypp::RepoManager::getRepositoryInfo
RepoInfo getRepositoryInfo(const std::string &alias, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Find a matching repository info.
Definition RepoManager.cc:216
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:131
zypp::RepoManager::buildCache
void buildCache(const RepoInfo &info, CacheBuildPolicy policy=BuildIfNeeded, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Refresh local cache.
Definition RepoManager.cc:156
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:169
zypp::RepoManager::cleanPackages
void cleanPackages(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Clean local package cache.
Definition RepoManager.cc:150
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:264
zypp::RepoManager::probe
repo::RepoType probe(const Url &url, const Pathname &path) const
Probe repo metadata type.
Definition RepoManager.cc:175
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: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:507
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:120
zypp::repo::RepoInfoBase::setFilepath
void setFilepath(const Pathname &filename)
set the path to the .repo file
Definition RepoInfoBase.cc:95
zypp::repo::RepoInfoBase::setAlias
void setAlias(const std::string &alias)
set the repository alias
Definition RepoInfoBase.cc:89
zypp::repo::RepoInfoBase::filepath
Pathname filepath() const
File where this repo was read from.
Definition RepoInfoBase.cc:127
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:98
zypp::repo::RepoInfoBase::alias
std::string alias() const
unique identifier for this source.
Definition RepoInfoBase.cc:104
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:426
zyppng::RepoManager::ServiceSet
std::set< ServiceInfo > ServiceSet
ServiceInfo typedefs.
Definition repomanager.h:293
zyppng::RepoManager::serviceBegin
ServiceConstIterator serviceBegin() const
Definition repomanager.h:420
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:1275
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:476
zyppng::RepoManager::RawMetadataRefreshPolicy
zypp::RepoManagerFlags::RawMetadataRefreshPolicy RawMetadataRefreshPolicy
Definition repomanager.h:257
zyppng::RepoManager::serviceEnd
ServiceConstIterator serviceEnd() const
Definition repomanager.h:421
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:1329
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:502
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:1261
zyppng::RepoManager::buildCache
expected< void > buildCache(const RepoInfo &info, CacheBuildPolicy policy, ProgressObserverRef myProgress=nullptr)
Definition repomanager.cc:981
zyppng::RepoManager::RepoConstIterator
RepoSet::const_iterator RepoConstIterator
Definition repomanager.h:299
zyppng::RepoManager::_reposX
RepoSet _reposX
Definition repomanager.h:512
zyppng::RepoManager::_options
RepoManagerOptions _options
Definition repomanager.h:511
zyppng::RepoManager::_services
ServiceSet _services
Definition repomanager.h:513
zyppng::RepoManager::init_knownRepositories
expected< void > init_knownRepositories()
Definition repomanager.cc:1403
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:515
zyppng::RepoManager::cleanMetadata
expected< void > cleanMetadata(const RepoInfo &info, ProgressObserverRef myProgress=nullptr)
Definition repomanager.cc:379
zyppng::RepoManager::metadataStatus
static expected< RepoStatus > metadataStatus(const RepoInfo &info, const RepoManagerOptions &options)
Definition repomanager.cc:309
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:423
zyppng::RepoManager::repoBegin
RepoConstIterator repoBegin() const
Definition repomanager.h:317
zyppng::RepoManager::saveService
expected< void > saveService(ServiceInfo &service) const
Definition repomanager.cc:1218
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:486
zyppng::RepoManager::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::_zyppContext
ContextRefType _zyppContext
Definition repomanager.h:510
zyppng::RepoManager::reposManip
RepoSet & reposManip()
Definition repomanager.h:503
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:32
zyppng::repo::RefreshContext::sigProbedTypeChanged
SignalProxy< void(zypp::repo::RepoType)> sigProbedTypeChanged()
Definition refresh.cc:158
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:25
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:333
zypp::str::numstring
std::string numstring(char n, int w=0)
Definition String.h:290
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: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::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:192
zyppng::RepoManagerWorkflow::addRepository
AsyncOpRef< expected< RepoInfo > > addRepository(AsyncRepoManagerRef mgr, RepoInfo info, ProgressObserverRef myProgress)
Definition repomanagerwf.cc:949
zyppng::RepoManagerWorkflow::checkIfToRefreshMetadata
AsyncOpRef< expected< repo::RefreshCheckStatus > > checkIfToRefreshMetadata(repo::AsyncRefreshContextRef refCtx, LazyMediaHandle< Provide > medium, ProgressObserverRef progressObserver)
Definition repomanagerwf.cc:361
zyppng::RepoManagerWorkflow::refreshGeoIPData
AsyncOpRef< expected< void > > refreshGeoIPData(ContextRef ctx, RepoInfo::url_set urls)
Definition repomanagerwf.cc:1230
zyppng::RepoManagerWorkflow::addRepositories
AsyncOpRef< expected< void > > addRepositories(AsyncRepoManagerRef mgr, zypp::Url url, ProgressObserverRef myProgress)
Definition repomanagerwf.cc:1052
zyppng::RepoManagerWorkflow::refreshMetadata
AsyncOpRef< expected< repo::AsyncRefreshContextRef > > refreshMetadata(repo::AsyncRefreshContextRef refCtx, LazyMediaHandle< Provide > medium, ProgressObserverRef progressObserver)
Definition repomanagerwf.cc:473
zyppng::RepoManagerWorkflow::buildCache
AsyncOpRef< expected< repo::AsyncRefreshContextRef > > buildCache(repo::AsyncRefreshContextRef refCtx, zypp::RepoManagerFlags::CacheBuildPolicy policy, ProgressObserverRef progressObserver)
Definition repomanagerwf.cc:870
zyppng::RepoServicesWorkflow::refreshService
AsyncOpRef< expected< void > > refreshService(AsyncRepoManagerRef repoMgr, ServiceInfo info, zypp::RepoManagerFlags::RefreshServiceOptions options)
Definition serviceswf.cc:763
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 MediaNetworkRequestExecutor.h:16
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: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: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: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
_
#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