libzypp  17.35.14
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() )
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())
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
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" )
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) )
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 
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 }
DlContextRefType _ctx
Definition: rpmmd.cc:69
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:424
Describes a resource file located on a medium.
std::enable_if_t<!std::is_same_v< void, T >, expected< Container< T >, E > > collect(Container< expected< T, E >, CArgs... > &&in)
Definition: expected.h:501
expected< T, E > inspect(expected< T, E > exp, Function &&f)
Definition: expected.h:531
auto finishProgress(ProgressObserverRef progressObserver, ProgressObserver::FinishResult result=ProgressObserver::Success)
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:397
unsigned medianr() const
The media number the resource is located on.
auto transform_collect(Container< Msg, CArgs... > &&in, Transformation &&f)
Definition: expected.h:666
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:223
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:24
const Pathname & filename() const
The path to the resource on the medium.
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:74
ProgressObserverRef _progressObserver
Definition: rpmmd.cc:167
MediaHandle _mediaHandle
Definition: rpmmd.cc:166
Interface of repomd.xml file reader.
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
Definition: rpmmd.cc:171
ResultType and_then(const expected< T, E > &exp, Function &&f)
Definition: expected.h:423
Track changing files or directories.
Definition: RepoStatus.h:40
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
Definition: Exception.h:436
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
MediaHandle _handle
Definition: rpmmd.cc:70
auto downloadMediaInfo(MediaHandle &&mediaHandle, const zypp::filesystem::Pathname &destdir)
auto incProgress(ProgressObserverRef progressObserver, double progrIncrease=1.0, std::optional< std::string > newStr={})