14#include <zypp-media/ng/Provide>
15#include <zypp-media/ng/ProvideSpec>
16#include <zypp/ng/Context>
17#include <zypp/ng/repo/Downloader>
33 using namespace zyppng::operators;
35 template <
class Executor,
class OpType >
36 struct DownloadMasterIndexLogic :
public LogicBase<Executor, OpType>
42 using ZyppContextType =
typename remove_smart_ptr_t<DlContextRefType>::ContextType;
43 using ProvideType =
typename ZyppContextType::ProvideType;
44 using MediaHandle =
typename ProvideType::MediaHandle;
45 using ProvideRes =
typename ProvideType::Res;
54 MaybeAsyncRef<expected<DlContextRefType>> execute( ) {
60 auto providerRef =
_dlContext->zyppContext()->provider();
64 | and_then( ProvideType::copyResultToDest ( providerRef, _destdir / _sigpath ) ),
66 | and_then( ProvideType::copyResultToDest ( providerRef, _destdir / _keypath ) ),
69 | [
this]( std::vector<expected<zypp::ManagedFile>> &&res ) {
72 std::for_each( res.begin (), res.end(),
73 [
this]( expected<zypp::ManagedFile> &f){
75 _dlContext->files().push_back( std::move(f.get()));
83 | and_then( std::bind( &DownloadMasterIndexLogic::pluginVerification,
this, std::placeholders::_1 ) )
86 | and_then( std::bind( &DownloadMasterIndexLogic::signatureCheck,
this, std::placeholders::_1 ) )
89 | and_then( ProvideType::copyResultToDest ( providerRef, _destdir / _masterIndex ) )
94 _dlContext->repoInfo().setMetadataPath( _destdir );
95 _dlContext->repoInfo().setValidRepoSignature( _repoSigValidated );
102 allFiles.insert( allFiles.begin (), std::move(masterIndex) );
103 return make_expected_success( std::move(_dlContext) );
113 MaybeAsyncRef<expected<ProvideRes>> signatureCheck ( ProvideRes &&res ) {
115 if (
_dlContext->repoInfo().repoGpgCheck() ) {
122 if ( isSigned ||
_dlContext->repoInfo().repoGpgCheckIsMandatory() ) {
128 verifyCtx.signature( sigpathLocal );
135 return makeReadyResult( expected<ProvideRes>::error( std::current_exception() ) );
141 verifyCtx.keyContext(
_dlContext->repoInfo() );
143 return getExtraKeysInRepomd( std::move(res ) )
144 | and_then([
this, vCtx = std::move(verifyCtx) ]( ProvideRes &&res )
mutable {
146 DBG <<
"Keyhint remember buddy " << keyData << std::endl;
147 vCtx.addBuddyKey( keyData.id() );
154 return make_expected_success(std::move(res));
159 WAR <<
"Accept unsigned repository because repoGpgCheck is not mandatory for " <<
_dlContext->repoInfo().alias() << std::endl;
162 WAR <<
"Signature checking disabled in config of repository " <<
_dlContext->repoInfo().alias() << std::endl;
164 return makeReadyResult(expected<ProvideRes>::success(res));
168 expected<ProvideRes> pluginVerification ( ProvideRes &&prevRes ) {
172 if (
_dlContext->pluginRepoverification() &&
_dlContext->pluginRepoverification()->isNeeded() ) {
174 _dlContext->pluginRepoverification()->getChecker( sigpathLocal, keypathLocal,
_dlContext->repoInfo() )( prevRes.file() );
176 return expected<ProvideRes>::error( std::current_exception () );
179 return make_expected_success(std::move(prevRes));
186 MaybeAsyncRef<expected<ProvideRes>> getExtraKeysInRepomd ( ProvideRes &&res ) {
189 return makeReadyResult( expected<ProvideRes>::success( std::move(res) ) );
193 if ( keyhints.empty() )
194 return makeReadyResult( expected<ProvideRes>::success( std::move(res) ) );
195 DBG <<
"Check keyhints: " << keyhints.size() << std::endl;
197 auto keyRing {
_dlContext->zyppContext()->keyRing() };
199 | transform([
this, keyRing]( std::pair<std::string, std::string> val ) {
201 const auto& [ file, keyid ] = val;
202 auto keyData = keyRing->trustedPublicKeyData( keyid );
204 DBG <<
"Keyhint is already trusted: " << keyid <<
" (" << file <<
")" << std::endl;
205 return makeReadyResult ( expected<zypp::PublicKeyData>::success(keyData) );
208 DBG <<
"Keyhint search key " << keyid <<
" (" << file <<
")" << std::endl;
210 keyData = keyRing->publicKeyData( keyid );
212 return makeReadyResult( expected<zypp::PublicKeyData>::success(keyData) );
219 | [ keyid = keyid ](
auto &&key ){
220 if ( key.fileProvidesKey( keyid ) )
221 return make_expected_success( std::forward<
decltype(key)>(key) );
223 return expected<zypp::PublicKey>::error( std::make_exception_ptr (
zypp::Exception(
"File does not provide key")));
225 | or_else ([
this, file = file, keyid = keyid, cacheFile ] (
auto && )
mutable -> MaybeAsyncRef<expected<zypp::PublicKey>> {
226 auto providerRef =
_dlContext->zyppContext()->provider();
227 return providerRef->provide(
_media, file, ProvideFileSpec().setOptional(
true) )
228 | and_then( ProvideType::copyResultToDest( providerRef,
_destdir / file ) )
229 | and_then( [
this, providerRef, file, keyid , cacheFile = std::move(cacheFile)](
zypp::ManagedFile &&res ) {
232 _dlContext->files().push_back ( std::move(res) );
235 if ( not key.fileProvidesKey( keyid ) ) {
236 const auto &
str =
zypp::str::Str() <<
"Keyhint " << file <<
" does not contain a key with id " << keyid <<
". Skipping it.";
238 return makeReadyResult(expected<zypp::PublicKey>::error( std::make_exception_ptr(
zypp::Exception(
str)) ));
243 return providerRef->copyFile( key.path(), cacheFile )
244 | [ key ]( expected<zypp::ManagedFile> res )
mutable {
247 res->resetDispose ();
249 return expected<zypp::PublicKey>::success( std::move(key) );
254 keyRing->importKey( key,
false );
255 return expected<zypp::PublicKeyData>::success(keyRing->publicKeyData( keyid ));
258 | [
this, res = res] ( std::vector<expected<zypp::PublicKeyData>> &&keyHints )
mutable {
259 std::for_each( keyHints.begin(), keyHints.end(), [
this]( expected<zypp::PublicKeyData> &keyData ){
260 if ( keyData && *keyData ) {
261 if ( not zypp::PublicKey::isSafeKeyId( keyData->id() ) ) {
262 WAR <<
"Keyhint " << keyData->id() <<
" for " << *keyData <<
" is not strong enough for auto import. Just caching it." << std::endl;
265 _buddyKeys.push_back ( std::move(keyData.get()) );
269 MIL <<
"Check keyhints done. Buddy keys: " <<
_buddyKeys.size() << std::endl;
270 return expected<ProvideRes>::success (std::move(res));
288 AsyncOpRef<expected<repo::AsyncDownloadContextRef> > RepoDownloaderWorkflow::downloadMasterIndex(repo::AsyncDownloadContextRef dl,
ProvideMediaHandle mediaHandle,
zypp::Pathname masterIndex_r)
293 expected<repo::SyncDownloadContextRef> RepoDownloaderWorkflow::downloadMasterIndex(repo::SyncDownloadContextRef dl,
SyncMediaHandle mediaHandle,
zypp::Pathname masterIndex_r)
300 template <
class DlContextRefType,
class MediaHandleType>
301 auto statusImpl ( DlContextRefType dlCtx, MediaHandleType &&mediaHandle ) {
303 constexpr bool isAsync = std::is_same_v<DlContextRefType,repo::AsyncDownloadContextRef>;
306 return expected<zypp::RepoStatus>::success(
zypp::RepoStatus( dlCtx->repoInfo()) && status );
309 switch( dlCtx->repoInfo().type().toEnum()) {
311 return RpmmdWorkflows::repoStatus( dlCtx, std::forward<MediaHandleType>(mediaHandle) ) | and_then( std::move(finalizeStatus) );
313 return SuseTagsWorkflows::repoStatus( dlCtx, std::forward<MediaHandleType>(mediaHandle) ) | and_then( std::move(finalizeStatus) );
315 return PlaindirWorkflows::repoStatus ( dlCtx, std::forward<MediaHandleType>(mediaHandle) ) | and_then( std::move(finalizeStatus) );
324 AsyncOpRef<expected<zypp::RepoStatus> > RepoDownloaderWorkflow::repoStatus(repo::AsyncDownloadContextRef dl,
ProvideMediaHandle mediaHandle) {
325 return statusImpl( dl, std::move(mediaHandle) );
328 expected<zypp::RepoStatus> RepoDownloaderWorkflow::repoStatus(repo::SyncDownloadContextRef dl,
SyncMediaHandle mediaHandle) {
329 return statusImpl( dl, std::move(mediaHandle) );
334 template <
class DlContextRefType,
class MediaHandleType>
335 auto downloadImpl ( DlContextRefType dlCtx, MediaHandleType &&mediaHandle, ProgressObserverRef &&progressObserver ) {
337 constexpr bool isAsync = std::is_same_v<DlContextRefType,repo::AsyncDownloadContextRef>;
339 switch( dlCtx->repoInfo().type().toEnum()) {
341 return RpmmdWorkflows::download( std::move(dlCtx), std::forward<MediaHandleType>(mediaHandle), std::move(progressObserver) );
343 return SuseTagsWorkflows::download( std::move(dlCtx), std::forward<MediaHandleType>(mediaHandle), std::move(progressObserver) );
345 return PlaindirWorkflows::download ( std::move(dlCtx), std::forward<MediaHandleType>(mediaHandle) );
354 AsyncOpRef<expected<repo::AsyncDownloadContextRef> > RepoDownloaderWorkflow::download(repo::AsyncDownloadContextRef dl,
ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
356 return downloadImpl( dl, std::move(mediaHandle), std::move(progressObserver) );
359 expected<repo::SyncDownloadContextRef> RepoDownloaderWorkflow::download(repo::SyncDownloadContextRef dl,
SyncMediaHandle mediaHandle, ProgressObserverRef progressObserver)
361 return downloadImpl( dl, std::move(mediaHandle), std::move(progressObserver) );
Interface of repomd.xml file reader.
Store and operate with byte count.
static const Unit MB
1000^2 Byte
Base class for Exception.
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
static PublicKey noThrow(const Pathname &keyFile_r)
Static ctor returning an empty PublicKey rather than throwing.
Track changing files or directories.
Interim helper class to collect global options and settings.
Pathname repoManagerRoot() const
The RepoManager root directory.
Pathname pubkeyCachePath() const
Path where the pubkey caches.
Wrapper class for stat/lstat.
bool isExist() const
Return whether valid stat info exists.
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
Pathname dirname() const
Return all but the last component od this path.
std::string basename() const
Return the last component of this path.
I/O context for KeyRing::verifyFileSignatureWorkflow.
bool fileValidated() const
Whether the signature was actually successfully verified.
Reads through a repomd.xml file and collects type, location, checksum and other data about metadata f...
std::vector< std::pair< std::string, std::string > > keyhints() const
gpg key hits shipped in keywords (bsc#1184326)
thrown when it was impossible to determine this repo type.
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
#define ZYPP_ENABLE_LOGIC_BASE(Executor, OpType)
typename conditional< B, T, F >::type conditional_t
String related utilities and Regular expression matching.
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
std::string join(TIterator begin, TIterator end, const C_Str &sep_r=" ")
Join strings using separator sep_r (defaults to BLANK).
expected< zypp::keyring::VerifyFileContext > verifySignature(SyncContextRef ctx, zypp::keyring::VerifyFileContext context)
zypp::Pathname _masterIndex
std::vector< zypp::PublicKeyData > _buddyKeys
zypp::TriBool _repoSigValidated
DlContextRefType _dlContext
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.