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