libzypp  17.32.5
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
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" )
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) )
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 
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 }
DlContextRefType _ctx
Definition: rpmmd.cc:66
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:429
Describes a resource file located on a medium.
expected< T, E > inspect(expected< T, E > exp, Function &&f)
Definition: expected.h:462
A ProvideRes object is a reference counted ownership of a resource in the cache provided by a Provide...
Definition: provideres.h:35
Helper filtering the files offered by a RepomdFileReader.
Definition: Arch.h:363
What is known about a repository.
Definition: RepoInfo.h:71
static expected< std::decay_t< Type >, Err > make_expected_success(Type &&t)
Definition: expected.h:341
unsigned medianr() const
The media number the resource is located on.
auto transform_collect(Container< Msg, CArgs... > &&in, Transformation &&f)
Definition: expected.h:597
AsyncOpRef< expected< zypp::ManagedFile > > provideToCacheDir(AsyncCacheProviderContextRef cacheContext, ProvideMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec)
Definition: downloadwf.cc:209
#define ZYPP_ENABLE_LOGIC_BASE(Executor, OpType)
Definition: logichelpers.h:199
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > downloadMasterIndex(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r)
typename conditional< B, T, F >::type conditional_t
Definition: TypeTraits.h:39
std::conditional_t< isAsync, AsyncOpRef< T >, T > makeReadyResult(T &&result)
Definition: asyncop.h:297
Downloader workspace for YUM (rpm-nmd) repositories Encapsulates all the knowledge of which files hav...
Definition: rpmmd.cc:21
const Pathname & filename() const
The path to the resource on the medium.
expected< Container< T >, E > collect(Container< expected< T, E >, CArgs... > &&in)
Definition: expected.h:448
static expected success(ConsParams &&...params)
Definition: expected.h:115
std::shared_ptr< AsyncOp< T > > AsyncOpRef
Definition: asyncop.h:255
Reads through a repomd.xml file and collects type, location, checksum and other data about metadata f...
Exception for repository handling.
Definition: RepoException.h:37
AsyncOpRef< expected< zypp::RepoStatus > > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
Definition: rpmmd.cc:71
ProgressObserverRef _progressObserver
Definition: rpmmd.cc:164
MediaHandle _mediaHandle
Definition: rpmmd.cc:163
auto finishProgress(ProgressObserverRef progressObserver)
Interface of repomd.xml file reader.
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
Definition: rpmmd.cc:168
ResultType and_then(const expected< T, E > &exp, Function &&f)
Definition: expected.h:367
Track changing files or directories.
Definition: RepoStatus.h:40
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
MediaHandle _handle
Definition: rpmmd.cc:67
auto downloadMediaInfo(MediaHandle &&mediaHandle, const zypp::filesystem::Pathname &destdir)
auto incProgress(ProgressObserverRef progressObserver, double progrIncrease=1.0, std::optional< std::string > newStr={})