libzypp 17.31.23
RepoMirrorList.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
13#include <iostream>
14#include <vector>
15#include <time.h>
17#include <zypp-curl/parser/MetaLinkParser>
18#include <zypp/MediaSetAccess.h>
19#include <zypp/base/LogTools.h>
20#include <zypp/ZConfig.h>
21#include <zypp/PathInfo.h>
22
23
25namespace zypp
26{
28 namespace repo
29 {
30
32 namespace
33 {
41 struct RepoMirrorListTempProvider
42 {
43 RepoMirrorListTempProvider()
44 {}
45 RepoMirrorListTempProvider( const Pathname & localfile_r )
46 : _localfile( localfile_r )
47 {}
48 RepoMirrorListTempProvider( const Url & url_r )
49 {
50 Url abs_url( url_r );
51 abs_url.setPathName( "/" );
52 abs_url.setQueryParam( "mediahandler", "curl" );
53 _access.reset( new MediaSetAccess( abs_url ) );
54 _localfile = _access->provideFile( url_r.getPathName() );
55 }
56
57 const Pathname & localfile() const
58 { return _localfile; }
59
60 private:
62 Pathname _localfile;
63 };
65
66 inline std::vector<Url> RepoMirrorListParseXML( const Pathname &tmpfile )
67 {
68 InputStream tmpfstream (tmpfile);
69 media::MetaLinkParser metalink;
70 metalink.parse(tmpfstream);
71 return metalink.getUrls();
72 }
73
74 inline std::vector<Url> RepoMirrorListParseTXT( const Pathname &tmpfile )
75 {
76 InputStream tmpfstream (tmpfile);
77 std::vector<Url> my_urls;
78 std::string tmpurl;
79 while (getline(tmpfstream.stream(), tmpurl))
80 {
81 if ( tmpurl[0] == '#' )
82 continue;
83 try {
84 my_urls.push_back(Url(tmpurl));
85 }
86 catch (...)
87 {;} // ignore malformed urls
88 }
89 return my_urls;
90 }
91
93 inline std::vector<Url> RepoMirrorListParse( const Url & url_r, const Pathname & listfile_r, bool mirrorListForceMetalink_r )
94 {
95 USR << url_r << " " << listfile_r << endl;
96
97 std::vector<Url> mirrorurls;
98 if ( mirrorListForceMetalink_r || url_r.asString().find( "/metalink" ) != std::string::npos )
99 mirrorurls = RepoMirrorListParseXML( listfile_r );
100 else
101 mirrorurls = RepoMirrorListParseTXT( listfile_r );
102
103
104 std::vector<Url> ret;
105 for ( auto & murl : mirrorurls )
106 {
107 if ( murl.getScheme() != "rsync" )
108 {
109 size_t delpos = murl.getPathName().find("repodata/repomd.xml");
110 if( delpos != std::string::npos )
111 {
112 murl.setPathName( murl.getPathName().erase(delpos) );
113 }
114 ret.push_back( murl );
115
116 if ( ret.size() >= 4 ) // why 4?
117 break;
118 }
119 }
120 return ret;
121 }
122
123 } // namespace
125
126 RepoMirrorList::RepoMirrorList( const Url & url_r, const Pathname & metadatapath_r, bool mirrorListForceMetalink_r )
127 {
128 if ( url_r.getScheme() == "file" )
129 {
130 // never cache for local mirrorlist
131 _urls = RepoMirrorListParse( url_r, url_r.getPathName(), mirrorListForceMetalink_r );
132 }
133 else if ( ! PathInfo( metadatapath_r).isDir() )
134 {
135 // no cachedir
136 RepoMirrorListTempProvider provider( url_r ); // RAII: lifetime of any downloaded files
137 _urls = RepoMirrorListParse( url_r, provider.localfile(), mirrorListForceMetalink_r );
138 }
139 else
140 {
141 // have cachedir
142 Pathname cachefile( metadatapath_r );
143 if ( mirrorListForceMetalink_r || url_r.asString().find( "/metalink" ) != std::string::npos )
144 cachefile /= "mirrorlist.xml";
145 else
146 cachefile /= "mirrorlist.txt";
147
148 zypp::filesystem::PathInfo cacheinfo( cachefile );
149 if ( !cacheinfo.isFile() || cacheinfo.mtime() < time(NULL) - (long) ZConfig::instance().repo_refresh_delay() * 60 )
150 {
151 DBG << "Getting MirrorList from URL: " << url_r << endl;
152 RepoMirrorListTempProvider provider( url_r ); // RAII: lifetime of downloaded file
153
154 // Create directory, if not existing
155 DBG << "Copy MirrorList file to " << cachefile << endl;
156 zypp::filesystem::assert_dir( metadatapath_r );
157 zypp::filesystem::hardlinkCopy( provider.localfile(), cachefile );
158 }
159
160 _urls = RepoMirrorListParse( url_r, cachefile, mirrorListForceMetalink_r );
161 if( _urls.empty() )
162 {
163 DBG << "Removing Cachefile as it contains no URLs" << endl;
164 zypp::filesystem::unlink( cachefile );
165 }
166 }
167 }
168
170 } // namespace repo
173} // namespace zypp
shared_ptr< MediaSetAccess > _access
Pathname _localfile
Url manipulation class.
Definition: Url.h:92
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:533
std::string asString() const
Returns a default string representation of the Url object.
Definition: Url.cc:497
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
Definition: Url.cc:604
static ZConfig & instance()
Singleton ctor.
Definition: ZConfig.cc:922
Wrapper class for stat/lstat.
Definition: PathInfo.h:221
time_t mtime() const
Definition: PathInfo.h:376
RepoMirrorList(const Url &url_r, const Pathname &metadatapath_r, bool mirrorListForceMetalink_r)
std::vector< Url > _urls
int unlink(const Pathname &path)
Like 'unlink'.
Definition: PathInfo.cc:700
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Definition: PathInfo.cc:319
int hardlinkCopy(const Pathname &oldpath, const Pathname &newpath)
Create newpath as hardlink or copy of oldpath.
Definition: PathInfo.cc:883
std::string getline(std::istream &str)
Read one line from stream.
Definition: IOStream.cc:33
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
constexpr std::string_view Url("url")
#define DBG
Definition: Logger.h:95
#define USR
Definition: Logger.h:101