libzypp: zypp/RepoManager.cc Source File

libzypp 17.25.10

RepoManager.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
13 #include <cstdlib>
14 #include <iostream>
15 #include <fstream>
16 #include <sstream>
17 #include <list>
18 #include <map>
19 #include <algorithm>
20
21 #include <solv/solvversion.h>
22
23 #include <zypp/base/InputStream.h>
24 #include <zypp/base/LogTools.h>
25 #include <zypp/base/Gettext.h>
26 #include <zypp/base/DefaultIntegral.h>
27 #include <zypp/base/Function.h>
28 #include <zypp/base/Regex.h>
29 #include <zypp/PathInfo.h>
30 #include <zypp/TmpPath.h>
31
32 #include <zypp/ServiceInfo.h>
33 #include <zypp/repo/RepoException.h>
34 #include <zypp/RepoManager.h>
35
36 #include <zypp/media/MediaManager.h>
37 #include <zypp/media/CredentialManager.h>
38 #include <zypp/MediaSetAccess.h>
39 #include <zypp/ExternalProgram.h>
40 #include <zypp/ManagedFile.h>
41
42 #include <zypp/parser/RepoFileReader.h>
43 #include <zypp/parser/ServiceFileReader.h>
44 #include <zypp/repo/ServiceRepos.h>
45 #include <zypp/repo/yum/Downloader.h>
46 #include <zypp/repo/susetags/Downloader.h>
47 #include <zypp/repo/PluginServices.h>
48
49 #include <zypp/Target.h> // for Target::targetDistribution() for repo index services
50 #include <zypp/ZYppFactory.h> // to get the Target from ZYpp instance
51 #include <zypp/HistoryLog.h> // to write history :O)
52
53 #include <zypp/ZYppCallbacks.h>
54
55 #include "sat/Pool.h"
56
57 using std::endl;
58 using std::string;
59 using namespace zypp::repo;
60
61 #define OPT_PROGRESS const ProgressData::ReceiverFnc & = ProgressData::ReceiverFnc()
62
64 namespace zypp
65 {
66
68 namespace env
69 {
71 inline bool ZYPP_PLUGIN_APPDATA_FORCE_COLLECT()
72 {
73 const char * env = getenv("ZYPP_PLUGIN_APPDATA_FORCE_COLLECT");
74 return( env && str::strToBool( env, true ) );
75 }
76 } // namespace env
78
80 namespace
81 {
103 class UrlCredentialExtractor
104 {
105 public:
106 UrlCredentialExtractor( Pathname & root_r )
107 : _root( root_r )
108 {}
109
110 ~~UrlCredentialExtractor()
111 { if ( _cmPtr ) _cmPtr->save(); }
112
114 bool collect( const Url & url_r )
115 {
116 bool ret = url_r.hasCredentialsInAuthority();
117 if ( ret )
118 {
119 if ( !_cmPtr ) _cmPtr.reset( new media::CredentialManager( _root ) );
120 _cmPtr->addUserCred( url_r );
121 }
122 return ret;
123 }
125 template<class TContainer>
126 bool collect( const TContainer & urls_r )
127 { bool ret = false; for ( const Url & url : urls_r ) { if ( collect( url ) && !ret ) ret = true; } return ret; }
128
130 bool extract( Url & url_r )
131 {
132 bool ret = collect( url_r );
133 if ( ret )
134 url_r.setPassword( std::string() );
135 return ret;
136 }
138 template<class TContainer>
139 bool extract( TContainer & urls_r )
140 { bool ret = false; for ( Url & url : urls_r ) { if ( extract( url ) && !ret ) ret = true; } return ret; }
141
142 private:
143 const Pathname & _root;
144 scoped_ptr<media::CredentialManager> _cmPtr;
145 };
146 } // namespace
148
150 namespace
151 {
155 class MediaMounter
156 {
157 public:
159 MediaMounter( const Url & url_r )
160 {
161 media::MediaManager mediamanager;
162 _mid = mediamanager.open( url_r );
163 mediamanager.attach( _mid );
164 }
165
167 ~~MediaMounter()
168 {
169 media::MediaManager mediamanager;
170 mediamanager.release( _mid );
171 mediamanager.close( _mid );
172 }
173
178 Pathname getPathName( const Pathname & path_r = Pathname() ) const
179 {
180 media::MediaManager mediamanager;
181 return mediamanager.localPath( _mid, path_r );
182 }
183
184 private:
185 media::MediaAccessId _mid;
186 };
188
190 template <class Iterator>
191 inline bool foundAliasIn( const std::string & alias_r, Iterator begin_r, Iterator end_r )
192 {
193 for_( it, begin_r, end_r )
194 if ( it->alias() == alias_r )
195 return true;
196 return false;
197 }
199 template <class Container>
200 inline bool foundAliasIn( const std::string & alias_r, const Container & cont_r )
201 { return foundAliasIn( alias_r, cont_r.begin(), cont_r.end() ); }
202
204 template <class Iterator>
205 inline Iterator findAlias( const std::string & alias_r, Iterator begin_r, Iterator end_r )
206 {
207 for_( it, begin_r, end_r )
208 if ( it->alias() == alias_r )
209 return it;
210 return end_r;
211 }
213 template <class Container>
214 inline typename Container::iterator findAlias( const std::string & alias_r, Container & cont_r )
215 { return findAlias( alias_r, cont_r.begin(), cont_r.end() ); }
217 template <class Container>
218 inline typename Container::const_iterator findAlias( const std::string & alias_r, const Container & cont_r )
219 { return findAlias( alias_r, cont_r.begin(), cont_r.end() ); }
220
221
223 inline std::string filenameFromAlias( const std::string & alias_r, const std::string & stem_r )
224 {
225 std::string filename( alias_r );
226 // replace slashes with underscores
227 str::replaceAll( filename, "/", "_" );
228
229 filename = Pathname(filename).extend("."+stem_r).asString();
230 MIL << "generating filename for " << stem_r << " [" << alias_r << "] : '" << filename << "'" << endl;
231 return filename;
232 }
233
249 struct RepoCollector : private base::NonCopyable
250 {
251 RepoCollector()
252 {}
253
254 RepoCollector(const std::string & targetDistro_)
255 : targetDistro(targetDistro_)
256 {}
257
258 bool collect( const RepoInfo &repo )
259 {
260 // skip repositories meant for other distros than specified
261 if (!targetDistro.empty()
262 && !repo.targetDistribution().empty()
263 && repo.targetDistribution() != targetDistro)
264 {
265 MIL
266 << "Skipping repository meant for '" << repo.targetDistribution()
267 << "' distribution (current distro is '"
268 << targetDistro << "')." << endl;
269
270 return true;
271 }
272
273 repos.push_back(repo);
274 return true;
275 }
276
277 RepoInfoList repos;
278 std::string targetDistro;
279 };
281
287 std::list<RepoInfo> repositories_in_file( const Pathname & file )
288 {
289 MIL << "repo file: " << file << endl;
290 RepoCollector collector;
291 parser::RepoFileReader parser( file, bind( &RepoCollector::collect, &collector, _1 ) );
292 return std::move(collector.repos);
293 }
294
296
305 std::list<RepoInfo> repositories_in_dir( const Pathname &dir )
306 {
307 MIL << "directory " << dir << endl;
308 std::list<RepoInfo> repos;
309 bool nonroot( geteuid() != 0 );
310 if ( nonroot && ! PathInfo(dir).userMayRX() )
311 {
312 JobReport::warning( str::Format(_("Cannot read repo directory '%1%': Permission denied")) % dir );
313 }
314 else
315 {
316 std::list<Pathname> entries;
317 if ( filesystem::readdir( entries, dir, false ) != 0 )
318 {
319 // TranslatorExplanation '%s' is a pathname
320 ZYPP_THROW(Exception(str::form(_("Failed to read directory '%s'"), dir.c_str())));
321 }
322
323 str::regex allowedRepoExt("^\\.repo(_[0-9]+)?$");
324 for ( std::list<Pathname>::const_iterator it = entries.begin(); it != entries.end(); ++it )
325 {
326 if ( str::regex_match(it->extension(), allowedRepoExt) )
327 {
328 if ( nonroot && ! PathInfo(*it).userMayR() )
329 {
330 JobReport::warning( str::Format(_("Cannot read repo file '%1%': Permission denied")) % *it );
331 }
332 else
333 {
334 const std::list<RepoInfo> & tmp( repositories_in_file( *it ) );
335 repos.insert( repos.end(), tmp.begin(), tmp.end() );
336 }
337 }
338 }
339 }
340 return repos;
341 }
342
344
345 inline void assert_alias( const RepoInfo & info )
346 {
347 if ( info.alias().empty() )
348 ZYPP_THROW( RepoNoAliasException( info ) );
349 // bnc #473834. Maybe we can match the alias against a regex to define
350 // and check for valid aliases
351 if ( info.alias()[0] == '.')
352 ZYPP_THROW(RepoInvalidAliasException(
353 info, _("Repository alias cannot start with dot.")));
354 }
355
356 inline void assert_alias( const ServiceInfo & info )
357 {
358 if ( info.alias().empty() )
359 ZYPP_THROW( ServiceNoAliasException( info ) );
360 // bnc #473834. Maybe we can match the alias against a regex to define
361 // and check for valid aliases
362 if ( info.alias()[0] == '.')
363 ZYPP_THROW(ServiceInvalidAliasException(
364 info, _("Service alias cannot start with dot.")));
365 }
366
368
369 inline void assert_urls( const RepoInfo & info )
370 {
371 if ( info.baseUrlsEmpty() )
372 ZYPP_THROW( RepoNoUrlException( info ) );
373 }
374
375 inline void assert_url( const ServiceInfo & info )
376 {
377 if ( ! info.url().isValid() )
378 ZYPP_THROW( ServiceNoUrlException( info ) );
379 }
380
382
384 namespace
385 {
387 inline bool isTmpRepo( const RepoInfo & info_r )
388 { return( info_r.filepath().empty() && info_r.usesAutoMethadataPaths() ); }
389 } // namespace
391
396 inline Pathname rawcache_path_for_repoinfo( const RepoManagerOptions &opt, const RepoInfo &info )
397 {
398 assert_alias(info);
399 return isTmpRepo( info ) ? info.metadataPath() : opt.repoRawCachePath / info.escaped_alias();
400 }
401
410 inline Pathname rawproductdata_path_for_repoinfo( const RepoManagerOptions &opt, const RepoInfo &info )
411 { return rawcache_path_for_repoinfo( opt, info ) / info.path(); }
412
416 inline Pathname packagescache_path_for_repoinfo( const RepoManagerOptions &opt, const RepoInfo &info )
417 {
418 assert_alias(info);
419 return isTmpRepo( info ) ? info.packagesPath() : opt.repoPackagesCachePath / info.escaped_alias();
420 }
421
425 inline Pathname solv_path_for_repoinfo( const RepoManagerOptions &opt, const RepoInfo &info )
426 {
427 assert_alias(info);
428 return isTmpRepo( info ) ? info.metadataPath().dirname() / "%SLV%" : opt.repoSolvCachePath / info.escaped_alias();
429 }
430
432
434 class ServiceCollector
435 {
436 public:
437 typedef std::set<ServiceInfo> ServiceSet;
438
439 ServiceCollector( ServiceSet & services_r )
440 : _services( services_r )
441 {}
442
443 bool operator()( const ServiceInfo & service_r ) const
444 {
445 _services.insert( service_r );
446 return true;
447 }
448
449 private:
450 ServiceSet & _services;
451 };
453
454 } // namespace
456
457 std::list<RepoInfo> readRepoFile( const Url & repo_file )
458 {
459 ManagedFile local = MediaSetAccess::provideFileFromUrl(repo_file);
460
461 DBG << "reading repo file " << repo_file << ", local path: " << local << endl;
462
463 return repositories_in_file(local);
464 }
465
467 //
468 // class RepoManagerOptions
469 //
471
472 RepoManagerOptions::RepoManagerOptions( const Pathname & root_r )
473 {
474 repoCachePath = Pathname::assertprefix( root_r, ZConfig::instance().repoCachePath() );
475 repoRawCachePath = Pathname::assertprefix( root_r, ZConfig::instance().repoMetadataPath() );
476 repoSolvCachePath = Pathname::assertprefix( root_r, ZConfig::instance().repoSolvfilesPath() );
477 repoPackagesCachePath = Pathname::assertprefix( root_r, ZConfig::instance().repoPackagesPath() );
478 knownReposPath = Pathname::assertprefix( root_r, ZConfig::instance().knownReposPath() );
479 knownServicesPath = Pathname::assertprefix( root_r, ZConfig::instance().knownServicesPath() );
480 pluginsPath = Pathname::assertprefix( root_r, ZConfig::instance().pluginsPath() );
481 probe = ZConfig::instance().repo_add_probe();
482
483 rootDir = root_r;
484 }
485
486 RepoManagerOptions RepoManagerOptions::makeTestSetup( const Pathname & root_r )
487 {
488 RepoManagerOptions ret;
489 ret.repoCachePath = root_r;
490 ret.repoRawCachePath = root_r/"raw";
491 ret.repoSolvCachePath = root_r/"solv";
492 ret.repoPackagesCachePath = root_r/"packages";
493 ret.knownReposPath = root_r/"repos.d";
494 ret.knownServicesPath = root_r/"services.d";
495 ret.pluginsPath = root_r/"plugins";
496 ret.rootDir = root_r;
497 return ret;
498 }
499
500 std:: ostream & operator<<( std::ostream & str, const RepoManagerOptions & obj )
501 {
502 #define OUTS(X) str << " " #X "\t" << obj.X << endl
503 str << "RepoManagerOptions (" << obj.rootDir << ") {" << endl;
504 OUTS( repoRawCachePath );
505 OUTS( repoSolvCachePath );
506 OUTS( repoPackagesCachePath );
507 OUTS( knownReposPath );
508 OUTS( knownServicesPath );
509 OUTS( pluginsPath );
510 str << "}" << endl;
511 #undef OUTS
512 return str;
513 }
514
520 struct RepoManager::Impl
521 {
522 public:
523 Impl( const RepoManagerOptions &opt )
524 : _options(opt)
525 {
526 init_knownServices();
527 init_knownRepositories();
528 }
529
530 ~Impl()
531 {
532 // trigger appdata refresh if some repos change
533 if ( ( _reposDirty || env::ZYPP_PLUGIN_APPDATA_FORCE_COLLECT() )
534 && geteuid() == 0 && ( _options.rootDir.empty() || _options.rootDir == "/" ) )
535 {
536 try {
537 std::list<Pathname> entries;
538 filesystem::readdir( entries, _options.pluginsPath/"appdata", false );
539 if ( ! entries.empty() )
540 {
541 ExternalProgram::Arguments cmd;
542 cmd.push_back( "<" ); // discard stdin
543 cmd.push_back( ">" ); // discard stdout
544 cmd.push_back( "PROGRAM" ); // [2] - fix index below if changing!
545 for ( const auto & rinfo : repos() )
546 {
547 if ( ! rinfo.enabled() )
548 continue;
549 cmd.push_back( "-R" );
550 cmd.push_back( rinfo.alias() );
551 cmd.push_back( "-t" );
552 cmd.push_back( rinfo.type().asString() );
553 cmd.push_back( "-p" );
554 cmd.push_back( rinfo.metadataPath().asString() );
555 }
556
557 for_( it, entries.begin(), entries.end() )
558 {
559 PathInfo pi( *it );
560 //DBG << "/tmp/xx ->" << pi << endl;
561 if ( pi.isFile() && pi.userMayRX() )
562 {
563 // trigger plugin
564 cmd[2] = pi.asString(); // [2] - PROGRAM
565 ExternalProgram prog( cmd, ExternalProgram::Stderr_To_Stdout );
566 }
567 }
568 }
569 }
570 catch (...) {} // no throw in dtor
571 }
572 }
573
574 public:
575 bool repoEmpty() const { return repos().empty(); }
576 RepoSizeType repoSize() const { return repos().size(); }
577 RepoConstIterator repoBegin() const { return repos().begin(); }
578 RepoConstIterator repoEnd() const { return repos().end(); }
579
580 bool hasRepo( const std::string & alias ) const
581 { return foundAliasIn( alias, repos() ); }
582
583 RepoInfo getRepo( const std::string & alias ) const
584 {
585 RepoConstIterator it( findAlias( alias, repos() ) );
586 return it == repos().end() ? RepoInfo::noRepo : *it;
587 }
588
589 public:
590 Pathname metadataPath( const RepoInfo & info ) const
591 { return rawcache_path_for_repoinfo( _options, info ); }
592
593 Pathname packagesPath( const RepoInfo & info ) const
594 { return packagescache_path_for_repoinfo( _options, info ); }
595
596 RepoStatus metadataStatus( const RepoInfo & info ) const;
597
598 RefreshCheckStatus checkIfToRefreshMetadata( const RepoInfo & info, const Url & url, RawMetadataRefreshPolicy policy );
599
600 void refreshMetadata( const RepoInfo & info, RawMetadataRefreshPolicy policy, OPT_PROGRESS );
601
602 void cleanMetadata( const RepoInfo & info, OPT_PROGRESS );
603
604 void cleanPackages( const RepoInfo & info, OPT_PROGRESS );
605
606 void buildCache( const RepoInfo & info, CacheBuildPolicy policy, OPT_PROGRESS );
607
608 repo::RepoType probe( const Url & url, const Pathname & path = Pathname() ) const;
609 repo::RepoType probeCache( const Pathname & path_r ) const;
610
611 void cleanCacheDirGarbage( OPT_PROGRESS );
612
613 void cleanCache( const RepoInfo & info, OPT_PROGRESS );
614
615 bool isCached( const RepoInfo & info ) const
616 { return PathInfo(solv_path_for_repoinfo( _options, info ) / "solv").isExist(); }
617
618 RepoStatus cacheStatus( const RepoInfo & info ) const
619 { return RepoStatus::fromCookieFile(solv_path_for_repoinfo(_options, info) / "cookie"); }
620
621 void loadFromCache( const RepoInfo & info, OPT_PROGRESS );
622
623 void addRepository( const RepoInfo & info, OPT_PROGRESS );
624
625 void addRepositories( const Url & url, OPT_PROGRESS );
626
627 void removeRepository( const RepoInfo & info, OPT_PROGRESS );
628
629 void modifyRepository( const std::string & alias, const RepoInfo & newinfo_r, OPT_PROGRESS );
630
631 RepoInfo getRepositoryInfo( const std::string & alias, OPT_PROGRESS );
632 RepoInfo getRepositoryInfo( const Url & url, const url::ViewOption & urlview, OPT_PROGRESS );
633
634 public:
635 bool serviceEmpty() const { return _services.empty(); }
636 ServiceSizeType serviceSize() const { return _services.size(); }
637 ServiceConstIterator serviceBegin() const { return _services.begin(); }
638 ServiceConstIterator serviceEnd() const { return _services.end(); }
639
640 bool hasService( const std::string & alias ) const
641 { return foundAliasIn( alias, _services ); }
642
643 ServiceInfo getService( const std::string & alias ) const
644 {
645 ServiceConstIterator it( findAlias( alias, _services ) );
646 return it == _services.end() ? ServiceInfo::noService : *it;
647 }
648
649 public:
650 void addService( const ServiceInfo & service );
651 void addService( const std::string & alias, const Url & url )
652 { addService( ServiceInfo( alias, url ) ); }
653
654 void removeService( const std::string & alias );
655 void removeService( const ServiceInfo & service )
656 { removeService( service.alias() ); }
657
658 void refreshServices( const RefreshServiceOptions & options_r );
659
660 void refreshService( const std::string & alias, const RefreshServiceOptions & options_r );
661 void refreshService( const ServiceInfo & service, const RefreshServiceOptions & options_r )
662 { refreshService( service.alias(), options_r ); }
663
664 void modifyService( const std::string & oldAlias, const ServiceInfo & newService );
665
666 repo::ServiceType probeService( const Url & url ) const;
667
668 private:
669 void saveService( ServiceInfo & service ) const;
670
671 Pathname generateNonExistingName( const Pathname & dir, const std::string & basefilename ) const;
672
673 std::string generateFilename( const RepoInfo & info ) const
674 { return filenameFromAlias( info.alias(), "repo" ); }
675
676 std::string generateFilename( const ServiceInfo & info ) const
677 { return filenameFromAlias( info.alias(), "service" ); }
678
679 void setCacheStatus( const RepoInfo & info, const RepoStatus & status )
680 {
681 Pathname base = solv_path_for_repoinfo( _options, info );
682 filesystem::assert_dir(base);
683 status.saveToCookieFile( base / "cookie" );
684 }
685
686 void touchIndexFile( const RepoInfo & info );
687
688 template<typename OutputIterator>
689 void getRepositoriesInService( const std::string & alias, OutputIterator out ) const
690 {
691 MatchServiceAlias filter( alias );
692 std::copy( boost::make_filter_iterator( filter, repos().begin(), repos().end() ),
693 boost::make_filter_iterator( filter, repos().end(), repos().end() ),
694 out);
695 }
696
697 private:
698 void init_knownServices();
699 void init_knownRepositories();
700
701 const RepoSet & repos() const { return _reposX; }
702 RepoSet & reposManip() { if ( ! _reposDirty ) _reposDirty = true; return _reposX; }
703
704 private:
705 RepoManagerOptions _options;
706 RepoSet _reposX;
707 ServiceSet _services;
708
709 DefaultIntegral<bool,false> _reposDirty;
710
711 private:
712 friend Impl * rwcowClone<Impl>( const Impl * rhs );
714 Impl * clone() const
715 { return new Impl( *this ); }
716 };
718
720 inline std::ostream & operator<<( std::ostream & str, const RepoManager::Impl & obj )
721 { return str << "RepoManager::Impl"; }
722
724
725 void RepoManager::Impl::saveService( ServiceInfo & service ) const
726 {
727 filesystem::assert_dir( _options.knownServicesPath );
728 Pathname servfile = generateNonExistingName( _options.knownServicesPath,
729 generateFilename( service ) );
730 service.setFilepath( servfile );
731
732 MIL << "saving service in " << servfile << endl;
733
734 std::ofstream file( servfile.c_str() );
735 if ( !file )
736 {
737 // TranslatorExplanation '%s' is a filename
738 ZYPP_THROW( Exception(str::form( _("Can't open file '%s' for writing."), servfile.c_str() )));
739 }
740 service.dumpAsIniOn( file );
741 MIL << "done" << endl;
742 }
743
759 Pathname RepoManager::Impl::generateNonExistingName( const Pathname & dir,
760 const std::string & basefilename ) const
761 {
762 std::string final_filename = basefilename;
763 int counter = 1;
764 while ( PathInfo(dir + final_filename).isExist() )
765 {
766 final_filename = basefilename + "_" + str::numstring(counter);
767 ++counter;
768 }
769 return dir + Pathname(final_filename);
770 }
771
773
774 void RepoManager::Impl::init_knownServices()
775 {
776 Pathname dir = _options.knownServicesPath;
777 std::list<Pathname> entries;
778 if (PathInfo(dir).isExist())
779 {
780 if ( filesystem::readdir( entries, dir, false ) != 0 )
781 {
782 // TranslatorExplanation '%s' is a pathname
783 ZYPP_THROW(Exception(str::form(_("Failed to read directory '%s'"), dir.c_str())));
784 }
785
786 //str::regex allowedServiceExt("^\\.service(_[0-9]+)?$");
787 for_(it, entries.begin(), entries.end() )
788 {
789 parser::ServiceFileReader(*it, ServiceCollector(_services));
790 }
791 }
792
793 repo::PluginServices(_options.pluginsPath/"services", ServiceCollector(_services));
794 }
795
797 namespace {
803 inline void cleanupNonRepoMetadtaFolders( const Pathname & cachePath_r,
804 const Pathname & defaultCachePath_r,
805 const std::list<std::string> & repoEscAliases_r )
806 {
807 if ( cachePath_r != defaultCachePath_r )
808 return;
809
810 std::list<std::string> entries;
811 if ( filesystem::readdir( entries, cachePath_r, false ) == 0 )
812 {
813 entries.sort();
814 std::set<std::string> oldfiles;
815 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
816 std::inserter( oldfiles, oldfiles.end() ) );
817
818 // bsc#1178966: Files or symlinks here have been created by the user
819 // for whatever purpose. It's our cache, so we purge them now before
820 // they may later conflict with directories we need.
821 PathInfo pi;
822 for ( const std::string & old : oldfiles )
823 {
824 if ( old == Repository::systemRepoAlias() ) // don't remove the @System solv file
825 continue;
826 pi( cachePath_r/old );
827 if ( pi.isDir() )
828 filesystem::recursive_rmdir( pi.path() );
829 else
830 filesystem::unlink( pi.path() );
831 }
832 }
833 }
834 } // namespace
836 void RepoManager::Impl::init_knownRepositories()
837 {
838 MIL << "start construct known repos" << endl;
839
840 if ( PathInfo(_options.knownReposPath).isExist() )
841 {
842 std::list<std::string> repoEscAliases;
843 std::list<RepoInfo> orphanedRepos;
844 for ( RepoInfo & repoInfo : repositories_in_dir(_options.knownReposPath) )
845 {
846 // set the metadata path for the repo
847 repoInfo.setMetadataPath( rawcache_path_for_repoinfo(_options, repoInfo) );
848 // set the downloaded packages path for the repo
849 repoInfo.setPackagesPath( packagescache_path_for_repoinfo(_options, repoInfo) );
850 // remember it
851 _reposX.insert( repoInfo ); // direct access via _reposX in ctor! no reposManip.
852
853 // detect orphaned repos belonging to a deleted service
854 const std::string & serviceAlias( repoInfo.service() );
855 if ( ! ( serviceAlias.empty() || hasService( serviceAlias ) ) )
856 {
857 WAR << "Schedule orphaned service repo for deletion: " << repoInfo << endl;
858 orphanedRepos.push_back( repoInfo );
859 continue; // don't remember it in repoEscAliases
860 }
861
862 repoEscAliases.push_back(repoInfo.escaped_alias());
863 }
864
865 // Cleanup orphanded service repos:
866 if ( ! orphanedRepos.empty() )
867 {
868 for ( const auto & repoInfo : orphanedRepos )
869 {
870 MIL << "Delete orphaned service repo " << repoInfo.alias() << endl;
871 // translators: Cleanup a repository previously owned by a meanwhile unknown (deleted) service.
872 // %1% = service name
873 // %2% = repository name
874 JobReport::warning( str::Format(_("Unknown service '%1%': Removing orphaned service repository '%2%'"))
875 % repoInfo.service()
876 % repoInfo.alias() );
877 try {
878 removeRepository( repoInfo );
879 }
880 catch ( const Exception & caugth )
881 {
882 JobReport::error( caugth.asUserHistory() );
883 }
884 }
885 }
886
887 // delete metadata folders without corresponding repo (e.g. old tmp directories)
888 //
889 // bnc#891515: Auto-cleanup only zypp.conf default locations. Otherwise
890 // we'd need somemagic file to identify zypp cache directories. Without this
891 // we may easily remove user data (zypper --pkg-cache-dir . download ...)
892 repoEscAliases.sort();
893 cleanupNonRepoMetadtaFolders( _options.repoRawCachePath,
894 Pathname::assertprefix( _options.rootDir, ZConfig::instance().builtinRepoMetadataPath() ),
895 repoEscAliases );
896 cleanupNonRepoMetadtaFolders( _options.repoSolvCachePath,
897 Pathname::assertprefix( _options.rootDir, ZConfig::instance().builtinRepoSolvfilesPath() ),
898 repoEscAliases );
899 cleanupNonRepoMetadtaFolders( _options.repoPackagesCachePath,
900 Pathname::assertprefix( _options.rootDir, ZConfig::instance().builtinRepoPackagesPath() ),
901 repoEscAliases );
902 }
903 MIL << "end construct known repos" << endl;
904 }
905
907
908 RepoStatus RepoManager::Impl::metadataStatus( const RepoInfo & info ) const
909 {
910 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
911 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
912
913 RepoType repokind = info.type();
914 // If unknown, probe the local metadata
915 if ( repokind == RepoType::NONE )
916 repokind = probeCache( productdatapath );
917
918 // NOTE: The calling code expects an empty RepoStatus being returned
919 // if the metadata cache is empty. So additioanl components like the
920 // RepoInfos status are joined after the switch IFF the status is not
921 // empty.
922 RepoStatus status;
923 switch ( repokind.toEnum() )
924 {
925 case RepoType::RPMMD_e :
926 status = RepoStatus( productdatapath/"repodata/repomd.xml") && RepoStatus( mediarootpath/"media.1/media" );
927 break;
928
929 case RepoType::YAST2_e :
930 status = RepoStatus( productdatapath/"content" ) && RepoStatus( mediarootpath/"media.1/media" );
931 break;
932
933 case RepoType::RPMPLAINDIR_e :
934 status = RepoStatus::fromCookieFile( productdatapath/"cookie" ); // dir status at last refresh
935 break;
936
937 case RepoType::NONE_e :
938 // Return default RepoStatus in case of RepoType::NONE
939 // indicating it should be created?
940 // ZYPP_THROW(RepoUnknownTypeException());
941 break;
942 }
943
944 if ( ! status.empty() )
945 status = status && RepoStatus( info );
946
947 return status;
948 }
949
950
951 void RepoManager::Impl::touchIndexFile( const RepoInfo & info )
952 {
953 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
954
955 RepoType repokind = info.type();
956 if ( repokind.toEnum() == RepoType::NONE_e )
957 // unknown, probe the local metadata
958 repokind = probeCache( productdatapath );
959 // if still unknown, just return
960 if (repokind == RepoType::NONE_e)
961 return;
962
963 Pathname p;
964 switch ( repokind.toEnum() )
965 {
966 case RepoType::RPMMD_e :
967 p = Pathname(productdatapath + "/repodata/repomd.xml");
968 break;
969
970 case RepoType::YAST2_e :
971 p = Pathname(productdatapath + "/content");
972 break;
973
974 case RepoType::RPMPLAINDIR_e :
975 p = Pathname(productdatapath + "/cookie");
976 break;
977
978 case RepoType::NONE_e :
979 default:
980 break;
981 }
982
983 // touch the file, ignore error (they are logged anyway)
984 filesystem::touch(p);
985 }
986
987
988 RepoManager::RefreshCheckStatus RepoManager::Impl::checkIfToRefreshMetadata( const RepoInfo & info, const Url & url, RawMetadataRefreshPolicy policy )
989 {
990 assert_alias(info);
991 try
992 {
993 MIL << "Check if to refresh repo " << info.alias() << " at " << url << " (" << info.type() << ")" << endl;
994
995 // first check old (cached) metadata
996 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
997 filesystem::assert_dir( mediarootpath );
998 RepoStatus oldstatus = metadataStatus( info );
999
1000 if ( oldstatus.empty() )
1001 {
1002 MIL << "No cached metadata, going to refresh" << endl;
1003 return REFRESH_NEEDED;
1004 }
1005
1006 if ( url.schemeIsVolatile() )
1007 {
1008 MIL << "Never refresh CD/DVD" << endl;
1009 return REPO_UP_TO_DATE;
1010 }
1011
1012 if ( policy == RefreshForced )
1013 {
1014 MIL << "Forced refresh!" << endl;
1015 return REFRESH_NEEDED;
1016 }
1017
1018 if ( url.schemeIsLocal() )
1019 {
1020 policy = RefreshIfNeededIgnoreDelay;
1021 }
1022
1023 // Check whether repo.refresh.delay applies...
1024 if ( policy != RefreshIfNeededIgnoreDelay )
1025 {
1026 // bsc#1174016: Prerequisite to skipping the refresh is that metadata
1027 // and solv cache status match. They will not, if the repos URL was
1028 // changed e.g. due to changed repovars.
1029 RepoStatus cachestatus = cacheStatus( info );
1030
1031 if ( oldstatus == cachestatus )
1032 {
1033 // difference in seconds
1034 double diff = ::difftime( (Date::ValueType)Date::now(), (Date::ValueType)oldstatus.timestamp() ) / 60;
1035 if ( diff < ZConfig::instance().repo_refresh_delay() )
1036 {
1037 if ( diff < 0 )
1038 {
1039 WAR << "Repository '" << info.alias() << "' was refreshed in the future!" << endl;
1040 }
1041 else
1042 {
1043 MIL << "Repository '" << info.alias()
1044 << "' has been refreshed less than repo.refresh.delay ("
1045 << ZConfig::instance().repo_refresh_delay()
1046 << ") minutes ago. Advising to skip refresh" << endl;
1047 return REPO_CHECK_DELAYED;
1048 }
1049 }
1050 }
1051 else {
1052 MIL << "Metadata and solv cache don't match. Check data on server..." << endl;
1053 }
1054 }
1055
1056 repo::RepoType repokind = info.type();
1057 // if unknown: probe it
1058 if ( repokind == RepoType::NONE )
1059 repokind = probe( url, info.path() );
1060
1061 // retrieve newstatus
1062 RepoStatus newstatus;
1063 switch ( repokind.toEnum() )
1064 {
1065 case RepoType::RPMMD_e:
1066 {
1067 MediaSetAccess media( url );
1068 newstatus = RepoStatus( info ) && yum::Downloader( info, mediarootpath ).status( media );
1069 }
1070 break;
1071
1072 case RepoType::YAST2_e:
1073 {
1074 MediaSetAccess media( url );
1075 newstatus = RepoStatus( info ) && susetags::Downloader( info, mediarootpath ).status( media );
1076 }
1077 break;
1078
1079 case RepoType::RPMPLAINDIR_e:
1080 newstatus = RepoStatus( info ) && RepoStatus( MediaMounter(url).getPathName(info.path()) ); // dir status
1081 break;
1082
1083 default:
1084 case RepoType::NONE_e:
1085 ZYPP_THROW( RepoUnknownTypeException( info ) );
1086 break;
1087 }
1088
1089 // check status
1090 if ( oldstatus == newstatus )
1091 {
1092 MIL << "repo has not changed" << endl;
1093 touchIndexFile( info );
1094 return REPO_UP_TO_DATE;
1095 }
1096 else // includes newstatus.empty() if e.g. repo format changed
1097 {
1098 MIL << "repo has changed, going to refresh" << endl;
1099 return REFRESH_NEEDED;
1100 }
1101 }
1102 catch ( const Exception &e )
1103 {
1104 ZYPP_CAUGHT(e);
1105 ERR << "refresh check failed for " << url << endl;
1106 ZYPP_RETHROW(e);
1107 }
1108
1109 return REFRESH_NEEDED; // default
1110 }
1111
1112
1113 void RepoManager::Impl::refreshMetadata( const RepoInfo & info, RawMetadataRefreshPolicy policy, const ProgressData::ReceiverFnc & progress )
1114 {
1115 assert_alias(info);
1116 assert_urls(info);
1117
1118 // we will throw this later if no URL checks out fine
1119 RepoException rexception( info, PL_("Valid metadata not found at specified URL",
1120 "Valid metadata not found at specified URLs",
1121 info.baseUrlsSize() ) );
1122
1123 // Suppress (interactive) media::MediaChangeReport if we in have multiple basurls (>1)
1124 media::ScopedDisableMediaChangeReport guard( info.baseUrlsSize() > 1 );
1125 // try urls one by one
1126 for ( RepoInfo::urls_const_iterator it = info.baseUrlsBegin(); it != info.baseUrlsEnd(); ++it )
1127 {
1128 try
1129 {
1130 Url url(*it);
1131
1132 // check whether to refresh metadata
1133 // if the check fails for this url, it throws, so another url will be checked
1134 if (checkIfToRefreshMetadata(info, url, policy)!=REFRESH_NEEDED)
1135 return;
1136
1137 MIL << "Going to refresh metadata from " << url << endl;
1138
1139 // bsc#1048315: Always re-probe in case of repo format change.
1140 // TODO: Would be sufficient to verify the type and re-probe
1141 // if verification failed (or type is RepoType::NONE)
1142 repo::RepoType repokind = info.type();
1143 {
1144 repo::RepoType probed = probe( *it, info.path() );
1145 if ( repokind != probed )
1146 {
1147 repokind = probed;
1148 // update probed type only for repos in system
1149 for_( it, repoBegin(), repoEnd() )
1150 {
1151 if ( info.alias() == (*it).alias() )
1152 {
1153 RepoInfo modifiedrepo = *it;
1154 modifiedrepo.setType( repokind );
1155 // don't modify .repo in refresh.
1156 // modifyRepository( info.alias(), modifiedrepo );
1157 break;
1158 }
1159 }
1160 // Adjust the probed type in RepoInfo
1161 info.setProbedType( repokind ); // lazy init!
1162 }
1163 // no need to continue with an unknown type
1164 if ( repokind.toEnum() == RepoType::NONE_e )
1165 ZYPP_THROW(RepoUnknownTypeException( info ));
1166 }
1167
1168 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1169 if( filesystem::assert_dir(mediarootpath) )
1170 {
1171 Exception ex(str::form( _("Can't create %s"), mediarootpath.c_str()) );
1172 ZYPP_THROW(ex);
1173 }
1174
1175 // create temp dir as sibling of mediarootpath
1176 filesystem::TmpDir tmpdir( filesystem::TmpDir::makeSibling( mediarootpath ) );
1177 if( tmpdir.path().empty() )
1178 {
1179 Exception ex(_("Can't create metadata cache directory."));
1180 ZYPP_THROW(ex);
1181 }
1182
1183 if ( ( repokind.toEnum() == RepoType::RPMMD_e ) ||
1184 ( repokind.toEnum() == RepoType::YAST2_e ) )
1185 {
1186 MediaSetAccess media(url);
1187 shared_ptr<repo::Downloader> downloader_ptr;
1188
1189 MIL << "Creating downloader for [ " << info.alias() << " ]" << endl;
1190
1191 if ( repokind.toEnum() == RepoType::RPMMD_e )
1192 downloader_ptr.reset(new yum::Downloader(info, mediarootpath));
1193 else
1194 downloader_ptr.reset( new susetags::Downloader(info, mediarootpath) );
1195
1202 for_( it, repoBegin(), repoEnd() )
1203 {
1204 Pathname cachepath(rawcache_path_for_repoinfo( _options, *it ));
1205 if ( PathInfo(cachepath).isExist() )
1206 downloader_ptr->addCachePath(cachepath);
1207 }
1208
1209 downloader_ptr->download( media, tmpdir.path() );
1210 }
1211 else if ( repokind.toEnum() == RepoType::RPMPLAINDIR_e )
1212 {
1213 // as substitute for real metadata remember the checksum of the directory we refreshed
1214 MediaMounter media( url );
1215 RepoStatus newstatus = RepoStatus( media.getPathName( info.path() ) ); // dir status
1216
1217 Pathname productpath( tmpdir.path() / info.path() );
1218 filesystem::assert_dir( productpath );
1219 newstatus.saveToCookieFile( productpath/"cookie" );
1220 }
1221 else
1222 {
1223 ZYPP_THROW(RepoUnknownTypeException( info ));
1224 }
1225
1226 // ok we have the metadata, now exchange
1227 // the contents
1228 filesystem::exchange( tmpdir.path(), mediarootpath );
1229 if ( ! isTmpRepo( info ) )
1230 reposManip(); // remember to trigger appdata refresh
1231
1232 // we are done.
1233 return;
1234 }
1235 catch ( const Exception &e )
1236 {
1237 ZYPP_CAUGHT(e);
1238 ERR << "Trying another url..." << endl;
1239
1240 // remember the exception caught for the *first URL*
1241 // if all other URLs fail, the rexception will be thrown with the
1242 // cause of the problem of the first URL remembered
1243 if (it == info.baseUrlsBegin())
1244 rexception.remember(e);
1245 else
1246 rexception.addHistory( e.asUserString() );
1247
1248 }
1249 } // for every url
1250 ERR << "No more urls..." << endl;
1251 ZYPP_THROW(rexception);
1252 }
1253
1255
1256 void RepoManager::Impl::cleanMetadata( const RepoInfo & info, const ProgressData::ReceiverFnc & progressfnc )
1257 {
1258 ProgressData progress(100);
1259 progress.sendTo(progressfnc);
1260
1261 filesystem::recursive_rmdir(rawcache_path_for_repoinfo(_options, info));
1262 progress.toMax();
1263 }
1264
1265
1266 void RepoManager::Impl::cleanPackages( const RepoInfo & info, const ProgressData::ReceiverFnc & progressfnc )
1267 {
1268 ProgressData progress(100);
1269 progress.sendTo(progressfnc);
1270
1271 filesystem::recursive_rmdir(packagescache_path_for_repoinfo(_options, info));
1272 progress.toMax();
1273 }
1274
1275
1276 void RepoManager::Impl::buildCache( const RepoInfo & info, CacheBuildPolicy policy, const ProgressData::ReceiverFnc & progressrcv )
1277 {
1278 assert_alias(info);
1279 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1280 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
1281
1282 if( filesystem::assert_dir(_options.repoCachePath) )
1283 {
1284 Exception ex(str::form( _("Can't create %s"), _options.repoCachePath.c_str()) );
1285 ZYPP_THROW(ex);
1286 }
1287 RepoStatus raw_metadata_status = metadataStatus(info);
1288 if ( raw_metadata_status.empty() )
1289 {
1290 /* if there is no cache at this point, we refresh the raw
1291 in case this is the first time - if it's !autorefresh,
1292 we may still refresh */
1293 refreshMetadata(info, RefreshIfNeeded, progressrcv );
1294 raw_metadata_status = metadataStatus(info);
1295 }
1296
1297 bool needs_cleaning = false;
1298 if ( isCached( info ) )
1299 {
1300 MIL << info.alias() << " is already cached." << endl;
1301 RepoStatus cache_status = cacheStatus(info);
1302
1303 if ( cache_status == raw_metadata_status )
1304 {
1305 MIL << info.alias() << " cache is up to date with metadata." << endl;
1306 if ( policy == BuildIfNeeded )
1307 {
1308 // On the fly add missing solv.idx files for bash completion.
1309 const Pathname & base = solv_path_for_repoinfo( _options, info);
1310 if ( ! PathInfo(base/"solv.idx").isExist() )
1311 sat::updateSolvFileIndex( base/"solv" );
1312
1313 return;
1314 }
1315 else {
1316 MIL << info.alias() << " cache rebuild is forced" << endl;
1317 }
1318 }
1319
1320 needs_cleaning = true;
1321 }
1322
1323 ProgressData progress(100);
1324 callback::SendReport<ProgressReport> report;
1325 progress.sendTo( ProgressReportAdaptor( progressrcv, report ) );
1326 progress.name(str::form(_("Building repository '%s' cache"), info.label().c_str()));
1327 progress.toMin();
1328
1329 if (needs_cleaning)
1330 {
1331 cleanCache(info);
1332 }
1333
1334 MIL << info.alias() << " building cache..." << info.type() << endl;
1335
1336 Pathname base = solv_path_for_repoinfo( _options, info);
1337
1338 if( filesystem::assert_dir(base) )
1339 {
1340 Exception ex(str::form( _("Can't create %s"), base.c_str()) );
1341 ZYPP_THROW(ex);
1342 }
1343
1344 if( ! PathInfo(base).userMayW() )
1345 {
1346 Exception ex(str::form( _("Can't create cache at %s - no writing permissions."), base.c_str()) );
1347 ZYPP_THROW(ex);
1348 }
1349 Pathname solvfile = base / "solv";
1350
1351 // do we have type?
1352 repo::RepoType repokind = info.type();
1353
1354 // if the type is unknown, try probing.
1355 switch ( repokind.toEnum() )
1356 {
1357 case RepoType::NONE_e:
1358 // unknown, probe the local metadata
1359 repokind = probeCache( productdatapath );
1360 break;
1361 default:
1362 break;
1363 }
1364
1365 MIL << "repo type is " << repokind << endl;
1366
1367 switch ( repokind.toEnum() )
1368 {
1369 case RepoType::RPMMD_e :
1370 case RepoType::YAST2_e :
1371 case RepoType::RPMPLAINDIR_e :
1372 {
1373 // Take care we unlink the solvfile on exception
1374 ManagedFile guard( solvfile, filesystem::unlink );
1375 scoped_ptr<MediaMounter> forPlainDirs;
1376
1377 ExternalProgram::Arguments cmd;
1378 cmd.push_back( PathInfo( "/usr/bin/repo2solv" ).isFile() ? "repo2solv" : "repo2solv.sh" );
1379 // repo2solv expects -o as 1st arg!
1380 cmd.push_back( "-o" );
1381 cmd.push_back( solvfile.asString() );
1382 cmd.push_back( "-X" ); // autogenerate pattern from pattern-package
1383 // bsc#1104415: no more application support // cmd.push_back( "-A" ); // autogenerate application pseudo packages
1384
1385 if ( repokind == RepoType::RPMPLAINDIR )
1386 {
1387 forPlainDirs.reset( new MediaMounter( info.url() ) );
1388 // recusive for plaindir as 2nd arg!
1389 cmd.push_back( "-R" );
1390 // FIXME this does only work form dir: URLs
1391 cmd.push_back( forPlainDirs->getPathName( info.path() ).c_str() );
1392 }
1393 else
1394 cmd.push_back( productdatapath.asString() );
1395
1396 ExternalProgram prog( cmd, ExternalProgram::Stderr_To_Stdout );
1397 std::string errdetail;
1398
1399 for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
1400 WAR << " " << output;
1401 if ( errdetail.empty() ) {
1402 errdetail = prog.command();
1403 errdetail += '\n';
1404 }
1405 errdetail += output;
1406 }
1407
1408 int ret = prog.close();
1409 if ( ret != 0 )
1410 {
1411 RepoException ex(str::form( _("Failed to cache repo (%d)."), ret ));
1412 ex.remember( errdetail );
1413 ZYPP_THROW(ex);
1414 }
1415
1416 // We keep it.
1417 guard.resetDispose();
1418 sat::updateSolvFileIndex( solvfile ); // content digest for zypper bash completion
1419 }
1420 break;
1421 default:
1422 ZYPP_THROW(RepoUnknownTypeException( info, _("Unhandled repository type") ));
1423 break;
1424 }
1425 // update timestamp and checksum
1426 setCacheStatus(info, raw_metadata_status);
1427 MIL << "Commit cache.." << endl;
1428 progress.toMax();
1429 }
1430
1432
1433
1440 repo::RepoType RepoManager::Impl::probe( const Url & url, const Pathname & path ) const
1441 {
1442 MIL << "going to probe the repo type at " << url << " (" << path << ")" << endl;
1443
1444 if ( url.getScheme() == "dir" && ! PathInfo( url.getPathName()/path ).isDir() )
1445 {
1446 // Handle non existing local directory in advance, as
1447 // MediaSetAccess does not support it.
1448 MIL << "Probed type NONE (not exists) at " << url << " (" << path << ")" << endl;
1449 return repo::RepoType::NONE;
1450 }
1451
1452 // prepare exception to be thrown if the type could not be determined
1453 // due to a media exception. We can't throw right away, because of some
1454 // problems with proxy servers returning an incorrect error
1455 // on ftp file-not-found(bnc #335906). Instead we'll check another types
1456 // before throwing.
1457
1458 // TranslatorExplanation '%s' is an URL
1459 RepoException enew(str::form( _("Error trying to read from '%s'"), url.asString().c_str() ));
1460 bool gotMediaException = false;
1461 try
1462 {
1463 MediaSetAccess access(url);
1464 try
1465 {
1466 if ( access.doesFileExist(path/"/repodata/repomd.xml") )
1467 {
1468 MIL << "Probed type RPMMD at " << url << " (" << path << ")" << endl;
1469 return repo::RepoType::RPMMD;
1470 }
1471 }
1472 catch ( const media::MediaException &e )
1473 {
1474 ZYPP_CAUGHT(e);
1475 DBG << "problem checking for repodata/repomd.xml file" << endl;
1476 enew.remember(e);
1477 gotMediaException = true;
1478 }
1479
1480 try
1481 {
1482 if ( access.doesFileExist(path/"/content") )
1483 {
1484 MIL << "Probed type YAST2 at " << url << " (" << path << ")" << endl;
1485 return repo::RepoType::YAST2;
1486 }
1487 }
1488 catch ( const media::MediaException &e )
1489 {
1490 ZYPP_CAUGHT(e);
1491 DBG << "problem checking for content file" << endl;
1492 enew.remember(e);
1493 gotMediaException = true;
1494 }
1495
1496 // if it is a non-downloading URL denoting a directory
1497 if ( ! url.schemeIsDownloading() )
1498 {
1499 MediaMounter media( url );
1500 if ( PathInfo(media.getPathName()/path).isDir() )
1501 {
1502 // allow empty dirs for now
1503 MIL << "Probed type RPMPLAINDIR at " << url << " (" << path << ")" << endl;
1504 return repo::RepoType::RPMPLAINDIR;
1505 }
1506 }
1507 }
1508 catch ( const Exception &e )
1509 {
1510 ZYPP_CAUGHT(e);
1511 // TranslatorExplanation '%s' is an URL
1512 Exception enew(str::form( _("Unknown error reading from '%s'"), url.asString().c_str() ));
1513 enew.remember(e);
1514 ZYPP_THROW(enew);
1515 }
1516
1517 if (gotMediaException)
1518 ZYPP_THROW(enew);
1519
1520 MIL << "Probed type NONE at " << url << " (" << path << ")" << endl;
1521 return repo::RepoType::NONE;
1522 }
1523
1529 repo::RepoType RepoManager::Impl::probeCache( const Pathname & path_r ) const
1530 {
1531 MIL << "going to probe the cached repo at " << path_r << endl;
1532
1533 repo::RepoType ret = repo::RepoType::NONE;
1534
1535 if ( PathInfo(path_r/"/repodata/repomd.xml").isFile() )
1536 { ret = repo::RepoType::RPMMD; }
1537 else if ( PathInfo(path_r/"/content").isFile() )
1538 { ret = repo::RepoType::YAST2; }
1539 else if ( PathInfo(path_r).isDir() )
1540 { ret = repo::RepoType::RPMPLAINDIR; }
1541
1542 MIL << "Probed cached type " << ret << " at " << path_r << endl;
1543 return ret;
1544 }
1545
1547
1548 void RepoManager::Impl::cleanCacheDirGarbage( const ProgressData::ReceiverFnc & progressrcv )
1549 {
1550 MIL << "Going to clean up garbage in cache dirs" << endl;
1551
1552 ProgressData progress(300);
1553 progress.sendTo(progressrcv);
1554 progress.toMin();
1555
1556 std::list<Pathname> cachedirs;
1557 cachedirs.push_back(_options.repoRawCachePath);
1558 cachedirs.push_back(_options.repoPackagesCachePath);
1559 cachedirs.push_back(_options.repoSolvCachePath);
1560
1561 for_( dir, cachedirs.begin(), cachedirs.end() )
1562 {
1563 if ( PathInfo(*dir).isExist() )
1564 {
1565 std::list<Pathname> entries;
1566 if ( filesystem::readdir( entries, *dir, false ) != 0 )
1567 // TranslatorExplanation '%s' is a pathname
1568 ZYPP_THROW(Exception(str::form(_("Failed to read directory '%s'"), dir->c_str())));
1569
1570 unsigned sdircount = entries.size();
1571 unsigned sdircurrent = 1;
1572 for_( subdir, entries.begin(), entries.end() )
1573 {
1574 // if it does not belong known repo, make it disappear
1575 bool found = false;
1576 for_( r, repoBegin(), repoEnd() )
1577 if ( subdir->basename() == r->escaped_alias() )
1578 { found = true; break; }
1579
1580 if ( ! found && ( Date::now()-PathInfo(*subdir).mtime() > Date::day ) )
1581 filesystem::recursive_rmdir( *subdir );
1582
1583 progress.set( progress.val() + sdircurrent * 100 / sdircount );
1584 ++sdircurrent;
1585 }
1586 }
1587 else
1588 progress.set( progress.val() + 100 );
1589 }
1590 progress.toMax();
1591 }
1592
1594
1595 void RepoManager::Impl::cleanCache( const RepoInfo & info, const ProgressData::ReceiverFnc & progressrcv )
1596 {
1597 ProgressData progress(100);
1598 progress.sendTo(progressrcv);
1599 progress.toMin();
1600
1601 MIL << "Removing raw metadata cache for " << info.alias() << endl;
1602 filesystem::recursive_rmdir(solv_path_for_repoinfo(_options, info));
1603
1604 progress.toMax();
1605 }
1606
1608
1609 void RepoManager::Impl::loadFromCache( const RepoInfo & info, const ProgressData::ReceiverFnc & progressrcv )
1610 {
1611 assert_alias(info);
1612 Pathname solvfile = solv_path_for_repoinfo(_options, info) / "solv";
1613
1614 if ( ! PathInfo(solvfile).isExist() )
1615 ZYPP_THROW(RepoNotCachedException(info));
1616
1617 sat::Pool::instance().reposErase( info.alias() );
1618 try
1619 {
1620 Repository repo = sat::Pool::instance().addRepoSolv( solvfile, info );
1621 // test toolversion in order to rebuild solv file in case
1622 // it was written by a different libsolv-tool parser.
1623 const std::string & toolversion( sat::LookupRepoAttr( sat::SolvAttr::repositoryToolVersion, repo ).begin().asString() );
1624 if ( toolversion != LIBSOLV_TOOLVERSION )
1625 {
1626 repo.eraseFromPool();
1627 ZYPP_THROW(Exception(str::Str() << "Solv-file was created by '"<<toolversion<<"'-parser (want "<<LIBSOLV_TOOLVERSION<<")."));
1628 }
1629 }
1630 catch ( const Exception & exp )
1631 {
1632 ZYPP_CAUGHT( exp );
1633 MIL << "Try to handle exception by rebuilding the solv-file" << endl;
1634 cleanCache( info, progressrcv );
1635 buildCache( info, BuildIfNeeded, progressrcv );
1636
1637 sat::Pool::instance().addRepoSolv( solvfile, info );
1638 }
1639 }
1640
1642
1643 void RepoManager::Impl::addRepository( const RepoInfo & info, const ProgressData::ReceiverFnc & progressrcv )
1644 {
1645 assert_alias(info);
1646
1647 ProgressData progress(100);
1648 callback::SendReport<ProgressReport> report;
1649 progress.sendTo( ProgressReportAdaptor( progressrcv, report ) );
1650 progress.name(str::form(_("Adding repository '%s'"), info.label().c_str()));
1651 progress.toMin();
1652
1653 MIL << "Try adding repo " << info << endl;
1654
1655 RepoInfo tosave = info;
1656 if ( repos().find(tosave) != repos().end() )
1657 ZYPP_THROW(RepoAlreadyExistsException(info));
1658
1659 // check the first url for now
1660 if ( _options.probe )
1661 {
1662 DBG << "unknown repository type, probing" << endl;
1663 assert_urls(tosave);
1664
1665 RepoType probedtype( probe( tosave.url(), info.path() ) );
1666 if ( probedtype == RepoType::NONE )
1667 ZYPP_THROW(RepoUnknownTypeException(info));
1668 else
1669 tosave.setType(probedtype);
1670 }
1671
1672 progress.set(50);
1673
1674 // assert the directory exists
1675 filesystem::assert_dir(_options.knownReposPath);
1676
1677 Pathname repofile = generateNonExistingName(
1678 _options.knownReposPath, generateFilename(tosave));
1679 // now we have a filename that does not exists
1680 MIL << "Saving repo in " << repofile << endl;
1681
1682 std::ofstream file(repofile.c_str());
1683 if (!file)
1684 {
1685 // TranslatorExplanation '%s' is a filename
1686 ZYPP_THROW( Exception(str::form( _("Can't open file '%s' for writing."), repofile.c_str() )));
1687 }
1688
1689 tosave.dumpAsIniOn(file);
1690 tosave.setFilepath(repofile);
1691 tosave.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ) );
1692 tosave.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ) );
1693 {
1694 // We should fix the API as we must inject those paths
1695 // into the repoinfo in order to keep it usable.
1696 RepoInfo & oinfo( const_cast<RepoInfo &>(info) );
1697 oinfo.setFilepath(repofile);
1698 oinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ) );
1699 oinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ) );
1700 }
1701 reposManip().insert(tosave);
1702
1703 progress.set(90);
1704
1705 // check for credentials in Urls
1706 UrlCredentialExtractor( _options.rootDir ).collect( tosave.baseUrls() );
1707
1708 HistoryLog(_options.rootDir).addRepository(tosave);
1709
1710 progress.toMax();
1711 MIL << "done" << endl;
1712 }
1713
1714
1715 void RepoManager::Impl::addRepositories( const Url & url, const ProgressData::ReceiverFnc & progressrcv )
1716 {
1717 std::list<RepoInfo> repos = readRepoFile(url);
1718 for ( std::list<RepoInfo>::const_iterator it = repos.begin();
1719 it != repos.end();
1720 ++it )
1721 {
1722 // look if the alias is in the known repos.
1723 for_ ( kit, repoBegin(), repoEnd() )
1724 {
1725 if ( (*it).alias() == (*kit).alias() )
1726 {
1727 ERR << "To be added repo " << (*it).alias() << " conflicts with existing repo " << (*kit).alias() << endl;
1728 ZYPP_THROW(RepoAlreadyExistsException(*it));
1729 }
1730 }
1731 }
1732
1733 std::string filename = Pathname(url.getPathName()).basename();
1734
1735 if ( filename == Pathname() )
1736 {
1737 // TranslatorExplanation '%s' is an URL
1738 ZYPP_THROW(RepoException(str::form( _("Invalid repo file name at '%s'"), url.asString().c_str() )));
1739 }
1740
1741 // assert the directory exists
1742 filesystem::assert_dir(_options.knownReposPath);
1743
1744 Pathname repofile = generateNonExistingName(_options.knownReposPath, filename);
1745 // now we have a filename that does not exists
1746 MIL << "Saving " << repos.size() << " repo" << ( repos.size() ? "s" : "" ) << " in " << repofile << endl;
1747
1748 std::ofstream file(repofile.c_str());
1749 if (!file)
1750 {
1751 // TranslatorExplanation '%s' is a filename
1752 ZYPP_THROW( Exception(str::form( _("Can't open file '%s' for writing."), repofile.c_str() )));
1753 }
1754
1755 for ( std::list<RepoInfo>::iterator it = repos.begin();
1756 it != repos.end();
1757 ++it )
1758 {
1759 MIL << "Saving " << (*it).alias() << endl;
1760 it->dumpAsIniOn(file);
1761 it->setFilepath(repofile);
1762 it->setMetadataPath( rawcache_path_for_repoinfo( _options, *it ) );
1763 it->setPackagesPath( packagescache_path_for_repoinfo( _options, *it ) );
1764 reposManip().insert(*it);
1765
1766 HistoryLog(_options.rootDir).addRepository(*it);
1767 }
1768
1769 MIL << "done" << endl;
1770 }
1771
1773
1774 void RepoManager::Impl::removeRepository( const RepoInfo & info, const ProgressData::ReceiverFnc & progressrcv )
1775 {
1776 ProgressData progress;
1777 callback::SendReport<ProgressReport> report;
1778 progress.sendTo( ProgressReportAdaptor( progressrcv, report ) );
1779 progress.name(str::form(_("Removing repository '%s'"), info.label().c_str()));
1780
1781 MIL << "Going to delete repo " << info.alias() << endl;
1782
1783 for_( it, repoBegin(), repoEnd() )
1784 {
1785 // they can be the same only if the provided is empty, that means
1786 // the provided repo has no alias
1787 // then skip
1788 if ( (!info.alias().empty()) && ( info.alias() != (*it).alias() ) )
1789 continue;
1790
1791 // TODO match by url
1792
1793 // we have a matcing repository, now we need to know
1794 // where it does come from.
1795 RepoInfo todelete = *it;
1796 if (todelete.filepath().empty())
1797 {
1798 ZYPP_THROW(RepoException( todelete, _("Can't figure out where the repo is stored.") ));
1799 }
1800 else
1801 {
1802 // figure how many repos are there in the file:
1803 std::list<RepoInfo> filerepos = repositories_in_file(todelete.filepath());
1804 if ( filerepos.size() == 0 // bsc#984494: file may have already been deleted
1805 ||(filerepos.size() == 1 && filerepos.front().alias() == todelete.alias() ) )
1806 {
1807 // easy: file does not exist, contains no or only the repo to delete: delete the file
1808 int ret = filesystem::unlink( todelete.filepath() );
1809 if ( ! ( ret == 0 || ret == ENOENT ) )
1810 {
1811 // TranslatorExplanation '%s' is a filename
1812 ZYPP_THROW(RepoException( todelete, str::form( _("Can't delete '%s'"), todelete.filepath().c_str() )));
1813 }
1814 MIL << todelete.alias() << " successfully deleted." << endl;
1815 }
1816 else
1817 {
1818 // there are more repos in the same file
1819 // write them back except the deleted one.
1820 //TmpFile tmp;
1821 //std::ofstream file(tmp.path().c_str());
1822
1823 // assert the directory exists
1824 filesystem::assert_dir(todelete.filepath().dirname());
1825
1826 std::ofstream file(todelete.filepath().c_str());
1827 if (!file)
1828 {
1829 // TranslatorExplanation '%s' is a filename
1830 ZYPP_THROW( Exception(str::form( _("Can't open file '%s' for writing."), todelete.filepath().c_str() )));
1831 }
1832 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1833 fit != filerepos.end();
1834 ++fit )
1835 {
1836 if ( (*fit).alias() != todelete.alias() )
1837 (*fit).dumpAsIniOn(file);
1838 }
1839 }
1840
1841 CombinedProgressData cSubprogrcv(progress, 20);
1842 CombinedProgressData mSubprogrcv(progress, 40);
1843 CombinedProgressData pSubprogrcv(progress, 40);
1844 // now delete it from cache
1845 if ( isCached(todelete) )
1846 cleanCache( todelete, cSubprogrcv);
1847 // now delete metadata (#301037)
1848 cleanMetadata( todelete, mSubprogrcv );
1849 cleanPackages( todelete, pSubprogrcv );
1850 reposManip().erase(todelete);
1851 MIL << todelete.alias() << " successfully deleted." << endl;
1852 HistoryLog(_options.rootDir).removeRepository(todelete);
1853 return;
1854 } // else filepath is empty
1855
1856 }
1857 // should not be reached on a sucess workflow
1858 ZYPP_THROW(RepoNotFoundException(info));
1859 }
1860
1862
1863 void RepoManager::Impl::modifyRepository( const std::string & alias, const RepoInfo & newinfo_r, const ProgressData::ReceiverFnc & progressrcv )
1864 {
1865 RepoInfo toedit = getRepositoryInfo(alias);
1866 RepoInfo newinfo( newinfo_r ); // need writable copy to upadte housekeeping data
1867
1868 // check if the new alias already exists when renaming the repo
1869 if ( alias != newinfo.alias() && hasRepo( newinfo.alias() ) )
1870 {
1871 ZYPP_THROW(RepoAlreadyExistsException(newinfo));
1872 }
1873
1874 if (toedit.filepath().empty())
1875 {
1876 ZYPP_THROW(RepoException( toedit, _("Can't figure out where the repo is stored.") ));
1877 }
1878 else
1879 {
1880 // figure how many repos are there in the file:
1881 std::list<RepoInfo> filerepos = repositories_in_file(toedit.filepath());
1882
1883 // there are more repos in the same file
1884 // write them back except the deleted one.
1885 //TmpFile tmp;
1886 //std::ofstream file(tmp.path().c_str());
1887
1888 // assert the directory exists
1889 filesystem::assert_dir(toedit.filepath().dirname());
1890
1891 std::ofstream file(toedit.filepath().c_str());
1892 if (!file)
1893 {
1894 // TranslatorExplanation '%s' is a filename
1895 ZYPP_THROW( Exception(str::form( _("Can't open file '%s' for writing."), toedit.filepath().c_str() )));
1896 }
1897 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1898 fit != filerepos.end();
1899 ++fit )
1900 {
1901 // if the alias is different, dump the original
1902 // if it is the same, dump the provided one
1903 if ( (*fit).alias() != toedit.alias() )
1904 (*fit).dumpAsIniOn(file);
1905 else
1906 newinfo.dumpAsIniOn(file);
1907 }
1908
1909 if ( toedit.enabled() && !newinfo.enabled() )
1910 {
1911 // On the fly remove solv.idx files for bash completion if a repo gets disabled.
1912 const Pathname & solvidx = solv_path_for_repoinfo(_options, newinfo)/"solv.idx";
1913 if ( PathInfo(solvidx).isExist() )
1914 filesystem::unlink( solvidx );
1915 }
1916
1917 newinfo.setFilepath(toedit.filepath());
1918 newinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ) );
1919 newinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ) );
1920 {
1921 // We should fix the API as we must inject those paths
1922 // into the repoinfo in order to keep it usable.
1923 RepoInfo & oinfo( const_cast<RepoInfo &>(newinfo_r) );
1924 oinfo.setFilepath(toedit.filepath());
1925 oinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ) );
1926 oinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ) );
1927 }
1928 reposManip().erase(toedit);
1929 reposManip().insert(newinfo);
1930 // check for credentials in Urls
1931 UrlCredentialExtractor( _options.rootDir ).collect( newinfo.baseUrls() );
1932 HistoryLog(_options.rootDir).modifyRepository(toedit, newinfo);
1933 MIL << "repo " << alias << " modified" << endl;
1934 }
1935 }
1936
1938
1939 RepoInfo RepoManager::Impl::getRepositoryInfo( const std::string & alias, const ProgressData::ReceiverFnc & progressrcv )
1940 {
1941 RepoConstIterator it( findAlias( alias, repos() ) );
1942 if ( it != repos().end() )
1943 return *it;
1944 RepoInfo info;
1945 info.setAlias( alias );
1946 ZYPP_THROW( RepoNotFoundException(info) );
1947 }
1948
1949
1950 RepoInfo RepoManager::Impl::getRepositoryInfo( const Url & url, const url::ViewOption & urlview, const ProgressData::ReceiverFnc & progressrcv )
1951 {
1952 for_( it, repoBegin(), repoEnd() )
1953 {
1954 for_( urlit, (*it).baseUrlsBegin(), (*it).baseUrlsEnd() )
1955 {
1956 if ( (*urlit).asString(urlview) == url.asString(urlview) )
1957 return *it;
1958 }
1959 }
1960 RepoInfo info;
1961 info.setBaseUrl( url );
1962 ZYPP_THROW( RepoNotFoundException(info) );
1963 }
1964
1966 //
1967 // Services
1968 //
1970
1971 void RepoManager::Impl::addService( const ServiceInfo & service )
1972 {
1973 assert_alias( service );
1974
1975 // check if service already exists
1976 if ( hasService( service.alias() ) )
1977 ZYPP_THROW( ServiceAlreadyExistsException( service ) );
1978
1979 // Writable ServiceInfo is needed to save the location
1980 // of the .service file. Finaly insert into the service list.
1981 ServiceInfo toSave( service );
1982 saveService( toSave );
1983 _services.insert( toSave );
1984
1985 // check for credentials in Url
1986 UrlCredentialExtractor( _options.rootDir ).collect( toSave.url() );
1987
1988 MIL << "added service " << toSave.alias() << endl;
1989 }
1990
1992
1993 void RepoManager::Impl::removeService( const std::string & alias )
1994 {
1995 MIL << "Going to delete service " << alias << endl;
1996
1997 const ServiceInfo & service = getService( alias );
1998
1999 Pathname location = service.filepath();
2000 if( location.empty() )
2001 {
2002 ZYPP_THROW(ServiceException( service, _("Can't figure out where the service is stored.") ));
2003 }
2004
2005 ServiceSet tmpSet;
2006 parser::ServiceFileReader( location, ServiceCollector(tmpSet) );
2007
2008 // only one service definition in the file
2009 if ( tmpSet.size() == 1 )
2010 {
2011 if ( filesystem::unlink(location) != 0 )
2012 {
2013 // TranslatorExplanation '%s' is a filename
2014 ZYPP_THROW(ServiceException( service, str::form( _("Can't delete '%s'"), location.c_str() ) ));
2015 }
2016 MIL << alias << " successfully deleted." << endl;
2017 }
2018 else
2019 {
2020 filesystem::assert_dir(location.dirname());
2021
2022 std::ofstream file(location.c_str());
2023 if( !file )
2024 {
2025 // TranslatorExplanation '%s' is a filename
2026 ZYPP_THROW( Exception(str::form( _("Can't open file '%s' for writing."), location.c_str() )));
2027 }
2028
2029 for_(it, tmpSet.begin(), tmpSet.end())
2030 {
2031 if( it->alias() != alias )
2032 it->dumpAsIniOn(file);
2033 }
2034
2035 MIL << alias << " successfully deleted from file " << location << endl;
2036 }
2037
2038 // now remove all repositories added by this service
2039 RepoCollector rcollector;
2040 getRepositoriesInService( alias,
2041 boost::make_function_output_iterator( bind( &RepoCollector::collect, &rcollector, _1 ) ) );
2042 // cannot do this directly in getRepositoriesInService - would invalidate iterators
2043 for_(rit, rcollector.repos.begin(), rcollector.repos.end())
2044 removeRepository(*rit);
2045 }
2046
2048
2049 void RepoManager::Impl::refreshServices( const RefreshServiceOptions & options_r )
2050 {
2051 // copy the set of services since refreshService
2052 // can eventually invalidate the iterator
2053 ServiceSet services( serviceBegin(), serviceEnd() );
2054 for_( it, services.begin(), services.end() )
2055 {
2056 if ( !it->enabled() )
2057 continue;
2058
2059 try {
2060 refreshService(*it, options_r);
2061 }
2062 catch ( const repo::ServicePluginInformalException & e )
2063 { ;/* ignore ServicePluginInformalException */ }
2064 }
2065 }
2066
2067 void RepoManager::Impl::refreshService( const std::string & alias, const RefreshServiceOptions & options_r )
2068 {
2069 ServiceInfo service( getService( alias ) );
2070 assert_alias( service );
2071 assert_url( service );
2072 MIL << "Going to refresh service '" << service.alias() << "', url: " << service.url() << ", opts: " << options_r << endl;
2073
2074 if ( service.ttl() && !( options_r.testFlag( RefreshService_forceRefresh) || options_r.testFlag( RefreshService_restoreStatus ) ) )
2075 {
2076 // Service defines a TTL; maybe we can re-use existing data without refresh.
2077 Date lrf = service.lrf();
2078 if ( lrf )
2079 {
2080 Date now( Date::now() );
2081 if ( lrf <= now )
2082 {
2083 if ( (lrf+=service.ttl()) > now ) // lrf+= !
2084 {
2085 MIL << "Skip: '" << service.alias() << "' metadata valid until " << lrf << endl;
2086 return;
2087 }
2088 }
2089 else
2090 WAR << "Force: '" << service.alias() << "' metadata last refresh in the future: " << lrf << endl;
2091 }
2092 }
2093
2094 // NOTE: It might be necessary to modify and rewrite the service info.
2095 // Either when probing the type, or when adjusting the repositories
2096 // enable/disable state.:
2097 bool serviceModified = false;
2098
2100
2101 // if the type is unknown, try probing.
2102 if ( service.type() == repo::ServiceType::NONE )
2103 {
2104 repo::ServiceType type = probeService( service.url() );
2105 if ( type != ServiceType::NONE )
2106 {
2107 service.setProbedType( type ); // lazy init!
2108 serviceModified = true;
2109 }
2110 }
2111
2112 // get target distro identifier
2113 std::string servicesTargetDistro = _options.servicesTargetDistro;
2114 if ( servicesTargetDistro.empty() )
2115 {
2116 servicesTargetDistro = Target::targetDistribution( Pathname() );
2117 }
2118 DBG << "ServicesTargetDistro: " << servicesTargetDistro << endl;
2119
2120 // parse it
2121 Date::Duration origTtl = service.ttl(); // FIXME Ugly hack: const service.ttl modified when parsing
2122 RepoCollector collector(servicesTargetDistro);
2123 // FIXME Ugly hack: ServiceRepos may throw ServicePluginInformalException
2124 // which is actually a notification. Using an exception for this
2125 // instead of signal/callback is bad. Needs to be fixed here, in refreshServices()
2126 // and in zypper.
2127 std::pair<DefaultIntegral<bool,false>, repo::ServicePluginInformalException> uglyHack;
2128 try {
2129 // FIXME bsc#1080693: Shortcoming of (plugin)services (and repos as well) is that they
2130 // are not aware of the RepoManagers rootDir. The service url, as created in known_services,
2131 // contains the full path to the script. The script however has to be executed chrooted.
2132 // Repos would need to know the RepoMangers rootDir to use the correct vars.d to replace
2133 // repos variables. Until RepoInfoBase is aware if the rootDir, we need to explicitly pass it
2134 // to ServiceRepos.
2135 ServiceRepos( _options.rootDir, service, bind( &RepoCollector::collect, &collector, _1 ) );
2136 }
2137 catch ( const repo::ServicePluginInformalException & e )
2138 {
2139 /* ignore ServicePluginInformalException and throw later */
2140 uglyHack.first = true;
2141 uglyHack.second = e;
2142 }
2143 if ( service.ttl() != origTtl ) // repoindex.xml changed ttl
2144 {
2145 if ( !service.ttl() )
2146 service.setLrf( Date() ); // don't need lrf when zero ttl
2147 serviceModified = true;
2148 }
2150 // On the fly remember the new repo states as defined the reopoindex.xml.
2151 // Move into ServiceInfo later.
2152 ServiceInfo::RepoStates newRepoStates;
2153
2154 // set service alias and base url for all collected repositories
2155 for_( it, collector.repos.begin(), collector.repos.end() )
2156 {
2157 // First of all: Prepend service alias:
2158 it->setAlias( str::form( "%s:%s", service.alias().c_str(), it->alias().c_str() ) );
2159 // set reference to the parent service
2160 it->setService( service.alias() );
2161
2162 // remember the new parsed repo state
2163 newRepoStates[it->alias()] = *it;
2164
2165 // - If the repo url was not set by the repoindex parser, set service's url.
2166 // - Libzypp currently has problem with separate url + path handling so just
2167 // append a path, if set, to the baseurls
2168 // - Credentials in the url authority will be extracted later, either if the
2169 // repository is added or if we check for changed urls.
2170 Pathname path;
2171 if ( !it->path().empty() )
2172 {
2173 if ( it->path() != "/" )
2174 path = it->path();
2175 it->setPath("");
2176 }
2177
2178 if ( it->baseUrlsEmpty() )
2179 {
2180 Url url( service.rawUrl() );
2181 if ( !path.empty() )
2182 url.setPathName( url.getPathName() / path );
2183 it->setBaseUrl( std::move(url) );
2184 }
2185 else if ( !path.empty() )
2186 {
2187 RepoInfo::url_set urls( it->rawBaseUrls() );
2188 for ( Url & url : urls )
2189 {
2190 url.setPathName( url.getPathName() / path );
2191 }
2192 it->setBaseUrls( std::move(urls) );
2193 }
2194 }
2195
2197 // Now compare collected repos with the ones in the system...
2198 //
2199 RepoInfoList oldRepos;
2200 getRepositoriesInService( service.alias(), std::back_inserter( oldRepos ) );
2201
2203 // find old repositories to remove...
2204 for_( oldRepo, oldRepos.begin(), oldRepos.end() )
2205 {
2206 if ( ! foundAliasIn( oldRepo->alias(), collector.repos ) )
2207 {
2208 if ( oldRepo->enabled() )
2209 {
2210 // Currently enabled. If this was a user modification remember the state.
2211 const auto & last = service.repoStates().find( oldRepo->alias() );
2212 if ( last != service.repoStates().end() && ! last->second.enabled )
2213 {
2214 DBG << "Service removes user enabled repo " << oldRepo->alias() << endl;
2215 service.addRepoToEnable( oldRepo->alias() );
2216 serviceModified = true;
2217 }
2218 else
2219 DBG << "Service removes enabled repo " << oldRepo->alias() << endl;
2220 }
2221 else
2222 DBG << "Service removes disabled repo " << oldRepo->alias() << endl;
2223
2224 removeRepository( *oldRepo );
2225 }
2226 }
2227
2229 // create missing repositories and modify existing ones if needed...
2230 UrlCredentialExtractor urlCredentialExtractor( _options.rootDir ); // To collect any credentials stored in repo URLs
2231 for_( it, collector.repos.begin(), collector.repos.end() )
2232 {
2233 // User explicitly requested the repo being enabled?
2234 // User explicitly requested the repo being disabled?
2235 // And hopefully not both ;) If so, enable wins.
2236
2237 TriBool toBeEnabled( indeterminate ); // indeterminate - follow the service request
2238 DBG << "Service request to " << (it->enabled()?"enable":"disable") << " service repo " << it->alias() << endl;
2239
2240 if ( options_r.testFlag( RefreshService_restoreStatus ) )
2241 {
2242 DBG << "Opt RefreshService_restoreStatus " << it->alias() << endl;
2243 // this overrides any pending request!
2244 // Remove from enable request list.
2245 // NOTE: repoToDisable is handled differently.
2246 // It gets cleared on each refresh.
2247 service.delRepoToEnable( it->alias() );
2248 // toBeEnabled stays indeterminate!
2249 }
2250 else
2251 {
2252 if ( service.repoToEnableFind( it->alias() ) )
2253 {
2254 DBG << "User request to enable service repo " << it->alias() << endl;
2255 toBeEnabled = true;
2256 // Remove from enable request list.
2257 // NOTE: repoToDisable is handled differently.
2258 // It gets cleared on each refresh.
2259 service.delRepoToEnable( it->alias() );
2260 serviceModified = true;
2261 }
2262 else if ( service.repoToDisableFind( it->alias() ) )
2263 {
2264 DBG << "User request to disable service repo " << it->alias() << endl;
2265 toBeEnabled = false;
2266 }
2267 }
2268
2269 RepoInfoList::iterator oldRepo( findAlias( it->alias(), oldRepos ) );
2270 if ( oldRepo == oldRepos.end() )
2271 {
2272 // Not found in oldRepos ==> a new repo to add
2273
2274 // Make sure the service repo is created with the appropriate enablement
2275 if ( ! indeterminate(toBeEnabled) )
2276 it->setEnabled( ( bool ) toBeEnabled );
2277
2278 DBG << "Service adds repo " << it->alias() << " " << (it->enabled()?"enabled":"disabled") << endl;
2279 addRepository( *it );
2280 }
2281 else
2282 {
2283 // ==> an exising repo to check
2284 bool oldRepoModified = false;
2285
2286 if ( indeterminate(toBeEnabled) )
2287 {
2288 // No user request: check for an old user modificaton otherwise follow service request.
2289 // NOTE: Assert toBeEnabled is boolean afterwards!
2290 if ( oldRepo->enabled() == it->enabled() )
2291 toBeEnabled = it->enabled(); // service requests no change to the system
2292 else if (options_r.testFlag( RefreshService_restoreStatus ) )
2293 {
2294 toBeEnabled = it->enabled(); // RefreshService_restoreStatus forced
2295 DBG << "Opt RefreshService_restoreStatus " << it->alias() << " forces " << (toBeEnabled?"enabled":"disabled") << endl;
2296 }
2297 else
2298 {
2299 const auto & last = service.repoStates().find( oldRepo->alias() );
2300 if ( last == service.repoStates().end() || last->second.enabled != it->enabled() )
2301 toBeEnabled = it->enabled(); // service request has changed since last refresh -> follow
2302 else
2303 {
2304 toBeEnabled = oldRepo->enabled(); // service request unchaned since last refresh -> keep user modification
2305 DBG << "User modified service repo " << it->alias() << " may stay " << (toBeEnabled?"enabled":"disabled") << endl;
2306 }
2307 }
2308 }
2309
2310 // changed enable?
2311 if ( toBeEnabled == oldRepo->enabled() )
2312 {
2313 DBG << "Service repo " << it->alias() << " stays " << (oldRepo->enabled()?"enabled":"disabled") << endl;
2314 }
2315 else if ( toBeEnabled )
2316 {
2317 DBG << "Service repo " << it->alias() << " gets enabled" << endl;
2318 oldRepo->setEnabled( true );
2319 oldRepoModified = true;
2320 }
2321 else
2322 {
2323 DBG << "Service repo " << it->alias() << " gets disabled" << endl;
2324 oldRepo->setEnabled( false );
2325 oldRepoModified = true;
2326 }
2327
2328 // all other attributes follow the service request:
2329
2330 // changed name (raw!)
2331 if ( oldRepo->rawName() != it->rawName() )
2332 {
2333 DBG << "Service repo " << it->alias() << " gets new NAME " << it->rawName() << endl;
2334 oldRepo->setName( it->rawName() );
2335 oldRepoModified = true;
2336 }
2337
2338 // changed autorefresh
2339 if ( oldRepo->autorefresh() != it->autorefresh() )
2340 {
2341 DBG << "Service repo " << it->alias() << " gets new AUTOREFRESH " << it->autorefresh() << endl;
2342 oldRepo->setAutorefresh( it->autorefresh() );
2343 oldRepoModified = true;
2344 }
2345
2346 // changed priority?
2347 if ( oldRepo->priority() != it->priority() )
2348 {
2349 DBG << "Service repo " << it->alias() << " gets new PRIORITY " << it->priority() << endl;
2350 oldRepo->setPriority( it->priority() );
2351 oldRepoModified = true;
2352 }
2353
2354 // changed url?
2355 {
2356 RepoInfo::url_set newUrls( it->rawBaseUrls() );
2357 urlCredentialExtractor.extract( newUrls ); // Extract! to prevent passwds from disturbing the comparison below
2358 if ( oldRepo->rawBaseUrls() != newUrls )
2359 {
2360 DBG << "Service repo " << it->alias() << " gets new URLs " << newUrls << endl;
2361 oldRepo->setBaseUrls( std::move(newUrls) );
2362 oldRepoModified = true;
2363 }
2364 }
2365
2366 // changed gpg check settings?
2367 // ATM only plugin services can set GPG values.
2368 if ( service.type() == ServiceType::PLUGIN )
2369 {
2370 TriBool ogpg[3]; // Gpg RepoGpg PkgGpg
2371 TriBool ngpg[3];
2372 oldRepo->getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] );
2373 it-> getRawGpgChecks( ngpg[0], ngpg[1], ngpg[2] );
2374 #define Z_CHKGPG(I,N) \
2375 if ( ! sameTriboolState( ogpg[I], ngpg[I] ) ) \
2376 { \
2377 DBG << "Service repo " << it->alias() << " gets new "#N"Check " << ngpg[I] << endl; \
2378 oldRepo->set##N##Check( ngpg[I] ); \
2379 oldRepoModified = true; \
2380 }
2381 Z_CHKGPG( 0, Gpg );
2382 Z_CHKGPG( 1, RepoGpg );
2383 Z_CHKGPG( 2, PkgGpg );
2384 #undef Z_CHKGPG
2385 }
2386
2387 // save if modified:
2388 if ( oldRepoModified )
2389 {
2390 modifyRepository( oldRepo->alias(), *oldRepo );
2391 }
2392 }
2393 }
2394
2395 // Unlike reposToEnable, reposToDisable is always cleared after refresh.
2396 if ( ! service.reposToDisableEmpty() )
2397 {
2398 service.clearReposToDisable();
2399 serviceModified = true;
2400 }
2401
2402 // Remember original service request for next refresh
2403 if ( service.repoStates() != newRepoStates )
2404 {
2405 service.setRepoStates( std::move(newRepoStates) );
2406 serviceModified = true;
2407 }
2408
2410 // save service if modified: (unless a plugin service)
2411 if ( service.type() != ServiceType::PLUGIN )
2412 {
2413 if ( service.ttl() )
2414 {
2415 service.setLrf( Date::now() ); // remember last refresh
2416 serviceModified = true; // or use a cookie file
2417 }
2418
2419 if ( serviceModified )
2420 {
2421 // write out modified service file.
2422 modifyService( service.alias(), service );
2423 }
2424 }
2425
2426 if ( uglyHack.first )
2427 {
2428 throw( uglyHack.second ); // intentionally not ZYPP_THROW
2429 }
2430 }
2431
2433
2434 void RepoManager::Impl::modifyService( const std::string & oldAlias, const ServiceInfo & newService )
2435 {
2436 MIL << "Going to modify service " << oldAlias << endl;
2437
2438 // we need a writable copy to link it to the file where
2439 // it is saved if we modify it
2440 ServiceInfo service(newService);
2441
2442 if ( service.type() == ServiceType::PLUGIN )
2443 {
2444 ZYPP_THROW(ServicePluginImmutableException( service ));
2445 }
2446
2447 const ServiceInfo & oldService = getService(oldAlias);
2448
2449 Pathname location = oldService.filepath();
2450 if( location.empty() )
2451 {
2452 ZYPP_THROW(ServiceException( oldService, _("Can't figure out where the service is stored.") ));
2453 }
2454
2455 // remember: there may multiple services being defined in one file:
2456 ServiceSet tmpSet;
2457 parser::ServiceFileReader( location, ServiceCollector(tmpSet) );
2458
2459 filesystem::assert_dir(location.dirname());
2460 std::ofstream file(location.c_str());
2461 for_(it, tmpSet.begin(), tmpSet.end())
2462 {
2463 if( *it != oldAlias )
2464 it->dumpAsIniOn(file);
2465 }
2466 service.dumpAsIniOn(file);
2467 file.close();
2468 service.setFilepath(location);
2469
2470 _services.erase(oldAlias);
2471 _services.insert(service);
2472 // check for credentials in Urls
2473 UrlCredentialExtractor( _options.rootDir ).collect( service.url() );
2474
2475
2476 // changed properties affecting also repositories
2477 if ( oldAlias != service.alias() // changed alias
2478 || oldService.enabled() != service.enabled() ) // changed enabled status
2479 {
2480 std::vector<RepoInfo> toModify;
2481 getRepositoriesInService(oldAlias, std::back_inserter(toModify));
2482 for_( it, toModify.begin(), toModify.end() )
2483 {
2484 if ( oldService.enabled() != service.enabled() )
2485 {
2486 if ( service.enabled() )
2487 {
2488 // reset to last refreshs state
2489 const auto & last = service.repoStates().find( it->alias() );
2490 if ( last != service.repoStates().end() )
2491 it->setEnabled( last->second.enabled );
2492 }
2493 else
2494 it->setEnabled( false );
2495 }
2496
2497 if ( oldAlias != service.alias() )
2498 it->setService(service.alias());
2499
2500 modifyRepository(it->alias(), *it);
2501 }
2502 }
2503
2505 }
2506
2508
2509 repo::ServiceType RepoManager::Impl::probeService( const Url & url ) const
2510 {
2511 try
2512 {
2513 MediaSetAccess access(url);
2514 if ( access.doesFileExist("/repo/repoindex.xml") )
2515 return repo::ServiceType::RIS;
2516 }
2517 catch ( const media::MediaException &e )
2518 {
2519 ZYPP_CAUGHT(e);
2520 // TranslatorExplanation '%s' is an URL
2521 RepoException enew(str::form( _("Error trying to read from '%s'"), url.asString().c_str() ));
2522 enew.remember(e);
2523 ZYPP_THROW(enew);
2524 }
2525 catch ( const Exception &e )
2526 {
2527 ZYPP_CAUGHT(e);
2528 // TranslatorExplanation '%s' is an URL
2529 Exception enew(str::form( _("Unknown error reading from '%s'"), url.asString().c_str() ));
2530 enew.remember(e);
2531 ZYPP_THROW(enew);
2532 }
2533
2534 return repo::ServiceType::NONE;
2535 }
2536
2538 //
2539 // CLASS NAME : RepoManager
2540 //
2542
2543 RepoManager::RepoManager( const RepoManagerOptions & opt )
2544 : _pimpl( new Impl(opt) )
2545 {}
2546
2547 RepoManager::~RepoManager()
2548 {}
2549
2550 bool RepoManager::repoEmpty() const
2551 { return _pimpl->repoEmpty(); }
2552
2553 RepoManager::RepoSizeType RepoManager::repoSize() const
2554 { return _pimpl->repoSize(); }
2555
2556 RepoManager::RepoConstIterator RepoManager::repoBegin() const
2557 { return _pimpl->repoBegin(); }
2558
2559 RepoManager::RepoConstIterator RepoManager::repoEnd() const
2560 { return _pimpl->repoEnd(); }
2561
2562 RepoInfo RepoManager::getRepo( const std::string & alias ) const
2563 { return _pimpl->getRepo( alias ); }
2564
2565 bool RepoManager::hasRepo( const std::string & alias ) const
2566 { return _pimpl->hasRepo( alias ); }
2567
2568 std::string RepoManager::makeStupidAlias( const Url & url_r )
2569 {
2570 std::string ret( url_r.getScheme() );
2571 if ( ret.empty() )
2572 ret = "repo-";
2573 else
2574 ret += "-";
2575
2576 std::string host( url_r.getHost() );
2577 if ( ! host.empty() )
2578 {
2579 ret += host;
2580 ret += "-";
2581 }
2582
2583 static Date::ValueType serial = Date::now();
2584 ret += Digest::digest( Digest::sha1(), str::hexstring( ++serial ) +url_r.asCompleteString() ).substr(0,8);
2585 return ret;
2586 }
2587
2588 RepoStatus RepoManager::metadataStatus( const RepoInfo & info ) const
2589 { return _pimpl->metadataStatus( info ); }
2590
2591 RepoManager::RefreshCheckStatus RepoManager::checkIfToRefreshMetadata( const RepoInfo &info, const Url &url, RawMetadataRefreshPolicy policy )
2592 { return _pimpl->checkIfToRefreshMetadata( info, url, policy ); }
2593
2594 Pathname RepoManager::metadataPath( const RepoInfo &info ) const
2595 { return _pimpl->metadataPath( info ); }
2596
2597 Pathname RepoManager::packagesPath( const RepoInfo &info ) const
2598 { return _pimpl->packagesPath( info ); }
2599
2600 void RepoManager::refreshMetadata( const RepoInfo &info, RawMetadataRefreshPolicy policy, const ProgressData::ReceiverFnc & progressrcv )
2601 { return _pimpl->refreshMetadata( info, policy, progressrcv ); }
2602
2603 void RepoManager::cleanMetadata( const RepoInfo &info, const ProgressData::ReceiverFnc & progressrcv )
2604 { return _pimpl->cleanMetadata( info, progressrcv ); }
2605
2606 void RepoManager::cleanPackages( const RepoInfo &info, const ProgressData::ReceiverFnc & progressrcv )
2607 { return _pimpl->cleanPackages( info, progressrcv ); }
2608
2609 RepoStatus RepoManager::cacheStatus( const RepoInfo &info ) const
2610 { return _pimpl->cacheStatus( info ); }
2611
2612 void RepoManager::buildCache( const RepoInfo &info, CacheBuildPolicy policy, const ProgressData::ReceiverFnc & progressrcv )
2613 { return _pimpl->buildCache( info, policy, progressrcv ); }
2614
2615 void RepoManager::cleanCache( const RepoInfo &info, const ProgressData::ReceiverFnc & progressrcv )
2616 { return _pimpl->cleanCache( info, progressrcv ); }
2617
2618 bool RepoManager::isCached( const RepoInfo &info ) const
2619 { return _pimpl->isCached( info ); }
2620
2621 void RepoManager::loadFromCache( const RepoInfo &info, const ProgressData::ReceiverFnc & progressrcv )
2622 { return _pimpl->loadFromCache( info, progressrcv ); }
2623
2624 void RepoManager::cleanCacheDirGarbage( const ProgressData::ReceiverFnc & progressrcv )
2625 { return _pimpl->cleanCacheDirGarbage( progressrcv ); }
2626
2627 repo::RepoType RepoManager::probe( const Url & url, const Pathname & path ) const
2628 { return _pimpl->probe( url, path ); }
2629
2630 repo::RepoType RepoManager::probe( const Url & url ) const
2631 { return _pimpl->probe( url ); }
2632
2633 void RepoManager::addRepository( const RepoInfo &info, const ProgressData::ReceiverFnc & progressrcv )
2634 { return _pimpl->addRepository( info, progressrcv ); }
2635
2636 void RepoManager::addRepositories( const Url &url, const ProgressData::ReceiverFnc & progressrcv )
2637 { return _pimpl->addRepositories( url, progressrcv ); }
2638
2639 void RepoManager::removeRepository( const RepoInfo & info, const ProgressData::ReceiverFnc & progressrcv )
2640 { return _pimpl->removeRepository( info, progressrcv ); }
2641
2642 void RepoManager::modifyRepository( const std::string &alias, const RepoInfo & newinfo, const ProgressData::ReceiverFnc & progressrcv )
2643 { return _pimpl->modifyRepository( alias, newinfo, progressrcv ); }
2644
2645 RepoInfo RepoManager::getRepositoryInfo( const std::string &alias, const ProgressData::ReceiverFnc & progressrcv )
2646 { return _pimpl->getRepositoryInfo( alias, progressrcv ); }
2647
2648 RepoInfo RepoManager::getRepositoryInfo( const Url & url, const url::ViewOption & urlview, const ProgressData::ReceiverFnc & progressrcv )
2649 { return _pimpl->getRepositoryInfo( url, urlview, progressrcv ); }
2650
2651 bool RepoManager::serviceEmpty() const
2652 { return _pimpl->serviceEmpty(); }
2653
2654 RepoManager::ServiceSizeType RepoManager::serviceSize() const
2655 { return _pimpl->serviceSize(); }
2656
2657 RepoManager::ServiceConstIterator RepoManager::serviceBegin() const
2658 { return _pimpl->serviceBegin(); }
2659
2660 RepoManager::ServiceConstIterator RepoManager::serviceEnd() const
2661 { return _pimpl->serviceEnd(); }
2662
2663 ServiceInfo RepoManager::getService( const std::string & alias ) const
2664 { return _pimpl->getService( alias ); }
2665
2666 bool RepoManager::hasService( const std::string & alias ) const
2667 { return _pimpl->hasService( alias ); }
2668
2669 repo::ServiceType RepoManager::probeService( const Url &url ) const
2670 { return _pimpl->probeService( url ); }
2671
2672 void RepoManager::addService( const std::string & alias, const Url& url )
2673 { return _pimpl->addService( alias, url ); }
2674
2675 void RepoManager::addService( const ServiceInfo & service )
2676 { return _pimpl->addService( service ); }
2677
2678 void RepoManager::removeService( const std::string & alias )
2679 { return _pimpl->removeService( alias ); }
2680
2681 void RepoManager::removeService( const ServiceInfo & service )
2682 { return _pimpl->removeService( service ); }
2683
2684 void RepoManager::refreshServices( const RefreshServiceOptions & options_r )
2685 { return _pimpl->refreshServices( options_r ); }
2686
2687 void RepoManager::refreshService( const std::string & alias, const RefreshServiceOptions & options_r )
2688 { return _pimpl->refreshService( alias, options_r ); }
2689
2690 void RepoManager::refreshService( const ServiceInfo & service, const RefreshServiceOptions & options_r )
2691 { return _pimpl->refreshService( service, options_r ); }
2692
2693 void RepoManager::modifyService( const std::string & oldAlias, const ServiceInfo & service )
2694 { return _pimpl->modifyService( oldAlias, service ); }
2695
2697
2698 std::ostream & operator<<( std::ostream & str, const RepoManager & obj )
2699 { return str << *obj._pimpl; }
2700
2702 } // namespace zypp
CredentialManager.h
DefaultIntegral.h
for_
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
ZYPP_RETHROW
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition: Exception.h:400
ZYPP_CAUGHT
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:396
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392
ExternalProgram.h
Function.h
Gettext.h
Interface to gettext.
PL_
#define PL_(MSG1, MSG2, N)
Definition: Gettext.h:40
_
#define _(MSG)
Definition: Gettext.h:37
HistoryLog.h
InputStream.h
LogTools.h
DBG
#define DBG
Definition: Logger.h:90
MIL
#define MIL
Definition: Logger.h:91
ERR
#define ERR
Definition: Logger.h:93
WAR
#define WAR
Definition: Logger.h:92
ManagedFile.h
report
callback::SendReport< DownloadProgressReport > * report
Definition: MediaCurl.cc:70
url
Url url
Definition: MediaCurl.cc:66
MediaManager.h
MediaSetAccess.h
PathInfo.h
PluginServices.h
Pool.h
Regex.h
RepoException.h
RepoFileReader.h
Z_CHKGPG
#define Z_CHKGPG(I, N)
_root
const Pathname & _root
Definition: RepoManager.cc:143
_services
ServiceSet & _services
Definition: RepoManager.cc:450
targetDistro
std::string targetDistro
Definition: RepoManager.cc:278
OPT_PROGRESS
#define OPT_PROGRESS
Definition: RepoManager.cc:61
OUTS
#define OUTS(X)
_mid
media::MediaAccessId _mid
Definition: RepoManager.cc:185
repos
RepoInfoList repos
Definition: RepoManager.cc:277
_cmPtr
scoped_ptr< media::CredentialManager > _cmPtr
Definition: RepoManager.cc:144
RepoManager.h
ServiceFileReader.h
ServiceInfo.h
ServiceRepos.h
Target.h
TmpPath.h
ZYppCallbacks.h
ZYppFactory.h
zypp::AutoDispose
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:93
zypp::AutoDispose::resetDispose
void resetDispose()
Set no dispose function.
Definition: AutoDispose.h:162
zypp::CombinedProgressData
Progress callback from another progress.
Definition: ProgressData.h:391
zypp::Date
Store and operate on date (time_t).
Definition: Date.h:33
zypp::Date::Duration
time_t Duration
Definition: Date.h:39
zypp::Date::day
static const ValueType day
Definition: Date.h:44
zypp::Date::ValueType
time_t ValueType
Definition: Date.h:38
zypp::Date::now
static Date now()
Return the current time.
Definition: Date.h:78
zypp::DefaultIntegral
Integral type with defined initial value when default constructed.
Definition: DefaultIntegral.h:42
zypp::Digest::digest
std::string digest()
get hex string representation of the digest
Definition: Digest.cc:189
zypp::Digest::sha1
static const std::string & sha1()
sha1
Definition: Digest.cc:49
zypp::Exception
Base class for Exception.
Definition: Exception.h:146
zypp::Exception::asUserHistory
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
Definition: Exception.cc:91
zypp::Exception::asUserString
std::string asUserString() const
Translated error message as string suitable for the user.
Definition: Exception.cc:82
zypp::Exception::addHistory
void addHistory(const std::string &msg_r)
Add some message text to the history.
Definition: Exception.cc:125
zypp::Exception::remember
void remember(const Exception &old_r)
Store an other Exception as history.
Definition: Exception.cc:105
zypp::ExternalProgram
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
Definition: ExternalProgram.h:60
zypp::ExternalProgram::Arguments
std::vector< std::string > Arguments
Definition: ExternalProgram.h:64
zypp::ExternalProgram::close
int close()
Wait for the progamm to complete.
Definition: ExternalProgram.cc:456
zypp::ExternalProgram::Stderr_To_Stdout
@ Stderr_To_Stdout
Definition: ExternalProgram.h:73
zypp::ExternalProgram::command
const std::string & command() const
The command we're executing.
Definition: ExternalProgram.h:174
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:310
zypp::HistoryLog::addRepository
void addRepository(const RepoInfo &repo)
Log a newly added repository.
Definition: HistoryLog.cc:287
zypp::HistoryLog::removeRepository
void removeRepository(const RepoInfo &repo)
Log recently removed repository.
Definition: HistoryLog.cc:299
zypp::MediaSetAccess
Media access layer responsible for handling files distributed on a set of media with media change and...
Definition: MediaSetAccess.h:81
zypp::MediaSetAccess::provideFileFromUrl
static ManagedFile provideFileFromUrl(const Url &file_url, ProvideFileOptions options=PROVIDE_DEFAULT)
Provides file from url.
Definition: MediaSetAccess.cc:194
zypp::MediaSetAccess::doesFileExist
bool doesFileExist(const Pathname &file, unsigned media_nr=1)
Checks if a file exists on the specified media, with user callbacks.
Definition: MediaSetAccess.cc:225
zypp::ProgressData
Maintain [min,max] and counter (value) for progress counting.
Definition: ProgressData.h:131
zypp::ProgressData::sendTo
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
Definition: ProgressData.h:226
zypp::ProgressData::toMax
bool toMax()
Set counter value to current max value (unless no range).
Definition: ProgressData.h:273
zypp::ProgressData::name
void name(const std::string &name_r)
Set counter name.
Definition: ProgressData.h:222
zypp::ProgressData::ReceiverFnc
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
Definition: ProgressData.h:139
zypp::ProgressData::toMin
bool toMin()
Set counter value to current min value.
Definition: ProgressData.h:269
zypp::ProgressData::set
bool set(value_type val_r)
Set new counter value.
Definition: ProgressData.h:246
zypp::ProgressData::val
value_type val() const
Definition: ProgressData.h:295
zypp::RepoInfo
What is known about a repository.
Definition: RepoInfo.h:72
zypp::RepoInfo::url_set
std::list< Url > url_set
Definition: RepoInfo.h:103
zypp::RepoInfo::setBaseUrl
void setBaseUrl(const Url &url)
Clears current base URL list and adds url.
Definition: RepoInfo.cc:643
zypp::RepoInfo::type
repo::RepoType type() const
Type of repository,.
Definition: RepoInfo.cc:689
zypp::RepoInfo::baseUrlsSize
urls_size_type baseUrlsSize() const
number of repository urls
Definition: RepoInfo.cc:740
zypp::RepoInfo::url
Url url() const
Pars pro toto: The first repository url.
Definition: RepoInfo.h:131
zypp::RepoInfo::noRepo
static const RepoInfo noRepo
Represents no Repository (one with an empty alias).
Definition: RepoInfo.h:80
zypp::RepoInfo::baseUrlsEnd
urls_const_iterator baseUrlsEnd() const
iterator that points at end of repository urls
Definition: RepoInfo.cc:737
zypp::RepoInfo::setPackagesPath
void setPackagesPath(const Pathname &path)
set the path where the local packages are stored
Definition: RepoInfo.cc:665
zypp::RepoInfo::dumpAsIniOn
virtual std::ostream & dumpAsIniOn(std::ostream &str) const
Write this RepoInfo object into str in a .repo file format.
Definition: RepoInfo.cc:933
zypp::RepoInfo::path
Pathname path() const
Repository path.
Definition: RepoInfo.cc:722
zypp::RepoInfo::baseUrls
url_set baseUrls() const
The complete set of repository urls.
Definition: RepoInfo.cc:716
zypp::RepoInfo::setProbedType
void setProbedType(const repo::RepoType &t) const
This allows to adjust the RepoType lazy, from NONE to some probed value, even for const objects.
Definition: RepoInfo.cc:658
zypp::RepoInfo::baseUrlsBegin
urls_const_iterator baseUrlsBegin() const
iterator that points at begin of repository urls
Definition: RepoInfo.cc:734
zypp::RepoInfo::setMetadataPath
void setMetadataPath(const Pathname &path)
Set the path where the local metadata is stored.
Definition: RepoInfo.cc:662
zypp::RepoInfo::urls_const_iterator
transform_iterator< repo::RepoVariablesUrlReplacer, url_set::const_iterator > urls_const_iterator
Definition: RepoInfo.h:105
zypp::RepoInfo::setType
void setType(const repo::RepoType &t)
set the repository type
Definition: RepoInfo.cc:655
zypp::RepoManager
creates and provides information about known sources.
Definition: RepoManager.h:106
zypp::RepoManager::hasRepo
bool hasRepo(const std::string &alias) const
Return whether there is a known repository for alias.
Definition: RepoManager.cc:2565
zypp::RepoManager::ServiceConstIterator
ServiceSet::const_iterator ServiceConstIterator
Definition: RepoManager.h:115
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:2624
zypp::RepoManager::cleanMetadata
void cleanMetadata(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Clean local metadata.
Definition: RepoManager.cc:2603
zypp::RepoManager::~RepoManager
~RepoManager()
Dtor.
Definition: RepoManager.cc:2547
zypp::RepoManager::serviceEmpty
bool serviceEmpty() const
Gets true if no service is in RepoManager (so no one in specified location)
Definition: RepoManager.cc:2651
zypp::RepoManager::hasService
bool hasService(const std::string &alias) const
Return whether there is a known service for alias.
Definition: RepoManager.cc:2666
zypp::RepoManager::RefreshCheckStatus
RefreshCheckStatus
Possibly return state of checkIfRefreshMEtadata function.
Definition: RepoManager.h:196
zypp::RepoManager::REFRESH_NEEDED
@ REFRESH_NEEDED
refresh is needed
Definition: RepoManager.h:197
zypp::RepoManager::REPO_UP_TO_DATE
@ REPO_UP_TO_DATE
repository not changed
Definition: RepoManager.h:198
zypp::RepoManager::REPO_CHECK_DELAYED
@ REPO_CHECK_DELAYED
refresh is delayed due to settings
Definition: RepoManager.h:199
zypp::RepoManager::RepoConstIterator
RepoSet::const_iterator RepoConstIterator
Definition: RepoManager.h:120
zypp::RepoManager::addService
void addService(const std::string &alias, const Url &url)
Adds new service by it's alias and url.
Definition: RepoManager.cc:2672
zypp::RepoManager::isCached
bool isCached(const RepoInfo &info) const
Whether a repository exists in cache.
Definition: RepoManager.cc:2618
zypp::RepoManager::removeService
void removeService(const std::string &alias)
Removes service specified by its name.
Definition: RepoManager.cc:2678
zypp::RepoManager::RawMetadataRefreshPolicy
RawMetadataRefreshPolicy
Definition: RepoManager.h:129
zypp::RepoManager::RefreshIfNeeded
@ RefreshIfNeeded
Definition: RepoManager.h:130
zypp::RepoManager::RefreshForced
@ RefreshForced
Definition: RepoManager.h:131
zypp::RepoManager::RefreshIfNeededIgnoreDelay
@ RefreshIfNeededIgnoreDelay
Definition: RepoManager.h:132
zypp::RepoManager::RepoManager
RepoManager(const RepoManagerOptions &options=RepoManagerOptions())
Definition: RepoManager.cc:2543
zypp::RepoManager::getRepo
RepoInfo getRepo(const std::string &alias) const
Find RepoInfo by alias or return RepoInfo::noRepo.
Definition: RepoManager.cc:2562
zypp::RepoManager::probeService
repo::ServiceType probeService(const Url &url) const
Probe the type or the service.
Definition: RepoManager.cc:2669
zypp::RepoManager::_pimpl
RWCOW_pointer< Impl > _pimpl
Pointer to implementation.
Definition: RepoManager.h:698
zypp::RepoManager::cleanCache
void cleanCache(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
clean local cache
Definition: RepoManager.cc:2615
zypp::RepoManager::refreshServices
void refreshServices(const RefreshServiceOptions &options_r=RefreshServiceOptions())
Refreshes all enabled services.
Definition: RepoManager.cc:2684
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:2633
zypp::RepoManager::repoEmpty
bool repoEmpty() const
Definition: RepoManager.cc:2550
zypp::RepoManager::metadataPath
Pathname metadataPath(const RepoInfo &info) const
Path where the metadata is downloaded and kept.
Definition: RepoManager.cc:2594
zypp::RepoManager::ServiceSizeType
ServiceSet::size_type ServiceSizeType
Definition: RepoManager.h:116
zypp::RepoManager::RepoSet
std::set< RepoInfo > RepoSet
RepoInfo typedefs.
Definition: RepoManager.h:119
zypp::RepoManager::packagesPath
Pathname packagesPath(const RepoInfo &info) const
Path where the rpm packages are downloaded and kept.
Definition: RepoManager.cc:2597
zypp::RepoManager::cacheStatus
RepoStatus cacheStatus(const RepoInfo &info) const
Status of metadata cache.
Definition: RepoManager.cc:2609
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:2636
zypp::RepoManager::refreshMetadata
void refreshMetadata(const RepoInfo &info, RawMetadataRefreshPolicy policy=RefreshIfNeeded, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Refresh local raw cache.
Definition: RepoManager.cc:2600
zypp::RepoManager::refreshService
void refreshService(const std::string &alias, const RefreshServiceOptions &options_r=RefreshServiceOptions())
Refresh specific service.
Definition: RepoManager.cc:2687
zypp::RepoManager::serviceEnd
ServiceConstIterator serviceEnd() const
Iterator to place behind last service in internal storage.
Definition: RepoManager.cc:2660
zypp::RepoManager::RefreshService_forceRefresh
@ RefreshService_forceRefresh
Force refresh even if TTL is not reached.
Definition: RepoManager.h:145
zypp::RepoManager::RefreshService_restoreStatus
@ RefreshService_restoreStatus
Force restoring repo enabled/disabled status.
Definition: RepoManager.h:144
zypp::RepoManager::serviceBegin
ServiceConstIterator serviceBegin() const
Iterator to first service in internal storage.
Definition: RepoManager.cc:2657
zypp::RepoManager::repoSize
RepoSizeType repoSize() const
Definition: RepoManager.cc:2553
zypp::RepoManager::modifyRepository
void modifyRepository(const std::string &alias, const RepoInfo &newinfo, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Modify repository attributes.
Definition: RepoManager.cc:2642
zypp::RepoManager::services
Iterable< ServiceConstIterator > services() const
Iterate the known services.
Definition: RepoManager.h:711
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:2639
zypp::RepoManager::getRepositoryInfo
RepoInfo getRepositoryInfo(const std::string &alias, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Find a matching repository info.
Definition: RepoManager.cc:2645
zypp::RepoManager::serviceSize
ServiceSizeType serviceSize() const
Gets count of service in RepoManager (in specified location)
Definition: RepoManager.cc:2654
zypp::RepoManager::RepoSizeType
RepoSet::size_type RepoSizeType
Definition: RepoManager.h:121
zypp::RepoManager::CacheBuildPolicy
CacheBuildPolicy
Definition: RepoManager.h:136
zypp::RepoManager::BuildIfNeeded
@ BuildIfNeeded
Definition: RepoManager.h:137
zypp::RepoManager::getService
ServiceInfo getService(const std::string &alias) const
Finds ServiceInfo by alias or return ServiceInfo::noService.
Definition: RepoManager.cc:2663
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:2591
zypp::RepoManager::repoBegin
RepoConstIterator repoBegin() const
Definition: RepoManager.cc:2556
zypp::RepoManager::repos
Iterable< RepoConstIterator > repos() const
Iterate the known repositories.
Definition: RepoManager.h:707
zypp::RepoManager::buildCache
void buildCache(const RepoInfo &info, CacheBuildPolicy policy=BuildIfNeeded, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Refresh local cache.
Definition: RepoManager.cc:2612
zypp::RepoManager::RefreshServiceOptions
RefreshServiceFlags RefreshServiceOptions
Options tuning RefreshService.
Definition: RepoManager.h:150
zypp::RepoManager::getRepositoriesInService
void getRepositoriesInService(const std::string &alias, OutputIterator out) const
fill to output iterator repositories in service name.
Definition: RepoManager.h:686
zypp::RepoManager::loadFromCache
void loadFromCache(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Load resolvables into the pool.
Definition: RepoManager.cc:2621
zypp::RepoManager::ServiceSet
std::set< ServiceInfo > ServiceSet
ServiceInfo typedefs.
Definition: RepoManager.h:111
zypp::RepoManager::cleanPackages
void cleanPackages(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Clean local package cache.
Definition: RepoManager.cc:2606
zypp::RepoManager::repoEnd
RepoConstIterator repoEnd() const
Definition: RepoManager.cc:2559
zypp::RepoManager::metadataStatus
RepoStatus metadataStatus(const RepoInfo &info) const
Status of local metadata.
Definition: RepoManager.cc:2588
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:2693
zypp::RepoManager::makeStupidAlias
static std::string makeStupidAlias(const Url &url_r=Url())
Some stupid string but suitable as alias for your url if nothing better is available.
Definition: RepoManager.cc:2568
zypp::RepoManager::probe
repo::RepoType probe(const Url &url, const Pathname &path) const
Probe repo metadata type.
Definition: RepoManager.cc:2627
zypp::RepoStatus
Track changing files or directories.
Definition: RepoStatus.h:41
zypp::RepoStatus::fromCookieFile
static RepoStatus fromCookieFile(const Pathname &path)
Reads the status from a cookie file.
Definition: RepoStatus.cc:194
zypp::RepoStatus::timestamp
Date timestamp() const
The time the data were changed the last time.
Definition: RepoStatus.cc:225
zypp::RepoStatus::empty
bool empty() const
Whether the status is empty (empty checksum)
Definition: RepoStatus.cc:222
zypp::RepoStatus::saveToCookieFile
void saveToCookieFile(const Pathname &path_r) const
Save the status information to a cookie file.
Definition: RepoStatus.cc:212
zypp::Repository
Definition: Repository.h:40
zypp::Repository::systemRepoAlias
static const std::string & systemRepoAlias()
Reserved system repository alias @System .
Definition: Repository.cc:37
zypp::Repository::eraseFromPool
void eraseFromPool()
Remove this Repository from it's Pool.
Definition: Repository.cc:297
zypp::ServiceInfo
Service data.
Definition: ServiceInfo.h:37
zypp::ServiceInfo::type
repo::ServiceType type() const
Service type.
Definition: ServiceInfo.cc:108
zypp::ServiceInfo::ttl
Date::Duration ttl() const
Sugested TTL between two metadata auto-refreshs.
Definition: ServiceInfo.cc:112
zypp::ServiceInfo::setLrf
void setLrf(Date lrf_r)
Set date of last refresh.
Definition: ServiceInfo.cc:117
zypp::ServiceInfo::lrf
Date lrf() const
Date of last refresh (if known).
Definition: ServiceInfo.cc:116
zypp::ServiceInfo::repoToDisableFind
bool repoToDisableFind(const std::string &alias_r) const
Whether alias_r is mentioned in ReposToDisable.
Definition: ServiceInfo.cc:145
zypp::ServiceInfo::repoToEnableFind
bool repoToEnableFind(const std::string &alias_r) const
Whether alias_r is mentioned in ReposToEnable.
Definition: ServiceInfo.cc:124
zypp::ServiceInfo::repoStates
const RepoStates & repoStates() const
Access the remembered repository states.
Definition: ServiceInfo.cc:161
zypp::ServiceInfo::url
Url url() const
The service url.
Definition: ServiceInfo.cc:99
zypp::ServiceInfo::setProbedType
void setProbedType(const repo::ServiceType &t) const
Lazy init service type.
Definition: ServiceInfo.cc:110
zypp::ServiceInfo::RepoStates
std::map< std::string, RepoState > RepoStates
Definition: ServiceInfo.h:185
zypp::ServiceInfo::rawUrl
Url rawUrl() const
The service raw url (no variables replaced)
Definition: ServiceInfo.cc:102
zypp::ServiceInfo::addRepoToEnable
void addRepoToEnable(const std::string &alias_r)
Add alias_r to the set of ReposToEnable.
Definition: ServiceInfo.cc:127
zypp::ServiceInfo::clearReposToDisable
void clearReposToDisable()
Clear the set of ReposToDisable.
Definition: ServiceInfo.cc:157
zypp::ServiceInfo::delRepoToEnable
void delRepoToEnable(const std::string &alias_r)
Remove alias_r from the set of ReposToEnable.
Definition: ServiceInfo.cc:133
zypp::ServiceInfo::dumpAsIniOn
virtual std::ostream & dumpAsIniOn(std::ostream &str) const
Writes ServiceInfo to stream in ".service" format.
Definition: ServiceInfo.cc:173
zypp::ServiceInfo::setRepoStates
void setRepoStates(RepoStates newStates_r)
Remember a new set of repository states.
Definition: ServiceInfo.cc:162
zypp::ServiceInfo::noService
static const ServiceInfo noService
Represents an empty service.
Definition: ServiceInfo.h:61
zypp::ServiceInfo::reposToDisableEmpty
bool reposToDisableEmpty() const
Definition: ServiceInfo.cc:140
zypp::Target::targetDistribution
std::string targetDistribution() const
This is register.target attribute of the installed base product.
Definition: Target.cc:102
zypp::Url
Url manipulation class.
Definition: Url.h:92
zypp::Url::getScheme
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:528
zypp::Url::asCompleteString
std::string asCompleteString() const
Returns a complete string representation of the Url object.
Definition: Url.cc:500
zypp::Url::getHost
std::string getHost(EEncoding eflag=zypp::url::E_DECODED) const
Returns the hostname or IP from the URL authority.
Definition: Url.cc:583
zypp::ZConfig::repo_refresh_delay
unsigned repo_refresh_delay() const
Amount of time in minutes that must pass before another refresh.
Definition: ZConfig.cc:1031
zypp::ZConfig::builtinRepoSolvfilesPath
Pathname builtinRepoSolvfilesPath() const
The builtin config file value.
Definition: ZConfig.cc:976
zypp::ZConfig::repo_add_probe
bool repo_add_probe() const
Whether repository urls should be probed.
Definition: ZConfig.cc:1028
zypp::ZConfig::instance
static ZConfig & instance()
Singleton ctor.
Definition: Resolver.cc:126
zypp::ZConfig::builtinRepoPackagesPath
Pathname builtinRepoPackagesPath() const
The builtin config file value.
Definition: ZConfig.cc:979
zypp::ZConfig::builtinRepoMetadataPath
Pathname builtinRepoMetadataPath() const
The builtin config file value.
Definition: ZConfig.cc:973
zypp::externalprogram::ExternalDataSource::receiveLine
std::string receiveLine()
Read one line from the input stream.
Definition: ExternalDataSource.cc:115
zypp::filesystem::PathInfo
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:221
zypp::filesystem::PathInfo::asString
const std::string & asString() const
Return current Pathname as String.
Definition: PathInfo.h:248
zypp::filesystem::PathInfo::mtime
time_t mtime() const
Definition: PathInfo.h:376
zypp::filesystem::PathInfo::userMayRX
bool userMayRX() const
Definition: PathInfo.h:350
zypp::filesystem::PathInfo::isDir
bool isDir() const
Definition: PathInfo.h:290
zypp::filesystem::PathInfo::isFile
bool isFile() const
Definition: PathInfo.h:289
zypp::filesystem::PathInfo::isExist
bool isExist() const
Return whether valid stat info exists.
Definition: PathInfo.h:281
zypp::filesystem::PathInfo::path
const Pathname & path() const
Return current Pathname.
Definition: PathInfo.h:246
zypp::filesystem::Pathname
Pathname.
Definition: Pathname.h:45
zypp::filesystem::Pathname::dirname
Pathname dirname() const
Return all but the last component od this path.
Definition: Pathname.h:124
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition: Pathname.h:91
zypp::filesystem::Pathname::basename
std::string basename() const
Return the last component of this path.
Definition: Pathname.h:128
zypp::filesystem::Pathname::empty
bool empty() const
Test for an empty path.
Definition: Pathname.h:114
zypp::filesystem::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:235
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition: Pathname.h:110
zypp::filesystem::TmpDir
Provide a new empty temporary directory and recursively delete it when no longer needed.
Definition: TmpPath.h:178
zypp::filesystem::TmpDir::makeSibling
static TmpDir makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Definition: TmpPath.cc:295
zypp::filesystem::TmpPath::path
Pathname path() const
Definition: TmpPath.cc:146
zypp::media::MediaException
Just inherits Exception to separate media exceptions.
Definition: MediaException.h:36
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::RepoInvalidAliasException
Thrown when the repo alias is found to be invalid.
Definition: RepoException.h:104
zypp::repo::RepoNoAliasException
thrown when it was impossible to determine an alias for this repo.
Definition: RepoException.h:92
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::RepoUnknownTypeException
thrown when it was impossible to determine this repo type.
Definition: RepoException.h:143
zypp::repo::ServiceAlreadyExistsException
Service already exists and some unique attribute can't be duplicated.
Definition: RepoException.h:224
zypp::repo::ServiceException
Base Exception for service handling.
Definition: RepoException.h:176
zypp::repo::ServiceInvalidAliasException
Thrown when the repo alias is found to be invalid.
Definition: RepoException.h:213
zypp::repo::ServiceNoAliasException
Service without alias was used in an operation.
Definition: RepoException.h:201
zypp::repo::ServiceNoUrlException
Service has no or invalid url defined.
Definition: RepoException.h:235
zypp::repo::ServicePluginImmutableException
Service plugin is immutable.
Definition: RepoException.h:274
zypp::repo::ServicePluginInformalException
Service plugin has trouble providing the metadata but this should not be treated as error.
Definition: RepoException.h:263
zypp::repo::ServiceRepos
Retrieval of repository list for a service.
Definition: ServiceRepos.h:26
zypp::repo::susetags::Downloader
Downloader for SUSETags (YaST2) repositories Encapsulates all the knowledge of which files have to be...
Definition: Downloader.h:35
zypp::repo::susetags::Downloader::status
RepoStatus status(MediaSetAccess &media) override
Status of the remote repository.
Definition: Downloader.cc:35
zypp::repo::yum::Downloader
Downloader for YUM (rpm-nmd) repositories Encapsulates all the knowledge of which files have to be do...
Definition: Downloader.h:41
zypp::repo::yum::Downloader::status
RepoStatus status(MediaSetAccess &media_r) override
Status of the remote repository.
Definition: Downloader.cc:198
zypp::sat::LookupRepoAttr
Lightweight repository attribute value lookup.
Definition: LookupAttr.h:258
zypp::sat::Pool::reposErase
void reposErase(const std::string &alias_r)
Remove a Repository named alias_r.
Definition: Pool.h:112
zypp::sat::Pool::addRepoSolv
Repository addRepoSolv(const Pathname &file_r, const std::string &name_r)
Load Solvables from a solv-file into a Repository named name_r.
Definition: Pool.cc:185
zypp::sat::Pool::instance
static Pool instance()
Singleton ctor.
Definition: Pool.h:55
zypp::sat::SolvAttr::repositoryToolVersion
static const SolvAttr repositoryToolVersion
Definition: SolvAttr.h:174
zypp::TriBool
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
Definition: String.h:30
str
String related utilities and Regular expression matching.
zypp::base::NonCopyable
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition: NonCopyable.h:26
zypp::env::ZYPP_PLUGIN_APPDATA_FORCE_COLLECT
bool ZYPP_PLUGIN_APPDATA_FORCE_COLLECT()
To trigger appdata refresh unconditionally.
Definition: RepoManager.cc:71
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:598
zypp::filesystem::unlink
int unlink(const Pathname &path)
Like 'unlink'.
Definition: PathInfo.cc:662
zypp::filesystem::recursive_rmdir
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
Definition: PathInfo.cc:413
zypp::filesystem::assert_dir
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Definition: PathInfo.cc:320
zypp::filesystem::touch
int touch(const Pathname &path)
Change file's modification and access times.
Definition: PathInfo.cc:1196
zypp::filesystem::exchange
int exchange(const Pathname &lpath, const Pathname &rpath)
Exchanges two files or directories.
Definition: PathInfo.cc:718
zypp::iostr::copy
std::ostream & copy(std::istream &from_r, std::ostream &to_r)
Copy istream to ostream.
Definition: IOStream.h:50
zypp::media::MediaAccessId
unsigned int MediaAccessId
Media manager access Id type.
Definition: MediaSource.h:29
zypp::misc::testcase::TestcaseRepoType::Url
@ Url
zypp::repo
Definition: DeltaCandidates.cc:29
zypp::sat::updateSolvFileIndex
void updateSolvFileIndex(const Pathname &solvfile_r)
Create solv file content digest for zypper bash completion.
Definition: Pool.cc:286
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:330
zypp::str::numstring
std::string numstring(char n, int w=0)
Definition: String.h:286
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:36
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:426
zypp::str::hexstring
std::string hexstring(char n, int w=4)
Definition: String.h:321
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
zypp::asString
std::string asString(const DefaultIntegral< Tp, TInitial > &obj)
Definition: DefaultIntegral.h:98
zypp::readRepoFile
std::list< RepoInfo > readRepoFile(const Url &repo_file)
Parses repo_file and returns a list of RepoInfo objects corresponding to repositories found within th...
Definition: RepoManager.cc:457
zypp::operator<<
std::ostream & operator<<(std::ostream &str, const Exception &obj)
Definition: Exception.cc:147
zypp::JobReport::warning
static bool warning(const std::string &msg_r, const UserData &userData_r=UserData())
send warning text
Definition: ZYppCallbacks.h:826
zypp::JobReport::error
static bool error(const std::string &msg_r, const UserData &userData_r=UserData())
send error text
Definition: ZYppCallbacks.h:830
zypp::ProgressReportAdaptor
Definition: ZYppCallbacks.h:59
zypp::RepoManagerOptions
Repo manager settings.
Definition: RepoManager.h:54
zypp::RepoManagerOptions::makeTestSetup
static RepoManagerOptions makeTestSetup(const Pathname &root_r)
Test setup adjusting all paths to be located below one root_r directory.
Definition: RepoManager.cc:486
zypp::RepoManagerOptions::repoSolvCachePath
Pathname repoSolvCachePath
Definition: RepoManager.h:81
zypp::RepoManagerOptions::knownReposPath
Pathname knownReposPath
Definition: RepoManager.h:83
zypp::RepoManagerOptions::repoCachePath
Pathname repoCachePath
Definition: RepoManager.h:79
zypp::RepoManagerOptions::pluginsPath
Pathname pluginsPath
Definition: RepoManager.h:85
zypp::RepoManagerOptions::probe
bool probe
Definition: RepoManager.h:86
zypp::RepoManagerOptions::rootDir
Pathname rootDir
remembers root_r value for later use
Definition: RepoManager.h:96
zypp::RepoManagerOptions::knownServicesPath
Pathname knownServicesPath
Definition: RepoManager.h:84
zypp::RepoManagerOptions::repoRawCachePath
Pathname repoRawCachePath
Definition: RepoManager.h:80
zypp::RepoManagerOptions::repoPackagesCachePath
Pathname repoPackagesCachePath
Definition: RepoManager.h:82
zypp::RepoManagerOptions::RepoManagerOptions
RepoManagerOptions(const Pathname &root_r=Pathname())
Default ctor following ZConfig global settings.
Definition: RepoManager.cc:472
zypp::RepoManager::Impl
RepoManager implementation.
Definition: RepoManager.cc:521
zypp::RepoManager::Impl::repoSize
RepoSizeType repoSize() const
Definition: RepoManager.cc:576
zypp::RepoManager::Impl::saveService
void saveService(ServiceInfo &service) const
Definition: RepoManager.cc:725
zypp::RepoManager::Impl::refreshService
void refreshService(const std::string &alias, const RefreshServiceOptions &options_r)
Definition: RepoManager.cc:2067
zypp::RepoManager::Impl::init_knownRepositories
void init_knownRepositories()
Definition: RepoManager.cc:836
zypp::RepoManager::Impl::addService
void addService(const ServiceInfo &service)
Definition: RepoManager.cc:1971
zypp::RepoManager::Impl::probeService
repo::ServiceType probeService(const Url &url) const
Definition: RepoManager.cc:2509
zypp::RepoManager::Impl::clone
Impl * clone() const
clone for RWCOW_pointer
Definition: RepoManager.cc:714
zypp::RepoManager::Impl::hasRepo
bool hasRepo(const std::string &alias) const
Definition: RepoManager.cc:580
zypp::RepoManager::Impl::serviceEmpty
bool serviceEmpty() const
Definition: RepoManager.cc:635
zypp::RepoManager::Impl::reposManip
RepoSet & reposManip()
Definition: RepoManager.cc:702
zypp::RepoManager::Impl::refreshServices
void refreshServices(const RefreshServiceOptions &options_r)
Definition: RepoManager.cc:2049
zypp::RepoManager::Impl::repoEmpty
bool repoEmpty() const
Definition: RepoManager.cc:575
zypp::RepoManager::Impl::generateFilename
std::string generateFilename(const ServiceInfo &info) const
Definition: RepoManager.cc:676
zypp::RepoManager::Impl::_reposX
RepoSet _reposX
Definition: RepoManager.cc:706
zypp::RepoManager::Impl::getRepositoryInfo
RepoInfo getRepositoryInfo(const Url &url, const url::ViewOption &urlview, OPT_PROGRESS)
zypp::RepoManager::Impl::_options
RepoManagerOptions _options
Definition: RepoManager.cc:705
zypp::RepoManager::Impl::operator<<
std::ostream & operator<<(std::ostream &str, const RepoManager::Impl &obj)
Stream output.
Definition: RepoManager.cc:720
zypp::RepoManager::Impl::refreshMetadata
void refreshMetadata(const RepoInfo &info, RawMetadataRefreshPolicy policy, OPT_PROGRESS)
Definition: RepoManager.cc:1113
zypp::RepoManager::Impl::generateFilename
std::string generateFilename(const RepoInfo &info) const
Definition: RepoManager.cc:673
zypp::RepoManager::Impl::repoEnd
RepoConstIterator repoEnd() const
Definition: RepoManager.cc:578
zypp::RepoManager::Impl::buildCache
void buildCache(const RepoInfo &info, CacheBuildPolicy policy, OPT_PROGRESS)
Definition: RepoManager.cc:1276
zypp::RepoManager::Impl::serviceSize
ServiceSizeType serviceSize() const
Definition: RepoManager.cc:636
zypp::RepoManager::Impl::addRepository
void addRepository(const RepoInfo &info, OPT_PROGRESS)
Definition: RepoManager.cc:1643
zypp::RepoManager::Impl::loadFromCache
void loadFromCache(const RepoInfo &info, OPT_PROGRESS)
Definition: RepoManager.cc:1609
zypp::RepoManager::Impl::addService
void addService(const std::string &alias, const Url &url)
Definition: RepoManager.cc:651
zypp::RepoManager::Impl::removeService
void removeService(const std::string &alias)
Definition: RepoManager.cc:1993
zypp::RepoManager::Impl::getRepositoriesInService
void getRepositoriesInService(const std::string &alias, OutputIterator out) const
Definition: RepoManager.cc:689
zypp::RepoManager::Impl::cleanMetadata
void cleanMetadata(const RepoInfo &info, OPT_PROGRESS)
Definition: RepoManager.cc:1256
zypp::RepoManager::Impl::cacheStatus
RepoStatus cacheStatus(const RepoInfo &info) const
Definition: RepoManager.cc:618
zypp::RepoManager::Impl::removeRepository
void removeRepository(const RepoInfo &info, OPT_PROGRESS)
Definition: RepoManager.cc:1774
zypp::RepoManager::Impl::packagesPath
Pathname packagesPath(const RepoInfo &info) const
Definition: RepoManager.cc:593
zypp::RepoManager::Impl::cleanPackages
void cleanPackages(const RepoInfo &info, OPT_PROGRESS)
Definition: RepoManager.cc:1266
zypp::RepoManager::Impl::repoBegin
RepoConstIterator repoBegin() const
Definition: RepoManager.cc:577
zypp::RepoManager::Impl::_services
ServiceSet _services
Definition: RepoManager.cc:707
zypp::RepoManager::Impl::addRepositories
void addRepositories(const Url &url, OPT_PROGRESS)
Definition: RepoManager.cc:1715
zypp::RepoManager::Impl::getService
ServiceInfo getService(const std::string &alias) const
Definition: RepoManager.cc:643
zypp::RepoManager::Impl::modifyService
void modifyService(const std::string &oldAlias, const ServiceInfo &newService)
Definition: RepoManager.cc:2434
zypp::RepoManager::Impl::probeCache
repo::RepoType probeCache(const Pathname &path_r) const
Probe Metadata in a local cache directory.
Definition: RepoManager.cc:1529
zypp::RepoManager::Impl::serviceEnd
ServiceConstIterator serviceEnd() const
Definition: RepoManager.cc:638
zypp::RepoManager::Impl::getRepositoryInfo
RepoInfo getRepositoryInfo(const std::string &alias, OPT_PROGRESS)
zypp::RepoManager::Impl::touchIndexFile
void touchIndexFile(const RepoInfo &info)
Definition: RepoManager.cc:951
zypp::RepoManager::Impl::Impl
Impl(const RepoManagerOptions &opt)
Definition: RepoManager.cc:523
zypp::RepoManager::Impl::checkIfToRefreshMetadata
RefreshCheckStatus checkIfToRefreshMetadata(const RepoInfo &info, const Url &url, RawMetadataRefreshPolicy policy)
Definition: RepoManager.cc:988
zypp::RepoManager::Impl::metadataPath
Pathname metadataPath(const RepoInfo &info) const
Definition: RepoManager.cc:590
zypp::RepoManager::Impl::isCached
bool isCached(const RepoInfo &info) const
Definition: RepoManager.cc:615
zypp::RepoManager::Impl::_reposDirty
DefaultIntegral< bool, false > _reposDirty
Definition: RepoManager.cc:709
zypp::RepoManager::Impl::cleanCache
void cleanCache(const RepoInfo &info, OPT_PROGRESS)
Definition: RepoManager.cc:1595
zypp::RepoManager::Impl::removeService
void removeService(const ServiceInfo &service)
Definition: RepoManager.cc:655
zypp::RepoManager::Impl::setCacheStatus
void setCacheStatus(const RepoInfo &info, const RepoStatus &status)
Definition: RepoManager.cc:679
zypp::RepoManager::Impl::serviceBegin
ServiceConstIterator serviceBegin() const
Definition: RepoManager.cc:637
zypp::RepoManager::Impl::refreshService
void refreshService(const ServiceInfo &service, const RefreshServiceOptions &options_r)
Definition: RepoManager.cc:661
zypp::RepoManager::Impl::init_knownServices
void init_knownServices()
Definition: RepoManager.cc:774
zypp::RepoManager::Impl::cleanCacheDirGarbage
void cleanCacheDirGarbage(OPT_PROGRESS)
Definition: RepoManager.cc:1548
zypp::RepoManager::Impl::repos
const RepoSet & repos() const
Definition: RepoManager.cc:701
zypp::RepoManager::Impl::probe
repo::RepoType probe(const Url &url, const Pathname &path=Pathname()) const
Probe the metadata type of a repository located at url.
Definition: RepoManager.cc:1440
zypp::RepoManager::Impl::metadataStatus
RepoStatus metadataStatus(const RepoInfo &info) const
Definition: RepoManager.cc:908
zypp::RepoManager::Impl::getRepo
RepoInfo getRepo(const std::string &alias) const
Definition: RepoManager.cc:583
zypp::RepoManager::Impl::generateNonExistingName
Pathname generateNonExistingName(const Pathname &dir, const std::string &basefilename) const
Generate a non existing filename in a directory, using a base name.
Definition: RepoManager.cc:759
zypp::RepoManager::Impl::modifyRepository
void modifyRepository(const std::string &alias, const RepoInfo &newinfo_r, OPT_PROGRESS)
Definition: RepoManager.cc:1863
zypp::RepoManager::Impl::hasService
bool hasService(const std::string &alias) const
Definition: RepoManager.cc:640
zypp::RepoManager::Impl::~Impl
~Impl()
Definition: RepoManager.cc:530
zypp::RepoManager::MatchServiceAlias
Functor thats filter RepoInfo by service which it belongs to.
Definition: RepoManager.h:642
zypp::callback::SendReport
Definition: Callback.h:237
zypp::media::ScopedDisableMediaChangeReport
Temporarily disable MediaChangeReport Sometimes helpful to suppress interactive messages connected to...
Definition: ZYppCallbacks.h:346
zypp::repo::RepoType
Repository type enumeration.
Definition: RepoType.h:28
zypp::repo::RepoType::YAST2
static const RepoType YAST2
Definition: RepoType.h:30
zypp::repo::RepoType::toEnum
Type toEnum() const
Definition: RepoType.h:48
zypp::repo::RepoType::RPMMD
static const RepoType RPMMD
Definition: RepoType.h:29
zypp::repo::RepoType::NONE
static const RepoType NONE
Definition: RepoType.h:32
zypp::repo::RepoType::RPMPLAINDIR
static const RepoType RPMPLAINDIR
Definition: RepoType.h:31
zypp::repo::ServiceType
Service type enumeration.
Definition: ServiceType.h:27
zypp::repo::ServiceType::NONE
static const ServiceType NONE
No service set.
Definition: ServiceType.h:34
zypp::repo::ServiceType::RIS
static const ServiceType RIS
Repository Index Service (RIS) (formerly known as 'Novell Update' (NU) service)
Definition: ServiceType.h:32
zypp::str::Format
Convenient building of std::string with boost::format.
Definition: String.h:250
zypp::str::Str
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:209
zypp::url::ViewOption
Url::asString() view options.
Definition: UrlBase.h:40
Downloader.h
Downloader.h