libzypp 17.34.1
rpmmd.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
9#include "rpmmd.h"
10#include <zypp-core/zyppng/ui/ProgressObserver>
11#include <zypp-media/ng/ProvideSpec>
12#include <zypp/ng/Context>
13
20
22
23 namespace {
24
25 using namespace zyppng::operators;
26
27 template<class Executor, class OpType>
28 struct StatusLogic : public LogicBase<Executor, OpType>{
29 ZYPP_ENABLE_LOGIC_BASE(Executor, OpType);
30
31 public:
32
33 using DlContextRefType = std::conditional_t<zyppng::detail::is_async_op_v<OpType>, repo::AsyncDownloadContextRef, repo::SyncDownloadContextRef>;
34 using ZyppContextType = typename DlContextRefType::element_type::ContextType;
35 using ProvideType = typename ZyppContextType::ProvideType;
36 using MediaHandle = typename ProvideType::MediaHandle;
37 using ProvideRes = typename ProvideType::Res;
38
39 StatusLogic( DlContextRefType ctx, MediaHandle &&media )
40 : _ctx(std::move(ctx))
41 , _handle(std::move(media))
42 {}
43
44 MaybeAsyncRef<expected<zypp::RepoStatus>> execute() {
45 return _ctx->zyppContext()->provider()->provide( _handle, _ctx->repoInfo().path() / "/repodata/repomd.xml" , ProvideFileSpec() )
46 | [this]( expected<ProvideRes> repomdFile ) {
47
48 if ( !repomdFile )
50
51 zypp::RepoStatus status ( repomdFile->file() );
52
53 if ( !status.empty() && _ctx->repoInfo ().requireStatusWithMediaFile()) {
54 return _ctx->zyppContext()->provider()->provide( _handle, "/media.1/media" , ProvideFileSpec())
55 | [status = std::move(status)]( expected<ProvideRes> mediaFile ) mutable {
56 if ( mediaFile ) {
57 return make_expected_success( status && zypp::RepoStatus( mediaFile->file()) );
58 }
59 return make_expected_success( std::move(status) );
60 };
61 }
62 return makeReadyResult( make_expected_success(std::move(status)) );
63 };
64 }
65
66 DlContextRefType _ctx;
67 MediaHandle _handle;
68 };
69 }
70
71 AsyncOpRef<expected<zypp::RepoStatus> > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
72 {
73 return SimpleExecutor< StatusLogic, AsyncOp<expected<zypp::RepoStatus>> >::run( std::move(dl), std::move(mediaHandle) );
74 }
75
76 expected<zypp::RepoStatus> repoStatus(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle)
77 {
78 return SimpleExecutor< StatusLogic, SyncOp<expected<zypp::RepoStatus>> >::run( std::move(dl), std::move(mediaHandle) );
79 }
80
81
82 namespace {
83
84 using namespace zyppng::operators;
85
86 template<class Executor, class OpType>
87 struct DlLogic : public LogicBase<Executor, OpType>, private zypp::repo::yum::RepomdFileCollector {
88
89 ZYPP_ENABLE_LOGIC_BASE(Executor, OpType);
90 public:
91
92 using DlContextRefType = std::conditional_t<zyppng::detail::is_async_op_v<OpType>, repo::AsyncDownloadContextRef, repo::SyncDownloadContextRef>;
93 using ZyppContextType = typename DlContextRefType::element_type::ContextType;
94 using ProvideType = typename ZyppContextType::ProvideType;
95 using MediaHandle = typename ProvideType::MediaHandle;
96 using ProvideRes = typename ProvideType::Res;
97
98 DlLogic( DlContextRefType ctx, MediaHandle &&mediaHandle, ProgressObserverRef &&progressObserver )
99 : zypp::repo::yum::RepomdFileCollector( ctx->destDir() )
100 , _ctx( std::move(ctx))
101 , _mediaHandle(std::move(mediaHandle))
102 , _progressObserver(std::move(progressObserver))
103 {}
104
105 auto execute() {
106 // download media file here
107 return RepoDownloaderWorkflow::downloadMediaInfo( _mediaHandle, _ctx->destDir() )
108 | [this]( expected<zypp::ManagedFile> &&mediaInfo ) {
109
110 // remember the media info if we had one
111 if ( mediaInfo ) _ctx->files().push_back ( std::move(mediaInfo.get()) );
112
113 if ( _progressObserver ) _progressObserver->inc();
114
115 return RepoDownloaderWorkflow::downloadMasterIndex( _ctx, _mediaHandle, _ctx->repoInfo().path() / "/repodata/repomd.xml" )
116 | inspect( incProgress( _progressObserver ) )
117 | and_then( [this] ( DlContextRefType && ) {
118
119 zypp::Pathname repomdPath = _ctx->files().front();
120 std::vector<zypp::OnMediaLocation> requiredFiles;
121 try {
122 zypp::parser::yum::RepomdFileReader reader( repomdPath, [this]( const zypp::OnMediaLocation & loc_r, const std::string & typestr_r ){ return collect( loc_r, typestr_r ); });
123 finalize([&]( const zypp::OnMediaLocation &file ){
124 if ( file.medianr () != 1 ) {
125 // ALL repo files NEED to come from media nr 1 , otherwise we fail
126 ZYPP_THROW(zypp::repo::RepoException( _ctx->repoInfo(), "Repo can only require metadata files from primary medium."));
127 }
128 requiredFiles.push_back( file );
129 });
130 } catch ( ... ) {
131 return makeReadyResult(expected<DlContextRefType>::error( std::current_exception() ) );
132 }
133
134 // add the required files to the base steps
135 if ( _progressObserver ) _progressObserver->setBaseSteps ( _progressObserver->baseSteps () + requiredFiles.size() );
136
137 return transform_collect ( std::move(requiredFiles), [this]( zypp::OnMediaLocation file ) {
138
139 return DownloadWorkflow::provideToCacheDir( _ctx, _mediaHandle, file.filename(), ProvideFileSpec(file) )
140 | inspect ( incProgress( _progressObserver ) );
141
142 }) | and_then ( [this]( std::vector<zypp::ManagedFile> &&dlFiles ) {
143 auto &downloadedFiles = _ctx->files();
144 downloadedFiles.insert( downloadedFiles.end(), std::make_move_iterator(dlFiles.begin()), std::make_move_iterator(dlFiles.end()) );
145 return expected<DlContextRefType>::success( std::move(_ctx) );
146 });
147 });
148
149 } | finishProgress( _progressObserver );
150 }
151
152 private:
153
154 const zypp::RepoInfo &repoInfo() const override {
155 return _ctx->repoInfo();
156 }
157
158 const zypp::filesystem::Pathname &deltaDir() const override {
159 return _ctx->deltaDir();
160 }
161
162 DlContextRefType _ctx;
163 MediaHandle _mediaHandle;
164 ProgressObserverRef _progressObserver;
165 };
166 }
167
168 AsyncOpRef<expected<repo::AsyncDownloadContextRef> > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
169 {
170 return SimpleExecutor< DlLogic, AsyncOp<expected<repo::AsyncDownloadContextRef>> >::run( std::move(dl), std::move(mediaHandle), std::move(progressObserver) );
171 }
172
173 expected<repo::SyncDownloadContextRef> download(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, ProgressObserverRef progressObserver)
174 {
175 return SimpleExecutor< DlLogic, SyncOp<expected<repo::SyncDownloadContextRef>> >::run( std::move(dl), std::move(mediaHandle), std::move(progressObserver) );
176 }
177
178
179}
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.
What is known about a repository.
Definition RepoInfo.h:72
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...
A ProvideRes object is a reference counted ownership of a resource in the cache provided by a Provide...
Definition provideres.h:36
static expected success(ConsParams &&...params)
Definition expected.h:115
#define ZYPP_ENABLE_LOGIC_BASE(Executor, OpType)
Definition Arch.h:364
typename conditional< B, T, F >::type conditional_t
Definition TypeTraits.h:39
Easy-to use interface to the ZYPP dependency resolver.
AsyncOpRef< expected< zypp::ManagedFile > > provideToCacheDir(AsyncCacheProviderContextRef cacheContext, ProvideMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec)
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > downloadMasterIndex(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r)
auto downloadMediaInfo(MediaHandle &&mediaHandle, const zypp::filesystem::Pathname &destdir)
Downloader workspace for YUM (rpm-nmd) repositories Encapsulates all the knowledge of which files hav...
Definition rpmmd.cc:21
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
Definition rpmmd.cc:168
AsyncOpRef< expected< zypp::RepoStatus > > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
Definition rpmmd.cc:71
auto transform_collect(Transformation &&f)
Definition expected.h:637
auto and_then(Fun &&function)
Definition expected.h:554
auto finishProgress(ProgressObserverRef progressObserver)
detail::collect_helper collect()
Definition expected.h:581
auto incProgress(ProgressObserverRef progressObserver, double progrIncrease=1.0, std::optional< std::string > newStr={})
auto inspect(Fun &&function)
Definition expected.h:568
std::conditional_t< isAsync, AsyncOpRef< T >, T > makeReadyResult(T &&result)
Definition asyncop.h:297
std::shared_ptr< AsyncOp< T > > AsyncOpRef
Definition asyncop.h:255
static expected< std::decay_t< Type >, Err > make_expected_success(Type &&t)
Definition expected.h:341
MediaHandle _mediaHandle
Definition rpmmd.cc:163
DlContextRefType _ctx
Definition rpmmd.cc:66
MediaHandle _handle
Definition rpmmd.cc:67
ProgressObserverRef _progressObserver
Definition rpmmd.cc:164
Helper filtering the files offered by a RepomdFileReader.