14 #include <zypp-media/ng/Provide> 15 #include <zypp-media/ng/ProvideSpec> 16 #include <zypp/ng/Context> 17 #include <zypp/ng/repo/Downloader> 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 ) )
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() ) {
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 ) {
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));
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) );
325 return statusImpl( dl, std::move(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) );
356 return downloadImpl( dl, std::move(mediaHandle), std::move(progressObserver) );
361 return downloadImpl( dl, std::move(mediaHandle), std::move(progressObserver) );
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver=nullptr)
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
thrown when it was impossible to determine this repo type.
std::string join(TIterator begin, TIterator end, const C_Str &sep_r=" ")
Join strings using separator sep_r (defaults to BLANK).
Store and operate with byte count.
Pathname pubkeyCachePath() const
Path where the pubkey caches.
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
zypp::Pathname _masterIndex
String related utilities and Regular expression matching.
zypp::TriBool _repoSigValidated
I/O context for KeyRing::verifyFileSignatureWorkflow.
static const Unit MB
1000^2 Byte
std::string basename() const
Return the last component of this path.
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Pathname repoManagerRoot() const
The RepoManager root directory.
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
const Pathname & signature() const
Detached signature or empty.
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
bool isExist() const
Return whether valid stat info exists.
Pathname dirname() const
Return all but the last component od this path.
Interim helper class to collect global options and settings.
#define ZYPP_ENABLE_LOGIC_BASE(Executor, OpType)
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > downloadMasterIndex(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r)
AsyncOpRef< expected< zypp::RepoStatus > > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
DlContextRefType _dlContext
typename conditional< B, T, F >::type conditional_t
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
Reads through a repomd.xml file and collects type, location, checksum and other data about metadata f...
AsyncOpRef< expected< zypp::RepoStatus > > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
Base class for Exception.
expected< zypp::keyring::VerifyFileContext > verifySignature(SyncContextRef ctx, zypp::keyring::VerifyFileContext context)
static bool isSafeKeyId(const std::string &id_r)
!<
AsyncOpRef< expected< zypp::RepoStatus > > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
Wrapper class for ::stat/::lstat.
Interface of repomd.xml file reader.
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
Track changing files or directories.
static PublicKey noThrow(const Pathname &keyFile_r)
Static ctor returning an empty PublicKey rather than throwing.
std::vector< zypp::PublicKeyData > _buddyKeys