libzypp 17.37.17
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
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 template<class Executor, class OpType>
31 struct StatusLogic : public LogicBase<Executor, OpType>{
32 ZYPP_ENABLE_LOGIC_BASE(Executor, OpType);
33
34 public:
35
36 using DlContextRefType = std::conditional_t<zyppng::detail::is_async_op_v<OpType>, repo::AsyncDownloadContextRef, repo::SyncDownloadContextRef>;
37 using ZyppContextType = typename DlContextRefType::element_type::ContextType;
38 using ProvideType = typename ZyppContextType::ProvideType;
39 using MediaHandle = typename ProvideType::MediaHandle;
40 using ProvideRes = typename ProvideType::Res;
41
42 StatusLogic( DlContextRefType ctx, MediaHandle &&media )
43 : _ctx(std::move(ctx))
44 , _handle(std::move(media))
45 {}
46
47 MaybeAsyncRef<expected<zypp::RepoStatus>> execute() {
48 return _ctx->zyppContext()->provider()->provide( _handle, _ctx->repoInfo().path() / "/repodata/repomd.xml" , ProvideFileSpec().setMirrorsAllowed(false) )
49 | [this]( expected<ProvideRes> repomdFile ) {
50
51 if ( !repomdFile )
53
54 zypp::RepoStatus status ( repomdFile->file() );
55
56 if ( !status.empty() && _ctx->repoInfo ().requireStatusWithMediaFile()) {
57 return _ctx->zyppContext()->provider()->provide( _handle, "/media.1/media" , ProvideFileSpec().setMirrorsAllowed(false) )
58 | [status = std::move(status)]( expected<ProvideRes> mediaFile ) mutable {
59 if ( mediaFile ) {
60 return make_expected_success( status && zypp::RepoStatus( mediaFile->file()) );
61 }
62 return make_expected_success( std::move(status) );
63 };
64 }
65 return makeReadyResult( make_expected_success(std::move(status)) );
66 };
67 }
68
69 DlContextRefType _ctx;
70 MediaHandle _handle;
71 };
72 }
73
74 AsyncOpRef<expected<zypp::RepoStatus> > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
75 {
76 return SimpleExecutor< StatusLogic, AsyncOp<expected<zypp::RepoStatus>> >::run( std::move(dl), std::move(mediaHandle) );
77 }
78
79 expected<zypp::RepoStatus> repoStatus(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle)
80 {
81 return SimpleExecutor< StatusLogic, SyncOp<expected<zypp::RepoStatus>> >::run( std::move(dl), std::move(mediaHandle) );
82 }
83
84
85 namespace {
86
87 using namespace zyppng::operators;
88
89 template<class Executor, class OpType>
90 struct DlLogic : public LogicBase<Executor, OpType>, private zypp::repo::yum::RepomdFileCollector {
91
92 ZYPP_ENABLE_LOGIC_BASE(Executor, OpType);
93 public:
94
95 using DlContextRefType = std::conditional_t<zyppng::detail::is_async_op_v<OpType>, repo::AsyncDownloadContextRef, repo::SyncDownloadContextRef>;
96 using ZyppContextType = typename DlContextRefType::element_type::ContextType;
97 using ProvideType = typename ZyppContextType::ProvideType;
98 using MediaHandle = typename ProvideType::MediaHandle;
99 using ProvideRes = typename ProvideType::Res;
100
101 DlLogic( DlContextRefType ctx, MediaHandle &&mediaHandle, ProgressObserverRef &&progressObserver )
102 : zypp::repo::yum::RepomdFileCollector( ctx->destDir() )
103 , _ctx( std::move(ctx))
104 , _mediaHandle(std::move(mediaHandle))
105 , _progressObserver(std::move(progressObserver))
106 {}
107
108 auto execute() {
109 // download media file here
110 return RepoDownloaderWorkflow::downloadMediaInfo( _mediaHandle, _ctx->destDir() )
111 | [this]( expected<zypp::ManagedFile> &&mediaInfo ) {
112
113 // remember the media info if we had one
114 if ( mediaInfo ) _ctx->files().push_back ( std::move(mediaInfo.get()) );
115
116 if ( _progressObserver ) _progressObserver->inc();
117
118 return RepoDownloaderWorkflow::downloadMasterIndex( _ctx, _mediaHandle, _ctx->repoInfo().path() / "/repodata/repomd.xml" )
119 | inspect( incProgress( _progressObserver ) )
120 | and_then( [this] ( DlContextRefType && ) {
121
122 zypp::Pathname repomdPath = _ctx->files().front();
123 std::vector<zypp::OnMediaLocation> requiredFiles;
124 try {
125 zypp::parser::yum::RepomdFileReader reader( repomdPath, [this]( const zypp::OnMediaLocation & loc_r, const std::string & typestr_r ){ return collect( loc_r, typestr_r ); });
126 finalize([&]( const zypp::OnMediaLocation &file ){
127 if ( file.medianr () != 1 ) {
128 // ALL repo files NEED to come from media nr 1 , otherwise we fail
129 ZYPP_THROW(zypp::repo::RepoException( _ctx->repoInfo(), "Repo can only require metadata files from primary medium."));
130 }
131 requiredFiles.push_back( file );
132 });
133 } catch ( ... ) {
135 }
136
137 // add the required files to the base steps
138 if ( _progressObserver ) _progressObserver->setBaseSteps ( _progressObserver->baseSteps () + requiredFiles.size() );
139
140 return transform_collect ( std::move(requiredFiles), [this]( zypp::OnMediaLocation file ) {
141
142 return DownloadWorkflow::provideToCacheDir( _ctx, _mediaHandle, file.filename(), ProvideFileSpec(file) )
143 | inspect ( incProgress( _progressObserver ) );
144
145 }) | and_then ( [this]( std::vector<zypp::ManagedFile> &&dlFiles ) {
146 auto &downloadedFiles = _ctx->files();
147 downloadedFiles.insert( downloadedFiles.end(), std::make_move_iterator(dlFiles.begin()), std::make_move_iterator(dlFiles.end()) );
148 return expected<DlContextRefType>::success( std::move(_ctx) );
149 });
150 });
151
152 } | finishProgress( _progressObserver );
153 }
154
155 private:
156
157 const zypp::RepoInfo &repoInfo() const override {
158 return _ctx->repoInfo();
159 }
160
161 const zypp::filesystem::Pathname &deltaDir() const override {
162 return _ctx->deltaDir();
163 }
164
165 DlContextRefType _ctx;
166 MediaHandle _mediaHandle;
167 ProgressObserverRef _progressObserver;
168 };
169 }
170
171 AsyncOpRef<expected<repo::AsyncDownloadContextRef> > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
172 {
173 return SimpleExecutor< DlLogic, AsyncOp<expected<repo::AsyncDownloadContextRef>> >::run( std::move(dl), std::move(mediaHandle), std::move(progressObserver) );
174 }
175
176 expected<repo::SyncDownloadContextRef> download(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, ProgressObserverRef progressObserver)
177 {
178 return SimpleExecutor< DlLogic, SyncOp<expected<repo::SyncDownloadContextRef>> >::run( std::move(dl), std::move(mediaHandle), std::move(progressObserver) );
179 }
180
181
182}
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...
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:24
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
Definition rpmmd.cc:171
AsyncOpRef< expected< zypp::RepoStatus > > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
Definition rpmmd.cc:74
auto transform_collect(Transformation &&f)
Definition expected.h:706
auto and_then(Fun &&function)
Definition expected.h:623
auto finishProgress(ProgressObserverRef progressObserver, ProgressObserver::FinishResult result=ProgressObserver::Success)
detail::collect_helper collect()
Definition expected.h:650
auto incProgress(ProgressObserverRef progressObserver, double progrIncrease=1.0, std::optional< std::string > newStr={})
auto inspect(Fun &&function)
Definition expected.h:637
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:397
Helper filtering the files offered by a RepomdFileReader.
#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