libzypp 17.38.3
rpmmd.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
9#include "rpmmd.h"
11#include <zypp-core/ng/ui/ProgressObserver>
12#include <zypp-media/ng/ProvideSpec>
13#include <zypp/ng/Context>
14
15
20
21#undef ZYPP_BASE_LOGGER_LOGGROUP
22#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::repomanager"
23
25
26 namespace {
27
28 using namespace zyppng::operators;
29
30 struct StatusLogic {
31
32 public:
33 using MediaHandle = typename Provide::MediaHandle;
34 using ProvideRes = typename Provide::Res;
35
36 StatusLogic( repo::DownloadContextRef ctx, MediaHandle &&media )
37 : _ctx(std::move(ctx))
38 , _handle(std::move(media))
39 {}
40
41 MaybeAwaitable<expected<zypp::RepoStatus>> execute() {
42 return _ctx->zyppContext()->provider()->provide( _handle, _ctx->repoInfo().path() / "/repodata/repomd.xml" , ProvideFileSpec().setMirrorsAllowed(false) )
43 | [this]( expected<ProvideRes> repomdFile ) {
44
45 if ( !repomdFile )
46 return makeReadyTask( make_expected_success (zypp::RepoStatus() ));
47
48 zypp::RepoStatus status ( repomdFile->file() );
49
50 if ( !status.empty() && _ctx->repoInfo ().requireStatusWithMediaFile()) {
51 return _ctx->zyppContext()->provider()->provide( _handle, "/media.1/media" , ProvideFileSpec().setMirrorsAllowed(false) )
52 | [status = std::move(status)]( expected<ProvideRes> mediaFile ) mutable {
53 if ( mediaFile ) {
54 return make_expected_success( status && zypp::RepoStatus( mediaFile->file()) );
55 }
56 return make_expected_success( std::move(status) );
57 };
58 }
59 return makeReadyTask( make_expected_success(std::move(status)) );
60 };
61 }
62
63 repo::DownloadContextRef _ctx;
64 MediaHandle _handle;
65 };
66 }
67
68 MaybeAwaitable<expected<zypp::RepoStatus> > repoStatus( repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle)
69 {
70 StatusLogic impl( std::move(dl), std::move(mediaHandle) );
71 zypp_co_return zypp_co_await( impl.execute() );
72 }
73
74
75 namespace {
76
77 using namespace zyppng::operators;
78
79 struct DlLogic : private zypp::repo::yum::RepomdFileCollector {
80
81 public:
82 using MediaHandle = typename Provide::MediaHandle;
83 using ProvideRes = typename Provide::Res;
84
85 DlLogic( repo::DownloadContextRef ctx, MediaHandle &&mediaHandle, ProgressObserverRef &&progressObserver )
86 : zypp::repo::yum::RepomdFileCollector( ctx->destDir() )
87 , _ctx( std::move(ctx))
88 , _mediaHandle(std::move(mediaHandle))
89 , _progressObserver(std::move(progressObserver))
90 {}
91
92 auto execute() {
93 // download media file here
94 return RepoDownloaderWorkflow::downloadMediaInfo( _mediaHandle, _ctx->destDir() )
95 | [this]( expected<zypp::ManagedFile> &&mediaInfo ) {
96
97 // remember the media info if we had one
98 if ( mediaInfo ) _ctx->files().push_back ( std::move(mediaInfo.get()) );
99
100 if ( _progressObserver ) _progressObserver->inc();
101
102 return RepoDownloaderWorkflow::downloadMasterIndex( _ctx, _mediaHandle, _ctx->repoInfo().path() / "/repodata/repomd.xml" )
103 | inspect( incProgress( _progressObserver ) )
104 | and_then( [this] ( repo::DownloadContextRef && ) {
105
106 zypp::Pathname repomdPath = _ctx->files().front();
107 std::vector<zypp::OnMediaLocation> requiredFiles;
108 try {
109 zypp::parser::yum::RepomdFileReader reader( repomdPath, [this]( const zypp::OnMediaLocation & loc_r, const std::string & typestr_r ){ return collect( loc_r, typestr_r ); });
110 finalize([&]( const zypp::OnMediaLocation &file ){
111 if ( file.medianr () != 1 ) {
112 // ALL repo files NEED to come from media nr 1 , otherwise we fail
113 ZYPP_THROW(zypp::repo::RepoException( _ctx->repoInfo(), "Repo can only require metadata files from primary medium."));
114 }
115 requiredFiles.push_back( file );
116 });
117 } catch ( ... ) {
119 }
120
121 // add the required files to the base steps
122 if ( _progressObserver ) _progressObserver->setBaseSteps ( _progressObserver->baseSteps () + requiredFiles.size() );
123
124 return transform_collect ( std::move(requiredFiles), [this]( zypp::OnMediaLocation file ) {
125
126 return DownloadWorkflow::provideToCacheDir( _ctx, _mediaHandle, file.filename(), ProvideFileSpec(file) )
127 | inspect ( incProgress( _progressObserver ) );
128
129 }) | and_then ( [this]( std::vector<zypp::ManagedFile> &&dlFiles ) {
130 auto &downloadedFiles = _ctx->files();
131 downloadedFiles.insert( downloadedFiles.end(), std::make_move_iterator(dlFiles.begin()), std::make_move_iterator(dlFiles.end()) );
132 return expected< repo::DownloadContextRef>::success( std::move(_ctx) );
133 });
134 });
135
136 } | finishProgress( _progressObserver );
137 }
138
139 private:
140
141 const zypp::RepoInfo &repoInfo() const override {
142 return _ctx->repoInfo();
143 }
144
145 const zypp::filesystem::Pathname &deltaDir() const override {
146 return _ctx->deltaDir();
147 }
148
149 repo::DownloadContextRef _ctx;
150 MediaHandle _mediaHandle;
151 ProgressObserverRef _progressObserver;
152 };
153 }
154
155 MaybeAwaitable<expected< repo::DownloadContextRef> > download( repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
156 {
157 DlLogic impl( std::move(dl), std::move(mediaHandle), std::move(progressObserver) );
158 zypp_co_return zypp_co_await( impl.execute() );
159 }
160
161
162}
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
Definition Exception.h:471
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
Interface of repomd.xml file reader.
Describes a resource file located on a medium.
const Pathname & filename() const
The path to the resource on the medium.
unsigned medianr() const
The media number the resource is located on.
Track changing files or directories.
Definition RepoStatus.h:41
bool empty() const
Whether the status is empty (empty checksum).
Reads through a repomd.xml file and collects type, location, checksum and other data about metadata f...
ProvideRes Res
Definition provide.h:111
ProvideMediaHandle MediaHandle
Definition provide.h:109
static expected success(ConsParams &&...params)
Definition expected.h:178
Definition ansi.h:855
Easy-to use interface to the ZYPP dependency resolver.
MaybeAwaitable< expected< zypp::ManagedFile > > provideToCacheDir(CacheProviderContextRef cacheContext, ProvideMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec)
auto downloadMediaInfo(MediaHandle &&mediaHandle, const zypp::filesystem::Pathname &destdir)
MaybeAwaitable< expected< repo::DownloadContextRef > > downloadMasterIndex(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r)
Downloader workspace for YUM (rpm-nmd) repositories Encapsulates all the knowledge of which files hav...
Definition rpmmd.cc:24
MaybeAwaitable< expected< repo::DownloadContextRef > > download(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
Definition rpmmd.cc:155
MaybeAwaitable< expected< zypp::RepoStatus > > repoStatus(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle)
Definition rpmmd.cc:68
auto transform_collect(Transformation &&f)
Definition expected.h:778
auto and_then(Fun &&function)
Definition expected.h:708
auto finishProgress(ProgressObserverRef progressObserver, ProgressObserver::FinishResult result=ProgressObserver::Success)
detail::collect_helper collect()
Definition expected.h:735
auto incProgress(ProgressObserverRef progressObserver, double progrIncrease=1.0, std::optional< std::string > newStr={})
auto inspect(Fun &&function)
Definition expected.h:722
static expected< std::decay_t< Type >, Err > make_expected_success(Type &&t)
Definition expected.h:470
Helper filtering the files offered by a RepomdFileReader.