libzypp 17.38.5

downloadwf.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
9
10#include "downloadwf.h"
11
12#include <utility>
13#include <zypp/ng/context.h>
14#include <zypp/ng/workflows/checksumwf.h>
15
16
17#include <zypp-core/fs/PathInfo.h>
18#include <zypp-core/ng/pipelines/Algorithm>
19
20#include <zypp/ng/media/provide.h>
21#include <zypp-media/ng/ProvideSpec>
22
23 namespace zyppng {
24
25 CacheProviderContext::CacheProviderContext( ZYPP_PRIVATE_CONSTR_ARG, ContextRef zyppContext, zypp::Pathname destDir )
26 : _zyppContext( std::move(zyppContext) )
27 , _destDir( std::move(destDir) )
28 { }
29
30
31 const ContextRef &CacheProviderContext::zyppContext() const
32 {
33 return _zyppContext;
34 }
35
36
37
38 const zypp::Pathname &CacheProviderContext::destDir() const
39 {
40 return _destDir;
41 }
42
43
44 void CacheProviderContext::addCacheDir(const zypp::Pathname &p)
45 {
46 _cacheDirs.push_back ( p );
47 }
48
49
50 const std::vector<zypp::Pathname> &CacheProviderContext::cacheDirs() const
51 {
52 return _cacheDirs;
53 }
54
55 namespace {
56
57 using namespace zyppng::operators;
58
59 class CacheMissException : public zypp::Exception
60 {
61 public:
62 CacheMissException( const zypp::Pathname &filename )
63 : zypp::Exception( zypp::str::Str() << filename << " not found in target cache" ) { }
64 };
65
66 struct ProvideFromCacheOrMediumLogic {
67 protected:
68
69 using ContextType = Context;
70 using ProvideType = typename ContextType::ProvideType;
71 using MediaHandle = typename ProvideType::MediaHandle;
72 using ProvideRes = typename ProvideType::Res;
73
74 public:
75 ProvideFromCacheOrMediumLogic( CacheProviderContextRef cacheContext, MediaHandle &&medium, zypp::Pathname &&file, ProvideFileSpec &&filespec )
76 : _ctx( std::move(cacheContext) )
77 , _medium( std::move(medium) )
78 , _file(std::move( file ))
79 , _filespec( std::move(filespec) ) {}
80
81 MaybeAwaitable<expected<zypp::ManagedFile>> execute() {
82
83 return findFileInCache( )
84 | [this]( expected<zypp::ManagedFile> cached ) -> MaybeAwaitable<expected<zypp::ManagedFile>> {
85 if ( !cached ) {
86 MIL << "Didn't find " << _file << " in the caches, providing from medium" << std::endl;
87
88 // we didn't find it in the caches or the lookup failed, lets provide and check it
89 std::shared_ptr<ProvideType> provider = _ctx->zyppContext()->provider();
90 return provider->provide( _medium, _file, _filespec )
91 | and_then( [this]( ProvideRes res ) {
92 return verifyFile( res.file() )
93 | and_then( [res = res]() {
94 return expected<ProvideRes>::success( std::move(res) );
95 });
96 })
97 | and_then( ProvideType::copyResultToDest( _ctx->zyppContext()->provider(), _ctx->destDir() / _file ) )
98 | and_then( []( zypp::ManagedFile &&file ){
99 file.resetDispose ();
100 return make_expected_success (std::move(file));
101 }) ;
102
103 } else {
104
105 return verifyFile ( cached.get() )
106 | and_then([ this, cachedFile = cached.get() ]() mutable {
107 if ( cachedFile == _ctx->destDir() / _file ) {
108 cachedFile.resetDispose(); // make sure dispose is reset
109 return makeReadyTask( expected<zypp::ManagedFile>::success(std::move(cachedFile) ));
110 }
111
112 const auto &targetPath = _ctx->destDir() / _file;
113 zypp::filesystem::assert_dir( targetPath.dirname () );
114
115 return _ctx->zyppContext()->provider()->copyFile( cachedFile, _ctx->destDir() / _file )
116 | and_then( [cachedFile]( zypp::ManagedFile &&f) { f.resetDispose(); return make_expected_success (std::move(f)); });
117 });
118 }};
119 }
120
121 protected:
126 MaybeAwaitable<expected<zypp::ManagedFile>> findFileInCache( ) {
127
128 // No checksum - no match
129 if ( _filespec.checksum().empty() )
130 return makeReadyTask( expected<zypp::ManagedFile>::error(std::make_exception_ptr( CacheMissException(_file) )) );
131
132 const auto &confDirs = _ctx->cacheDirs();
133 const auto targetFile = _ctx->destDir() / _file ;
134 std::vector<zypp::Pathname> caches;
135 caches.push_back( _ctx->destDir() );
136 caches.insert( caches.end(), confDirs.begin(), confDirs.end() );
137
138 auto makeSearchPipeline = [this, targetFile]( zypp::Pathname cachePath ) -> expected<zypp::ManagedFile> {
139 zypp::Pathname cacheFilePath( cachePath / _file );
140 zypp::PathInfo cacheFileInfo( cacheFilePath );
141 if ( !cacheFileInfo.isExist () ) {
142 return makeReadyTask(expected<zypp::ManagedFile>::error( std::make_exception_ptr (CacheMissException(_file)) ));
143 } else {
144 auto provider = _ctx->zyppContext()->provider();
145
146 // calc checksum, but do not use the workflow. Here we don't want to ask the user if a wrong checksum should
147 // be accepted
148 return provider->checksumForFile( cacheFilePath, _filespec.checksum().type() )
149 | and_then([this, cacheFilePath, targetFile]( zypp::CheckSum sum ) {
150
151 auto mgdFile = zypp::ManagedFile( cacheFilePath );
152
153 // if the file is in the target dir, make sure to release it if its not used
154 if ( cacheFilePath == targetFile )
155 mgdFile.setDispose ( zypp::filesystem::unlink );
156
157 if ( sum == _filespec.checksum () ) {
158 // we found the file!
159 return expected<zypp::ManagedFile>::success( std::move(mgdFile) );
160 }
161
162 return expected<zypp::ManagedFile>::error( std::make_exception_ptr (CacheMissException(_file)) );
163 });
164 }
165 };
166
167 auto defVal = expected<zypp::ManagedFile>::error( std::make_exception_ptr (CacheMissException(_file) ) );
168 return std::move(caches) | firstOf( std::move(makeSearchPipeline), std::move(defVal), detail::ContinueUntilValidPredicate() );
169 }
170
171 MaybeAwaitable<expected<void>> verifyFile ( const zypp::Pathname &dlFilePath ) {
172
173 return zypp::Pathname( dlFilePath )
174 | [this]( zypp::Pathname &&dlFilePath ) {
175 if ( !_filespec.checksum().empty () ) {
176 return CheckSumWorkflow::verifyChecksum( _ctx->zyppContext(), _filespec.checksum (), std::move(dlFilePath) );
177 }
178 return makeReadyTask(expected<void>::success());
179 };
180 // add other verifier here via and_then(), like a signature based one
181 }
182
183 CacheProviderContextRef _ctx;
184 MediaHandle _medium;
185 zypp::Pathname _file;
186 ProvideFileSpec _filespec;
187 };
188 }
189
190 namespace DownloadWorkflow {
191
192 MaybeAwaitable<expected<zypp::ManagedFile> > provideToCacheDir( CacheProviderContextRef cacheContext, ProvideMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec )
193 {
194 ProvideFromCacheOrMediumLogic impl(std::move(cacheContext), std::move(medium), std::move(file), std::move(filespec));
195 zypp_co_return zypp_co_await( impl.execute() );
196 }
197
198 }
199
200}
MIL
#define MIL
Definition Logger.h:100
checksumwf.h
zypp::CheckSum
Definition CheckSum.h:34
zypp::Exception
Base class for Exception.
Definition Exception.h:153
zypp::filesystem::PathInfo
Wrapper class for stat/lstat.
Definition PathInfo.h:226
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:48
zyppng::CacheProviderContext::destDir
const zypp::Pathname & destDir() const
Definition downloadwf.cc:38
zyppng::CacheProviderContext::zyppContext
const ContextRef & zyppContext() const
Definition downloadwf.cc:31
zyppng::CacheProviderContext::addCacheDir
void addCacheDir(const zypp::Pathname &p)
Definition downloadwf.cc:44
zyppng::CacheProviderContext::_destDir
zypp::Pathname _destDir
Definition downloadwf.h:44
zyppng::CacheProviderContext::_cacheDirs
std::vector< zypp::Pathname > _cacheDirs
Definition downloadwf.h:45
zyppng::CacheProviderContext::cacheDirs
const std::vector< zypp::Pathname > & cacheDirs() const
Definition downloadwf.cc:50
zyppng::CacheProviderContext::_zyppContext
ContextRef _zyppContext
Definition downloadwf.h:43
zyppng::Context::ProvideType
Provide ProvideType
Definition context.h:34
zyppng::ProvideFileSpec
Definition providespec.h:95
zyppng::ProvideMediaHandle
Definition provide.h:27
zyppng::ProvideRes::file
const zypp::Pathname file() const
Definition provide.cc:152
zyppng::expected
Definition expected.h:56
zyppng::expected::success
static expected success(ConsParams &&...params)
Definition expected.h:178
zyppng::expected::error
static expected error(ConsParams &&...params)
Definition expected.h:189
context.h
downloadwf.h
str
String related utilities and Regular expression matching.
zypp::filesystem::unlink
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:719
zypp::filesystem::assert_dir
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Definition PathInfo.cc:338
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition CodePitfalls.doc:2
zypp::ManagedFile
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
Definition ManagedFile.h:27
zypp::_file
Pathname _file
Definition SystemCheck.cc:34
zyppng::CheckSumWorkflow::verifyChecksum
MaybeAwaitable< expected< void > > verifyChecksum(ContextRef zyppCtx, zypp::CheckSum checksum, zypp::filesystem::Pathname file)
Definition checksumwf.cc:111
zyppng::DownloadWorkflow
Definition downloadwf.cc:190
zyppng::DownloadWorkflow::provideToCacheDir
MaybeAwaitable< expected< zypp::ManagedFile > > provideToCacheDir(CacheProviderContextRef cacheContext, ProvideMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec)
Definition downloadwf.cc:192
zyppng::operators
Definition expected.h:699
zyppng::operators::and_then
auto and_then(Fun &&function)
Definition expected.h:708
zyppng
Definition MediaNetworkRequestExecutor.h:16
zyppng::and_then
ResultType and_then(const expected< T, E > &exp, Function &&f)
Definition expected.h:520
zyppng::firstOf
auto firstOf(Transformation &&transformFunc, DefaultType &&def, Predicate &&predicate=detail::ContinueUntilValidPredicate())
Definition algorithm.h:94
provide.h
zyppng::detail::ContinueUntilValidPredicate
Definition algorithm.h:25
PathInfo.h
ZYPP_PRIVATE_CONSTR_ARG
#define ZYPP_PRIVATE_CONSTR_ARG
Definition zyppglobal.h:160