diff --git a/tests/media/CredentialManager_test.cc b/tests/media/CredentialManager_test.cc index 094c79d0b3..8d381b7499 100644 --- a/tests/media/CredentialManager_test.cc +++ b/tests/media/CredentialManager_test.cc @@ -4,14 +4,16 @@ #include #include #include -#include +#include #include +#include using std::cout; using std::endl; using namespace zypp; using namespace zypp::media; +using zyppng::media::CredentialManager; inline void testGetCreds( CredentialManager & cm_r, const std::string & url_r, const std::string & user_r = "", @@ -34,19 +36,22 @@ inline void testGetCreds( CredentialManager & cm_r, const std::string & url_r, BOOST_AUTO_TEST_CASE(read_cred_for_url) { - CredManagerOptions opts; + auto ctx = zyppng::SyncContext::create(); + ctx->initialize().unwrap (); + + CredManagerSettings opts(ctx); opts.globalCredFilePath = TESTS_SRC_DIR "/media/data/credentials.cat"; opts.userCredFilePath = Pathname(); - CredentialManager cm( opts ); + auto cm = CredentialManager::create( opts ); - BOOST_CHECK_EQUAL( cm.credsGlobalSize(), 3 ); + BOOST_CHECK_EQUAL( cm->credsGlobalSize(), 3 ); - testGetCreds( cm, "https://drink.it/repo/roots", "ginger", "ale" ); - testGetCreds( cm, "ftp://weprovidesoft.fr/download/opensuse/110", "agda", "ichard" ); - testGetCreds( cm, "ftp://magda@weprovidesoft.fr/download/opensuse/110", "magda", "richard" ); - testGetCreds( cm, "ftp://agda@weprovidesoft.fr/download/opensuse/110", "agda", "ichard" ); - testGetCreds( cm, "ftp://unknown@weprovidesoft.fr/download/opensuse/110" ); // NULL - testGetCreds( cm, "http://url.ok/but/not/creds" ); // NULL + testGetCreds( *cm, "https://drink.it/repo/roots", "ginger", "ale" ); + testGetCreds( *cm, "ftp://weprovidesoft.fr/download/opensuse/110", "agda", "ichard" ); + testGetCreds( *cm, "ftp://magda@weprovidesoft.fr/download/opensuse/110", "magda", "richard" ); + testGetCreds( *cm, "ftp://agda@weprovidesoft.fr/download/opensuse/110", "agda", "ichard" ); + testGetCreds( *cm, "ftp://unknown@weprovidesoft.fr/download/opensuse/110" ); // NULL + testGetCreds( *cm, "http://url.ok/but/not/creds" ); // NULL } struct CredCollector @@ -64,10 +69,15 @@ struct CredCollector BOOST_AUTO_TEST_CASE(save_creds) { + auto ctx = zyppng::SyncContext::create(); + ctx->initialize().unwrap (); + + CredManagerSettings opts(ctx); + filesystem::TmpDir tmp; - CredManagerOptions opts; opts.globalCredFilePath = tmp / "fooha"; - CredentialManager cm1(opts); + + auto cm1 = CredentialManager::create(opts); AuthData cr1("benson","absolute"); cr1.setUrl(Url("http://joooha.com")); @@ -76,20 +86,20 @@ BOOST_AUTO_TEST_CASE(save_creds) cr2.setUrl(Url("ftp://filesuck.org")); // should create a new file - cm1.saveInGlobal(cr1); + cm1->saveInGlobal(cr1); CredCollector collector; CredentialFileReader( opts.globalCredFilePath, bind( &CredCollector::collect, &collector, _1 ) ); BOOST_CHECK_EQUAL( collector.creds.size(), 1 ); collector.creds.clear(); - cm1.saveInGlobal(cr2); + cm1->saveInGlobal(cr2); CredentialFileReader( opts.globalCredFilePath, bind( &CredCollector::collect, &collector, _1 ) ); BOOST_CHECK_EQUAL(collector.creds.size(), 2 ); collector.creds.clear(); // save the same creds again - cm1.saveInGlobal(cr2); + cm1->saveInGlobal(cr2); CredentialFileReader( opts.globalCredFilePath, bind( &CredCollector::collect, &collector, _1 ) ); BOOST_CHECK_EQUAL(collector.creds.size(), 2 ); @@ -98,16 +108,21 @@ BOOST_AUTO_TEST_CASE(save_creds) BOOST_AUTO_TEST_CASE(service_base_url) { + auto ctx = zyppng::SyncContext::create(); + ctx->initialize().unwrap (); + + CredManagerSettings opts(ctx); + filesystem::TmpDir tmp; - CredManagerOptions opts; opts.globalCredFilePath = tmp / "fooha"; - CredentialManager cm( opts ); + + auto cm = CredentialManager::create( opts ); AuthData cred( "benson","absolute" ); cred.setUrl( Url( "http://joooha.com/service/path" ) ); - cm.addGlobalCred( cred ); + cm->addGlobalCred( cred ); - testGetCreds( cm, "http://joooha.com/service/path/repo/repofoo", "benson", "absolute" ); - testGetCreds( cm, "http://benson@joooha.com/service/path/repo/repofoo", "benson", "absolute" ); - testGetCreds( cm, "http://nobody@joooha.com/service/path/repo/repofoo" ); // NULL + testGetCreds( *cm, "http://joooha.com/service/path/repo/repofoo", "benson", "absolute" ); + testGetCreds( *cm, "http://benson@joooha.com/service/path/repo/repofoo", "benson", "absolute" ); + testGetCreds( *cm, "http://nobody@joooha.com/service/path/repo/repofoo" ); // NULL } diff --git a/tests/parser/RepoFileReader_test.cc b/tests/parser/RepoFileReader_test.cc index 6b861d0c8e..bcb33c779e 100644 --- a/tests/parser/RepoFileReader_test.cc +++ b/tests/parser/RepoFileReader_test.cc @@ -1,13 +1,14 @@ #include #include -#include +#include +#include +#include #include #include "TestSetup.h" using std::stringstream; using std::string; -using namespace zypp; static std::string suse_repo = "[factory-oss]\n" "name=factory-oss $releasever - $basearch\n" @@ -29,13 +30,13 @@ static std::string suse_repo = "[factory-oss]\n" struct RepoCollector : private base::NonCopyable { - bool collect( const RepoInfo &repo ) + bool collect( const zyppng::RepoInfo &repo ) { repos.push_back(repo); return true; } - RepoInfoList repos; + zyppng::RepoInfoList repos; }; // Must be the first test! @@ -44,10 +45,12 @@ BOOST_AUTO_TEST_CASE(read_repo_file) { std::stringstream input(suse_repo); RepoCollector collector; - parser::RepoFileReader parser( input, bind( &RepoCollector::collect, &collector, _1 ) ); + zyppng::SyncContextRef ctx = zyppng::SyncContext::create (); + ctx->initialize().unwrap(); + zyppng::parser::RepoFileReader parser( ctx, input, bind( &RepoCollector::collect, &collector, _1 ) ); BOOST_CHECK_EQUAL(1, collector.repos.size()); - const RepoInfo & repo( collector.repos.front() ); + const zyppng::RepoInfo & repo( collector.repos.front() ); BOOST_CHECK_EQUAL( 5, repo.baseUrlsSize() ); BOOST_CHECK_EQUAL( 5, repo.gpgKeyUrlsSize() ); diff --git a/tests/parser/RepoindexFileReader_test.cc b/tests/parser/RepoindexFileReader_test.cc index 25b68ff002..5e61220b9d 100644 --- a/tests/parser/RepoindexFileReader_test.cc +++ b/tests/parser/RepoindexFileReader_test.cc @@ -1,9 +1,12 @@ #include #include #include -#include #include +#include +#include +#include + #include "TestSetup.h" using std::stringstream; @@ -21,13 +24,13 @@ static string service = "" struct RepoCollector : private base::NonCopyable { - bool collect( const RepoInfo &repo ) + bool collect( const zyppng::RepoInfo &repo ) { repos.push_back(repo); return true; } - RepoInfoList repos; + zyppng::RepoInfoList repos; }; // Must be the first test! @@ -36,11 +39,14 @@ BOOST_AUTO_TEST_CASE(read_index_file) { stringstream input(service); RepoCollector collector; - parser::RepoindexFileReader parser( input, bind( &RepoCollector::collect, &collector, _1 ) ); + + auto ctx = zyppng::SyncContext::create(); + ctx->initialize().unwrap(); + + zyppng::parser::RepoIndexFileReader parser( ctx, input, bind( &RepoCollector::collect, &collector, _1 ) ); BOOST_REQUIRE_EQUAL(3, collector.repos.size()); - RepoInfo repo; - repo = collector.repos.front(); + zyppng::RepoInfo repo = collector.repos.front(); BOOST_CHECK_EQUAL("Company's Foo", repo.name()); BOOST_CHECK_EQUAL("company-foo", repo.alias()); diff --git a/tests/repo/MirrorList_test.cc b/tests/repo/MirrorList_test.cc index 89f8494aec..514192ce04 100644 --- a/tests/repo/MirrorList_test.cc +++ b/tests/repo/MirrorList_test.cc @@ -1,10 +1,10 @@ -#include #include #include #include "WebServer.h" #include +#include using namespace zypp; using namespace zypp::repo; @@ -20,8 +20,11 @@ BOOST_AUTO_TEST_CASE(get_mirrorlist) weburl1.setPathName("/metalink.xml"); weburl2.setPathName("/mirrors.txt"); - RepoMirrorList rml1 (weburl1); - RepoMirrorList rml2 (weburl2); + auto ctx = zyppng::SyncContext::create(); + ctx->initialize ().unwrap (); + + RepoMirrorList rml1 ( ctx, weburl1 ); + RepoMirrorList rml2 ( ctx, weburl2 ); BOOST_CHECK(rml1.getUrls().begin()->asString() == "http://ftp-stud.hs-esslingen.de/pub/fedora/linux/updates/13/x86_64/"); BOOST_CHECK(rml2.getUrls().begin()->asString() == "http://ftp-stud.hs-esslingen.de/pub/fedora/linux/updates/13/x86_64/"); diff --git a/tests/repo/PluginServices_test.cc b/tests/repo/PluginServices_test.cc index 8fdd0c4b94..59824a540c 100644 --- a/tests/repo/PluginServices_test.cc +++ b/tests/repo/PluginServices_test.cc @@ -1,8 +1,4 @@ -#include #include -#include -#include -#include #include #include @@ -10,15 +6,17 @@ #include #include #include -#include -#include + +#include +#include +#include using std::cout; using std::endl; using std::string; -using namespace zypp; +using namespace zyppng; using namespace boost::unit_test; -using namespace zypp::repo; +using namespace zyppng::repo; #define DATADIR (Pathname(TESTS_SRC_DIR) + "/repo/yum/data") @@ -46,7 +44,9 @@ BOOST_AUTO_TEST_CASE(plugin_services) { ServiceCollector::ServiceSet services; - PluginServices local("/space/tmp/services", ServiceCollector(services)); + auto ctx = SyncContext::create(); + ctx->initialize().unwrap(); + PluginServices local(ctx, "/space/tmp/services", ServiceCollector(services)); } // vim: set ts=2 sts=2 sw=2 ai et: diff --git a/tests/repo/susetags/Downloader_test.cc b/tests/repo/susetags/Downloader_test.cc index 36ad292263..04149b3466 100644 --- a/tests/repo/susetags/Downloader_test.cc +++ b/tests/repo/susetags/Downloader_test.cc @@ -31,16 +31,17 @@ BOOST_AUTO_TEST_CASE(susetags_download) KeyRingTestReceiver keyring_callbacks; keyring_callbacks.answerAcceptKey(KeyRingReport::KEY_TRUST_TEMPORARILY); + + auto ctx = zyppng::SyncContext::create (); + Pathname p = DATADIR + "/stable-x86-subset"; - RepoInfo repoinfo; + zyppng::RepoInfo repoinfo(ctx); repoinfo.setAlias("testrepo"); repoinfo.setPath("/"); filesystem::TmpDir tmp; Pathname localdir(tmp.path()); - - auto ctx = zyppng::SyncContext::create (); auto res = ctx->initialize () | and_then( [&]() { return ctx->provider()->attachMedia( p.asDirUrl() , zyppng::ProvideMediaSpec() ); } ) | and_then( [&]( zyppng::SyncMediaHandle h ){ @@ -106,16 +107,16 @@ BOOST_AUTO_TEST_CASE(susetags_gz_download) KeyRingTestReceiver keyring_callbacks; keyring_callbacks.answerAcceptKey(KeyRingReport::KEY_TRUST_TEMPORARILY); + auto ctx = zyppng::SyncContext::create (); + Pathname p = DATADIR + "/stable-x86-subset-gz"; - RepoInfo repoinfo; + zyppng::RepoInfo repoinfo(ctx); repoinfo.setAlias("testrepo"); repoinfo.setPath("/"); filesystem::TmpDir tmp; Pathname localdir(tmp.path()); - - auto ctx = zyppng::SyncContext::create (); auto res = ctx->initialize () | and_then( [&]() { return ctx->provider()->attachMedia( p.asDirUrl() , zyppng::ProvideMediaSpec() ); } ) | and_then( [&]( zyppng::SyncMediaHandle h ){ diff --git a/tests/repo/yum/YUMDownloader_test.cc b/tests/repo/yum/YUMDownloader_test.cc index dfb4c259ea..af7cadf7d5 100644 --- a/tests/repo/yum/YUMDownloader_test.cc +++ b/tests/repo/yum/YUMDownloader_test.cc @@ -28,16 +28,17 @@ BOOST_AUTO_TEST_CASE(yum_download) KeyRingTestReceiver keyring_callbacks; keyring_callbacks.answerAcceptKey(KeyRingReport::KEY_TRUST_TEMPORARILY); + auto ctx = zyppng::SyncContext::create (); + Pathname p = DATADIR + "/ZCHUNK"; Url url(p.asDirUrl()); - RepoInfo repoinfo; + zyppng::RepoInfo repoinfo(ctx); repoinfo.setAlias("testrepo"); repoinfo.setPath("/"); filesystem::TmpDir tmp; Pathname localdir(tmp.path()); - auto ctx = zyppng::SyncContext::create (); auto res = ctx->initialize () | and_then( [&]() { return ctx->provider()->attachMedia( p.asDirUrl() , zyppng::ProvideMediaSpec() ); } ) | and_then( [&]( zyppng::SyncMediaHandle h ){ diff --git a/tests/zypp/RepoManager_test.cc b/tests/zypp/RepoManager_test.cc index 32343b75a7..15101f2bb2 100644 --- a/tests/zypp/RepoManager_test.cc +++ b/tests/zypp/RepoManager_test.cc @@ -1,4 +1,3 @@ - #include #include #include diff --git a/tests/zyppng/Pipelines_test.cc b/tests/zyppng/Pipelines_test.cc index 3ff716435f..b68986022e 100644 --- a/tests/zyppng/Pipelines_test.cc +++ b/tests/zyppng/Pipelines_test.cc @@ -153,9 +153,9 @@ BOOST_AUTO_TEST_CASE( asyncToMixedPipelineWithIndirectAsyncCB ) auto op = zyppng::AsyncOpRef(std::make_shared>("5")) | &toSignedInt - | []( auto &&in ){ in.value += 5; return std::make_shared>(std::move(in)); } + | []( auto in ){ in.value += 5; return std::make_shared>(std::move(in)); } | &toString - | [&]( auto && res ){ + | [&]( auto res ){ BOOST_CHECK_EQUAL ( std::string("10") , res ); ev->quit (); return res; @@ -172,13 +172,13 @@ BOOST_AUTO_TEST_CASE( asyncToMixedPipelineWithIndirectAsyncCBInStdFunction ) const auto &makePipeline = [&](){ - const std::function< AsyncOpRef( Int && ) > &addFiveAsync = []( auto &&in ){ in.value += 5; return std::make_shared>(std::move(in)); }; + const std::function< AsyncOpRef( Int && ) > &addFiveAsync = []( auto in ){ in.value += 5; return std::make_shared>(std::move(in)); }; return zyppng::AsyncOpRef(std::make_shared>("5")) | &toSignedInt | addFiveAsync | &toString - | [&]( auto && res ){ + | [&]( auto res ){ BOOST_CHECK_EQUAL ( std::string("10") , res ); ev->quit (); return res; diff --git a/tests/zyppng/media/Provider_test.cc b/tests/zyppng/media/Provider_test.cc index 696b760194..c59facdab4 100644 --- a/tests/zyppng/media/Provider_test.cc +++ b/tests/zyppng/media/Provider_test.cc @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -314,7 +315,8 @@ BOOST_AUTO_TEST_CASE( http_prov_auth ) //don't write or read creds from real settings dir zypp::filesystem::TmpDir globCredPath; zypp::filesystem::TmpDir userCredPath; - zypp::media::CredManagerOptions opts; + + zypp::media::CredManagerSettings opts; opts.globalCredFilePath = globCredPath.path() / "credentials.cat"; opts.userCredFilePath = userCredPath.path() / "credentials.cat"; prov->setCredManagerOptions( opts ); @@ -387,7 +389,7 @@ BOOST_AUTO_TEST_CASE( http_prov_auth_nouserresponse ) //don't write or read creds from real settings dir zypp::filesystem::TmpDir globCredPath; zypp::filesystem::TmpDir userCredPath; - zypp::media::CredManagerOptions opts; + zypp::media::CredManagerSettings opts; opts.globalCredFilePath = globCredPath.path() / "credentials.cat"; opts.userCredFilePath = userCredPath.path() / "credentials.cat"; prov->setCredManagerOptions( opts ); @@ -450,7 +452,7 @@ BOOST_AUTO_TEST_CASE( http_prov_auth_wrongpw ) //don't write or read creds from real settings dir zypp::filesystem::TmpDir globCredPath; zypp::filesystem::TmpDir userCredPath; - zypp::media::CredManagerOptions opts; + zypp::media::CredManagerSettings opts; opts.globalCredFilePath = globCredPath.path() / "credentials.cat"; opts.userCredFilePath = userCredPath.path() / "credentials.cat"; prov->setCredManagerOptions( opts ); @@ -524,7 +526,7 @@ BOOST_AUTO_TEST_CASE( http_attach_prov_auth ) //don't write or read creds from real settings dir zypp::filesystem::TmpDir globCredPath; zypp::filesystem::TmpDir userCredPath; - zypp::media::CredManagerOptions opts; + zypp::media::CredManagerSettings opts; opts.globalCredFilePath = globCredPath.path() / "credentials.cat"; opts.userCredFilePath = userCredPath.path() / "credentials.cat"; prov->setCredManagerOptions( opts ); diff --git a/zypp-core/CMakeLists.txt b/zypp-core/CMakeLists.txt index 989e244f0f..d823646c63 100644 --- a/zypp-core/CMakeLists.txt +++ b/zypp-core/CMakeLists.txt @@ -320,6 +320,9 @@ SET( zyppng_pipelines_HEADERS zyppng/pipelines/lift.h zyppng/pipelines/MTry zyppng/pipelines/mtry.h + zyppng/pipelines/operators.h + zyppng/pipelines/Optional + zyppng/pipelines/optional.h zyppng/pipelines/Redo zyppng/pipelines/redo.h zyppng/pipelines/Transform diff --git a/zypp-core/Globals.h b/zypp-core/Globals.h index a512fce874..3f22b6bb21 100644 --- a/zypp-core/Globals.h +++ b/zypp-core/Globals.h @@ -12,6 +12,7 @@ #ifndef ZYPP_GLOBALS_H #define ZYPP_GLOBALS_H +#include #include // LIBZYPP_ version defines for the LEGACY macro #include // some macros used almost everywhere @@ -118,7 +119,6 @@ #endif - #ifdef ZYPP_DLL //defined if zypp is compiled as DLL // used to flag API to be deprected inside of libzypp. #define ZYPP_INTERNAL_DEPRECATE ZYPP_DEPRECATED @@ -129,5 +129,77 @@ #define ZYPP_LEGACY_API #endif +/** + * Macro to disable legacy warnings for code that was otherwise marked as + * internal deprecated, for examples in files that are defining legacy API. + */ +#if __GNUC__ - 0 > 3 || (__GNUC__ - 0 == 3 && __GNUC_MINOR__ - 0 >= 2) + #ifndef ZYPP_BEGIN_LEGACY_API + #define ZYPP_BEGIN_LEGACY_API \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated\"") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") + #endif + + #ifndef ZYPP_END_LEGACY_API + #define ZYPP_END_LEGACY_API \ + _Pragma("GCC diagnostic pop") + #endif + +#else + #define ZYPP_BEGIN_LEGACY_API + #define ZYPP_END_LEGACY_API +#endif + +namespace zyppng { + template + using Ref = std::shared_ptr; + + template + using WeakRef = std::weak_ptr; +} + +namespace zypp { + template + using Ref = std::shared_ptr; + + template + using WeakRef = std::weak_ptr; +} + +/*! + * Helper macro to declare Ref types + */ +#define ZYPP_FWD_DECL_REFS(T) \ + using T##Ref = Ref; \ + using T##WeakRef = WeakRef + +/* + * Helper Macro to forward declare types and ref types + */ +#define ZYPP_FWD_DECL_TYPE_WITH_REFS(T) \ + class T; \ + ZYPP_FWD_DECL_REFS(T) + +#define ZYPP_FWD_DECL_TEMPL_TYPE_WITH_REFS_ARG1(T, TArg1) \ + template< typename TArg1> \ + class T; \ + template< typename TArg1> \ + using T##Ref = Ref>; \ + template< typename TArg1> \ + using T##WeakRef = WeakRef> + + +//@TODO enable for c++20 +#if 0 +#define ZYPP_FWD_DECL_TEMPL_TYPE_WITH_REFS(T, TArg1, ...) \ + template< typename TArg1 __VA_OPT__(, typename) __VA_ARGS__ > \ + class T; \ + template< typename TArg1 __VA_OPT__(, typename) __VA_ARGS__ > \ + using T##Ref = std::shared_ptr>; \ + template< typename TArg1 __VA_OPT__(, typename) __VA_ARGS__ > \ + using T##WeakRef = std::weak_ptr> +#endif + #endif diff --git a/zypp-core/base/Iterator.h b/zypp-core/base/Iterator.h index 791973c61a..dfba3e3489 100644 --- a/zypp-core/base/Iterator.h +++ b/zypp-core/base/Iterator.h @@ -13,6 +13,7 @@ #define ZYPP_BASE_ITERATOR_H #include +#include #include #include @@ -148,6 +149,49 @@ namespace zypp using boost::transform_iterator; using boost::make_transform_iterator; + + template + class GenericIteratorNode { + using NodePtr = std::unique_ptr; + virtual RefT ref() = 0; + virtual NodePtr clone() const = 0; + virtual NodePtr next() const = 0; + virtual NodePtr prev() const = 0; + virtual bool equals( const GenericIteratorNode &other ) const = 0; + }; + + template + class GenericIterator : public boost::iterators::iterator_facade < GenericIterator, T, boost::iterators::bidirectional_traversal_tag, RefT > { + public: + GenericIterator( std::unique_ptr> &&node ) : _node(std::move(node)){} + ~GenericIterator() = default; + + template + GenericIterator(GenericIterator const& other) + : _node(other._node) {} + + GenericIterator(const GenericIterator &other) : _node( other._node->clone() ) {} + GenericIterator(GenericIterator &&other) : _node(std::move(other._node) ) {} + GenericIterator &operator=(const GenericIterator &other) { _node = other._node->clone(); } + GenericIterator &operator=(GenericIterator &&other) { _node = std::move(other._node); } + + private: + friend class boost::iterator_core_access; + + void increment() { _node = _node->next(); } + void decrement() { _node = _node->prev(); } + + bool equal( GenericIterator const& other) const + { + return this->_node->equals( *other._node ); + } + + RefT dereference() const { return _node->ref(); } + + private: + std::unique_ptr> _node; + }; + /** Functor taking a \c std::pair returning \c std::pair.first. * \see MapKVIteratorTraits */ diff --git a/zypp-core/base/defaultintegral.h b/zypp-core/base/defaultintegral.h index 3235f3e1bc..73eb321120 100644 --- a/zypp-core/base/defaultintegral.h +++ b/zypp-core/base/defaultintegral.h @@ -13,6 +13,7 @@ #define ZYPP_CORE_BASE_DEFAULTINTEGRAL_H #include +#include #include #include diff --git a/zypp-core/zyppng/base/zyppglobal.h b/zypp-core/zyppng/base/zyppglobal.h index 5e989c029b..ee66252543 100644 --- a/zypp-core/zyppng/base/zyppglobal.h +++ b/zypp-core/zyppng/base/zyppglobal.h @@ -3,6 +3,7 @@ #include #include +#include /* * Convenience helpers to automatically generate boilerplate code @@ -98,56 +99,6 @@ template inline auto zyppGetPtrHelper(Ptr &ptr) -> decltype(ptr.o #define Z_D() auto const d = d_func() #define Z_Z() auto const z = z_func() -namespace zyppng { - template - using Ref = std::shared_ptr; - - template - using WeakRef = std::weak_ptr; -} - -namespace zypp { - template - using Ref = std::shared_ptr; - - template - using WeakRef = std::weak_ptr; -} - -/*! - * Helper macro to declare Ref types - */ -#define ZYPP_FWD_DECL_REFS(T) \ - using T##Ref = Ref; \ - using T##WeakRef = WeakRef - -/* - * Helper Macro to forward declare types and ref types - */ -#define ZYPP_FWD_DECL_TYPE_WITH_REFS(T) \ - class T; \ - ZYPP_FWD_DECL_REFS(T) - -#define ZYPP_FWD_DECL_TEMPL_TYPE_WITH_REFS_ARG1(T, TArg1) \ - template< typename TArg1> \ - class T; \ - template< typename TArg1> \ - using T##Ref = Ref>; \ - template< typename TArg1> \ - using T##WeakRef = WeakRef> - - -//@TODO enable for c++20 -#if 0 -#define ZYPP_FWD_DECL_TEMPL_TYPE_WITH_REFS(T, TArg1, ...) \ - template< typename TArg1 __VA_OPT__(, typename) __VA_ARGS__ > \ - class T; \ - template< typename TArg1 __VA_OPT__(, typename) __VA_ARGS__ > \ - using T##Ref = std::shared_ptr>; \ - template< typename TArg1 __VA_OPT__(, typename) __VA_ARGS__ > \ - using T##WeakRef = std::weak_ptr> -#endif - /*! * Defines a dummy struct that can be used to make a public constructor unusable * outside the class. \sa ZYPP_ADD_CREATE_FUNC. diff --git a/zypp-core/zyppng/pipelines/Optional b/zypp-core/zyppng/pipelines/Optional new file mode 100644 index 0000000000..16d841e3fc --- /dev/null +++ b/zypp-core/zyppng/pipelines/Optional @@ -0,0 +1 @@ +#include "optional.h" diff --git a/zypp-core/zyppng/pipelines/asyncresult.h b/zypp-core/zyppng/pipelines/asyncresult.h index 7a3cd4a986..4984170372 100644 --- a/zypp-core/zyppng/pipelines/asyncresult.h +++ b/zypp-core/zyppng/pipelines/asyncresult.h @@ -125,6 +125,13 @@ namespace zyppng { template constexpr bool is_nested_async_v = is_nested_async::value; + // helper to figure out the return type for a mbind callback, if the ArgType is void the callback is considered to take no argument. + // Due to how std::conditional works, we cannot pass std::invoke_result_t but instead use the template type std::invoke_result, since + // one of the two options have no "::type" because the substitution fails, this breaks the std::conditional_t since it can only work with two well formed + // types. Instead we pass in the template types and evaluate the ::type in the end, when the correct invoke_result was chosen. + template < typename Function, typename ArgType> + using mbind_cb_result_t = typename std::conditional_t< std::is_same_v, std::invoke_result,std::invoke_result >::type; + // case 1: connect async result to async callback template diff --git a/zypp-core/zyppng/pipelines/expected.h b/zypp-core/zyppng/pipelines/expected.h index 08b275e162..e513df72d4 100644 --- a/zypp-core/zyppng/pipelines/expected.h +++ b/zypp-core/zyppng/pipelines/expected.h @@ -20,6 +20,7 @@ #include #include #include +#include namespace zyppng { @@ -403,14 +404,6 @@ namespace zyppng { } namespace detail { - - // helper to figure out the return type for a mbind callback, if the ArgType is void the callback is considered to take no argument. - // Due to how std::conditional works, we cannot pass std::invoke_result_t but instead use the template type std::invoke_result, since - // one of the two options have no "::type" because the substitution fails, this breaks the std::conditional_t since it can only work with two well formed - // types. Instead we pass in the template types and evaluate the ::type in the end, when the correct invoke_result was chosen. - template < typename Function, typename ArgType> - using mbind_cb_result_t = typename std::conditional_t< std::is_same_v, std::invoke_result,std::invoke_result >::type; - template bool waitForCanContinueExpected( const expected &value ) { return value.is_valid(); @@ -555,57 +548,6 @@ namespace zyppng { namespace detail { - - template - struct and_then_helper { - Callback function; - - template< typename T, typename E > - auto operator()( const expected& exp ) { - return and_then( exp, function ); - } - - template< typename T, typename E > - auto operator()( expected&& exp ) { - return and_then( std::move(exp), function ); - } - }; - - template - struct or_else_helper { - Callback function; - - template< typename T, typename E > - auto operator()( const expected& exp ) { - return or_else( exp, function ); - } - - template< typename T, typename E > - auto operator()( expected&& exp ) { - return or_else( std::move(exp), function ); - } - }; - - template - struct inspect_helper { - Callback function; - - template< typename T, typename E > - auto operator()( expected&& exp ) { - return inspect( std::move(exp), function ); - } - }; - - template - struct inspect_err_helper { - Callback function; - - template< typename T, typename E > - auto operator()( expected&& exp ) { - return inspect_err( std::move(exp), function ); - } - }; - struct collect_helper { template < typename T > inline auto operator()( T&& in ) { @@ -615,41 +557,6 @@ namespace zyppng { } namespace operators { - template - auto mbind ( Fun && function ) { - return detail::and_then_helper { - std::forward(function) - }; - } - - template - auto and_then ( Fun && function ) { - return detail::and_then_helper { - std::forward(function) - }; - } - - template - auto or_else ( Fun && function ) { - return detail::or_else_helper { - std::forward(function) - }; - } - - template - auto inspect ( Fun && function ) { - return detail::inspect_helper { - std::forward(function) - }; - } - - template - auto inspect_err ( Fun && function ) { - return detail::inspect_err_helper { - std::forward(function) - }; - } - inline detail::collect_helper collect() { return detail::collect_helper(); } diff --git a/zypp-core/zyppng/pipelines/operators.h b/zypp-core/zyppng/pipelines/operators.h new file mode 100644 index 0000000000..309fcbff58 --- /dev/null +++ b/zypp-core/zyppng/pipelines/operators.h @@ -0,0 +1,96 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +----------------------------------------------------------------------/ +* +* This file contains private API, this might break at any time between releases. +* You have been warned! +*/ + +#ifndef ZYPP_ZYPPNG_PIPELINES_OPERATORS_H +#define ZYPP_ZYPPNG_PIPELINES_OPERATORS_H + +#include + +namespace zyppng { + + namespace detail { + template + struct and_then_helper { + Callback function; + + template< typename T > + auto operator()( T&& exp ) { + return and_then( std::forward(exp), function ); + } + }; + + template + struct or_else_helper { + Callback function; + + template< typename T > + auto operator()(T&& exp ) { + return or_else( std::forward(exp), function ); + } + }; + + template + struct inspect_helper { + Callback function; + + template< typename T> + auto operator()( T &&exp ) { + return inspect( std::forward(exp), function ); + } + }; + + template + struct inspect_err_helper { + Callback function; + + template< typename T> + auto operator()( T &&exp ) { + return inspect_err( std::forward(exp), function ); + } + }; + } + + + namespace operators { + template + auto inspect ( Fun && function ) { + return detail::inspect_helper { + std::forward(function) + }; + } + + template + auto inspect_err ( Fun && function ) { + return detail::inspect_err_helper { + std::forward(function) + }; + } + + template + auto and_then ( Fun && function ) { + return detail::and_then_helper { + std::forward(function) + }; + } + + template + auto or_else ( Fun && function ) { + return detail::or_else_helper { + std::forward(function) + }; + } + } + +} + +#endif diff --git a/zypp-core/zyppng/pipelines/optional.h b/zypp-core/zyppng/pipelines/optional.h new file mode 100644 index 0000000000..9c8a9a242a --- /dev/null +++ b/zypp-core/zyppng/pipelines/optional.h @@ -0,0 +1,93 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +----------------------------------------------------------------------/ +* +* This file contains private API, this might break at any time between releases. +* You have been warned! +*/ + +#ifndef ZYPP_ZYPPNG_PIPELINES_OPTIONAL_H +#define ZYPP_ZYPPNG_PIPELINES_OPTIONAL_H + +#include + +#ifdef __cpp_lib_optional +#include +#include +#include +#include +#include + +namespace zyppng { + + template < typename T + , typename Function + , typename ResultType = std::invoke_result_t + > + ResultType and_then( const std::optional& opt, Function &&f) + { + if (opt) { + return std::invoke( std::forward(f), opt.value() ); + } else { + if constexpr ( !detail::is_async_op< remove_smart_ptr_t >::value ) + return std::optional(); + else + return makeReadyResult( std::optional::value_type>() ); + } + } + + template < typename T + , typename Function + , typename ResultType = std::invoke_result_t + > + ResultType and_then( std::optional &&opt, Function &&f) + { + if (opt) { + return std::invoke( std::forward(f), std::move(opt.value()) ); + } else { + if constexpr ( !detail::is_async_op< remove_smart_ptr_t >::value ) + return std::optional(); + else + return makeReadyResult( std::optional::value_type>() ); + } + } + + template < typename T + , typename Function + , typename ResultType = std::invoke_result_t + > + ResultType or_else( const std::optional& opt, Function &&f) + { + if (!opt) { + return std::invoke( std::forward(f), opt.error() ); + } else { + if constexpr ( !detail::is_async_op< remove_smart_ptr_t >::value ) + return opt; + else + return makeReadyResult( std::move(opt) ); + } + } + + template < typename T + , typename Function + , typename ResultType = std::invoke_result_t + > + ResultType or_else( std::optional&& opt, Function &&f) + { + if (!opt) { + return std::invoke( std::forward(f), std::move(opt.error()) ); + } else { + if constexpr ( !detail::is_async_op< remove_smart_ptr_t >::value ) + return opt; + else + return makeReadyResult( std::move(opt) ); + } + } +} +#endif +#endif diff --git a/zypp-curl/ng/network/downloader.cc b/zypp-curl/ng/network/downloader.cc index df8639b4f8..94930fdedd 100644 --- a/zypp-curl/ng/network/downloader.cc +++ b/zypp-curl/ng/network/downloader.cc @@ -63,7 +63,7 @@ namespace zyppng { - zypp::url::ViewOption::WITH_PASSWORD - zypp::url::ViewOption::WITH_QUERY_STR; - auto cachedCred = zypp::media::CredentialManager::findIn( _credCache, req->url(), vopt ); + auto cachedCred = zyppng::media::CredentialManager::findIn( _credCache, req->url(), vopt ); // only consider a cache entry if its newer than what we tried last time if ( cachedCred && cachedCred->lastDatabaseUpdate() > req->_authTimestamp ) { @@ -177,7 +177,7 @@ namespace zyppng { if ( set.authType() == "basic" && set.username().size() && !set.password().size() ) { - zypp::media::CredentialManager cm( _parent ? _parent->credManagerOptions() : zypp::media::CredManagerOptions() ); + zypp::media::CredentialManager cm( _parent ? _parent->credManagerOptions() : zypp::media::CredManagerSettings() ); const auto cred = cm.getCred( url ); if ( cred && cred->valid() ) { if ( !set.username().size() ) diff --git a/zypp-curl/ng/network/private/downloaderstates/base_p.h b/zypp-curl/ng/network/private/downloaderstates/base_p.h index 0eac110544..a7bfb96c89 100644 --- a/zypp-curl/ng/network/private/downloaderstates/base_p.h +++ b/zypp-curl/ng/network/private/downloaderstates/base_p.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include namespace zyppng { @@ -93,7 +93,7 @@ namespace zyppng { std::shared_ptr _requestDispatcher; std::shared_ptr _mirrorControl; - zypp::media::CredentialManager::CredentialSet _credCache; //< the credential cache for this download + zyppng::media::CredentialManager::CredentialSet _credCache; //< the credential cache for this download DownloadSpec _spec; // the download settings mutable zypp::TriBool _specHasZckInfo = zypp::indeterminate; diff --git a/zypp-curl/transfersettings.cc b/zypp-curl/transfersettings.cc index ad10640ed9..46d9225c1f 100644 --- a/zypp-curl/transfersettings.cc +++ b/zypp-curl/transfersettings.cc @@ -36,12 +36,12 @@ namespace zypp { public: Impl() : _useproxy( false ), - _timeout( MediaConfig::instance().download_transfer_timeout() ), - _connect_timeout( MediaConfig::instance().download_connect_timeout() ), - _maxConcurrentConnections( MediaConfig::instance().download_max_concurrent_connections() ), - _minDownloadSpeed(MediaConfig::instance().download_min_download_speed()), - _maxDownloadSpeed(MediaConfig::instance().download_max_download_speed()), - _maxSilentTries(MediaConfig::instance().download_max_silent_tries() ), + _timeout( MediaConfig::systemConfig().download_transfer_timeout() ), + _connect_timeout( MediaConfig::systemConfig().download_connect_timeout() ), + _maxConcurrentConnections( MediaConfig::systemConfig().download_max_concurrent_connections() ), + _minDownloadSpeed(MediaConfig::systemConfig().download_min_download_speed()), + _maxDownloadSpeed(MediaConfig::systemConfig().download_max_download_speed()), + _maxSilentTries(MediaConfig::systemConfig().download_max_silent_tries() ), _verify_host(false), _verify_peer(false), _ca_path("/etc/ssl/certs"), diff --git a/zypp-glib/CMakeLists.txt b/zypp-glib/CMakeLists.txt index 103c7ba388..4214e42495 100644 --- a/zypp-glib/CMakeLists.txt +++ b/zypp-glib/CMakeLists.txt @@ -28,7 +28,6 @@ SET( zypp_glib_HEADERS progressobserver.h repoinfo.h repomanager.h - repomanageroptions.h repository.h serviceinfo.h #userrequest.h @@ -45,7 +44,6 @@ SET( zypp_glib_private_HEADERS private/progressobserver_p.h private/repoinfo_p.h private/repomanager_p.h - private/repomanageroptions_p.h private/repository_p.h private/serviceinfo_p.h #private/userrequest_p.h @@ -61,7 +59,6 @@ SET( zypp_glib_SRCS progressobserver.cc repoinfo.cc repomanager.cc - repomanageroptions.cc repository.cc serviceinfo.cc #userrequest.cc diff --git a/zypp-glib/private/repoinfo_p.h b/zypp-glib/private/repoinfo_p.h index 1c577a54cd..0ca9012136 100644 --- a/zypp-glib/private/repoinfo_p.h +++ b/zypp-glib/private/repoinfo_p.h @@ -13,18 +13,18 @@ #include #include #include -#include +#include #include struct ZyppRepoInfoPrivate { struct ConstructionProps { - std::optional _cppObj; + std::optional _cppObj; zypp::glib::ZyppContextRef _context = nullptr; }; - std::optional _constrProps = ConstructionProps(); - zypp::RepoInfo _info{nullptr}; + std::optional _constrProps = ConstructionProps(); + zyppng::RepoInfo _info{ zyppng::ContextBaseRef(nullptr) }; ZyppRepoInfoPrivate( ZyppRepoInfo *pub ) : _gObject(nullptr) {} void initialize(); @@ -40,11 +40,11 @@ struct _ZyppRepoInfo GObjectClass parent_class; }; -ZyppRepoInfo *zypp_wrap_cpp ( zypp::RepoInfo info ); +ZyppRepoInfo *zypp_wrap_cpp ( zyppng::RepoInfo info ); /** * zypp_repo_info_get_cpp: (skip) */ -zypp::RepoInfo &zypp_repo_info_get_cpp( ZyppRepoInfo *self ); +zyppng::RepoInfo &zypp_repo_info_get_cpp( ZyppRepoInfo *self ); #endif // ZYPP_GLIB_PRIVATE_REPOINFO_P_H diff --git a/zypp-glib/private/serviceinfo_p.h b/zypp-glib/private/serviceinfo_p.h index 1f579d654d..421419a6aa 100644 --- a/zypp-glib/private/serviceinfo_p.h +++ b/zypp-glib/private/serviceinfo_p.h @@ -13,18 +13,18 @@ #include #include #include -#include +#include #include struct ZyppServiceInfoPrivate { struct ConstructionProps { - std::optional _cppObj; + std::optional _cppObj; zypp::glib::ZyppContextRef _context = nullptr; }; std::optional _constrProps = ConstructionProps(); - zypp::ServiceInfo _info{ zyppng::ContextBaseRef(nullptr) }; + zyppng::ServiceInfo _info{ zyppng::ContextBaseRef(nullptr) }; ZyppServiceInfoPrivate( ZyppServiceInfo *pub ) : _gObject(nullptr) {} void initialize(); @@ -37,12 +37,12 @@ struct ZyppServiceInfoPrivate struct _ZyppServiceInfo { GObject parent_instance; struct Cpp { - zypp::ServiceInfo _info; + zyppng::ServiceInfo _info; } _data; }; -ZyppServiceInfo *zypp_wrap_cpp(zypp::ServiceInfo info); +ZyppServiceInfo *zypp_wrap_cpp(zyppng::ServiceInfo info); #endif // SERVICEINFO_P_H diff --git a/zypp-glib/repoinfo.cc b/zypp-glib/repoinfo.cc index d6132feda9..08572b7ac9 100644 --- a/zypp-glib/repoinfo.cc +++ b/zypp-glib/repoinfo.cc @@ -126,7 +126,7 @@ zypp_repo_info_set_property (GObject *object, { case PROP_CPPOBJ: g_return_if_fail( d->_constrProps ); // only if the constr props are still valid - ZYPP_GLIB_SET_CPPOBJ_PROP( zypp::RepoInfo, value, d->_constrProps->_cppObj ) + ZYPP_GLIB_SET_CPPOBJ_PROP( zyppng::RepoInfo, value, d->_constrProps->_cppObj ) case PROP_CONTEXT: { g_return_if_fail( d->_constrProps ); // only if the constr props are still valid ZyppContext *obj = ZYPP_CONTEXT(g_value_get_object( value )); @@ -161,7 +161,7 @@ void ZyppRepoInfoPrivate::initialize() _info = std::move( _constrProps->_cppObj.value() ); } else { if ( !_constrProps->_context ) g_error("Context argument can not be NULL"); - _info = zypp::RepoInfo( zypp_context_get_cpp( _constrProps->_context.get() ) ); + _info = zyppng::RepoInfo( zypp_context_get_cpp( _constrProps->_context.get() ) ); } _constrProps.reset(); } @@ -172,12 +172,12 @@ ZyppRepoInfo *zypp_repo_info_new(ZyppContext *context) return static_cast(g_object_new (ZYPP_TYPE_REPOINFO, "zyppcontext", context, NULL)); } -ZyppRepoInfo *zypp_wrap_cpp( zypp::RepoInfo info ) +ZyppRepoInfo *zypp_wrap_cpp(zyppng::RepoInfo info ) { return static_cast(g_object_new (ZYPP_TYPE_REPOINFO, zypp::glib::internal::ZYPP_CPP_OBJECT_PROPERTY_NAME.data(), &info, NULL)); } -zypp::RepoInfo &zypp_repo_info_get_cpp( ZyppRepoInfo *self ) +zyppng::RepoInfo &zypp_repo_info_get_cpp( ZyppRepoInfo *self ) { ZYPP_REPO_INFO_D(); return d->_info; diff --git a/zypp-glib/repomanager.cc b/zypp-glib/repomanager.cc index 3e18e4ffe6..6f9bfdf16f 100644 --- a/zypp-glib/repomanager.cc +++ b/zypp-glib/repomanager.cc @@ -9,7 +9,6 @@ #include "private/repomanager_p.h" #include "private/serviceinfo_p.h" #include "private/repoinfo_p.h" -#include "private/repomanageroptions_p.h" #include "expected.h" #include #include @@ -27,7 +26,6 @@ typedef enum { PROP_CPPOBJ = 1, CONTEXT_PROPERTY, - OPTIONS_PROPERTY, N_PROPERTIES } ZyppRepoManagerProperty; static GParamSpec *obj_properties[N_PROPERTIES] = { NULL }; @@ -60,12 +58,15 @@ void zypp_repo_manager_class_init( ZyppRepoManagerClass *klass ) zypp_context_get_type(), GParamFlags( G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE) ); + /* + for now we do not support passing RepoManagerOptions, the context defines those obj_properties[OPTIONS_PROPERTY] = g_param_spec_boxed( "options", "ZyppRepoManagerOptions", "The repo manager options to be used", zypp_repo_manager_options_get_type (), GParamFlags( G_PARAM_CONSTRUCT | G_PARAM_READWRITE ) ); + */ g_object_class_install_properties (object_class, N_PROPERTIES, @@ -80,7 +81,8 @@ void ZyppRepoManagerPrivate::initializeCpp( ) _cppObj = std::move( _constrProps->_cppObj ); } else { if ( !_constrProps->_ctx ) g_error("Context argument can not be NULL"); - _cppObj = zyppng::SyncRepoManager::create ( zypp_context_get_cpp( _constrProps->_ctx.get() ), _constrProps->_options ); + auto ctx = zypp_context_get_cpp( _constrProps->_ctx.get() ); + _cppObj = zyppng::SyncRepoManager::create ( ctx, zyppng::RepoManagerOptions(ctx) ); } _constrProps.reset(); } @@ -110,13 +112,6 @@ zypp_repo_manager_set_property (GObject *object, } break; } - case OPTIONS_PROPERTY: { - auto rO = reinterpret_cast(g_value_get_boxed ( value )); - if ( d->_constrProps ) { - d->_constrProps->_options = rO->_opts; - } - break; - } default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -134,11 +129,7 @@ zypp_repo_manager_get_property (GObject *object, ZyppRepoManager *self = ZYPP_REPOMANAGER (object); ZYPP_REPO_MANAGER_D(); - switch ((ZyppRepoManagerProperty)property_id ) - { - case OPTIONS_PROPERTY: { - g_value_set_boxed ( value, zypp_repo_manager_options_new( d->_cppObj->options() ) ); - } + switch ((ZyppRepoManagerProperty)property_id ) { default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -153,9 +144,7 @@ zypp_repo_manager_get_property (GObject *object, ZyppRepoManager *zypp_repo_manager_new( ZyppContext *ctx ) { g_return_val_if_fail( ctx != nullptr, nullptr ); - - zypp::AutoDisposeoptions( zypp_repo_manager_options_new( zypp_context_sysroot(ctx) ), zypp_repo_manager_options_free ); - return static_cast( g_object_new( zypp_repo_manager_get_type(), "zyppcontext", ctx, "options", options.value(), nullptr ) ); + return static_cast( g_object_new( zypp_repo_manager_get_type(), "zyppcontext", ctx, nullptr ) ); } gboolean zypp_repo_manager_initialize( ZyppRepoManager *self, GError **error ) @@ -209,7 +198,7 @@ GList *zypp_repo_manager_get_known_repos(ZyppRepoManager *self) g_return_val_if_fail( d->_cppObj.operator bool() , nullptr ); for ( auto i = d->_cppObj->repoBegin (); i != d->_cppObj->repoEnd(); i++ ) { - ret = g_list_append( ret, zypp_wrap_cpp ( *i ) ); + ret = g_list_append( ret, zypp_wrap_cpp ( i->second ) ); } return ret; @@ -224,7 +213,7 @@ GList *zypp_repo_manager_get_known_services(ZyppRepoManager *self) g_return_val_if_fail( d->_cppObj.operator bool() , nullptr ); for ( auto i = d->_cppObj->serviceBegin (); i != d->_cppObj->serviceEnd(); i++ ) { - ret = g_list_append( ret, zypp_wrap_cpp ( *i ) ); + ret = g_list_append( ret, zypp_wrap_cpp ( i->second ) ); } return ret; diff --git a/zypp-glib/repomanager.h b/zypp-glib/repomanager.h index 690c70fc64..8651cafb76 100644 --- a/zypp-glib/repomanager.h +++ b/zypp-glib/repomanager.h @@ -12,7 +12,6 @@ #include #include -#include G_BEGIN_DECLS @@ -43,7 +42,6 @@ typedef enum { /** * zypp_repo_manager_new: (constructor) * @ctx: The #ZyppContext the RepoManager should operate on - * @options: (nullable): The RepoManager options, if null then a default option set is created based on the context * Returns: (transfer full): newly created #ZyppRepoManager */ ZyppRepoManager *zypp_repo_manager_new( ZyppContext *ctx ) LIBZYPP_GLIB_EXPORT; diff --git a/zypp-glib/repomanageroptions.cc b/zypp-glib/repomanageroptions.cc deleted file mode 100644 index 93159f9327..0000000000 --- a/zypp-glib/repomanageroptions.cc +++ /dev/null @@ -1,44 +0,0 @@ -/*---------------------------------------------------------------------\ -| ____ _ __ __ ___ | -| |__ / \ / / . \ . \ | -| / / \ V /| _/ _/ | -| / /__ | | | | | | | -| /_____||_| |_| |_| | -| | -\---------------------------------------------------------------------*/ - -#include "private/repomanageroptions_p.h" -#include -#include - -ZyppRepoManagerOptions *zypp_repo_manager_options_new( const gchar *path ) -{ - std::unique_ptr ptr( new ZyppRepoManagerOptions() ); - ptr->_opts = zypp::RepoManagerOptions( zypp::str::asString( path ) ); - return ptr.release(); -} - -ZyppRepoManagerOptions * zypp_repo_manager_options_copy ( ZyppRepoManagerOptions *r ) -{ - return zypp_repo_manager_options_new( r->_opts ); -} - -void zypp_repo_manager_options_free ( ZyppRepoManagerOptions *r ) -{ - delete r; -} - -G_DEFINE_BOXED_TYPE (ZyppRepoManagerOptions, zypp_repo_manager_options, - zypp_repo_manager_options_copy, - zypp_repo_manager_options_free) - - -ZyppRepoManagerOptions *zypp_repo_manager_options_new( const zypp::RepoManagerOptions &opts ) -{ - return ( new _ZyppRepoManagerOptions{opts} ); -} - -gchar *zypp_repo_manager_options_get_root( ZyppRepoManagerOptions *self ) -{ - return g_strdup( self->_opts.rootDir.c_str() ); -} diff --git a/zypp-glib/repomanageroptions.h b/zypp-glib/repomanageroptions.h deleted file mode 100644 index 2351899fd1..0000000000 --- a/zypp-glib/repomanageroptions.h +++ /dev/null @@ -1,56 +0,0 @@ -/*---------------------------------------------------------------------\ -| ____ _ __ __ ___ | -| |__ / \ / / . \ . \ | -| / / \ V /| _/ _/ | -| / /__ | | | | | | | -| /_____||_| |_| |_| | -| | -\---------------------------------------------------------------------*/ - -#ifndef ZYPP_GLIB_REPO_MANAGER_OPTIONS_P_H -#define ZYPP_GLIB_REPO_MANAGER_OPTIONS_P_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define ZYPP_TYPE_REPO_MANAGER_OPTIONS ( zypp_repo_manager_options_get_type() ) - -typedef struct _ZyppRepoManagerOptions ZyppRepoManagerOptions; - -GType zypp_repo_manager_options_get_type (void) LIBZYPP_GLIB_EXPORT; - -/** - * zypp_repo_manager_options_new: (constructor): - * @root: (in): The prefix for all paths - * Returns: (transfer full): newly created #ZyppRepoManagerOptions - */ -ZyppRepoManagerOptions *zypp_repo_manager_options_new( const gchar *root ) LIBZYPP_GLIB_EXPORT; - -/** - * zypp_repo_manager_options_copy: (skip): - * - * Copy the boxed type - */ -ZyppRepoManagerOptions * zypp_repo_manager_options_copy ( ZyppRepoManagerOptions *self ) LIBZYPP_GLIB_EXPORT; - -/** - * zypp_repo_manager_options_free: (skip): - * - * Free the boxed type - */ -void zypp_repo_manager_options_free ( ZyppRepoManagerOptions *self ) LIBZYPP_GLIB_EXPORT; - - -/** - * zypp_repo_manager_options_get_root: - * - * Returns: (transfer full): The currently managed path - */ -gchar *zypp_repo_manager_options_get_root( ZyppRepoManagerOptions *self ) LIBZYPP_GLIB_EXPORT; - -G_END_DECLS - -#endif // ZYPP_REPO_MANAGER_OPTIONS_P_H diff --git a/zypp-glib/repository.cc b/zypp-glib/repository.cc index dade494d5f..9e8cadd754 100644 --- a/zypp-glib/repository.cc +++ b/zypp-glib/repository.cc @@ -71,7 +71,7 @@ gchar *zypp_repository_get_name( ZyppRepository *self ) ZyppRepoInfo *zypp_repository_get_repoinfo(ZyppRepository *self) { - if ( !self || !self->_data._repoManager ) + if ( !self || !self->_data._repoManager || !self->_data._repo.ngInfo() ) return nullptr; - return zypp_wrap_cpp ( self->_data._repo.info () ); + return zypp_wrap_cpp ( *self->_data._repo.ngInfo() ); } diff --git a/zypp-glib/serviceinfo.cc b/zypp-glib/serviceinfo.cc index 5e47c18fad..a7a567c817 100644 --- a/zypp-glib/serviceinfo.cc +++ b/zypp-glib/serviceinfo.cc @@ -67,7 +67,7 @@ zypp_service_info_set_property (GObject *object, { case PROP_CPPOBJ: g_return_if_fail( d->_constrProps ); // only if the constr props are still valid - ZYPP_GLIB_SET_CPPOBJ_PROP( zypp::ServiceInfo, value, d->_constrProps->_cppObj ) + ZYPP_GLIB_SET_CPPOBJ_PROP( zyppng::ServiceInfo, value, d->_constrProps->_cppObj ) case PROP_CONTEXT: { g_return_if_fail( d->_constrProps ); // only if the constr props are still valid ZyppContext *obj = ZYPP_CONTEXT(g_value_get_object( value )); @@ -90,7 +90,7 @@ void ZyppServiceInfoPrivate::initialize() _info = std::move( _constrProps->_cppObj.value() ); } else { if ( !_constrProps->_context ) g_error("Context argument can not be NULL"); - _info = zypp::ServiceInfo( zypp_context_get_cpp( _constrProps->_context.get() ) ); + _info = zyppng::ServiceInfo( zypp_context_get_cpp( _constrProps->_context.get() ) ); } _constrProps.reset(); } @@ -101,7 +101,7 @@ ZyppServiceInfo *zypp_service_info_new ( ZyppContext *context ) return static_cast( g_object_new (ZYPP_TYPE_SERVICE_INFO, "zyppcontext", context, NULL) ); } -ZyppServiceInfo *zypp_wrap_cpp( zypp::ServiceInfo info ) +ZyppServiceInfo *zypp_wrap_cpp( zyppng::ServiceInfo info ) { return static_cast(g_object_new (ZYPP_TYPE_SERVICE_INFO, zypp::glib::internal::ZYPP_CPP_OBJECT_PROPERTY_NAME.data(), &info, NULL)); } diff --git a/zypp-glib/zypp-glib.h b/zypp-glib/zypp-glib.h index 3529e1cc90..a53758fb12 100644 --- a/zypp-glib/zypp-glib.h +++ b/zypp-glib/zypp-glib.h @@ -12,3 +12,5 @@ #include #include #include +#include +#include diff --git a/zypp-media/CMakeLists.txt b/zypp-media/CMakeLists.txt index 0b256333b2..e608ad9382 100644 --- a/zypp-media/CMakeLists.txt +++ b/zypp-media/CMakeLists.txt @@ -67,8 +67,11 @@ SET( zypp_media_ng_HEADERS ng/provideres.h ng/provideitem.h ng/ProvideRes + ng/mediacontext.h + ng/MediaContext ng/mediaverifier.h ng/MediaVerifier + ng/auth/credentialmanager.h ng/worker/devicedriver.h ng/worker/DeviceDriver ng/worker/provideworker.h @@ -93,11 +96,13 @@ SET( zypp_media_ng_SRCS ng/headervaluemap.cc ng/provide.cc ng/provideres.cc + ng/mediacontext.cc ng/providespec.cc ng/provideitem.cc ng/providemessage.cc ng/providequeue.cc ng/mediaverifier.cc + ng/auth/credentialmanager.cc ng/worker/devicedriver.cc ng/worker/provideworker.cc ng/worker/mountingworker.cc diff --git a/zypp-media/auth/authdata.cc b/zypp-media/auth/authdata.cc index 8ae4fab9d5..8a95b86094 100644 --- a/zypp-media/auth/authdata.cc +++ b/zypp-media/auth/authdata.cc @@ -92,5 +92,24 @@ std::ostream & operator << (std::ostream & str, const AuthData & auth_data) return str; } +////////////////////////////////////////////////////////////////////// +// +// CLASS NAME : AuthDataComparator +// +////////////////////////////////////////////////////////////////////// + +bool AuthDataComparator::operator()( const AuthData_Ptr & lhs, const AuthData_Ptr & rhs ) const +{ + static const url::ViewOption vopt = url::ViewOption::DEFAULTS + - url::ViewOption::WITH_USERNAME + - url::ViewOption::WITH_PASSWORD + - url::ViewOption::WITH_QUERY_STR; + // std::less semantic! + int cmp = lhs->url().asString(vopt).compare( rhs->url().asString(vopt) ); + if ( ! cmp ) + cmp = lhs->username().compare( rhs->username() ); + return( cmp < 0 ); +} + } // namespace media } // namespace zypp diff --git a/zypp-media/auth/authdata.h b/zypp-media/auth/authdata.h index 746c0aed65..4819e9a05c 100644 --- a/zypp-media/auth/authdata.h +++ b/zypp-media/auth/authdata.h @@ -81,6 +81,12 @@ class ZYPP_API AuthData using AuthData_Ptr = shared_ptr; std::ostream & operator << (std::ostream & str, const AuthData & auth_data); +// comparator for CredentialSet +struct ZYPP_API AuthDataComparator +{ + bool operator()(const AuthData_Ptr & lhs, const AuthData_Ptr & rhs) const; +}; + /////////////////////////////////////////////////////////////////// } // namespace media diff --git a/zypp-media/auth/credentialmanager.cc b/zypp-media/auth/credentialmanager.cc index 75f35278d4..8361de04fb 100644 --- a/zypp-media/auth/credentialmanager.cc +++ b/zypp-media/auth/credentialmanager.cc @@ -12,497 +12,44 @@ #include "credentialmanager.h" -#include -#include - -#include #include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -namespace bpci = boost::interprocess; +#include using std::endl; -#define USER_CREDENTIALS_FILE ".zypp/credentials.cat" +constexpr std::string_view USER_CREDENTIALS_FILE(".zypp/credentials.cat"); -////////////////////////////////////////////////////////////////////// namespace zypp -{ //////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// +{ namespace media - { //////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////// - // - // CLASS NAME : AuthDataComparator - // - ////////////////////////////////////////////////////////////////////// - - bool AuthDataComparator::operator()( const AuthData_Ptr & lhs, const AuthData_Ptr & rhs ) const - { - static const url::ViewOption vopt = url::ViewOption::DEFAULTS - - url::ViewOption::WITH_USERNAME - - url::ViewOption::WITH_PASSWORD - - url::ViewOption::WITH_QUERY_STR; - // std::less semantic! - int cmp = lhs->url().asString(vopt).compare( rhs->url().asString(vopt) ); - if ( ! cmp ) - cmp = lhs->username().compare( rhs->username() ); - return( cmp < 0 ); - } - - ////////////////////////////////////////////////////////////////////// - // - // CLASS NAME : CredManagerOptions - // - ////////////////////////////////////////////////////////////////////// - - CredManagerOptions::CredManagerOptions(const Pathname & rootdir) - : globalCredFilePath(rootdir / MediaConfig::instance().credentialsGlobalFile()) - , customCredFileDir(rootdir / MediaConfig::instance().credentialsGlobalDir()) - { - char * homedir = getenv("HOME"); - if (homedir) - userCredFilePath = rootdir / homedir / USER_CREDENTIALS_FILE; - } - - - ////////////////////////////////////////////////////////////////////// - // - // CLASS NAME : CredentialManager::Impl - // - struct CredentialManager::Impl - { - Impl(CredManagerOptions &&options); - - Impl(const Impl &) = delete; - Impl(Impl &&) = delete; - Impl &operator=(const Impl &) = delete; - Impl &operator=(Impl &&) = delete; - - ~Impl() - {} - - void init_globalCredentials(); - void init_userCredentials(); - - bool processCredentials(AuthData_Ptr & cred); - - AuthData_Ptr getCred(const Url & url) const; - AuthData_Ptr getCredFromFile(const Pathname & file); - void saveGlobalCredentials(); - void saveUserCredentials(); - - - CredManagerOptions _options; - - CredentialSet _credsGlobal; - CredentialSet _credsUser; - CredentialSet _credsTmp; - - bool _globalDirty; - bool _userDirty; - }; - ////////////////////////////////////////////////////////////////////// - - - ////////////////////////////////////////////////////////////////////// - // - // CLASS NAME : CredentialManager::Impl - // - ////////////////////////////////////////////////////////////////////// - - CredentialManager::Impl::Impl(CredManagerOptions &&options) - : _options(std::move(options)) - , _globalDirty(false) - , _userDirty(false) - { - init_globalCredentials(); - init_userCredentials(); - } - - - void CredentialManager::Impl::init_globalCredentials() { - if (_options.globalCredFilePath.empty()) - DBG << "global cred file not known"; - else if (PathInfo(_options.globalCredFilePath).isExist()) - { - /* list entries; - if (filesystem::readdir(entries, _options.globalCredFilePath, false) != 0) - ZYPP_THROW(Exception("failed to read directory")); - - for_(it, entries.begin(), entries.end())*/ - - CredentialFileReader(_options.globalCredFilePath, - bind(&Impl::processCredentials, this, _1)); - } - else - DBG << "global cred file does not exist"; - - _credsGlobal = _credsTmp; _credsTmp.clear(); - DBG << "Got " << _credsGlobal.size() << " global records." << endl; - } - - - void CredentialManager::Impl::init_userCredentials() - { - if (_options.userCredFilePath.empty()) - DBG << "user cred file not known"; - else if (PathInfo(_options.userCredFilePath).isExist()) - { - /* list entries; - if (filesystem::readdir(entries, _options.userCredFilePath, false ) != 0) - ZYPP_THROW(Exception("failed to read directory")); - - for_(it, entries.begin(), entries.end())*/ - CredentialFileReader(_options.userCredFilePath, - bind(&Impl::processCredentials, this, _1)); - } - else - DBG << "user cred file does not exist" << endl; - - _credsUser = _credsTmp; _credsTmp.clear(); - DBG << "Got " << _credsUser.size() << " user records." << endl; - } - - - bool CredentialManager::Impl::processCredentials(AuthData_Ptr & cred) - { - _credsTmp.insert(cred); - return true; - } - - - AuthData_Ptr CredentialManager::findIn(const CredentialManager::CredentialSet & set, - const Url & url, - url::ViewOption vopt) - { - const std::string & username = url.getUsername(); - for( CredentialManager::CredentialIterator it = set.begin(); it != set.end(); ++it ) - { - if ( !(*it)->url().isValid() ) - continue; - - // this ignores url params - not sure if it is good or bad... - if ( url.asString(vopt).find((*it)->url().asString(vopt)) == 0 ) - { - if ( username.empty() || username == (*it)->username() ) - return *it; + namespace { + void setUserCredFilePath( const zypp::Pathname &root, zypp::Pathname &userCredFilePath ) { + char * homedir = getenv("HOME"); + if (homedir) + userCredFilePath = root / homedir / USER_CREDENTIALS_FILE.data (); } } - return AuthData_Ptr(); - } - - AuthData_Ptr CredentialManager::Impl::getCred(const Url & url) const - { - AuthData_Ptr result; - - // compare the urls via asString(), but ignore password - // default url::ViewOption will take care of that. - // operator==(Url,Url) compares the whole Url - - url::ViewOption vopt; - vopt = vopt - - url::ViewOption::WITH_USERNAME - - url::ViewOption::WITH_PASSWORD - - url::ViewOption::WITH_QUERY_STR; - - // search in global credentials - result = findIn(_credsGlobal, url, vopt); - - // search in home credentials - if (!result) - result = findIn(_credsUser, url, vopt); - - if (result) - DBG << "Found credentials for '" << url << "':" << endl << *result; - else - DBG << "No credentials for '" << url << "'" << endl; - - return result; - } - - - AuthData_Ptr CredentialManager::Impl::getCredFromFile(const Pathname & file) - { - AuthData_Ptr result; - - Pathname credfile; - if (file.absolute()) - // get from that file - credfile = file; - else - // get from /etc/zypp/credentials.d, delete the leading path - credfile = _options.customCredFileDir / file.basename(); - - PathInfo pi { credfile }; - if ( pi.userMayR() ) try { - // make sure only our thread accesses the file - bpci::file_lock lockFile ( credfile.c_str() ); - bpci::scoped_lock lock( lockFile ); - - CredentialFileReader(credfile, bind(&Impl::processCredentials, this, _1)); - } - catch ( ... ) { - WAR << pi << " failed to lock file for reading." << endl; - } - - if (_credsTmp.empty()) - WAR << pi << " does not contain valid credentials or is not readable." << endl; - else + CredManagerSettings::CredManagerSettings( zyppng::MediaContextRef ctx ) + : globalCredFilePath( ctx->contextRoot() / ctx->mediaConfig().credentialsGlobalFile() ) + , customCredFileDir ( ctx->contextRoot() / ctx->mediaConfig().credentialsGlobalDir() ) { - result = *_credsTmp.begin(); - _credsTmp.clear(); + setUserCredFilePath( ctx->contextRoot(), userCredFilePath ); } - return result; - } - - static int save_creds_in_file( - CredentialManager::CredentialSet &creds, - const Pathname & file, - const mode_t mode) - { - int ret = 0; - filesystem::assert_file_mode( file, mode ); - - const auto now = time( nullptr ); - - PathInfo pi { file }; - if ( pi.userMayRW() ) try { - // make sure only our thread accesses the file - bpci::file_lock lockFile ( file.c_str() ); - bpci::scoped_lock lock( lockFile ); - - std::ofstream fs(file.c_str()); - for_(it, creds.begin(), creds.end()) - { - (*it)->dumpAsIniOn(fs); - (*it)->setLastDatabaseUpdate( now ); - fs << endl; - } - if ( !fs ) { - WAR << pi << " failed to write credentials to file." << endl; - ret = 1; - } - fs.close(); - } - catch ( ... ) { - WAR << pi << " failed to lock file for writing." << endl; - ret = 1; - } - - return ret; - } - - void CredentialManager::Impl::saveGlobalCredentials() - { - save_creds_in_file(_credsGlobal, _options.globalCredFilePath, 0640); - } - - void CredentialManager::Impl::saveUserCredentials() - { - save_creds_in_file(_credsUser, _options.userCredFilePath, 0600); - } - - - ////////////////////////////////////////////////////////////////////// - // - // CLASS NAME : CredentialManager - // - ////////////////////////////////////////////////////////////////////// - - CredentialManager::CredentialManager(CredManagerOptions opts) - : _pimpl(new Impl(std::move(opts))) - {} - - - AuthData_Ptr CredentialManager::getCred(const Url & url) - { - std::string credfile = url.getQueryParam("credentials"); - if (credfile.empty()) - return _pimpl->getCred(url); - return _pimpl->getCredFromFile(credfile); - } - - - AuthData_Ptr CredentialManager::getCredFromFile(const Pathname & file) - { return _pimpl->getCredFromFile(file); } - - - void CredentialManager::addCred(const AuthData & cred) - { - if ( !cred.url().isValid() ) - ZYPP_THROW( MediaInvalidCredentialsException( "URL must be valid in order to save AuthData." ) ); - - Pathname credfile = cred.url().getQueryParam("credentials"); - if (credfile.empty()) - //! \todo ask user where to store these creds. saving to user creds for now - addUserCred(cred); - else - saveInFile(cred, credfile); - } - - time_t CredentialManager::timestampForCredDatabase ( const zypp::Url &url ) - { - Pathname credfile; - if ( url.isValid() ) { - credfile = url.getQueryParam("credentials"); - } - - if (credfile.empty()) - credfile = _pimpl->_options.userCredFilePath; - - zypp::PathInfo pi(credfile); - if ( pi.isExist() && pi.isFile() ) - return pi.mtime(); - - return 0; - } - - void CredentialManager::addGlobalCred(const AuthData & cred) - { - if ( !cred.url().isValid() ) - ZYPP_THROW( MediaInvalidCredentialsException( "URL must be valid in order to save AuthData." ) ); - - AuthData_Ptr c_ptr; - c_ptr.reset(new AuthData(cred)); // FIX for child classes if needed - std::pair ret = _pimpl->_credsGlobal.insert(c_ptr); - if (ret.second) - _pimpl->_globalDirty = true; - else if ((*ret.first)->password() != cred.password()) + CredManagerSettings::CredManagerSettings() + : globalCredFilePath( MediaConfig::defaults().credentialsGlobalFile() ) + , customCredFileDir ( MediaConfig::defaults().credentialsGlobalDir() ) { - _pimpl->_credsGlobal.erase(ret.first); - _pimpl->_credsGlobal.insert(c_ptr); - _pimpl->_globalDirty = true; + setUserCredFilePath( "", userCredFilePath ); } - } - - void CredentialManager::addUserCred(const AuthData & cred) - { - if ( !cred.url().isValid() ) - ZYPP_THROW( MediaInvalidCredentialsException( "URL must be valid in order to save AuthData." ) ); - - AuthData_Ptr c_ptr; - c_ptr.reset(new AuthData(cred)); // FIX for child classes if needed - std::pair ret = _pimpl->_credsUser.insert(c_ptr); - if (ret.second) - _pimpl->_userDirty = true; - else if ((*ret.first)->password() != cred.password()) - { - _pimpl->_credsUser.erase(ret.first); - _pimpl->_credsUser.insert(c_ptr); - _pimpl->_userDirty = true; - } - } - - - void CredentialManager::save() - { - if (_pimpl->_globalDirty) - _pimpl->saveGlobalCredentials(); - if (_pimpl->_userDirty) - _pimpl->saveUserCredentials(); - _pimpl->_globalDirty = false; - _pimpl->_userDirty = false; - } - - - void CredentialManager::saveInGlobal(const AuthData & cred) - { - addGlobalCred(cred); - save(); - } - - - void CredentialManager::saveInUser(const AuthData & cred) - { - addUserCred(cred); - save(); - } - - - void CredentialManager::saveInFile(const AuthData & cred, const Pathname & credFile) - { - AuthData_Ptr c_ptr; - c_ptr.reset(new AuthData(cred)); // FIX for child classes if needed - c_ptr->setUrl(Url()); // don't save url in custom creds file - CredentialManager::CredentialSet creds; - creds.insert(c_ptr); - - int ret = 0; - if (credFile.absolute()) - ret = save_creds_in_file(creds, credFile, 0640); - else - ret = save_creds_in_file( - creds, _pimpl->_options.customCredFileDir / credFile, 0600); - - if (!ret) + const char *CredManagerSettings::userCredFile() { - //! \todo figure out the reason(?), call back to user - ERR << "error saving the credentials" << endl; + return USER_CREDENTIALS_FILE.data(); } - } - - - void CredentialManager::clearAll(bool global) - { - if (global) - { - if (!filesystem::unlink(_pimpl->_options.globalCredFilePath)) - ERR << "could not delete user credentials file " - << _pimpl->_options.globalCredFilePath << endl; - _pimpl->_credsUser.clear(); - } - else - { - if (!filesystem::unlink(_pimpl->_options.userCredFilePath)) - ERR << "could not delete global credentials file" - << _pimpl->_options.userCredFilePath << endl; - _pimpl->_credsGlobal.clear(); - } - } - - - CredentialManager::CredentialIterator CredentialManager::credsGlobalBegin() const - { return _pimpl->_credsGlobal.begin(); } - - CredentialManager::CredentialIterator CredentialManager::credsGlobalEnd() const - { return _pimpl->_credsGlobal.end(); } - - CredentialManager::CredentialSize CredentialManager::credsGlobalSize() const - { return _pimpl->_credsGlobal.size(); } - - bool CredentialManager::credsGlobalEmpty() const - { return _pimpl->_credsGlobal.empty(); } - - - CredentialManager::CredentialIterator CredentialManager::credsUserBegin() const - { return _pimpl->_credsUser.begin(); } - - CredentialManager::CredentialIterator CredentialManager::credsUserEnd() const - { return _pimpl->_credsUser.end(); } - - CredentialManager::CredentialSize CredentialManager::credsUserSize() const - { return _pimpl->_credsUser.size(); } - - bool CredentialManager::credsUserEmpty() const - { return _pimpl->_credsUser.empty(); } - //////////////////////////////////////////////////////////////////// } // media diff --git a/zypp-media/auth/credentialmanager.h b/zypp-media/auth/credentialmanager.h index 0c31b281f3..3185f8c754 100644 --- a/zypp-media/auth/credentialmanager.h +++ b/zypp-media/auth/credentialmanager.h @@ -12,23 +12,19 @@ #ifndef ZYPP_MEDIA_AUTH_CREDENTIALMANAGER_H #define ZYPP_MEDIA_AUTH_CREDENTIALMANAGER_H -#include - #include #include #include -////////////////////////////////////////////////////////////////////// -namespace zypp -{ //////////////////////////////////////////////////////////////////// +namespace zyppng { + ZYPP_FWD_DECL_TYPE_WITH_REFS (MediaContext); +} +namespace zypp +{ class Url; - - ////////////////////////////////////////////////////////////////////// namespace media - { //////////////////////////////////////////////////////////////////// - - + { ////////////////////////////////////////////////////////////////////// // // CLASS NAME : CredManagerOptions @@ -36,161 +32,18 @@ namespace zypp /** * \todo configurable cred file locations */ - struct ZYPP_API CredManagerOptions + struct ZYPP_API CredManagerSettings { - CredManagerOptions(const Pathname & rootdir = ""); - + CredManagerSettings( zyppng::MediaContextRef ctx ); + CredManagerSettings() ZYPP_LOCAL; // to support legacy API and tests Pathname globalCredFilePath; Pathname userCredFilePath; Pathname customCredFileDir; - }; - ////////////////////////////////////////////////////////////////////// - // comparator for CredentialSet - struct ZYPP_API AuthDataComparator - { - bool operator()(const AuthData_Ptr & lhs, const AuthData_Ptr & rhs) const; + static const char *userCredFile(); }; - ////////////////////////////////////////////////////////////////////// - // - // CLASS NAME : CredentialManager - // - /** - * \todo better method names - * \todo delete(AuthData) method - */ - class ZYPP_API CredentialManager - { - public: - using CredentialSet = std::set; - using CredentialSize = CredentialSet::size_type; - using CredentialIterator = CredentialSet::const_iterator; - - - CredentialManager(CredManagerOptions opts = CredManagerOptions()); - - ~CredentialManager() - {} - - public: - /** - * Get credentials for the specified \a url. - * - * If the URL contains also username, it will be used to find the match - * for this user (in case mutliple are available). - * - * \param url URL to find credentials for. - * \return Pointer to retrieved authentication data on success or an empty - * AuthData_Ptr otherwise. - * \todo return a copy instead? - */ - AuthData_Ptr getCred(const Url & url); - - /** - * Read credentials from a file. - */ - AuthData_Ptr getCredFromFile(const Pathname & file); - - /** - * Add new global credentials. - */ - void addGlobalCred(const AuthData & cred); - - /** - * Add new user credentials. - */ - void addUserCred(const AuthData & cred); - - /** - * Add new credentials with user callbacks. - * - * If the cred->url() contains 'credentials' query parameter, the - * credentials will be automatically saved to the specified file using the - * \ref saveInFile() method. - * - * Otherwise a callback will be called asking whether to save to custom - * file, or to global or user's credentials catalog. - * - * \todo Currently no callback is called, credentials are automatically - * saved to user's credentials.cat if no 'credentials' parameter - * has been specified - */ - void addCred(const AuthData & cred); - - /** - * Saves any unsaved credentials added via \ref addUserCred() or - * \a addGlobalCred() methods. - */ - void save(); - - /** - * Saves given \a cred to global credentials file. - * - * \note Use this method to add just one piece of credentials. To add - * multiple items at once, use addGlobalCred() followed - * by save() - */ - void saveInGlobal(const AuthData & cred); - - /** - * Saves given \a cred to user's credentials file. - * - * \note Use this method to add just one piece of credentials. To add - * multiple items at once, use addUserCred() followed - * by save() - */ - void saveInUser(const AuthData & cred); - - /** - * Saves given \a cred to user specified credentials file. - * - * If the credFile path is absolute, it will be saved at that precise - * location. If \a credFile is just a filename, it will be saved - * in \ref CredManagerOptions::customCredFileDir. Otherwise the current - * working directory will be prepended to the file path. - */ - void saveInFile(const AuthData &, const Pathname & credFile); - - /** - * Remove all global or user credentials from memory and disk. - * - * \param global Whether to remove global or user credentials. - */ - void clearAll(bool global = false); - - /*! - * Helper function to find a matching AuthData instance in a CredentialSet - */ - static AuthData_Ptr findIn( const CredentialManager::CredentialSet & set, const Url & url, url::ViewOption vopt ); - - /*! - * Returns the timestamp of the database the given URL creds would be stored - */ - time_t timestampForCredDatabase ( const zypp::Url &url ); - - CredentialIterator credsGlobalBegin() const; - CredentialIterator credsGlobalEnd() const; - CredentialSize credsGlobalSize() const; - bool credsGlobalEmpty() const; - - CredentialIterator credsUserBegin() const; - CredentialIterator credsUserEnd() const; - CredentialSize credsUserSize() const; - bool credsUserEmpty() const; - - struct Impl; - private: - RW_pointer _pimpl; - }; - ////////////////////////////////////////////////////////////////////// - - - //////////////////////////////////////////////////////////////////// } // media - ////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////// } // zypp -////////////////////////////////////////////////////////////////////// #endif /* ZYPP_MEDIA_AUTH_CREDENTIALMANAGER_H */ diff --git a/zypp-media/mediaconfig.cc b/zypp-media/mediaconfig.cc index 589c73f190..143cc2190f 100644 --- a/zypp-media/mediaconfig.cc +++ b/zypp-media/mediaconfig.cc @@ -11,11 +11,24 @@ */ #include "mediaconfig.h" +#include +#include #include #include +#include + namespace zypp { + namespace { + // LEGACY: detect zypp conf + zypp::Pathname autodetectZyppConfPath() { + const char *env_confpath = getenv("ZYPP_CONF"); + return env_confpath ? env_confpath + : zyppng::MediaContext::defaultConfigPath(); + } + } + class MediaConfigPrivate { public: @@ -40,13 +53,42 @@ namespace zypp { }; - MediaConfig::MediaConfig() : d_ptr( new MediaConfigPrivate() ) + MediaConfig::MediaConfig( Pathname confFile ) : d_ptr( new MediaConfigPrivate() ) + { + if ( zypp::filesystem::PathInfo(confFile).isExist() ) + { + zypp::parser::IniDict dict( confFile ); + for ( auto sit = dict.sectionsBegin(); + sit != dict.sectionsEnd(); + ++sit ) + { + const std::string& section(*sit); + //MIL << section << endl; + for ( auto it = dict.entriesBegin(*sit); + it != dict.entriesEnd(*sit); + ++it ) + { + std::string entry(it->first); + std::string value(it->second); + setConfigValue( section, entry, value ); + } + } + } + } + + MediaConfig::~MediaConfig() { } - MediaConfig &MediaConfig::instance() + MediaConfig &MediaConfig::systemConfig() + { + static MediaConfig _sysConf( autodetectZyppConfPath() ); + return _sysConf; + } + + const MediaConfig &MediaConfig::defaults() { - static MediaConfig instance; - return instance; + static MediaConfig _defConf( "" ); + return _defConf; } bool MediaConfig::setConfigValue( const std::string §ion, const std::string &entry, const std::string &value ) diff --git a/zypp-media/mediaconfig.h b/zypp-media/mediaconfig.h index 8e0de5e91b..a4079c4f03 100644 --- a/zypp-media/mediaconfig.h +++ b/zypp-media/mediaconfig.h @@ -43,9 +43,11 @@ namespace zypp { { ZYPP_DECLARE_PRIVATE(MediaConfig) public: + MediaConfig( zypp::Pathname confFile ); + ~MediaConfig(); - /*! Singleton ctor */ - static MediaConfig & instance(); + static MediaConfig & systemConfig(); + static const MediaConfig & defaults(); bool setConfigValue ( const std::string §ion, const std::string &entry, const std::string &value ); @@ -91,7 +93,6 @@ namespace zypp { long download_connect_timeout() const; private: - MediaConfig(); std::unique_ptr d_ptr; }; diff --git a/zypp-media/ng/MediaContext b/zypp-media/ng/MediaContext new file mode 100644 index 0000000000..67abe91264 --- /dev/null +++ b/zypp-media/ng/MediaContext @@ -0,0 +1 @@ +#include "mediacontext.h" diff --git a/zypp-media/ng/auth/credentialmanager.cc b/zypp-media/ng/auth/credentialmanager.cc new file mode 100644 index 0000000000..72e77ff8d8 --- /dev/null +++ b/zypp-media/ng/auth/credentialmanager.cc @@ -0,0 +1,393 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ + +#include +#include + +#include "credentialmanager.h" +#include +#include + +#include +#include + +#include +#include +#include + +namespace bpci = boost::interprocess; + + +namespace zyppng::media { + + CredentialManager::CredentialManager( ZYPP_PRIVATE_CONSTR_ARG, zypp::media::CredManagerSettings options ) + : _options(std::move(options)) + , _globalDirty(false) + , _userDirty(false) + { + init_globalCredentials(); + init_userCredentials(); + } + + CredentialManager::~CredentialManager() + { } + + + void CredentialManager::init_globalCredentials() + { + if (_options.globalCredFilePath.empty()) + DBG << "global cred file not known"; + else if ( zypp::PathInfo(_options.globalCredFilePath).isExist()) + { + /* list entries; + if (filesystem::readdir(entries, _options.globalCredFilePath, false) != 0) + ZYPP_THROW(Exception("failed to read directory")); + + for_(it, entries.begin(), entries.end())*/ + + zypp::media::CredentialFileReader(_options.globalCredFilePath, + bind(&CredentialManager::processCredentials, this, std::placeholders::_1)); + } + else + DBG << "global cred file does not exist"; + + _credsGlobal = _credsTmp; _credsTmp.clear(); + DBG << "Got " << _credsGlobal.size() << " global records." << std::endl; + } + + + void CredentialManager::init_userCredentials() + { + if (_options.userCredFilePath.empty()) + DBG << "user cred file not known"; + else if ( zypp::PathInfo(_options.userCredFilePath).isExist() ) + { + /* list entries; + if (filesystem::readdir(entries, _options.userCredFilePath, false ) != 0) + ZYPP_THROW(Exception("failed to read directory")); + + for_(it, entries.begin(), entries.end())*/ + zypp::media::CredentialFileReader(_options.userCredFilePath, + bind(&CredentialManager::processCredentials, this, std::placeholders::_1)); + } + else + DBG << "user cred file does not exist" << std::endl; + + _credsUser = _credsTmp; _credsTmp.clear(); + DBG << "Got " << _credsUser.size() << " user records." << std::endl; + } + + + bool CredentialManager::processCredentials( zypp::media::AuthData_Ptr & cred ) + { + _credsTmp.insert(cred); + return true; + } + + + zypp::media::AuthData_Ptr CredentialManager::findIn(const CredentialManager::CredentialSet & set, + const zypp::Url & url, + zypp::url::ViewOption vopt) + { + const std::string & username = url.getUsername(); + for( CredentialManager::CredentialIterator it = set.begin(); it != set.end(); ++it ) + { + if ( !(*it)->url().isValid() ) + continue; + + // this ignores url params - not sure if it is good or bad... + if ( url.asString(vopt).find((*it)->url().asString(vopt)) == 0 ) + { + if ( username.empty() || username == (*it)->username() ) + return *it; + } + } + + return zypp::media::AuthData_Ptr(); + } + + zypp::media::AuthData_Ptr CredentialManager::getCredFromUrl( const zypp::Url & url ) const + { + zypp::media::AuthData_Ptr result; + + // compare the urls via asString(), but ignore password + // default url::ViewOption will take care of that. + // operator==(Url,Url) compares the whole Url + + zypp::url::ViewOption vopt; + vopt = vopt + - zypp::url::ViewOption::WITH_USERNAME + - zypp::url::ViewOption::WITH_PASSWORD + - zypp::url::ViewOption::WITH_QUERY_STR; + + // search in global credentials + result = findIn(_credsGlobal, url, vopt); + + // search in home credentials + if (!result) + result = findIn(_credsUser, url, vopt); + + if (result) + DBG << "Found credentials for '" << url << "':" << std::endl << *result; + else + DBG << "No credentials for '" << url << "'" << std::endl; + + return result; + } + + + zypp::media::AuthData_Ptr CredentialManager::getCredFromFile(const zypp::Pathname & file) + { + zypp::media::AuthData_Ptr result; + + zypp::Pathname credfile; + if (file.absolute()) + // get from that file + credfile = file; + else + // get from /etc/zypp/credentials.d, delete the leading path + credfile = _options.customCredFileDir / file.basename(); + + zypp::PathInfo pi { credfile }; + if ( pi.userMayR() ) try { + // make sure only our thread accesses the file + bpci::file_lock lockFile ( credfile.c_str() ); + bpci::scoped_lock lock( lockFile ); + + zypp::media::CredentialFileReader(credfile, bind(&CredentialManager::processCredentials, this, std::placeholders::_1)); + } + catch ( ... ) { + WAR << pi << " failed to lock file for reading." << std::endl; + } + + if (_credsTmp.empty()) + WAR << pi << " does not contain valid credentials or is not readable." << std::endl; + else + { + result = *_credsTmp.begin(); + _credsTmp.clear(); + } + + return result; + } + + static int save_creds_in_file( + CredentialManager::CredentialSet &creds, + const zypp::Pathname & file, + const mode_t mode) + { + int ret = 0; + zypp::filesystem::assert_file_mode( file, mode ); + + const auto now = time( nullptr ); + + zypp::PathInfo pi { file }; + if ( pi.userMayRW() ) try { + // make sure only our thread accesses the file + bpci::file_lock lockFile ( file.c_str() ); + bpci::scoped_lock lock( lockFile ); + + std::ofstream fs(file.c_str()); + for_(it, creds.begin(), creds.end()) + { + (*it)->dumpAsIniOn(fs); + (*it)->setLastDatabaseUpdate( now ); + fs << std::endl; + } + if ( !fs ) { + WAR << pi << " failed to write credentials to file." << std::endl; + ret = 1; + } + fs.close(); + } + catch ( ... ) { + WAR << pi << " failed to lock file for writing." << std::endl; + ret = 1; + } + + return ret; + } + + void CredentialManager::saveGlobalCredentials() + { + save_creds_in_file(_credsGlobal, _options.globalCredFilePath, 0640); + } + + void CredentialManager::saveUserCredentials() + { + save_creds_in_file( _credsUser, _options.userCredFilePath, 0600); + } + + zypp::media::AuthData_Ptr CredentialManager::getCred(const zypp::Url & url) + { + std::string credfile = url.getQueryParam("credentials"); + if (credfile.empty()) + return getCredFromUrl(url); + return getCredFromFile(credfile); + } + + void CredentialManager::addCred(const zypp::media::AuthData & cred) + { + if ( !cred.url().isValid() ) + ZYPP_THROW( zypp::media::MediaInvalidCredentialsException( "URL must be valid in order to save AuthData." ) ); + + zypp::Pathname credfile = cred.url().getQueryParam("credentials"); + if (credfile.empty()) + //! \todo ask user where to store these creds. saving to user creds for now + addUserCred(cred); + else + saveInFile(cred, credfile); + } + + time_t CredentialManager::timestampForCredDatabase ( const zypp::Url &url ) + { + zypp::Pathname credfile; + if ( url.isValid() ) { + credfile = url.getQueryParam("credentials"); + } + + if (credfile.empty()) + credfile = _options.userCredFilePath; + + zypp::PathInfo pi(credfile); + if ( pi.isExist() && pi.isFile() ) + return pi.mtime(); + + return 0; + } + + void CredentialManager::addGlobalCred(const zypp::media::AuthData & cred) + { + if ( !cred.url().isValid() ) + ZYPP_THROW( zypp::media::MediaInvalidCredentialsException( "URL must be valid in order to save AuthData." ) ); + + zypp::media::AuthData_Ptr c_ptr; + c_ptr.reset(new zypp::media::AuthData(cred)); // FIX for child classes if needed + std::pair ret = _credsGlobal.insert(c_ptr); + if (ret.second) + _globalDirty = true; + else if ((*ret.first)->password() != cred.password()) + { + _credsGlobal.erase(ret.first); + _credsGlobal.insert(c_ptr); + _globalDirty = true; + } + } + + + void CredentialManager::addUserCred(const zypp::media::AuthData & cred) + { + if ( !cred.url().isValid() ) + ZYPP_THROW( zypp::media::MediaInvalidCredentialsException( "URL must be valid in order to save AuthData." ) ); + + zypp::media::AuthData_Ptr c_ptr; + c_ptr.reset(new zypp::media::AuthData(cred)); // FIX for child classes if needed + std::pair ret = _credsUser.insert(c_ptr); + if (ret.second) + _userDirty = true; + else if ((*ret.first)->password() != cred.password()) + { + _credsUser.erase(ret.first); + _credsUser.insert(c_ptr); + _userDirty = true; + } + } + + + void CredentialManager::save() + { + if (_globalDirty) + saveGlobalCredentials(); + if (_userDirty) + saveUserCredentials(); + _globalDirty = false; + _userDirty = false; + } + + + void CredentialManager::saveInGlobal(const zypp::media::AuthData & cred) + { + addGlobalCred(cred); + save(); + } + + + void CredentialManager::saveInUser(const zypp::media::AuthData & cred) + { + addUserCred(cred); + save(); + } + + + void CredentialManager::saveInFile(const zypp::media::AuthData & cred, const zypp::Pathname & credFile) + { + zypp::media::AuthData_Ptr c_ptr; + c_ptr.reset(new zypp::media::AuthData(cred)); // FIX for child classes if needed + c_ptr->setUrl( zypp::Url() ); // don't save url in custom creds file + CredentialManager::CredentialSet creds; + creds.insert(c_ptr); + + int ret = 0; + if (credFile.absolute()) + ret = save_creds_in_file(creds, credFile, 0640); + else + ret = save_creds_in_file( + creds, _options.customCredFileDir / credFile, 0600); + + if (!ret) + { + //! \todo figure out the reason(?), call back to user + ERR << "error saving the credentials" << std::endl; + } + } + + + void CredentialManager::clearAll(bool global) + { + if (global) + { + if (!zypp::filesystem::unlink(_options.globalCredFilePath)) + ERR << "could not delete user credentials file " + << _options.globalCredFilePath << std::endl; + _credsUser.clear(); + } + else + { + if (!zypp::filesystem::unlink(_options.userCredFilePath)) + ERR << "could not delete global credentials file" + << _options.userCredFilePath << std::endl; + _credsGlobal.clear(); + } + } + + CredentialManager::CredentialIterator CredentialManager::credsGlobalBegin() const + { return _credsGlobal.begin(); } + + CredentialManager::CredentialIterator CredentialManager::credsGlobalEnd() const + { return _credsGlobal.end(); } + + CredentialManager::CredentialSize CredentialManager::credsGlobalSize() const + { return _credsGlobal.size(); } + + bool CredentialManager::credsGlobalEmpty() const + { return _credsGlobal.empty(); } + + CredentialManager::CredentialIterator CredentialManager::credsUserBegin() const + { return _credsUser.begin(); } + + CredentialManager::CredentialIterator CredentialManager::credsUserEnd() const + { return _credsUser.end(); } + + CredentialManager::CredentialSize CredentialManager::credsUserSize() const + { return _credsUser.size(); } + + bool CredentialManager::credsUserEmpty() const + { return _credsUser.empty(); } + +} diff --git a/zypp-media/ng/auth/credentialmanager.h b/zypp-media/ng/auth/credentialmanager.h new file mode 100644 index 0000000000..54eea5e2dc --- /dev/null +++ b/zypp-media/ng/auth/credentialmanager.h @@ -0,0 +1,172 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp-media/ng/auth/CredentialManager + * + */ +#ifndef ZYPP_MEDIA_NG_AUTH_CREDENTIALMANAGER_H +#define ZYPP_MEDIA_NG_AUTH_CREDENTIALMANAGER_H + +#include +#include +#include +#include + +namespace zyppng { + + namespace media { + + ZYPP_FWD_DECL_TYPE_WITH_REFS (CredentialManager); + + class CredentialManager : public Base + { + ZYPP_ADD_CREATE_FUNC (CredentialManager) + public: + using CredentialSet = std::set; + using CredentialSize = CredentialSet::size_type; + using CredentialIterator = CredentialSet::const_iterator; + + CredentialManager( const CredentialManager &) = delete; + CredentialManager( CredentialManager &&) = delete; + CredentialManager &operator=(const CredentialManager &) = delete; + CredentialManager &operator=(CredentialManager &&) = delete; + CredentialManager( ZYPP_PRIVATE_CONSTR_ARG, zypp::media::CredManagerSettings opts); + + ~CredentialManager() override; + + public: + /** + * Get credentials for the specified \a url. + * + * If the URL contains also username, it will be used to find the match + * for this user (in case mutliple are available). + * + * \param url URL to find credentials for. + * \return Pointer to retrieved authentication data on success or an empty + * AuthData_Ptr otherwise. + * \todo return a copy instead? + */ + zypp::media::AuthData_Ptr getCred(const zypp::Url & url); + + /** + * Read credentials from a file. + */ + zypp::media::AuthData_Ptr getCredFromFile(const zypp::Pathname & file); + + /** + * Add new global credentials. + */ + void addGlobalCred(const zypp::media::AuthData & cred); + + /** + * Add new user credentials. + */ + void addUserCred(const zypp::media::AuthData & cred); + + /** + * Add new credentials with user callbacks. + * + * If the cred->url() contains 'credentials' query parameter, the + * credentials will be automatically saved to the specified file using the + * \ref saveInFile() method. + * + * Otherwise a callback will be called asking whether to save to custom + * file, or to global or user's credentials catalog. + * + * \todo Currently no callback is called, credentials are automatically + * saved to user's credentials.cat if no 'credentials' parameter + * has been specified + */ + void addCred(const zypp::media::AuthData & cred); + + /** + * Saves any unsaved credentials added via \ref addUserCred() or + * \a addGlobalCred() methods. + */ + void save(); + + /** + * Saves given \a cred to global credentials file. + * + * \note Use this method to add just one piece of credentials. To add + * multiple items at once, use addGlobalCred() followed + * by save() + */ + void saveInGlobal(const zypp::media::AuthData & cred); + + /** + * Saves given \a cred to user's credentials file. + * + * \note Use this method to add just one piece of credentials. To add + * multiple items at once, use addUserCred() followed + * by save() + */ + void saveInUser(const zypp::media::AuthData & cred); + + /** + * Saves given \a cred to user specified credentials file. + * + * If the credFile path is absolute, it will be saved at that precise + * location. If \a credFile is just a filename, it will be saved + * in \ref CredManagerOptions::customCredFileDir. Otherwise the current + * working directory will be prepended to the file path. + */ + void saveInFile(const zypp::media::AuthData &, const zypp::Pathname & credFile); + + /** + * Remove all global or user credentials from memory and disk. + * + * \param global Whether to remove global or user credentials. + */ + void clearAll(bool global = false); + + /*! + * Helper function to find a matching AuthData instance in a CredentialSet + */ + static zypp::media::AuthData_Ptr findIn(const CredentialManager::CredentialSet & set, const zypp::Url & url, zypp::url::ViewOption vopt ); + + /*! + * Returns the timestamp of the database the given URL creds would be stored + */ + time_t timestampForCredDatabase ( const zypp::Url &url ); + + CredentialIterator credsGlobalBegin() const; + CredentialIterator credsGlobalEnd() const; + CredentialSize credsGlobalSize() const; + bool credsGlobalEmpty() const; + + CredentialIterator credsUserBegin() const; + CredentialIterator credsUserEnd() const; + CredentialSize credsUserSize() const; + bool credsUserEmpty() const; + + struct Impl; + private: + void init_globalCredentials(); + void init_userCredentials(); + + bool processCredentials(zypp::media::AuthData_Ptr & cred); + + zypp::media::AuthData_Ptr getCredFromUrl(const zypp::Url & url) const; + void saveGlobalCredentials(); + void saveUserCredentials(); + + zypp::media::CredManagerSettings _options; + + CredentialSet _credsGlobal; + CredentialSet _credsUser; + CredentialSet _credsTmp; + + bool _globalDirty; + bool _userDirty; + }; + } +} + + +#endif diff --git a/zypp-media/ng/mediacontext.cc b/zypp-media/ng/mediacontext.cc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/zypp-media/ng/mediacontext.h b/zypp-media/ng/mediacontext.h new file mode 100644 index 0000000000..06c6d10ccc --- /dev/null +++ b/zypp-media/ng/mediacontext.h @@ -0,0 +1,35 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +#ifndef ZYPP_MEDIA_NG_MEDIACONTEXT_H_INCLUDED +#define ZYPP_MEDIA_NG_MEDIACONTEXT_H_INCLUDED + +#include + +namespace zypp { + class MediaConfig; +} + +namespace zyppng { + + ZYPP_FWD_DECL_TYPE_WITH_REFS( MediaContext ); + + class MediaContext : public UserInterface { + public: + virtual zypp::Pathname contextRoot() const = 0; + virtual zypp::MediaConfig &mediaConfig() = 0; + + static zypp::Pathname defaultConfigPath(){ + return "/etc/zypp/zypp.conf"; + } + }; + +} + + +#endif diff --git a/zypp-media/ng/private/provide_p.h b/zypp-media/ng/private/provide_p.h index a97166c924..1d9c6ef1f7 100644 --- a/zypp-media/ng/private/provide_p.h +++ b/zypp-media/ng/private/provide_p.h @@ -18,7 +18,7 @@ #include "providequeue_p.h" #include "attachedmediainfo_p.h" -#include +#include #include #include #include @@ -83,7 +83,7 @@ namespace zyppng { std::list &items(); - zypp::media::CredManagerOptions &credManagerOptions (); + zypp::media::CredManagerSettings &credManagerOptions (); std::vector sanitizeUrls ( const std::vector &urls ); @@ -140,7 +140,7 @@ namespace zyppng { std::unordered_map< std::string, FileCacheItem > _fileCache; zypp::Pathname _workerPath; - zypp::media::CredManagerOptions _credManagerOptions; + zypp::media::CredManagerSettings _credManagerOptions; ProvideStatusRef _log; Signal _sigIdle; diff --git a/zypp-media/ng/provide.cc b/zypp-media/ng/provide.cc index 72b9acd573..e4d37d6586 100644 --- a/zypp-media/ng/provide.cc +++ b/zypp-media/ng/provide.cc @@ -701,7 +701,7 @@ namespace zyppng { return _items; } - zypp::media::CredManagerOptions &ProvidePrivate::credManagerOptions () + zypp::media::CredManagerSettings &ProvidePrivate::credManagerOptions() { return _credManagerOptions; } @@ -1195,13 +1195,13 @@ namespace zyppng { return d_func()->_workDir; } - const zypp::media::CredManagerOptions &Provide::credManangerOptions () const + const zypp::media::CredManagerSettings &Provide::credManangerOptions () const { Z_D(); return d->_credManagerOptions; } - void Provide::setCredManagerOptions( const zypp::media::CredManagerOptions & opt ) + void Provide::setCredManagerOptions( const zypp::media::CredManagerSettings & opt ) { d_func()->_credManagerOptions = opt; } diff --git a/zypp-media/ng/provide.h b/zypp-media/ng/provide.h index d932bcaaab..28465b393a 100644 --- a/zypp-media/ng/provide.h +++ b/zypp-media/ng/provide.h @@ -25,7 +25,7 @@ namespace zypp { class Url; namespace media { - struct CredManagerOptions; + struct CredManagerSettings; } } @@ -160,8 +160,8 @@ namespace zyppng { const zypp::Pathname &providerWorkdir () const; - const zypp::media::CredManagerOptions &credManangerOptions () const; - void setCredManagerOptions( const zypp::media::CredManagerOptions & opt ); + const zypp::media::CredManagerSettings &credManangerOptions () const; + void setCredManagerOptions(const zypp::media::CredManagerSettings &opt ); SignalProxy sigIdle(); @@ -182,7 +182,7 @@ namespace zyppng { /*! * This signal is emitted in case a request signaled a need to get Auth Info and nothing was found - * in the \ref zypp::media::CredentialManager. + * in the \ref zyppng::media::CredentialManager. */ SignalProxy< std::optional ( const zypp::Url &reqUrl, const std::string &triedUsername, const std::map &extraValues ) > sigAuthRequired(); diff --git a/zypp-media/ng/provideitem.cc b/zypp-media/ng/provideitem.cc index 87afebc257..e59b2271c9 100644 --- a/zypp-media/ng/provideitem.cc +++ b/zypp-media/ng/provideitem.cc @@ -405,11 +405,11 @@ namespace zyppng { } try { - zypp::media::CredentialManager mgr ( provider().credManagerOptions() ); + auto mgr = zyppng::media::CredentialManager::create( provider().credManagerOptions() ); MIL << "Looking for existing auth data for " << effectiveUrl << "more recent then " << lastTimestamp << std::endl; - auto credPtr = mgr.getCred( effectiveUrl ); + auto credPtr = mgr->getCred( effectiveUrl ); if ( credPtr && credPtr->lastDatabaseUpdate() > lastTimestamp ) { MIL << "Found existing auth data for " << effectiveUrl << "ts: " << credPtr->lastDatabaseUpdate() << std::endl; return expected::success( *credPtr ); @@ -431,12 +431,12 @@ namespace zyppng { return expected::error( ZYPP_EXCPT_PTR( zypp::media::MediaException("No auth given by user." ) ) ); } - mgr.addCred( *userAuth ); - mgr.save(); + mgr->addCred( *userAuth ); + mgr->save(); // rather ugly, but update the timestamp to the last mtime of the cred database our URL belongs to // otherwise we'd need to reload the cred database - userAuth->setLastDatabaseUpdate( mgr.timestampForCredDatabase( effectiveUrl ) ); + userAuth->setLastDatabaseUpdate( mgr->timestampForCredDatabase( effectiveUrl ) ); return expected::success(*userAuth); } catch ( const zypp::Exception &e ) { diff --git a/zypp-media/ng/worker/provideworker.cc b/zypp-media/ng/worker/provideworker.cc index d5ccb90f4e..42b9933744 100644 --- a/zypp-media/ng/worker/provideworker.cc +++ b/zypp-media/ng/worker/provideworker.cc @@ -304,7 +304,7 @@ namespace zyppng::worker { _workerConf = std::move(conf); - auto &mediaConf = zypp::MediaConfig::instance(); + auto &mediaConf = zypp::MediaConfig::systemConfig(); for( const auto &[key,value] : _workerConf ) { zypp::Url keyUrl( key ); if ( keyUrl.getScheme() == "zconfig" && keyUrl.getAuthority() == "main" ) { diff --git a/zypp/CMakeLists.txt b/zypp/CMakeLists.txt index 5528cc4d6d..c3e70aed9b 100644 --- a/zypp/CMakeLists.txt +++ b/zypp/CMakeLists.txt @@ -46,6 +46,7 @@ SET( zypp_SRCS IdString.cc InstanceId.cc KeyManager.cc + KeyContext.cc KeyRing.cc KeyRingContexts.cc Locks.cc @@ -70,6 +71,7 @@ SET( zypp_SRCS RepoManagerOptions.cc Repository.cc RepoStatus.cc + ResFilters.cc ResKind.cc ResObject.cc Resolvable.cc @@ -293,11 +295,22 @@ SET( zypp_ng_SRCS ng/contextbase.cc ng/fusionpool.cc ng/progressobserveradaptor.cc + ng/repoinfo.cc ng/reporthelper.cc ng/repomanager.cc + ng/serviceinfo.cc + ng/userdata.cc ng/userrequest.cc + ng/parser/RepoFileReader.cc + ng/parser/repoindexfilereader.cc + ng/parser/servicefilereader.cc ng/repo/downloader.cc + ng/repo/pluginservices.cc ng/repo/refresh.cc + ng/repo/repoinfobase.cc + ng/repo/repoinfobaseshareddata.cc + ng/repo/repovariables.cc + ng/repo/repovariablescache.cc ng/repo/workflows/plaindir.cc ng/repo/workflows/repodownloaderwf.cc ng/repo/workflows/repomanagerwf.cc @@ -321,15 +334,28 @@ SET( zypp_ng_HEADERS ng/FusionPool ng/Context ng/progressobserveradaptor.h + ng/repoinfo.h + ng/repoinfoshareddata.h ng/reporthelper.h ng/repomanager.h + ng/serviceinfo.h + ng/serviceinfoshareddata.h ng/RepoManager + ng/userdata.h ng/userrequest.h ng/UserRequest + ng/parser/RepoFileReader.h + ng/parser/repoindexfilereader.h + ng/parser/servicefilereader.h ng/repo/downloader.h ng/repo/Downloader + ng/repo/pluginservices.h ng/repo/refresh.h ng/repo/Refresh + ng/repo/repoinfobase.h + ng/repo/repoinfobaseshareddata.h + ng/repo/repovariables.h + ng/repo/repovariablescache.h ng/repo/workflows/plaindir.h ng/repo/workflows/repodownloaderwf.h ng/repo/workflows/repomanagerwf.h @@ -356,18 +382,12 @@ SET( zypp_ng_private_HEADERS SET( zypp_parser_SRCS parser/HistoryLogReader.cc - parser/RepoFileReader.cc - parser/RepoindexFileReader.cc - parser/ServiceFileReader.cc parser/ProductFileReader.cc ) SET( zypp_parser_HEADERS parser/HistoryLogReader.h parser/ParserProgress.h - parser/RepoFileReader.h - parser/RepoindexFileReader.h - parser/ServiceFileReader.h parser/ProductFileReader.h ) @@ -670,9 +690,11 @@ INSTALL( FILES ) SET( zypp_repo_SRCS + repo/GpgCheck.cc repo/RepoException.cc repo/RepoMirrorList.cc repo/RepoType.cc + repo/ServiceRepoState.cc repo/ServiceType.cc repo/PackageProvider.cc repo/SrcPackageProvider.cc @@ -685,30 +707,29 @@ SET( zypp_repo_SRCS repo/RepoVariables.cc repo/RepoInfoBase.cc repo/PluginRepoverification.cc - repo/PluginServices.cc ) SET( zypp_repo_HEADERS + repo/GpgCheck.h repo/RepoException.h - repo/RepoMirrorList.h repo/RepoType.h + repo/ServiceRepoState.h repo/ServiceType.h repo/PackageProvider.h repo/SrcPackageProvider.h repo/RepoProvideFile.h repo/DeltaCandidates.h - repo/Applydeltarpm.h - repo/PackageDelta.h - repo/SUSEMediaVerifier.h - repo/MediaInfoDownloader.h repo/RepoVariables.h repo/RepoInfoBase.h repo/PluginRepoverification.h - repo/PluginServices.h ) SET( zypp_repo_detail_HEADERS - repo/detail/RepoInfoBaseImpl.h + repo/RepoMirrorList.h + repo/Applydeltarpm.h + repo/PackageDelta.h + repo/SUSEMediaVerifier.h + repo/MediaInfoDownloader.h ) INSTALL( FILES @@ -735,14 +756,12 @@ SET( zypp_repo_susetags_HEADERS SET( zypp_misc_HEADERS Misc.h - misc/DefaultLoadSystem.h misc/CheckAccessDeleted.h misc/TestcaseSetup.h misc/LoadTestcase.h ) SET( zypp_misc_SRCS - misc/DefaultLoadSystem.cc misc/CheckAccessDeleted.cc misc/TestcaseSetup.cc misc/LoadTestcase.cc @@ -846,6 +865,10 @@ SET ( zypp_media_compat_HEADERS media/CurlConfig.h ) +SET( zypp_media_compat_SOURCES + media/CredentialManager.cc +) + INSTALL( FILES ${zypp_media_compat_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/zypp/media @@ -895,6 +918,7 @@ ${zypp_parser_susetags_SRCS} ${zypp_parser_xml_SRCS} ${zypp_parser_yum_SRCS} ${zypp_parser_SRCS} +${zypp_media_compat_SOURCES} ${zypp_media_proxyinfo_SRCS} ${zypp_media_SRCS} ${zypp_ng_SRCS} diff --git a/zypp/HistoryLog.cc b/zypp/HistoryLog.cc index a1a5444a40..a35360cba8 100644 --- a/zypp/HistoryLog.cc +++ b/zypp/HistoryLog.cc @@ -21,12 +21,13 @@ #include #include -#include +#include #include #include #include #include +#include using std::endl; using std::string; @@ -111,7 +112,7 @@ namespace zypp inline void openLog() { if ( _fname.empty() ) - _fname = ZConfig::instance().historyLogFile(); + _fname = ZConfig::systemConfig().historyLogFile(); _log.clear(); _log.open( _fname.asString().c_str(), std::ios::out|std::ios::app ); @@ -168,7 +169,7 @@ namespace zypp if ( _refcnt ) closeLog(); - _fname = ZConfig::instance().historyLogFile(); + _fname = ZConfig::systemConfig().historyLogFile(); if ( _fname != "/dev/null" ) // no need to redirect /dev/null into the target _fname = rootdir / _fname; filesystem::assert_dir( _fname.dirname() ); @@ -181,7 +182,7 @@ namespace zypp const Pathname & HistoryLog::fname() { if ( _fname.empty() ) - _fname = ZConfig::instance().historyLogFile(); + _fname = ZConfig::systemConfig().historyLogFile(); return _fname; } @@ -226,7 +227,7 @@ namespace zypp << _sep << HistoryActionID::STAMP_COMMAND.asString(true) // 2 action << _sep << userAtHostname() // 3 requested by << _sep << cmdline() // 4 command - << _sep << str::escape(ZConfig::instance().userData(), _sep) // 6 userdata + << _sep << str::escape(zyppng::UserData::data(), _sep) // 6 userdata << endl; } @@ -252,9 +253,9 @@ namespace zypp _log << _sep; _log - << _sep << p->repoInfo().alias() // 7 repo alias + << _sep << (p->ngRepoInfo().has_value () ? p->ngRepoInfo()->alias() : std::string()) // 7 repo alias << _sep << p->checksum().checksum() // 8 checksum - << _sep << str::escape(ZConfig::instance().userData(), _sep) // 9 userdata + << _sep << str::escape(zyppng::UserData::data(), _sep) // 9 userdata << endl; } @@ -280,37 +281,37 @@ namespace zypp _log << _sep; _log - << _sep << str::escape(ZConfig::instance().userData(), _sep) // 7 userdata + << _sep << str::escape(zyppng::UserData::data(), _sep) // 7 userdata << endl; } ///////////////////////////////////////////////////////////////////////// - void HistoryLog::addRepository(const RepoInfo & repo) + void HistoryLog::addRepository(const zyppng::RepoInfo & repo) { _log << timestamp() // 1 timestamp << _sep << HistoryActionID::REPO_ADD.asString(true) // 2 action << _sep << str::escape(repo.alias(), _sep) // 3 alias << _sep << str::escape(repo.url().asString(), _sep) // 4 primary URL - << _sep << str::escape(ZConfig::instance().userData(), _sep) // 5 userdata + << _sep << str::escape(zyppng::UserData::data(), _sep) // 5 userdata << endl; } - void HistoryLog::removeRepository(const RepoInfo & repo) + void HistoryLog::removeRepository(const zyppng::RepoInfo & repo) { _log << timestamp() // 1 timestamp << _sep << HistoryActionID::REPO_REMOVE.asString(true) // 2 action << _sep << str::escape(repo.alias(), _sep) // 3 alias - << _sep << str::escape(ZConfig::instance().userData(), _sep) // 4 userdata + << _sep << str::escape(zyppng::UserData::data(), _sep) // 4 userdata << endl; } void HistoryLog::modifyRepository( - const RepoInfo & oldrepo, const RepoInfo & newrepo) + const zyppng::RepoInfo & oldrepo, const zyppng::RepoInfo & newrepo) { if (oldrepo.alias() != newrepo.alias()) { @@ -319,7 +320,7 @@ namespace zypp << _sep << HistoryActionID::REPO_CHANGE_ALIAS.asString(true) // 2 action << _sep << str::escape(oldrepo.alias(), _sep) // 3 old alias << _sep << str::escape(newrepo.alias(), _sep) // 4 new alias - << _sep << str::escape(ZConfig::instance().userData(), _sep) // 5 userdata + << _sep << str::escape(zyppng::UserData::data(), _sep) // 5 userdata << endl; } if ( oldrepo.url() != newrepo.url() ) @@ -329,7 +330,7 @@ namespace zypp << _sep << HistoryActionID::REPO_CHANGE_URL.asString(true) // 2 action << _sep << str::escape(oldrepo.url().asString(), _sep) // 3 old url << _sep << str::escape(newrepo.url().asString(), _sep) // 4 new url - << _sep << str::escape(ZConfig::instance().userData(), _sep) // 5 userdata + << _sep << str::escape(zyppng::UserData::data(), _sep) // 5 userdata << endl; } } @@ -345,12 +346,12 @@ namespace zypp << _sep << p->name() // 3 name << _sep << p->edition() // 4 evr << _sep << p->arch() // 5 arch - << _sep << p->repoInfo().alias() // 6 repo alias + << _sep << (p->ngRepoInfo().has_value () ? p->ngRepoInfo()->alias() : std::string()) // 6 repo alias << _sep << p->severity() // 7 severity << _sep << p->category() // 8 category << _sep << ResStatus::validateValueAsString( oldstate ) // 9 old state << _sep << pi.status().validateValueAsString() // 10 new state - << _sep << str::escape(ZConfig::instance().userData(), _sep) // 11 userdata + << _sep << str::escape(zyppng::UserData::data(), _sep) // 11 userdata << endl; } diff --git a/zypp/HistoryLog.h b/zypp/HistoryLog.h index 96c9a7f354..c57ed164fd 100644 --- a/zypp/HistoryLog.h +++ b/zypp/HistoryLog.h @@ -17,10 +17,13 @@ #include #include +namespace zyppng { + class RepoInfo; +} + namespace zypp { class PoolItem; - class RepoInfo; /////////////////////////////////////////////////////////////////// /// \class HistoryLog @@ -107,14 +110,14 @@ namespace zypp * * \param repo info about the added repository */ - void addRepository( const RepoInfo & repo ); + void addRepository( const zyppng::RepoInfo & repo ); /** * Log recently removed repository. * * \param repo info about the removed repository */ - void removeRepository( const RepoInfo & repo ); + void removeRepository( const zyppng::RepoInfo & repo ); /** * Log certain modifications to a repository. @@ -122,7 +125,7 @@ namespace zypp * \param oldrepo info about the old repository * \param newrepo info about the new repository */ - void modifyRepository( const RepoInfo & oldrepo, const RepoInfo & newrepo ); + void modifyRepository( const zyppng::RepoInfo & oldrepo, const zyppng::RepoInfo & newrepo ); /** * Log state changes in patches diff --git a/zypp/KeyContext.cc b/zypp/KeyContext.cc new file mode 100644 index 0000000000..6dec3e37a2 --- /dev/null +++ b/zypp/KeyContext.cc @@ -0,0 +1,62 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +#include "KeyContext.h" + +#include +#include + +namespace zypp { + + class KeyContext::Impl { + + public: + Impl(){} + Impl( zyppng::RepoInfo ri ) : _repoInfo( std::move(ri) ) {} + + std::optional _repoInfo; + + private: + friend KeyContext::Impl * zypp::rwcowClone( const KeyContext::Impl * rhs ); + Impl * clone() const { return new Impl( *this ); } + }; + + ZYPP_BEGIN_LEGACY_API + KeyContext::KeyContext(const RepoInfo &repoinfo) : KeyContext( repoinfo.ngRepoInfo() ) + { } + + const RepoInfo KeyContext::repoInfo() const + { + if ( _pimpl->_repoInfo ) { + return RepoInfo( *_pimpl->_repoInfo ); + } + return RepoInfo(); + } + ZYPP_END_LEGACY_API + + void KeyContext::setRepoInfo(const RepoInfo &repoinfo) + { + _pimpl->_repoInfo = repoinfo.ngRepoInfo(); + } + + KeyContext::KeyContext() : _pimpl(new Impl()) {} + KeyContext::KeyContext(const zyppng::RepoInfo &repoinfo) + : _pimpl( new Impl(repoinfo) ) + { } + + bool KeyContext::empty() const { + return (!_pimpl->_repoInfo.has_value()) || _pimpl->_repoInfo->alias().empty(); + } + void KeyContext::setRepoInfo( const zyppng::RepoInfo &repoinfo ) + { + _pimpl->_repoInfo = repoinfo; + } + const std::optional &KeyContext::ngRepoInfo() const { + return _pimpl->_repoInfo; + } +} // namespace zypp diff --git a/zypp/KeyContext.h b/zypp/KeyContext.h index 2768a7dc0b..4360e1501b 100644 --- a/zypp/KeyContext.h +++ b/zypp/KeyContext.h @@ -1,25 +1,57 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/KeyManager.h + * +*/ #ifndef KEYCONTEXT_H_ #define KEYCONTEXT_H_ -#include +#include +#include +#include + +namespace zyppng { + class RepoInfo; +} namespace zypp { - struct KeyContext + class RepoInfo; + + struct ZYPP_API KeyContext { + class Impl; public: - KeyContext(){} - KeyContext( const RepoInfo & repoinfo ) : _repoInfo( repoinfo ) {} + KeyContext(); + KeyContext(const zyppng::RepoInfo &repoinfo); + KeyContext(const KeyContext &) = default; + KeyContext(KeyContext &&) = default; + KeyContext &operator=(const KeyContext &) = default; + KeyContext &operator=(KeyContext &&) = default; + ~KeyContext() = default; /** Is the context unknown? */ - bool empty() const { return _repoInfo.alias().empty(); } + bool empty() const; public: - const RepoInfo repoInfo() const { return _repoInfo; } - void setRepoInfo(const RepoInfo & repoinfo) { _repoInfo = repoinfo; } - +#ifdef __cpp_lib_optional // YAST/PK explicitly use c++11 until 15-SP3 + const std::optional &ngRepoInfo() const; +#endif + void setRepoInfo(const zyppng::RepoInfo &repoinfo); + + ZYPP_BEGIN_LEGACY_API + KeyContext(const RepoInfo &repoinfo) ZYPP_INTERNAL_DEPRECATE; + const RepoInfo repoInfo() const ZYPP_INTERNAL_DEPRECATE; + void setRepoInfo(const RepoInfo &repoinfo) ZYPP_INTERNAL_DEPRECATE; + ZYPP_END_LEGACY_API private: - RepoInfo _repoInfo; + zypp::RWCOW_pointer _pimpl; }; } diff --git a/zypp/MediaSetAccess.cc b/zypp/MediaSetAccess.cc index b4295e9e64..b157365fa2 100644 --- a/zypp/MediaSetAccess.cc +++ b/zypp/MediaSetAccess.cc @@ -19,6 +19,7 @@ #include #include #include +#include //#include #undef ZYPP_BASE_LOGGER_LOGGROUP @@ -34,16 +35,30 @@ IMPL_PTR_TYPE(MediaSetAccess); /////////////////////////////////////////////////////////////////// - MediaSetAccess::MediaSetAccess(Url url, - Pathname prefered_attach_point) - : _url(std::move(url)) - , _prefAttachPoint(std::move(prefered_attach_point)) + MediaSetAccess::MediaSetAccess(Url url, Pathname prefered_attach_point) + : MediaSetAccess( zypp_detail::GlobalStateHelper::context(), std::move(url), std::move(prefered_attach_point) ) {} MediaSetAccess::MediaSetAccess(std::string label_r, Url url, Pathname prefered_attach_point) - : _url(std::move(url)) + : MediaSetAccess( zypp_detail::GlobalStateHelper::context(), std::move(label_r), std::move(url), std::move(prefered_attach_point) ) + {} + + MediaSetAccess::MediaSetAccess(zyppng::ContextBaseRef ctx, + Url url, + Pathname prefered_attach_point) + : _zyppContext( std::move(ctx) ) + , _url(std::move(url)) + , _prefAttachPoint(std::move(prefered_attach_point)) + {} + + MediaSetAccess::MediaSetAccess( zyppng::ContextBaseRef ctx, + std::string label_r, + Url url, + Pathname prefered_attach_point) + : _zyppContext( std::move(ctx) ) + , _url(std::move(url)) , _prefAttachPoint(std::move(prefered_attach_point)) , _label(std::move( label_r )) {} @@ -192,13 +207,13 @@ IMPL_PTR_TYPE(MediaSetAccess); return Pathname(); } - ManagedFile MediaSetAccess::provideFileFromUrl(const Url &file_url, ProvideFileOptions options) + ManagedFile MediaSetAccess::provideFileFromUrl( zyppng::ContextBaseRef ctx, const Url &file_url, ProvideFileOptions options ) { Url url(file_url); Pathname path(url.getPathName()); url.setPathName ("/"); - MediaSetAccess access(url); + MediaSetAccess access(ctx, url); ManagedFile tmpFile = filesystem::TmpFile::asManagedFile(); @@ -212,11 +227,16 @@ IMPL_PTR_TYPE(MediaSetAccess); return tmpFile; } - ManagedFile MediaSetAccess::provideOptionalFileFromUrl( const Url & file_url ) + ManagedFile MediaSetAccess::provideFileFromUrl(const Url &file_url, ProvideFileOptions options) + { + return provideFileFromUrl( zypp_detail::GlobalStateHelper::context(), file_url, options ); + } + + ManagedFile MediaSetAccess::provideOptionalFileFromUrl( zyppng::ContextBaseRef ctx, const Url & file_url ) { try { - return provideFileFromUrl( file_url, PROVIDE_NON_INTERACTIVE ); + return provideFileFromUrl( ctx, file_url, PROVIDE_NON_INTERACTIVE ); } catch ( const media::MediaFileNotFoundException & excpt_r ) { ZYPP_CAUGHT( excpt_r ); } @@ -225,6 +245,11 @@ IMPL_PTR_TYPE(MediaSetAccess); return ManagedFile(); } + ManagedFile MediaSetAccess::provideOptionalFileFromUrl( const Url & file_url ) + { + return provideOptionalFileFromUrl( zypp_detail::GlobalStateHelper::context(), file_url ); + } + bool MediaSetAccess::doesFileExist(const Pathname & file, unsigned media_nr ) { ProvideFileExistenceOperation op; @@ -413,7 +438,7 @@ IMPL_PTR_TYPE(MediaSetAccess); Url url( medianr > 1 ? rewriteUrl( _url, medianr ) : _url ); media::MediaManager media_mgr; - media::MediaAccessId id = media_mgr.open( url, _prefAttachPoint ); + media::MediaAccessId id = media_mgr.open( _zyppContext, url, _prefAttachPoint ); _medias[medianr] = id; try diff --git a/zypp/MediaSetAccess.h b/zypp/MediaSetAccess.h index 3146296c2c..d1001413e2 100644 --- a/zypp/MediaSetAccess.h +++ b/zypp/MediaSetAccess.h @@ -25,6 +25,10 @@ #include #include +namespace zyppng { + ZYPP_FWD_DECL_TYPE_WITH_REFS(ContextBase); +} + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// @@ -89,9 +93,23 @@ namespace zypp * \param prefered_attach_point Prefered attach (mount) point. Use, if * you want to mount the media to a specific directory. */ - MediaSetAccess( Url url, Pathname prefered_attach_point = "" ); + MediaSetAccess( Url url, Pathname prefered_attach_point = "" ) ZYPP_INTERNAL_DEPRECATE; /** \overload Also taking a \ref label. */ - MediaSetAccess( std::string label_r, Url url, Pathname prefered_attach_point = "" ); + MediaSetAccess( std::string label_r, Url url, Pathname prefered_attach_point = "" ) ZYPP_INTERNAL_DEPRECATE; + + + /** + * Creates a callback enabled media access for specified \a url. + * + * \param url + * \param prefered_attach_point Prefered attach (mount) point. Use, if + * you want to mount the media to a specific directory. + */ + MediaSetAccess( zyppng::ContextBaseRef ctx, Url url, Pathname prefered_attach_point = "" ); + /** \overload Also taking a \ref label. */ + MediaSetAccess( zyppng::ContextBaseRef ctx, std::string label_r, Url url, Pathname prefered_attach_point = "" ); + + ~MediaSetAccess() override; /** @@ -215,7 +233,8 @@ namespace zypp * with the next one, if possible. * \see zypp::media::MediaManager::provideFile() */ - static ManagedFile provideFileFromUrl( const Url & file_url, ProvideFileOptions options = PROVIDE_DEFAULT ); + static ManagedFile provideFileFromUrl( const Url & file_url, ProvideFileOptions options = PROVIDE_DEFAULT ) ZYPP_INTERNAL_DEPRECATE; + static ManagedFile provideFileFromUrl( zyppng::ContextBaseRef ctx, const Url & file_url, ProvideFileOptions options = PROVIDE_DEFAULT ); /** * Provides an optional \a file from \a url. @@ -224,7 +243,8 @@ namespace zypp * rather than throwing a \ref MediaException if the file is not present on * the media. */ - static ManagedFile provideOptionalFileFromUrl( const Url & file_url ); + static ManagedFile provideOptionalFileFromUrl( const Url & file_url ) ZYPP_INTERNAL_DEPRECATE; + static ManagedFile provideOptionalFileFromUrl( zyppng::ContextBaseRef ctx, const Url & file_url ); /** * Release file from media. @@ -364,6 +384,7 @@ namespace zypp std::ostream & dumpOn( std::ostream & str ) const override; private: + zyppng::ContextBaseRef _zyppContext; /** Media or media set URL */ Url _url; diff --git a/zypp/Misc.h b/zypp/Misc.h index bf09a4a3a1..f90e196092 100644 --- a/zypp/Misc.h +++ b/zypp/Misc.h @@ -12,7 +12,6 @@ #ifndef ZYPP_MISC_H #define ZYPP_MISC_H -#include #include #endif // ZYPP_MISC_H diff --git a/zypp/Package.cc b/zypp/Package.cc index c711610da4..ab3c1150a0 100644 --- a/zypp/Package.cc +++ b/zypp/Package.cc @@ -22,6 +22,8 @@ #include #include +#include + /////////////////////////////////////////////////////////////////// namespace zyppintern { @@ -96,7 +98,7 @@ namespace zyppintern } // here and from SrcPackage.cc - Pathname cachedLocation( const OnMediaLocation & loc_r, const RepoInfo & repo_r ) + Pathname cachedLocation( const OnMediaLocation & loc_r, const zyppng::RepoInfo & repo_r ) { PathInfo pi( repo_r.packagesPath() / repo_r.path() / loc_r.filename() ); @@ -277,7 +279,12 @@ namespace zypp { return lookupLocation(); } Pathname Package::cachedLocation() const - { return zyppintern::cachedLocation( location(), repoInfo() ); } + { + const auto &optRepoInfo = ngRepoInfo (); + if ( !optRepoInfo ) + return Pathname(); + return zyppintern::cachedLocation( location(), *optRepoInfo ); + } std::string Package::sourcePkgName() const { diff --git a/zypp/PluginExecutor.cc b/zypp/PluginExecutor.cc index 826a915cf5..792c691f11 100644 --- a/zypp/PluginExecutor.cc +++ b/zypp/PluginExecutor.cc @@ -16,6 +16,8 @@ #include #include +#include + using std::endl; #undef ZYPP_BASE_LOGGER_LOGGROUP @@ -111,8 +113,8 @@ namespace zypp plugin.open(); PluginFrame frame( "PLUGINBEGIN" ); - if ( ZConfig::instance().hasUserData() ) - frame.setHeader( "userdata", ZConfig::instance().userData() ); + if ( zyppng::UserData::hasData() ) + frame.setHeader( "userdata", zyppng::UserData::data() ); doSend( plugin, frame ); // closes on error if ( plugin.isOpen() ) diff --git a/zypp/PurgeKernels.cc b/zypp/PurgeKernels.cc index bb7d16a848..0aa3728317 100644 --- a/zypp/PurgeKernels.cc +++ b/zypp/PurgeKernels.cc @@ -22,12 +22,10 @@ #include #include -#include #include #include #include #include -#include #include #undef ZYPP_BASE_LOGGER_LOGGROUP @@ -132,7 +130,7 @@ namespace zypp { std::set _runningKernelEditionVariants; Flavour _runningKernelFlavour; Arch _kernelArch; - std::string _keepSpec = ZConfig::instance().multiversionKernels(); + std::string _keepSpec = ZConfig::systemConfig().multiversionKernels(); bool _keepRunning = true; bool _detectedRunning = false; }; diff --git a/zypp/RepoInfo.cc b/zypp/RepoInfo.cc index 0e7143a824..6fbc509bea 100644 --- a/zypp/RepoInfo.cc +++ b/zypp/RepoInfo.cc @@ -10,1037 +10,311 @@ * */ -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include +#include "RepoInfo.h" #include -#include +#include +#include -using std::endl; -using zypp::xml::escape; +namespace zypp { -/////////////////////////////////////////////////////////////////// -namespace zypp -{ ///////////////////////////////////////////////////////////////// + ZYPP_BEGIN_LEGACY_API - namespace - { - repo::RepoType probeCache( const Pathname & path_r ) - { - repo::RepoType ret = repo::RepoType::NONE; - if ( PathInfo(path_r).isDir() ) - { - if ( PathInfo(path_r/"/repodata/repomd.xml").isFile() ) - { ret = repo::RepoType::RPMMD; } - else if ( PathInfo(path_r/"/content").isFile() ) - { ret = repo::RepoType::YAST2; } - else if ( PathInfo(path_r/"/cookie").isFile() ) - { ret = repo::RepoType::RPMPLAINDIR; } - } - DBG << "Probed cached type " << ret << " at " << path_r << endl; - return ret; - } - } // namespace - - /////////////////////////////////////////////////////////////////// - // - // CLASS NAME : RepoInfo::Impl - // - /** RepoInfo implementation. */ - struct RepoInfo::Impl : public repo::RepoInfoBase::Impl - { - Impl( zyppng::ContextBaseRef &&context ) - : RepoInfoBase::Impl( std::move(context) ) - , _rawGpgCheck( indeterminate ) - , _rawRepoGpgCheck( indeterminate ) - , _rawPkgGpgCheck( indeterminate ) - , _validRepoSignature( indeterminate ) - , _type(repo::RepoType::NONE_e) - , keeppackages(indeterminate) - , _mirrorListForceMetalink(false) - , emptybaseurls(false) - {} - - Impl(const Impl &) = default; - Impl(Impl &&) = delete; - Impl &operator=(const Impl &) = delete; - Impl &operator=(Impl &&) = delete; - - ~Impl() override {} - - public: - static const unsigned defaultPriority = 99; - static const unsigned noPriority = unsigned(-1); - - void setType( const repo::RepoType & t ) - { _type = t; } - - void setProbedType( const repo::RepoType & t ) const - { - if ( _type == repo::RepoType::NONE && t != repo::RepoType::NONE ) - { const_cast(this)->_type = t; } - } - - repo::RepoType type() const - { - if ( _type == repo::RepoType::NONE ) - setProbedType( probeCache( metadataPath() / path ) ); - return _type; - } - - public: - /** Path to a license tarball in case it exists in the repo. */ - Pathname licenseTgz( const std::string & name_r ) const - { - Pathname ret; - if ( !metadataPath().empty() ) - { - std::string licenseStem( "license" ); - if ( !name_r.empty() ) - { - licenseStem += "-"; - licenseStem += name_r; - } - - filesystem::Glob g; - // TODO: REPOMD: this assumes we know the name of the tarball. In fact - // we'd need to get the file from repomd.xml () - g.add( metadataPath() / path / ("repodata/*"+licenseStem+".tar.gz") ); - if ( g.empty() ) - g.add( metadataPath() / path / (licenseStem+".tar.gz") ); - - if ( !g.empty() ) - ret = *g.begin(); - } - return ret; - } - - const RepoVariablesReplacedUrlList & baseUrls() const - { - const Url & mlurl( _mirrorListUrl.transformed() ); // Variables replaced! - if ( _baseUrls.empty() && ! mlurl.asString().empty() ) - { - emptybaseurls = true; - DBG << "MetadataPath: " << metadataPath() << endl; - repo::RepoMirrorList rmurls( mlurl, metadataPath(), _mirrorListForceMetalink ); - _baseUrls.raw().insert( _baseUrls.raw().end(), rmurls.getUrls().begin(), rmurls.getUrls().end() ); - } - return _baseUrls; - } - - RepoVariablesReplacedUrlList & baseUrls() - { return _baseUrls; } - - bool baseurl2dump() const - { return !emptybaseurls && !_baseUrls.empty(); } - - - const RepoVariablesReplacedUrlList & gpgKeyUrls() const - { return _gpgKeyUrls; } - - RepoVariablesReplacedUrlList & gpgKeyUrls() - { return _gpgKeyUrls; } - - - const std::set & contentKeywords() const - { hasContent()/*init if not yet done*/; return _keywords.second; } - - void addContent( const std::string & keyword_r ) - { _keywords.second.insert( keyword_r ); if ( ! hasContent() ) _keywords.first = true; } - - bool hasContent() const - { - if ( !_keywords.first && ! metadataPath().empty() ) - { - // HACK directly check master index file until RepoManager offers - // some content probing and zypper uses it. - ///////////////////////////////////////////////////////////////// - MIL << "Empty keywords...." << metadataPath() << endl; - Pathname master; - if ( PathInfo( (master=metadataPath()/"/repodata/repomd.xml") ).isFile() ) - { - //MIL << "GO repomd.." << endl; - xml::Reader reader( master ); - while ( reader.seekToNode( 2, "content" ) ) - { - _keywords.second.insert( reader.nodeText().asString() ); - reader.seekToEndNode( 2, "content" ); - } - _keywords.first = true; // valid content in _keywords even if empty - } - else if ( PathInfo( (master=metadataPath()/"/content") ).isFile() ) - { - //MIL << "GO content.." << endl; - iostr::forEachLine( InputStream( master ), - [this]( int num_r, const std::string& line_r )->bool - { - if ( str::startsWith( line_r, "REPOKEYWORDS" ) ) - { - std::vector words; - if ( str::split( line_r, std::back_inserter(words) ) > 1 - && words[0].length() == 12 /*"REPOKEYWORDS"*/ ) - { - this->_keywords.second.insert( ++words.begin(), words.end() ); - } - return true; // mult. occurrances are ok. - } - return( ! str::startsWith( line_r, "META " ) ); // no need to parse into META section. - } ); - _keywords.first = true; // valid content in _keywords even if empty - } - ///////////////////////////////////////////////////////////////// - } - return _keywords.first; - } - - bool hasContent( const std::string & keyword_r ) const - { return( hasContent() && _keywords.second.find( keyword_r ) != _keywords.second.end() ); } - - /** Signature check result needs to be stored/retrieved from _metadataPath. - * Don't call them from outside validRepoSignature/setValidRepoSignature - */ - //@{ - TriBool internalValidRepoSignature() const - { - if ( ! indeterminate(_validRepoSignature) ) - return _validRepoSignature; - // check metadata: - if ( ! metadataPath().empty() ) - { - // A missing ".repo_gpgcheck" might be plaindir(no Downloader) or not yet refreshed signed repo! - TriBool linkval = triBoolFromPath( metadataPath() / ".repo_gpgcheck" ); - return linkval; - } - return indeterminate; - } - - void internalSetValidRepoSignature( TriBool value_r ) - { - if ( PathInfo(metadataPath()).isDir() ) - { - Pathname gpgcheckFile( metadataPath() / ".repo_gpgcheck" ); - if ( PathInfo(gpgcheckFile).isExist() ) - { - TriBool linkval( indeterminate ); - if ( triBoolFromPath( gpgcheckFile, linkval ) && linkval == value_r ) - return; // existing symlink fits value_r - else - filesystem::unlink( gpgcheckFile ); // will write a new one - } - filesystem::symlink( asString(value_r), gpgcheckFile ); - } - _validRepoSignature = value_r; - } - - /** We definitely have a symlink pointing to "indeterminate" (for repoGpgCheckIsMandatory)? - * I.e. user accepted the unsigned repo in Downloader. A test whether `internalValidRepoSignature` - * is indeterminate would include not yet checked repos, which is unwanted here. - */ - bool internalUnsignedConfirmed() const - { - TriBool linkval( true ); // want to see it being switched to indeterminate - return triBoolFromPath( metadataPath() / ".repo_gpgcheck", linkval ) && indeterminate(linkval); - } - - bool triBoolFromPath( const Pathname & path_r, TriBool & ret_r ) const - { - static const Pathname truePath( "true" ); - static const Pathname falsePath( "false" ); - static const Pathname indeterminatePath( "indeterminate" ); - - // Quiet readlink; - static const ssize_t bufsiz = 63; - static char buf[bufsiz+1]; - ssize_t ret = ::readlink( path_r.c_str(), buf, bufsiz ); - buf[ret == -1 ? 0 : ret] = '\0'; - - Pathname linkval( buf ); - - bool known = true; - if ( linkval == truePath ) - ret_r = true; - else if ( linkval == falsePath ) - ret_r = false; - else if ( linkval == indeterminatePath ) - ret_r = indeterminate; - else - known = false; - return known; - } - - TriBool triBoolFromPath( const Pathname & path_r ) const - { TriBool ret(indeterminate); triBoolFromPath( path_r, ret ); return ret; } - - //@} - - private: - TriBool _rawGpgCheck; ///< default gpgcheck behavior: Y/N/ZConf - TriBool _rawRepoGpgCheck; ///< need to check repo sign.: Y/N/(ZConf(Y/N/gpgCheck)) - TriBool _rawPkgGpgCheck; ///< need to check pkg sign.: Y/N/(ZConf(Y/N/gpgCheck)) - - public: - TriBool rawGpgCheck() const { return _rawGpgCheck; } - TriBool rawRepoGpgCheck() const { return _rawRepoGpgCheck; } - TriBool rawPkgGpgCheck() const { return _rawPkgGpgCheck; } - - void rawGpgCheck( TriBool val_r ) { _rawGpgCheck = val_r; } - void rawRepoGpgCheck( TriBool val_r ) { _rawRepoGpgCheck = val_r; } - void rawPkgGpgCheck( TriBool val_r ) { _rawPkgGpgCheck = val_r; } - - bool cfgGpgCheck() const { - if ( !this->_ctx ) { - MIL << "RepoInfo has no context, returning default setting for cfgGpgCheck!" << std::endl; - return true; - } - return indeterminate(_rawGpgCheck) ? this->_ctx->config().gpgCheck() : (bool)_rawGpgCheck; - } - - TriBool cfgRepoGpgCheck() const { - if ( !this->_ctx ) { - MIL << "RepoInfo has no context, returning default setting for cfgRepoGpgCheck!" << std::endl; - return zypp::indeterminate; - } - return indeterminate(_rawGpgCheck) && indeterminate(_rawRepoGpgCheck) ? this->_ctx->config().repoGpgCheck() : _rawRepoGpgCheck; - } - - TriBool cfgPkgGpgCheck() const { - if ( !this->_ctx ) { - MIL << "RepoInfo has no context, returning default setting for cfgPkgGpgCheck!" << std::endl; - return zypp::indeterminate; - } - return indeterminate(_rawGpgCheck) && indeterminate(_rawPkgGpgCheck) ? this->_ctx->config().pkgGpgCheck() : _rawPkgGpgCheck; - } - - private: - TriBool _validRepoSignature; ///< have signed and valid repo metadata - repo::RepoType _type; - public: - TriBool keeppackages; - RepoVariablesReplacedUrl _mirrorListUrl; - bool _mirrorListForceMetalink; - Pathname path; - std::string service; - std::string targetDistro; - - void solvPath ( Pathname new_r ) - { _slvPath = std::move(new_r); } - - void metadataPath( Pathname new_r ) - { _metadataPath = std::move( new_r ); } - - void packagesPath( Pathname new_r ) - { _packagesPath = std::move( new_r ); } - - bool usesAutoMetadataPaths() const - { return str::hasSuffix( _metadataPath.asString(), "/%AUTO%" ); } - - Pathname solvPath() const - { - if ( usesAutoMetadataPaths () ) - return _metadataPath.dirname() / "%SLV%"; - return _slvPath; - } - - Pathname metadataPath() const - { - if ( usesAutoMetadataPaths() ) - return _metadataPath.dirname() / "%RAW%"; - return _metadataPath; - } - - Pathname packagesPath() const - { - if ( _packagesPath.empty() && usesAutoMetadataPaths() ) - return _metadataPath.dirname() / "%PKG%"; - return _packagesPath; - } - - DefaultIntegral priority; - mutable bool emptybaseurls; - - private: - Pathname _slvPath; - Pathname _metadataPath; - Pathname _packagesPath; - - mutable RepoVariablesReplacedUrlList _baseUrls; - mutable std::pair > _keywords; - - RepoVariablesReplacedUrlList _gpgKeyUrls; - - friend Impl * rwcowClone( const Impl * rhs ); - /** clone for RWCOW_pointer */ - Impl * clone() const override - { return new Impl( *this ); } - }; - /////////////////////////////////////////////////////////////////// - - /** \relates RepoInfo::Impl Stream output */ - inline std::ostream & operator<<( std::ostream & str, const RepoInfo::Impl & obj ) + const RepoInfo RepoInfo::noRepo( zyppng::RepoInfo(nullptr) ); + + RepoInfo::RepoInfo( ) + : _pimpl( std::make_unique( zypp_detail::GlobalStateHelper::context() ) ) + {} + + RepoInfo::RepoInfo(zyppng::RepoInfo *pimpl) + : _pimpl(pimpl) + , _ownsImpl(false) + {} + + RepoInfo::~RepoInfo() { - return str << "RepoInfo::Impl"; + if ( !_ownsImpl ) + _pimpl.release(); } - /////////////////////////////////////////////////////////////////// - // - // CLASS NAME : RepoInfo - // - /////////////////////////////////////////////////////////////////// + RepoInfo::RepoInfo( const zyppng::RepoInfo &pimpl ) + : _pimpl( std::make_unique(pimpl) ) + , _ownsImpl( true ) + { } - const RepoInfo RepoInfo::noRepo(nullptr); + RepoInfo::RepoInfo(const RepoInfo &other) + : _pimpl( std::make_unique(*other._pimpl) ) + , _ownsImpl( true ) + {} - RepoInfo::RepoInfo( zyppng::ContextBaseRef context ) - : RepoInfoBase( *( new Impl( std::move(context) ) ) ) + RepoInfo::RepoInfo(RepoInfo &&other) + : _pimpl( std::move(other._pimpl) ) + , _ownsImpl( other._ownsImpl ) {} - RepoInfo::RepoInfo() : RepoInfo( zypp_detail::GlobalStateHelper::context() ) - { /* LEGACY DO NOT ADD CODE */ } + zyppng::repo::RepoInfoBase &RepoInfo::pimpl() + { + return *_pimpl; + } - RepoInfo::~RepoInfo() - {} + const zyppng::repo::RepoInfoBase &RepoInfo::pimpl() const + { + return *_pimpl; + } + + RepoInfo &RepoInfo::operator=(const RepoInfo &other) + { + _pimpl = std::make_unique(*other._pimpl); + _ownsImpl = true; + return *this; + } + + RepoInfo &RepoInfo::operator=( RepoInfo &&other ) + { + _pimpl = std::move(other._pimpl); + _ownsImpl = other._ownsImpl; + return *this; + } unsigned RepoInfo::priority() const - { return pimpl()->priority; } + { return _pimpl->priority(); } unsigned RepoInfo::defaultPriority() - { return Impl::defaultPriority; } + { return zyppng::RepoInfoSharedData::defaultPriority; } unsigned RepoInfo::noPriority() - { return Impl::noPriority; } + { return zyppng::RepoInfoSharedData::noPriority; } void RepoInfo::setPriority( unsigned newval_r ) - { pimpl()->priority = newval_r ? newval_r : Impl::defaultPriority; } - + { _pimpl->setPriority(newval_r); } bool RepoInfo::gpgCheck() const - { return pimpl()->cfgGpgCheck(); } - - void RepoInfo::setGpgCheck( TriBool value_r ) - { pimpl()->rawGpgCheck( value_r ); } + { return _pimpl->gpgCheck(); } - void RepoInfo::setGpgCheck( bool value_r ) // deprecated legacy and for squid - { setGpgCheck( TriBool(value_r) ); } + void RepoInfo::setGpgCheck( zypp::TriBool value_r ) + { _pimpl->setGpgCheck(value_r); } + void RepoInfo::setGpgCheck(bool value_r) + { _pimpl->setGpgCheck(zypp::TriBool(value_r)); } bool RepoInfo::repoGpgCheck() const - { return gpgCheck() || bool(pimpl()->cfgRepoGpgCheck()); } + { return _pimpl->repoGpgCheck(); } bool RepoInfo::repoGpgCheckIsMandatory() const - { - bool ret = ( gpgCheck() && indeterminate(pimpl()->cfgRepoGpgCheck()) ) || bool(pimpl()->cfgRepoGpgCheck()); - if ( ret && pimpl()->internalUnsignedConfirmed() ) // relax if unsigned repo was confirmed in the past - ret = false; - return ret; - } - - void RepoInfo::setRepoGpgCheck( TriBool value_r ) - { pimpl()->rawRepoGpgCheck( value_r ); } + { return _pimpl->repoGpgCheckIsMandatory (); } + void RepoInfo::setRepoGpgCheck( zypp::TriBool value_r ) + { _pimpl->setRepoGpgCheck(value_r); } bool RepoInfo::pkgGpgCheck() const - { return bool(pimpl()->cfgPkgGpgCheck()) || ( gpgCheck() && !bool(validRepoSignature())/*enforced*/ ) ; } + { return _pimpl->pkgGpgCheck(); } bool RepoInfo::pkgGpgCheckIsMandatory() const - { return bool(pimpl()->cfgPkgGpgCheck()) || ( gpgCheck() && indeterminate(pimpl()->cfgPkgGpgCheck()) && !bool(validRepoSignature())/*enforced*/ ); } + { return _pimpl->pkgGpgCheckIsMandatory(); } - void RepoInfo::setPkgGpgCheck( TriBool value_r ) - { pimpl()->rawPkgGpgCheck( value_r ); } + void RepoInfo::setPkgGpgCheck( zypp::TriBool value_r ) + { _pimpl->setPkgGpgCheck(value_r); } + void RepoInfo::getRawGpgChecks( zypp::TriBool & g_r, zypp::TriBool & r_r, zypp::TriBool & p_r ) const + { _pimpl->getRawGpgChecks( g_r, r_r, p_r ); } - void RepoInfo::getRawGpgChecks( TriBool & g_r, TriBool & r_r, TriBool & p_r ) const - { - g_r = pimpl()->rawGpgCheck(); - r_r = pimpl()->rawRepoGpgCheck(); - p_r = pimpl()->rawPkgGpgCheck(); - } - - void RepoInfo::setContext( zyppng::ContextBaseRef context ) - { - pimpl()->_ctx = std::move(context); - } + zypp::TriBool RepoInfo::validRepoSignature() const + { return _pimpl->validRepoSignature(); } - RepoInfo::Impl *RepoInfo::pimpl() - { - return static_cast(_pimpl.get()); - } + void RepoInfo::setValidRepoSignature( zypp::TriBool value_r ) + { _pimpl->setValidRepoSignature (value_r ); } - const RepoInfo::Impl *RepoInfo::pimpl() const - { - return static_cast( _pimpl.get() ); - } - - TriBool RepoInfo::validRepoSignature() const - { - TriBool ret( pimpl()->internalValidRepoSignature() ); - if ( ret && !repoGpgCheck() ) ret = false; // invalidate any old signature if repoGpgCheck is off - return ret; - } - - void RepoInfo::setValidRepoSignature( TriBool value_r ) - { pimpl()->internalSetValidRepoSignature( value_r ); } - - /////////////////////////////////////////////////////////////////// - namespace - { - inline bool changeGpgCheckTo( TriBool & lhs, TriBool rhs ) - { if ( ! sameTriboolState( lhs, rhs ) ) { lhs = rhs; return true; } return false; } - - inline bool changeGpgCheckTo( TriBool ogpg[3], TriBool g, TriBool r, TriBool p ) - { - bool changed = false; - if ( changeGpgCheckTo( ogpg[0], g ) ) changed = true; - if ( changeGpgCheckTo( ogpg[1], r ) ) changed = true; - if ( changeGpgCheckTo( ogpg[2], p ) ) changed = true; - return changed; - } - } // namespace - /////////////////////////////////////////////////////////////////// bool RepoInfo::setGpgCheck( GpgCheck mode_r ) - { - TriBool ogpg[3]; // Gpg RepoGpg PkgGpg - getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] ); - - bool changed = false; - switch ( mode_r ) - { - case GpgCheck::On: - changed = changeGpgCheckTo( ogpg, true, indeterminate, indeterminate ); - break; - case GpgCheck::Strict: - changed = changeGpgCheckTo( ogpg, true, true, true ); - break; - case GpgCheck::AllowUnsigned: - changed = changeGpgCheckTo( ogpg, true, false, false ); - break; - case GpgCheck::AllowUnsignedRepo: - changed = changeGpgCheckTo( ogpg, true, false, indeterminate ); - break; - case GpgCheck::AllowUnsignedPackage: - changed = changeGpgCheckTo( ogpg, true, indeterminate, false ); - break; - case GpgCheck::Default: - changed = changeGpgCheckTo( ogpg, indeterminate, indeterminate, indeterminate ); - break; - case GpgCheck::Off: - changed = changeGpgCheckTo( ogpg, false, indeterminate, indeterminate ); - break; - case GpgCheck::indeterminate: // no change - break; - } - - if ( changed ) - { - setGpgCheck ( ogpg[0] ); - setRepoGpgCheck( ogpg[1] ); - setPkgGpgCheck ( ogpg[2] ); - } - return changed; - } + { return _pimpl->setGpgCheck(mode_r); } - void RepoInfo::setMirrorListUrl( const Url & url_r ) // Raw - { pimpl()->_mirrorListUrl.raw() = url_r; pimpl()->_mirrorListForceMetalink = false; } + void RepoInfo::setMirrorListUrl( const zypp::Url & url_r ) // Raw + { _pimpl->setMirrorListUrl(url_r); } void RepoInfo::setMirrorListUrls( url_set urls ) // Raw - { setMirrorListUrl( urls.empty() ? Url() : urls.front() ); } + { _pimpl->setMirrorListUrls(std::move(urls)); } - void RepoInfo::setMetalinkUrl( const Url & url_r ) // Raw - { pimpl()->_mirrorListUrl.raw() = url_r; pimpl()->_mirrorListForceMetalink = true; } + void RepoInfo::setMetalinkUrl( const zypp::Url & url_r ) // Raw + { _pimpl->setMetalinkUrl(url_r); } void RepoInfo::setMetalinkUrls( url_set urls ) // Raw - { setMetalinkUrl( urls.empty() ? Url() : urls.front() ); } + { _pimpl->setMetalinkUrls(std::move(urls)); } void RepoInfo::setGpgKeyUrls( url_set urls ) - { pimpl()->gpgKeyUrls().raw().swap( urls ); } - - void RepoInfo::setGpgKeyUrl( const Url & url_r ) - { - pimpl()->gpgKeyUrls().raw().clear(); - pimpl()->gpgKeyUrls().raw().push_back( url_r ); - } + { _pimpl->setGpgKeyUrls(std::move(urls)); } + void RepoInfo::setGpgKeyUrl( const zypp::Url & url_r ) + { _pimpl->setGpgKeyUrl(url_r); } - Pathname RepoInfo::provideKey(const std::string &keyID_r, const Pathname &targetDirectory_r) const { - // LEGACY, only supported with SyncContext - auto sCtx = std::dynamic_pointer_cast( context() ); - if ( sCtx ) return zyppng::RepoInfoWorkflow::provideKey( sCtx, *this, keyID_r, targetDirectory_r ); - ERR << "Calling RepoInfo::provideKey in a async context is not supported" << std::endl; - return {}; - } - - void RepoInfo::addBaseUrl( Url url_r ) - { - for ( const auto & url : pimpl()->baseUrls().raw() ) // Raw unique! - if ( url == url_r ) - return; - pimpl()->baseUrls().raw().push_back( std::move(url_r) ); - } + void RepoInfo::addBaseUrl( zypp::Url url_r ) + { _pimpl->addBaseUrl( std::move(url_r) ); } - void RepoInfo::setBaseUrl( Url url_r ) - { - pimpl()->baseUrls().raw().clear(); - pimpl()->baseUrls().raw().push_back( std::move(url_r) ); - } + void RepoInfo::setBaseUrl( zypp::Url url_r ) + { _pimpl->setBaseUrl( std::move(url_r) ); } void RepoInfo::setBaseUrls( url_set urls ) - { pimpl()->baseUrls().raw().swap( urls ); } + { _pimpl->setBaseUrls(std::move(urls)); } - void RepoInfo::setPath( const Pathname &path ) - { pimpl()->path = path; } + void RepoInfo::setPath( const zypp::Pathname &path ) + { _pimpl->setPath(path); } - void RepoInfo::setType( const repo::RepoType &t ) - { pimpl()->setType( t ); } + void RepoInfo::setType( const zypp::repo::RepoType &t ) + { _pimpl->setType(t); } - void RepoInfo::setProbedType( const repo::RepoType &t ) const - { pimpl()->setProbedType( t ); } + void RepoInfo::setProbedType( const zypp::repo::RepoType &t ) const + { _pimpl->setProbedType(t); } + void RepoInfo::setMetadataPath( const zypp::Pathname &path ) + { _pimpl->setMetadataPath(path); } - void RepoInfo::setMetadataPath( const Pathname &path ) - { pimpl()->metadataPath( path ); } + void RepoInfo::setPackagesPath( const zypp::Pathname &path ) + { _pimpl->setPackagesPath(path); } - void RepoInfo::setPackagesPath( const Pathname &path ) - { pimpl()->packagesPath( path ); } - - void RepoInfo::setSolvCachePath(const Pathname &path) - { pimpl()->solvPath (path); } + void RepoInfo::setSolvCachePath(const zypp::Pathname &path) + { _pimpl->setSolvCachePath(path); } void RepoInfo::setKeepPackages( bool keep ) - { pimpl()->keeppackages = keep; } + { _pimpl->setKeepPackages( keep ); } void RepoInfo::setService( const std::string& name ) - { pimpl()->service = name; } + { _pimpl->setService(name); } void RepoInfo::setTargetDistribution( const std::string & targetDistribution ) - { pimpl()->targetDistro = targetDistribution; } + { _pimpl->setTargetDistribution( targetDistribution ); } bool RepoInfo::keepPackages() const - { return indeterminate(pimpl()->keeppackages) ? false : (bool)pimpl()->keeppackages; } + { return _pimpl->keepPackages(); } - Pathname RepoInfo::metadataPath() const - { return pimpl()->metadataPath(); } + zypp::Pathname RepoInfo::metadataPath() const + { return _pimpl->metadataPath(); } - Pathname RepoInfo::packagesPath() const - { return pimpl()->packagesPath(); } + zypp::Pathname RepoInfo::packagesPath() const + { return _pimpl->packagesPath(); } - Pathname RepoInfo::solvCachePath() const - { return pimpl()->solvPath(); } + zypp::Pathname RepoInfo::solvCachePath() const + { return _pimpl->solvCachePath(); } bool RepoInfo::usesAutoMetadataPaths() const - { return pimpl()->usesAutoMetadataPaths(); } + { return _pimpl->usesAutoMetadataPaths(); } - repo::RepoType RepoInfo::type() const - { return pimpl()->type(); } + zypp::repo::RepoType RepoInfo::type() const + { return _pimpl->type(); } - Url RepoInfo::mirrorListUrl() const // Variables replaced! - { return pimpl()->_mirrorListUrl.transformed(); } + zypp::Url RepoInfo::mirrorListUrl() const + { return _pimpl->mirrorListUrl(); } - Url RepoInfo::rawMirrorListUrl() const // Raw - { return pimpl()->_mirrorListUrl.raw(); } + zypp::Url RepoInfo::rawMirrorListUrl() const // Raw + { return _pimpl->rawMirrorListUrl(); } bool RepoInfo::gpgKeyUrlsEmpty() const - { return pimpl()->gpgKeyUrls().empty(); } + { return _pimpl->gpgKeyUrlsEmpty(); } RepoInfo::urls_size_type RepoInfo::gpgKeyUrlsSize() const - { return pimpl()->gpgKeyUrls().size(); } + { return _pimpl->gpgKeyUrlsSize(); } RepoInfo::url_set RepoInfo::gpgKeyUrls() const // Variables replaced! - { return pimpl()->gpgKeyUrls().transformed(); } + { return _pimpl->gpgKeyUrls(); } RepoInfo::url_set RepoInfo::rawGpgKeyUrls() const // Raw - { return pimpl()->gpgKeyUrls().raw(); } + { return _pimpl->rawGpgKeyUrls(); } - Url RepoInfo::gpgKeyUrl() const // Variables replaced! - { return( pimpl()->gpgKeyUrls().empty() ? Url() : *pimpl()->gpgKeyUrls().transformedBegin() ); } + zypp::Url RepoInfo::gpgKeyUrl() const // Variables replaced! + { return _pimpl->gpgKeyUrl(); } - Url RepoInfo::rawGpgKeyUrl() const // Raw - { return( pimpl()->gpgKeyUrls().empty() ? Url() : *pimpl()->gpgKeyUrls().rawBegin() ) ; } + zypp::Url RepoInfo::rawGpgKeyUrl() const // Raw + { return _pimpl->rawGpgKeyUrl(); } RepoInfo::url_set RepoInfo::baseUrls() const // Variables replaced! - { return pimpl()->baseUrls().transformed(); } + { return _pimpl->baseUrls(); } RepoInfo::url_set RepoInfo::rawBaseUrls() const // Raw - { return pimpl()->baseUrls().raw(); } + { return _pimpl->rawBaseUrls(); } - Pathname RepoInfo::path() const - { return pimpl()->path; } + zypp::Pathname RepoInfo::path() const + { return _pimpl->path(); } std::string RepoInfo::service() const - { return pimpl()->service; } + { return _pimpl->service(); } std::string RepoInfo::targetDistribution() const - { return pimpl()->targetDistro; } + { return _pimpl->targetDistribution(); } - Url RepoInfo::rawUrl() const - { return( pimpl()->baseUrls().empty() ? Url() : *pimpl()->baseUrls().rawBegin() ); } + zypp::Url RepoInfo::rawUrl() const + { return _pimpl->rawUrl(); } RepoInfo::urls_const_iterator RepoInfo::baseUrlsBegin() const - { return pimpl()->baseUrls().transformedBegin(); } + { return _pimpl->baseUrlsBegin(); } RepoInfo::urls_const_iterator RepoInfo::baseUrlsEnd() const - { return pimpl()->baseUrls().transformedEnd(); } + { return _pimpl->baseUrlsEnd(); } RepoInfo::urls_size_type RepoInfo::baseUrlsSize() const - { return pimpl()->baseUrls().size(); } + { return _pimpl->baseUrlsSize(); } bool RepoInfo::baseUrlsEmpty() const - { return pimpl()->baseUrls().empty(); } + { return _pimpl->baseUrlsEmpty(); } bool RepoInfo::baseUrlSet() const - { return pimpl()->baseurl2dump(); } + { return _pimpl->baseUrlSet(); } const std::set & RepoInfo::contentKeywords() const - { return pimpl()->contentKeywords(); } + { return _pimpl->contentKeywords(); } void RepoInfo::addContent( const std::string & keyword_r ) - { pimpl()->addContent( keyword_r ); } + { _pimpl->addContent( keyword_r ); } bool RepoInfo::hasContent() const - { return pimpl()->hasContent(); } + { return _pimpl->hasContent(); } bool RepoInfo::hasContent( const std::string & keyword_r ) const - { return pimpl()->hasContent( keyword_r ); } - - /////////////////////////////////////////////////////////////////// + { return _pimpl->hasContent( keyword_r ); } bool RepoInfo::hasLicense() const - { return hasLicense( std::string() ); } + { return _pimpl->hasLicense( ); } bool RepoInfo::hasLicense( const std::string & name_r ) const - { return !pimpl()->licenseTgz( name_r ).empty(); } - + { return _pimpl->hasLicense(name_r); } bool RepoInfo::needToAcceptLicense() const - { return needToAcceptLicense( std::string() ); } + { return _pimpl->needToAcceptLicense(); } bool RepoInfo::needToAcceptLicense( const std::string & name_r ) const - { - const Pathname & licenseTgz( pimpl()->licenseTgz( name_r ) ); - if ( licenseTgz.empty() ) - return false; // no licenses at all - - ExternalProgram::Arguments cmd; - cmd.push_back( "tar" ); - cmd.push_back( "-t" ); - cmd.push_back( "-z" ); - cmd.push_back( "-f" ); - cmd.push_back( licenseTgz.asString() ); - ExternalProgram prog( cmd, ExternalProgram::Stderr_To_Stdout ); - - bool accept = true; - static const std::string noAcceptanceFile = "no-acceptance-needed\n"; - for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) - { - if ( output == noAcceptanceFile ) - { - accept = false; - } - } - prog.close(); - MIL << "License(" << name_r << ") in " << name() << " has to be accepted: " << (accept?"true":"false" ) << endl; - return accept; - } + { return _pimpl->needToAcceptLicense( name_r ); } + std::string RepoInfo::getLicense( const zypp::Locale & lang_r ) + { return _pimpl->getLicense(lang_r); } - std::string RepoInfo::getLicense( const Locale & lang_r ) - { return const_cast(this)->getLicense( std::string(), lang_r ); } + std::string RepoInfo::getLicense( const zypp::Locale & lang_r ) const + { return _pimpl->getLicense (lang_r); } - std::string RepoInfo::getLicense( const Locale & lang_r ) const - { return getLicense( std::string(), lang_r ); } + std::string RepoInfo::getLicense( const std::string & name_r, const zypp::Locale & lang_r ) const + { return _pimpl->getLicense ( name_r, lang_r ); } - std::string RepoInfo::getLicense( const std::string & name_r, const Locale & lang_r ) const - { - LocaleSet avlocales( getLicenseLocales( name_r ) ); - if ( avlocales.empty() ) - return std::string(); - - Locale getLang( Locale::bestMatch( avlocales, lang_r ) ); - if ( !getLang && avlocales.find( Locale::noCode ) == avlocales.end() ) - { - WAR << "License(" << name_r << ") in " << name() << " contains no fallback text!" << endl; - // Using the fist locale instead of returning no text at all. - // So the user might recognize that there is a license, even if they - // can't read it. - getLang = *avlocales.begin(); - } - - // now extract the license file. - static const std::string licenseFileFallback( "license.txt" ); - std::string licenseFile( !getLang ? licenseFileFallback - : str::form( "license.%s.txt", getLang.c_str() ) ); - - ExternalProgram::Arguments cmd; - cmd.push_back( "tar" ); - cmd.push_back( "-x" ); - cmd.push_back( "-z" ); - cmd.push_back( "-O" ); - cmd.push_back( "-f" ); - cmd.push_back( pimpl()->licenseTgz( name_r ).asString() ); // if it not exists, avlocales was empty. - cmd.push_back( licenseFile ); - - std::string ret; - ExternalProgram prog( cmd, ExternalProgram::Discard_Stderr ); - for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) - { - ret += output; - } - prog.close(); - return ret; - } - - - LocaleSet RepoInfo::getLicenseLocales() const - { return getLicenseLocales( std::string() ); } - - LocaleSet RepoInfo::getLicenseLocales( const std::string & name_r ) const - { - const Pathname & licenseTgz( pimpl()->licenseTgz( name_r ) ); - if ( licenseTgz.empty() ) - return LocaleSet(); - - ExternalProgram::Arguments cmd; - cmd.push_back( "tar" ); - cmd.push_back( "-t" ); - cmd.push_back( "-z" ); - cmd.push_back( "-f" ); - cmd.push_back( licenseTgz.asString() ); - - LocaleSet ret; - ExternalProgram prog( cmd, ExternalProgram::Stderr_To_Stdout ); - for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) - { - static const C_Str license( "license." ); - static const C_Str dotTxt( ".txt\n" ); - if ( str::hasPrefix( output, license ) && str::hasSuffix( output, dotTxt ) ) - { - if ( output.size() <= license.size() + dotTxt.size() ) // license.txt - ret.insert( Locale() ); - else - ret.insert( Locale( std::string( output.c_str()+license.size(), output.size()- license.size() - dotTxt.size() ) ) ); - } - } - prog.close(); - return ret; - } + zypp::LocaleSet RepoInfo::getLicenseLocales() const + { return _pimpl->getLicenseLocales(); } - /////////////////////////////////////////////////////////////////// + zypp::LocaleSet RepoInfo::getLicenseLocales( const std::string & name_r ) const + { return _pimpl->getLicenseLocales( name_r ); } std::ostream & RepoInfo::dumpOn( std::ostream & str ) const - { - RepoInfoBase::dumpOn(str); - if ( pimpl()->baseurl2dump() ) - { - for ( const auto & url : pimpl()->baseUrls().raw() ) - { - str << "- url : " << url << std::endl; - } - } - - // print if non empty value - auto strif( [&] ( const std::string & tag_r, const std::string & value_r ) { - if ( ! value_r.empty() ) - str << tag_r << value_r << std::endl; - }); - - strif( (pimpl()->_mirrorListForceMetalink ? "- metalink : " : "- mirrorlist : "), rawMirrorListUrl().asString() ); - strif( "- path : ", path().asString() ); - str << "- type : " << type() << std::endl; - str << "- priority : " << priority() << std::endl; - - // Yes No Default(Y) Default(N) -#define OUTS(T,B) ( indeterminate(T) ? (std::string("D(")+(B?"Y":"N")+")") : ((bool)T?"Y":"N") ) - str << "- gpgcheck : " << OUTS(pimpl()->rawGpgCheck(),gpgCheck()) - << " repo" << OUTS(pimpl()->rawRepoGpgCheck(),repoGpgCheck()) << (repoGpgCheckIsMandatory() ? "* ": " " ) - << "sig" << asString( validRepoSignature(), "?", "Y", "N" ) - << " pkg" << OUTS(pimpl()->rawPkgGpgCheck(),pkgGpgCheck()) << (pkgGpgCheckIsMandatory() ? "* ": " " ) - << std::endl; -#undef OUTS - - for ( const auto & url : pimpl()->gpgKeyUrls().raw() ) - { - str << "- gpgkey : " << url << std::endl; - } - - if ( ! indeterminate(pimpl()->keeppackages) ) - str << "- keeppackages: " << keepPackages() << std::endl; - - strif( "- service : ", service() ); - strif( "- targetdistro: ", targetDistribution() ); - strif( "- filePath: ", filepath().asString() ); - strif( "- metadataPath: ", metadataPath().asString() ); - strif( "- packagesPath: ", packagesPath().asString() ); - - return str; - } + { return _pimpl->dumpOn( str ); } std::ostream & RepoInfo::dumpAsIniOn( std::ostream & str ) const - { - RepoInfoBase::dumpAsIniOn(str); - - if ( pimpl()->baseurl2dump() ) - { - str << "baseurl="; - std::string indent; - for ( const auto & url : pimpl()->baseUrls().raw() ) - { - str << indent << hotfix1050625::asString( url ) << endl; - if ( indent.empty() ) indent = " "; // "baseurl=" - } - } - - if ( ! pimpl()->path.empty() ) - str << "path="<< path() << endl; - - if ( ! (rawMirrorListUrl().asString().empty()) ) - str << (pimpl()->_mirrorListForceMetalink ? "metalink=" : "mirrorlist=") << hotfix1050625::asString( rawMirrorListUrl() ) << endl; - - if ( type() != repo::RepoType::NONE ) - str << "type=" << type().asString() << endl; - - if ( priority() != defaultPriority() ) - str << "priority=" << priority() << endl; - - if ( ! indeterminate(pimpl()->rawGpgCheck()) ) - str << "gpgcheck=" << (pimpl()->rawGpgCheck() ? "1" : "0") << endl; - - if ( ! indeterminate(pimpl()->rawRepoGpgCheck()) ) - str << "repo_gpgcheck=" << (pimpl()->rawRepoGpgCheck() ? "1" : "0") << endl; - - if ( ! indeterminate(pimpl()->rawPkgGpgCheck()) ) - str << "pkg_gpgcheck=" << (pimpl()->rawPkgGpgCheck() ? "1" : "0") << endl; - - { - std::string indent( "gpgkey="); - for ( const auto & url : pimpl()->gpgKeyUrls().raw() ) - { - str << indent << url << endl; - if ( indent[0] != ' ' ) - indent = " "; - } - } - - if (!indeterminate(pimpl()->keeppackages)) - str << "keeppackages=" << keepPackages() << endl; - - if( ! service().empty() ) - str << "service=" << service() << endl; - - return str; - } + { return _pimpl->dumpAsIniOn( str ); } std::ostream & RepoInfo::dumpAsXmlOn( std::ostream & str, const std::string & content ) const - { - std::string tmpstr; - str - << "rawGpgCheck()) ) - str << " raw_gpgcheck=\"" << (pimpl()->rawGpgCheck() ? "1" : "0") << "\""; - if ( ! indeterminate(pimpl()->rawRepoGpgCheck()) ) - str << " raw_repo_gpgcheck=\"" << (pimpl()->rawRepoGpgCheck() ? "1" : "0") << "\""; - if ( ! indeterminate(pimpl()->rawPkgGpgCheck()) ) - str << " raw_pkg_gpgcheck=\"" << (pimpl()->rawPkgGpgCheck() ? "1" : "0") << "\""; - if (!(tmpstr = gpgKeyUrl().asString()).empty()) - if (!(tmpstr = gpgKeyUrl().asString()).empty()) - str << " gpgkey=\"" << escape(tmpstr) << "\""; - if (!(tmpstr = mirrorListUrl().asString()).empty()) - str << (pimpl()->_mirrorListForceMetalink ? " metalink=\"" : " mirrorlist=\"") << escape(tmpstr) << "\""; - str << ">" << endl; - - if ( pimpl()->baseurl2dump() ) - { - for_( it, baseUrlsBegin(), baseUrlsEnd() ) // !transform iterator replaces variables - str << "" << escape((*it).asString()) << "" << endl; - } - - str << "" << endl; - return str; - } - + { return _pimpl->dumpAsXmlOn ( str, content );} std::ostream & operator<<( std::ostream & str, const RepoInfo & obj ) - { - return obj.dumpOn(str); - } - - std::ostream & operator<<( std::ostream & str, const RepoInfo::GpgCheck & obj ) - { - switch ( obj ) - { -#define OUTS( V ) case RepoInfo::V: return str << #V; break - OUTS( GpgCheck::On ); - OUTS( GpgCheck::Strict ); - OUTS( GpgCheck::AllowUnsigned ); - OUTS( GpgCheck::AllowUnsignedRepo ); - OUTS( GpgCheck::AllowUnsignedPackage ); - OUTS( GpgCheck::Default ); - OUTS( GpgCheck::Off ); - OUTS( GpgCheck::indeterminate ); -#undef OUTS - } - return str << "GpgCheck::UNKNOWN"; - } + { return obj.dumpOn(str); } bool RepoInfo::requireStatusWithMediaFile () const - { - // We skip the check for downloading media unless a local copy of the - // media file exists and states that there is more than one medium. - bool canSkipMediaCheck = std::all_of( baseUrlsBegin(), baseUrlsEnd(), []( const zypp::Url &url ) { return url.schemeIsDownloading(); }); - if ( canSkipMediaCheck ) { - const auto &mDataPath = metadataPath(); - if ( not mDataPath.empty() ) { - PathInfo mediafile { mDataPath/"media.1/media" }; - if ( mediafile.isExist() ) { - repo::SUSEMediaVerifier lverifier { mediafile.path() }; - if ( lverifier && lverifier.totalMedia() > 1 ) { - canSkipMediaCheck = false; - } - } - } - } - if ( canSkipMediaCheck ) - DBG << "Can SKIP media.1/media check for status calc of repo " << alias() << endl; - return not canSkipMediaCheck; - } + { return _pimpl->requireStatusWithMediaFile(); } + + zyppng::RepoInfo &RepoInfo::ngRepoInfo() + { return *_pimpl; } + + const zyppng::RepoInfo &RepoInfo::ngRepoInfo() const + { return *_pimpl; } - ///////////////////////////////////////////////////////////////// -} // namespace zypp -/////////////////////////////////////////////////////////////////// + ZYPP_END_LEGACY_API +} diff --git a/zypp/RepoInfo.h b/zypp/RepoInfo.h index d03363092b..cb9ce885aa 100644 --- a/zypp/RepoInfo.h +++ b/zypp/RepoInfo.h @@ -24,17 +24,19 @@ #include #include #include - -#include +#include namespace zyppng { - ZYPP_FWD_DECL_TEMPL_TYPE_WITH_REFS_ARG1 ( RepoManager, ContextType ); + class RepoInfo; } +ZYPP_BEGIN_LEGACY_API + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// // // CLASS NAME : RepoInfo @@ -73,22 +75,21 @@ namespace zypp * \note Name, baseUrls and mirrorUrl are subject to repo variable replacement * (\see \ref RepoVariablesStringReplacer). */ - class ZYPP_API RepoInfo : public repo::RepoInfoBase + class ZYPP_API ZYPP_INTERNAL_DEPRECATE RepoInfo : public repo::RepoInfoBase { friend std::ostream & operator<<( std::ostream & str, const RepoInfo & obj ); public: - - // nullable -> ContextFactory::defaultContext() ? - RepoInfo ( zyppng::ContextBaseRef context ) ZYPP_LOCAL; - - ZYPP_INTERNAL_DEPRECATE RepoInfo(); + RepoInfo(); ~RepoInfo() override; - RepoInfo(const RepoInfo &) = default; - RepoInfo(RepoInfo &&) = default; - RepoInfo &operator=(const RepoInfo &) = default; - RepoInfo &operator=(RepoInfo &&) = default; + // copy of the ng repoinfo, cow semantics apply + explicit RepoInfo( const zyppng::RepoInfo &pimpl ); + + RepoInfo(const RepoInfo &); + RepoInfo(RepoInfo &&); + RepoInfo &operator=(const RepoInfo &) ; + RepoInfo &operator=(RepoInfo &&); /** Represents no Repository (one with an empty alias). */ static const ZYPP_INTERNAL_DEPRECATE RepoInfo noRepo; @@ -116,7 +117,7 @@ namespace zypp using url_set = std::list; using urls_size_type = url_set::size_type; - using urls_const_iterator = transform_iterator; + using urls_const_iterator = transform_iterator; /** * whether repository urls are available */ @@ -389,17 +390,7 @@ namespace zypp /** Set the value for \ref validRepoSignature (or \c indeterminate if unsigned). */ void setValidRepoSignature( TriBool value_r ); - /** Some predefined settings */ - enum class GpgCheck { - indeterminate, //< not specified - On, //< 1** --gpgcheck - Strict, //< 111 --gpgcheck-strict - AllowUnsigned, //< 100 --gpgcheck-allow-unsigned - AllowUnsignedRepo, //< 10* --gpgcheck-allow-unsigned-repo - AllowUnsignedPackage, //< 1*0 --gpgcheck-allow-unsigned-package - Default, //< *** --default-gpgcheck - Off, //< 0** --no-gpgcheck - }; + using GpgCheck = zypp::repo::GpgCheck; /** Adjust *GpgCheck settings according to \a mode_r. * \c GpgCheck::indeterminate will leave the settings as they are. @@ -580,24 +571,29 @@ namespace zypp */ void getRawGpgChecks( TriBool & g_r, TriBool & r_r, TriBool & p_r ) const; - struct Impl; + zyppng::RepoInfo &ngRepoInfo(); + const zyppng::RepoInfo &ngRepoInfo() const; + private: friend class RepoManager; - template friend class zyppng::RepoManager; - // for RepoManager to be able to set the context - void setContext( zyppng::ContextBaseRef context ); + /*! + * Creates a RepoInfo instance that basically works like + * a reference to the ng object. Moving it will keep the same reference semantics, + * however a copy also will copy the ng RepoInfo + * \internal + */ + RepoInfo( zyppng::RepoInfo *pimpl ); - Impl *pimpl(); - const Impl *pimpl() const; + zyppng::repo::RepoInfoBase &pimpl() override; + const zyppng::repo::RepoInfoBase &pimpl() const override; -#if LEGACY(1735) - /** Pointer to implementation */ - RWCOW_pointer _dummy_for_abi; -#endif + // only reason this is a pointer , is that we do not want to export the ng symbols + std::unique_ptr _pimpl; + bool _ownsImpl = true; }; /////////////////////////////////////////////////////////////////// - + /// /** \relates RepoInfo */ using RepoInfo_Ptr = shared_ptr; /** \relates RepoInfo */ @@ -620,10 +616,10 @@ namespace zypp /** \relates RepoInfo Stream output */ std::ostream & operator<<( std::ostream & str, const RepoInfo & obj ) ZYPP_API; - /** \relates RepoInfo::GpgCheck Stream output */ - std::ostream & operator<<( std::ostream & str, const RepoInfo::GpgCheck & obj ) ZYPP_API; - ///////////////////////////////////////////////////////////////// } // namespace zypp + +ZYPP_END_LEGACY_API + /////////////////////////////////////////////////////////////////// #endif // ZYPP2_REPOSITORYINFO_H diff --git a/zypp/RepoManager.cc b/zypp/RepoManager.cc index abc9414bcb..d2ae4a6add 100644 --- a/zypp/RepoManager.cc +++ b/zypp/RepoManager.cc @@ -20,6 +20,7 @@ #include #include #include +#include #undef ZYPP_BASE_LOGGER_LOGGROUP #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::repomanager" @@ -33,6 +34,9 @@ using namespace zypp::repo; /////////////////////////////////////////////////////////////////// namespace zypp { + + ZYPP_BEGIN_LEGACY_API + /////////////////////////////////////////////////////////////////// /// \class RepoManager::Impl /// \brief RepoManager implementation. @@ -44,6 +48,7 @@ namespace zypp Impl( zyppng::SyncContextRef &&ctx, RepoManagerOptions &&opt) { _ngMgr = zyppng::SyncRepoManager::create( std::move(ctx), std::move(opt) ); _ngMgr->initialize().unwrap(); + sync(); } Impl(const Impl &) = delete; @@ -64,6 +69,43 @@ namespace zypp return _ngMgr; } + void syncRepos() { + auto &ngRepos = _ngMgr->reposManip(); + _repos.clear(); + + // add repos we do not know yet + for ( const auto &r : ngRepos ) { + // COW semantics apply + zypp::RepoInfo tmp(r.second); + if ( _repos.count(tmp) == 0 ) + _repos.insert( std::move(tmp) ); + } + } + + void syncServices() { + auto &ngServices = _ngMgr->servicesManip(); + _services.clear(); + + // add repos we do not know yet + for ( const auto &s : ngServices ) { + // COW semantics apply + zypp::ServiceInfo tmp = s.second; + if ( _services.count(tmp) == 0 ) + _services.insert( std::move(tmp) ); + } + } + + void sync() { + // we need to keep source level compatibility, and because we return direct iterators + // into our service and repo sets we need to provide real sets of the legacy RepoInfo and ServiceInfo + // using sync'ed sets is the only way I could think of for now + syncRepos(); + syncServices(); + } + + ServiceSet _services; + RepoSet _repos; + private: zyppng::SyncRepoManagerRef _ngMgr; @@ -99,13 +141,18 @@ namespace zypp { return _pimpl->ngMgr().repoSize(); } RepoManager::RepoConstIterator RepoManager::repoBegin() const - { return _pimpl->ngMgr().repoBegin(); } + { return _pimpl->_repos.begin(); } RepoManager::RepoConstIterator RepoManager::repoEnd() const - { return _pimpl->ngMgr().repoEnd(); } + { return _pimpl->_repos.end(); } RepoInfo RepoManager::getRepo( const std::string & alias ) const - { return _pimpl->ngMgr().getRepo( alias ); } + { + const auto &optRepo = _pimpl->ngMgr().getRepo( alias ); + if ( !optRepo ) + return RepoInfo(); + return RepoInfo(*optRepo); + } bool RepoManager::hasRepo( const std::string & alias ) const { return _pimpl->ngMgr().hasRepo( alias ); } @@ -131,48 +178,54 @@ namespace zypp } RepoStatus RepoManager::metadataStatus( const RepoInfo & info ) const - { return _pimpl->ngMgr().metadataStatus( info ).unwrap(); } + { return _pimpl->ngMgr().metadataStatus( info.ngRepoInfo() ).unwrap(); } RepoManager::RefreshCheckStatus RepoManager::checkIfToRefreshMetadata( const RepoInfo &info, const Url &url, RawMetadataRefreshPolicy policy ) - { return _pimpl->ngMgr().checkIfToRefreshMetadata( const_cast(info), url, policy ).unwrap(); } + { + auto res = _pimpl->ngMgr().checkIfToRefreshMetadata( const_cast(info).ngRepoInfo() , url, policy ).unwrap(); + _pimpl->syncRepos(); + return res; + } Pathname RepoManager::metadataPath( const RepoInfo &info ) const - { return _pimpl->ngMgr().metadataPath( info ).unwrap(); } + { return _pimpl->ngMgr().metadataPath( info.ngRepoInfo() ).unwrap(); } Pathname RepoManager::packagesPath( const RepoInfo &info ) const - { return _pimpl->ngMgr().packagesPath( info ).unwrap(); } + { return _pimpl->ngMgr().packagesPath( info.ngRepoInfo() ).unwrap(); } void RepoManager::refreshMetadata( const RepoInfo &info, RawMetadataRefreshPolicy policy, const ProgressData::ReceiverFnc & progressrcv ) { // Suppress (interactive) media::MediaChangeReport if we in have multiple basurls (>1) zypp::media::ScopedDisableMediaChangeReport guard( info.baseUrlsSize() > 1 ); - return _pimpl->ngMgr().refreshMetadata( const_cast(info), policy, nullptr ).unwrap(); + _pimpl->ngMgr().refreshMetadata( const_cast(info).ngRepoInfo(), policy, nullptr ).unwrap(); + _pimpl->syncRepos(); } void RepoManager::cleanMetadata( const RepoInfo &info, const ProgressData::ReceiverFnc & progressrcv ) - { return _pimpl->ngMgr().cleanMetadata( info, nullptr ).unwrap(); } + { return _pimpl->ngMgr().cleanMetadata( info.ngRepoInfo(), nullptr ).unwrap(); } void RepoManager::cleanPackages( const RepoInfo &info, const ProgressData::ReceiverFnc & progressrcv ) - { return _pimpl->ngMgr().cleanPackages( info, nullptr ).unwrap(); } + { return _pimpl->ngMgr().cleanPackages( info.ngRepoInfo(), nullptr ).unwrap(); } RepoStatus RepoManager::cacheStatus( const RepoInfo &info ) const - { return _pimpl->ngMgr().cacheStatus( info ).unwrap(); } + { return _pimpl->ngMgr().cacheStatus( info.ngRepoInfo() ).unwrap(); } void RepoManager::buildCache( const RepoInfo &info, CacheBuildPolicy policy, const ProgressData::ReceiverFnc & progressrcv ) { callback::SendReport report; auto adapt = zyppng::ProgressObserverAdaptor( progressrcv, report ); - return _pimpl->ngMgr().buildCache( const_cast(info), policy, adapt.observer() ).unwrap(); + _pimpl->ngMgr().buildCache( const_cast(info).ngRepoInfo(), policy, adapt.observer() ).unwrap(); + _pimpl->syncRepos(); } void RepoManager::cleanCache( const RepoInfo &info, const ProgressData::ReceiverFnc & progressrcv ) - { return _pimpl->ngMgr().cleanCache( info, nullptr ).unwrap(); } + { return _pimpl->ngMgr().cleanCache( info.ngRepoInfo(), nullptr ).unwrap(); } bool RepoManager::isCached( const RepoInfo &info ) const - { return _pimpl->ngMgr().isCached( info ).unwrap(); } + { return _pimpl->ngMgr().isCached( info.ngRepoInfo() ).unwrap(); } void RepoManager::loadFromCache( const RepoInfo &info, const ProgressData::ReceiverFnc & progressrcv ) - { return zypp_detail::GlobalStateHelper::pool ()->loadFromCache ( info, nullptr ).unwrap(); } + { return zypp_detail::GlobalStateHelper::pool ()->loadFromCache ( info.ngRepoInfo() , nullptr ).unwrap(); } void RepoManager::cleanCacheDirGarbage( const ProgressData::ReceiverFnc & progressrcv ) { return _pimpl->ngMgr().cleanCacheDirGarbage( nullptr ).unwrap(); } @@ -187,17 +240,22 @@ namespace zypp { callback::SendReport report; auto adapt = zyppng::ProgressObserverAdaptor( progressrcv, report ); - _pimpl->ngMgr().addRepository( const_cast(info), adapt.observer() ).unwrap(); + _pimpl->ngMgr().addRepository( const_cast(info).ngRepoInfo(), adapt.observer() ).unwrap(); + _pimpl->syncRepos(); } void RepoManager::addRepositories( const Url &url, const ProgressData::ReceiverFnc & progressrcv ) - { return _pimpl->ngMgr().addRepositories( url, nullptr ).unwrap(); } + { + _pimpl->ngMgr().addRepositories( url, nullptr ).unwrap(); + _pimpl->syncRepos(); + } void RepoManager::removeRepository( const RepoInfo & info, const ProgressData::ReceiverFnc & progressrcv ) { callback::SendReport report; auto adapt = zyppng::ProgressObserverAdaptor( progressrcv, report ); - return _pimpl->ngMgr().removeRepository( const_cast(info), adapt.observer() ).unwrap(); + _pimpl->ngMgr().removeRepository( const_cast(info).ngRepoInfo(), adapt.observer() ).unwrap(); + _pimpl->syncRepos(); } void RepoManager::modifyRepository( const std::string &alias, const RepoInfo & newinfo, const ProgressData::ReceiverFnc & progressrcv ) @@ -205,14 +263,17 @@ namespace zypp // We should fix the API as we must inject those paths // into the repoinfo in order to keep it usable. RepoInfo & oinfo( const_cast(newinfo) ); - _pimpl->ngMgr().modifyRepository( alias, oinfo, nullptr ).unwrap(); + _pimpl->ngMgr().modifyRepository( alias, oinfo.ngRepoInfo(), nullptr ).unwrap(); + _pimpl->syncRepos(); } RepoInfo RepoManager::getRepositoryInfo( const std::string &alias, const ProgressData::ReceiverFnc & progressrcv ) - { return _pimpl->ngMgr().getRepositoryInfo( alias ).unwrap(); } + { + return RepoInfo(_pimpl->ngMgr().getRepositoryInfo( alias ).unwrap()); + } RepoInfo RepoManager::getRepositoryInfo( const Url & url, const url::ViewOption & urlview, const ProgressData::ReceiverFnc & progressrcv ) - { return _pimpl->ngMgr().getRepositoryInfo( url, urlview ).unwrap(); } + { return RepoInfo(_pimpl->ngMgr().getRepositoryInfo( url, urlview ).unwrap()); } bool RepoManager::serviceEmpty() const { return _pimpl->ngMgr().serviceEmpty(); } @@ -221,13 +282,17 @@ namespace zypp { return _pimpl->ngMgr().serviceSize(); } RepoManager::ServiceConstIterator RepoManager::serviceBegin() const - { return _pimpl->ngMgr().serviceBegin(); } + { return _pimpl->_services.begin(); } RepoManager::ServiceConstIterator RepoManager::serviceEnd() const - { return _pimpl->ngMgr().serviceEnd(); } + { return _pimpl->_services.end(); } ServiceInfo RepoManager::getService( const std::string & alias ) const - { return _pimpl->ngMgr().getService( alias ); } + { + const auto &optService = _pimpl->ngMgr().getService( alias ); + if ( !optService ) return ServiceInfo(); + return ServiceInfo(*optService); + } bool RepoManager::hasService( const std::string & alias ) const { return _pimpl->ngMgr().hasService( alias ); } @@ -236,28 +301,52 @@ namespace zypp { return _pimpl->ngMgr().probeService( url ).unwrap(); } void RepoManager::addService( const std::string & alias, const Url& url ) - { return _pimpl->ngMgr().addService( alias, url ).unwrap(); } + { + _pimpl->ngMgr().addService( alias, url ).unwrap(); + _pimpl->syncServices(); + } void RepoManager::addService( const ServiceInfo & service ) - { return _pimpl->ngMgr().addService( service ).unwrap(); } + { + _pimpl->ngMgr().addService( service.ngServiceInfo() ).unwrap(); + _pimpl->syncServices(); + } void RepoManager::removeService( const std::string & alias ) - { return _pimpl->ngMgr().removeService( alias ).unwrap(); } + { + _pimpl->ngMgr().removeService( alias ).unwrap(); + _pimpl->syncServices(); + } void RepoManager::removeService( const ServiceInfo & service ) - { return _pimpl->ngMgr().removeService( service ).unwrap(); } + { + _pimpl->ngMgr().removeService( service.ngServiceInfo() ).unwrap(); + _pimpl->syncServices(); + } void RepoManager::refreshServices( const RefreshServiceOptions & options_r ) - { return _pimpl->ngMgr().refreshServices( options_r ).unwrap(); } + { + _pimpl->ngMgr().refreshServices( options_r ).unwrap(); + _pimpl->sync(); + } void RepoManager::refreshService( const std::string & alias, const RefreshServiceOptions & options_r ) - { return _pimpl->ngMgr().refreshService( alias, options_r ).unwrap(); } + { + _pimpl->ngMgr().refreshService( alias, options_r ).unwrap(); + _pimpl->sync(); + } void RepoManager::refreshService( const ServiceInfo & service, const RefreshServiceOptions & options_r ) - { return _pimpl->ngMgr().refreshService( service, options_r ).unwrap(); } + { + _pimpl->ngMgr().refreshService( service.ngServiceInfo(), options_r ).unwrap(); + _pimpl->sync(); + } void RepoManager::modifyService( const std::string & oldAlias, const ServiceInfo & service ) - { return _pimpl->ngMgr().modifyService( oldAlias, service ).unwrap(); } + { + _pimpl->ngMgr().modifyService( oldAlias, service.ngServiceInfo() ).unwrap(); + _pimpl->syncServices(); + } void RepoManager::refreshGeoIp (const RepoInfo::url_set &urls) { (void) _pimpl->ngMgr().refreshGeoIp( urls ); } @@ -269,9 +358,17 @@ namespace zypp std::list readRepoFile(const Url &repo_file) { - return zyppng::RepoManagerWorkflow::readRepoFile( zypp_detail::GlobalStateHelper::context(), repo_file ).unwrap(); + std::list rIs; + + auto ngList = zyppng::RepoManagerWorkflow::readRepoFile( zypp_detail::GlobalStateHelper::context(), repo_file ).unwrap(); + for ( const auto &ngRi : ngList ) + rIs.push_back( zypp::RepoInfo(ngRi) ); + + return rIs; } + ZYPP_END_LEGACY_API + ///////////////////////////////////////////////////////////////// } // namespace zypp /////////////////////////////////////////////////////////////////// diff --git a/zypp/RepoManager.h b/zypp/RepoManager.h index 8f511a5a07..6476d31177 100644 --- a/zypp/RepoManager.h +++ b/zypp/RepoManager.h @@ -36,6 +36,8 @@ namespace zypp { ///////////////////////////////////////////////////////////////// + ZYPP_BEGIN_LEGACY_API + /** * Parses \a repo_file and returns a list of \ref RepoInfo objects * corresponding to repositories found within the file. @@ -659,6 +661,8 @@ namespace zypp inline Iterable RepoManager::services() const { return makeIterable( serviceBegin(), serviceEnd() ); } + ZYPP_END_LEGACY_API + ///////////////////////////////////////////////////////////////// } // namespace zypp /////////////////////////////////////////////////////////////////// diff --git a/zypp/RepoManagerOptions.cc b/zypp/RepoManagerOptions.cc index 402e01aee5..987c9bc61e 100644 --- a/zypp/RepoManagerOptions.cc +++ b/zypp/RepoManagerOptions.cc @@ -12,6 +12,8 @@ #include "RepoManagerOptions.h" #include +#include +#include namespace zypp { @@ -21,7 +23,8 @@ namespace zypp // //////////////////////////////////////////////////////////////////// - RepoManagerOptions::RepoManagerOptions( const Pathname & root_r ) + ZYPP_BEGIN_LEGACY_API + RepoManagerOptions::RepoManagerOptions( const Pathname & root_r ) : probe(ZConfig::instance().repo_add_probe()) { repoCachePath = Pathname::assertprefix( root_r, ZConfig::instance().repoCachePath() ); repoRawCachePath = Pathname::assertprefix( root_r, ZConfig::instance().repoMetadataPath() ); @@ -30,13 +33,30 @@ namespace zypp knownReposPath = Pathname::assertprefix( root_r, ZConfig::instance().knownReposPath() ); knownServicesPath = Pathname::assertprefix( root_r, ZConfig::instance().knownServicesPath() ); pluginsPath = Pathname::assertprefix( root_r, ZConfig::instance().pluginsPath() ); - probe = ZConfig::instance().repo_add_probe(); + rootDir = root_r; + context = zypp_detail::GlobalStateHelper::context(); + } + ZYPP_END_LEGACY_API + + RepoManagerOptions::RepoManagerOptions( zyppng::ContextBaseRef ctx ) + : probe(ctx->config().repo_add_probe()) + , context(ctx) + { + rootDir = ctx->contextRoot(); + repoCachePath = Pathname::assertprefix( rootDir, ctx->config().repoCachePath() ); + repoRawCachePath = Pathname::assertprefix( rootDir, ctx->config().repoMetadataPath() ); + repoSolvCachePath = Pathname::assertprefix( rootDir, ctx->config().repoSolvfilesPath() ); + repoPackagesCachePath = Pathname::assertprefix( rootDir, ctx->config().repoPackagesPath() ); + knownReposPath = Pathname::assertprefix( rootDir, ctx->config().knownReposPath() ); + knownServicesPath = Pathname::assertprefix( rootDir, ctx->config().knownServicesPath() ); + pluginsPath = Pathname::assertprefix( rootDir, ctx->config().pluginsPath() ); } RepoManagerOptions RepoManagerOptions::makeTestSetup( const Pathname & root_r ) { + ZYPP_BEGIN_LEGACY_API RepoManagerOptions ret; ret.repoCachePath = root_r; ret.repoRawCachePath = root_r/"raw"; @@ -46,6 +66,7 @@ namespace zypp ret.knownServicesPath = root_r/"services.d"; ret.pluginsPath = root_r/"plugins"; ret.rootDir = root_r; + ZYPP_END_LEGACY_API return ret; } diff --git a/zypp/RepoManagerOptions.h b/zypp/RepoManagerOptions.h index fa37c646f6..069f635882 100644 --- a/zypp/RepoManagerOptions.h +++ b/zypp/RepoManagerOptions.h @@ -16,6 +16,10 @@ #include #include +namespace zyppng { + ZYPP_FWD_DECL_TYPE_WITH_REFS (ContextBase); +} + namespace zypp { /** @@ -35,7 +39,21 @@ namespace zypp * \knownReposPath * \endcode */ - RepoManagerOptions( const Pathname & root_r = Pathname() ); + RepoManagerOptions( const Pathname & root_r = Pathname() ) ZYPP_INTERNAL_DEPRECATE; + + + /** Default ctor following \ref ZConfig global settings. + * If an optional \c root_r directory is given, all paths will + * be prefixed accordingly. + * \code + * ctx->contextRoot() \repoCachePath + * \repoRawCachePath + * \repoSolvCachePath + * \repoPackagesCachePath + * \knownReposPath + * \endcode + */ + RepoManagerOptions( zyppng::ContextBaseRef ctx ); /** Test setup adjusting all paths to be located below one \c root_r directory. * \code @@ -66,6 +84,9 @@ namespace zypp /** remembers root_r value for later use */ Pathname rootDir; + + /** remember the context we want to use */ + zyppng::ContextBaseWeakRef context; }; std::ostream & operator<<( std::ostream & str, const RepoManagerOptions & obj ); diff --git a/zypp/RepoStatus.cc b/zypp/RepoStatus.cc index f0756b4dd4..bbac78e511 100644 --- a/zypp/RepoStatus.cc +++ b/zypp/RepoStatus.cc @@ -19,6 +19,7 @@ #include #include #include +#include using std::endl; @@ -192,12 +193,18 @@ namespace zypp } } - RepoStatus::RepoStatus( const RepoInfo & info_r ) + ZYPP_BEGIN_LEGACY_API + RepoStatus::RepoStatus( const RepoInfo & info_r ) : RepoStatus( info_r.ngRepoInfo() ) + { } + ZYPP_END_LEGACY_API + + RepoStatus::RepoStatus( const zyppng::RepoInfo & info_r ) : _pimpl( new Impl() ) { _pimpl->assignFromCtor( CheckSum::sha1FromString( info_r.url().asString() ).checksum(), Date() ); } + RepoStatus::RepoStatus( std::string checksum_r, Date timestamp_r ) : _pimpl( new Impl() ) { diff --git a/zypp/RepoStatus.h b/zypp/RepoStatus.h index 7aaf2c72fc..f4acdd00ca 100644 --- a/zypp/RepoStatus.h +++ b/zypp/RepoStatus.h @@ -17,6 +17,10 @@ #include #include +namespace zyppng { + class RepoInfo; +} + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// @@ -56,8 +60,13 @@ namespace zypp */ explicit RepoStatus( const Pathname & path_r ); +ZYPP_BEGIN_LEGACY_API /** Compute status of a \a RepoInfo to track changes requiring a refresh. */ explicit RepoStatus( const RepoInfo & info_r ); +ZYPP_END_LEGACY_API + + /** Compute status of a \a RepoInfo to track changes requiring a refresh. */ + explicit RepoStatus( const zyppng::RepoInfo & info_r ); /** Explicitly specify checksum string and timestamp to use. */ RepoStatus( std::string checksum_r, Date timestamp_r ); diff --git a/zypp/Repository.cc b/zypp/Repository.cc index f28e2f3403..b44747f7d2 100644 --- a/zypp/Repository.cc +++ b/zypp/Repository.cc @@ -27,6 +27,8 @@ #include #include +#include + using std::endl; /////////////////////////////////////////////////////////////////// @@ -66,10 +68,20 @@ namespace zypp } std::string Repository::name() const - { return info().name(); } + { + const auto &info = ngInfo(); + if ( info ) + return info->name(); + return std::string(); + } std::string Repository::label() const - { return info().label(); } + { + const auto &info = ngInfo(); + if ( info ) + return info->label(); + return std::string(); + } int Repository::satInternalPriority() const { @@ -271,13 +283,24 @@ namespace zypp return ProductInfoIterator(); } + const std::optional &Repository::ngInfo() const + { + NO_REPOSITORY_RETURN( zyppng::RepoInfo::nullRepo() ); + return myPool().repoInfo( _repo ); + } + + ZYPP_BEGIN_LEGACY_API RepoInfo Repository::info() const { NO_REPOSITORY_RETURN( RepoInfo() ); - return myPool().repoInfo( _repo ); + const auto &i = myPool().repoInfo( _repo ); + if ( i ) + return RepoInfo(*i); + return RepoInfo(); } + ZYPP_END_LEGACY_API - void Repository::setInfo( const RepoInfo & info_r ) + void Repository::setInfo( const zyppng::RepoInfo & info_r ) { NO_REPOSITORY_THROW( Exception( "Can't set RepoInfo for norepo." ) ); if ( info_r.alias() != alias() ) @@ -289,10 +312,17 @@ namespace zypp MIL << *this << endl; } + ZYPP_BEGIN_LEGACY_API + void Repository::setInfo( const RepoInfo & info_r ) + { + setInfo( info_r.ngRepoInfo() ); + } + ZYPP_END_LEGACY_API + void Repository::clearInfo() { NO_REPOSITORY_RETURN(); - myPool().setRepoInfo( _repo, RepoInfo() ); + myPool().eraseRepoInfo( _repo ); } void Repository::eraseFromPool() diff --git a/zypp/Repository.h b/zypp/Repository.h index 67147a9d8c..5804cc8368 100644 --- a/zypp/Repository.h +++ b/zypp/Repository.h @@ -22,6 +22,12 @@ #include #include +#include + +namespace zyppng { + class RepoInfo; +} + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// @@ -251,15 +257,22 @@ namespace zypp Iterable updatesProduct() const; public: - /** Return any associated \ref RepoInfo. */ - RepoInfo info() const; +#ifdef __cpp_lib_optional + const std::optional &ngInfo() const; +#endif /** Set \ref RepoInfo for this repository. * \throws Exception if this is \ref noRepository * \throws Exception if the \ref RepoInfo::alias * does not match the \ref Repository::name. */ - void setInfo( const RepoInfo & info_r ); + void setInfo( const zyppng::RepoInfo &info_r ); + + ZYPP_BEGIN_LEGACY_API + void ZYPP_INTERNAL_DEPRECATE setInfo( const RepoInfo & info_r ); + /** Return any associated \ref RepoInfo. */ + RepoInfo ZYPP_INTERNAL_DEPRECATE info() const; + ZYPP_END_LEGACY_API /** Remove any \ref RepoInfo set for this repository. */ void clearInfo(); diff --git a/zypp/ResFilters.cc b/zypp/ResFilters.cc new file mode 100644 index 0000000000..bde9d139cc --- /dev/null +++ b/zypp/ResFilters.cc @@ -0,0 +1,20 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +#include "ResFilters.h" +#include + +namespace zypp { + resfilter::ByRepository::ByRepository(Repository repository_r) + : _alias(repository_r.ngInfo() ? repository_r.ngInfo()->alias() : "" ) {} + resfilter::ByRepository::ByRepository(std::string alias_r) + : _alias(std::move(alias_r)) {} + bool resfilter::ByRepository::operator()(const ResObject::constPtr &p) const { + return (p->ngRepoInfo() ? p->ngRepoInfo()->alias() : "" ) == _alias; + } +} // namespace zypp diff --git a/zypp/ResFilters.h b/zypp/ResFilters.h index f52e05f490..dfa02d6ff0 100644 --- a/zypp/ResFilters.h +++ b/zypp/ResFilters.h @@ -166,20 +166,13 @@ namespace zypp }; /** Select ResObject by repository or repository alias. */ - struct ByRepository + struct ZYPP_API ByRepository { - ByRepository( Repository repository_r ) - : _alias( repository_r.info().alias() ) - {} + ByRepository(Repository repository_r); - ByRepository( std::string alias_r ) - : _alias(std::move( alias_r )) - {} + ByRepository(std::string alias_r); - bool operator()( const ResObject::constPtr& p ) const - { - return p->repoInfo().alias() == _alias; - } + bool operator()(const ResObject::constPtr &p) const; std::string _alias; }; diff --git a/zypp/ServiceInfo.cc b/zypp/ServiceInfo.cc index dd2f1888f0..f5c1e4e59c 100644 --- a/zypp/ServiceInfo.cc +++ b/zypp/ServiceInfo.cc @@ -6,252 +6,178 @@ | /_____||_| |_| |_| | | | \---------------------------------------------------------------------*/ -/** \file zypp/ServiceInfo.cc - * - */ -#include -#include +#include "ServiceInfo.h" +#include #include -#include -#include -#include -#include -#include +ZYPP_BEGIN_LEGACY_API -#include +namespace zypp { -using std::endl; -using zypp::xml::escape; + const ServiceInfo ServiceInfo::noService( zyppng::ServiceInfo(nullptr) ); -/////////////////////////////////////////////////////////////////////////////// -namespace zypp -{////////////////////////////////////////////////////////////////////////////// + ServiceInfo::ServiceInfo( ) + : _pimpl( new zyppng::ServiceInfo( zypp_detail::GlobalStateHelper::context() ) ) + { } - /////////////////////////////////////////////////////////////////// - // - // CLASS NAME : ServiceInfo::Impl - // - struct ServiceInfo::Impl - { - using ReposToEnable = ServiceInfo::ReposToEnable; - using ReposToDisable = ServiceInfo::ReposToDisable; - - public: - RepoVariablesReplacedUrl _url; - repo::ServiceType _type; - ReposToEnable _reposToEnable; - ReposToDisable _reposToDisable; - RepoStates _repoStates; - DefaultIntegral _ttl; - Date _lrf; - - public: - Impl() - {} - - Impl(const Url &url_r) : _url(url_r) {} + ServiceInfo::ServiceInfo( const zyppng::ServiceInfo &i ) + : _pimpl( std::make_unique(i) ) + { } - Impl(const Impl &) = default; - Impl(Impl &&) = delete; - Impl &operator=(const Impl &) = delete; - Impl &operator=(Impl &&) = delete; + ServiceInfo::ServiceInfo( const ServiceInfo &other ) + : _pimpl( std::make_unique(*other._pimpl) ) + { } - ~Impl() - {} + ServiceInfo::ServiceInfo(ServiceInfo &&other) + : _pimpl( std::move(other._pimpl) ) + , _ownsPimpl( other._ownsPimpl ) + { } - void setProbedType( const repo::ServiceType & type_r ) const - { - if ( _type == repo::ServiceType::NONE - && type_r != repo::ServiceType::NONE ) - { - // lazy init! - const_cast(this)->_type = type_r; - } - } - - private: - friend Impl * rwcowClone( const Impl * rhs ); + ServiceInfo &ServiceInfo::operator=(const ServiceInfo &other) + { + _pimpl = std::make_unique(*other._pimpl); + _ownsPimpl = true; + return *this; + } - /** clone for RWCOW_pointer */ - Impl * clone() const - { return new Impl( *this ); } - }; - /////////////////////////////////////////////////////////////////// + ServiceInfo &ServiceInfo::operator=(ServiceInfo &&other) + { + _pimpl = std::move(other._pimpl); + _ownsPimpl = other._ownsPimpl; + return *this; + } + ServiceInfo::ServiceInfo( const std::string & alias ) : _pimpl( new zyppng::ServiceInfo( zypp_detail::GlobalStateHelper::context(), alias ) ) {} - /////////////////////////////////////////////////////////////////// - // - // CLASS NAME : ServiceInfo::Impl - // - /////////////////////////////////////////////////////////////////// + ServiceInfo::ServiceInfo( const std::string & alias, const zypp::Url & url ) : _pimpl( new zyppng::ServiceInfo( zypp_detail::GlobalStateHelper::context(), alias, url ) ) {} - const ServiceInfo ServiceInfo::noService( zyppng::ContextBaseRef(nullptr) ); + ServiceInfo::~ServiceInfo() + { + if ( !_ownsPimpl ) _pimpl.release(); + } - ServiceInfo::ServiceInfo( zyppng::ContextBaseRef ctx ) : repo::RepoInfoBase( std::move(ctx) ), _pimpl( new Impl() ) {} + zypp::Url ServiceInfo::url() const + { return _pimpl->url(); } - ServiceInfo::ServiceInfo( zyppng::ContextBaseRef ctx, const std::string & alias ) - : repo::RepoInfoBase( std::move(ctx), alias ), _pimpl( new Impl() ) - {} + zypp::Url ServiceInfo::rawUrl() const + { return _pimpl->rawUrl(); } - ServiceInfo::ServiceInfo( zyppng::ContextBaseRef ctx, const std::string & alias, const Url & url ) - : repo::RepoInfoBase( std::move(ctx), alias ), _pimpl( new Impl(url) ) - {} + void ServiceInfo::setUrl( const zypp::Url& url ) + { _pimpl->setUrl(url); } + zypp::repo::ServiceType ServiceInfo::type() const + { return _pimpl->type(); } - ServiceInfo::ServiceInfo() : ServiceInfo( zypp_detail::GlobalStateHelper::context() ) - { /* LEGACY, DO NOT ADD CODE HERE */ } + void ServiceInfo::setType( const zypp::repo::ServiceType & type ) + { _pimpl->setType(type); } - ServiceInfo::ServiceInfo(const std::string & alias) - : ServiceInfo( zypp_detail::GlobalStateHelper::context(), alias ) - { /* LEGACY, DO NOT ADD CODE HERE */ } + void ServiceInfo::setProbedType( const zypp::repo::ServiceType &t ) const + { _pimpl->setProbedType( t ); } - ServiceInfo::ServiceInfo(const std::string & alias, const Url & url) - : ServiceInfo( zypp_detail::GlobalStateHelper::context(), alias, url ) - { /* LEGACY, DO NOT ADD CODE HERE */ } + zypp::Date::Duration ServiceInfo::ttl() const + { return _pimpl->ttl(); } - ServiceInfo::~ServiceInfo() - {} + void ServiceInfo::setTtl( zypp::Date::Duration ttl_r ) + { return _pimpl->setTtl(ttl_r); } - Url ServiceInfo::url() const // Variables replaced - { return _pimpl->_url.transformed(); } + void ServiceInfo::setProbedTtl( zypp::Date::Duration ttl_r ) const + { _pimpl->setProbedTtl(ttl_r); } - Url ServiceInfo::rawUrl() const // Raw - { return _pimpl->_url.raw(); } + zypp::Date ServiceInfo::lrf() const + { return _pimpl->lrf(); } - void ServiceInfo::setUrl( const Url& url ) // Raw - { _pimpl->_url.raw() = url; } + void ServiceInfo::setLrf( zypp::Date lrf_r ) + { _pimpl->setLrf(lrf_r); } - repo::ServiceType ServiceInfo::type() const { return _pimpl->_type; } - void ServiceInfo::setType( const repo::ServiceType & type ) { _pimpl->_type = type; } - void ServiceInfo::setProbedType( const repo::ServiceType &t ) const { _pimpl->setProbedType( t ); } + bool ServiceInfo::reposToEnableEmpty() const + { return _pimpl->reposToEnableEmpty(); } - Date::Duration ServiceInfo::ttl() const { return _pimpl->_ttl; } - void ServiceInfo::setTtl( Date::Duration ttl_r ) { _pimpl->_ttl = ttl_r; } - void ServiceInfo::setProbedTtl( Date::Duration ttl_r ) const { const_cast(this)->setTtl( ttl_r ); } + ServiceInfo::ReposToEnable::size_type ServiceInfo::reposToEnableSize() const + { return _pimpl->reposToEnableSize(); } - Date ServiceInfo::lrf() const { return _pimpl->_lrf; } - void ServiceInfo::setLrf( Date lrf_r ) { _pimpl->_lrf = lrf_r; } + ServiceInfo::ReposToEnable::const_iterator ServiceInfo::reposToEnableBegin() const + { return _pimpl->reposToEnableBegin(); } - bool ServiceInfo::reposToEnableEmpty() const { return _pimpl->_reposToEnable.empty(); } - ServiceInfo::ReposToEnable::size_type ServiceInfo::reposToEnableSize() const { return _pimpl->_reposToEnable.size(); } - ServiceInfo::ReposToEnable::const_iterator ServiceInfo::reposToEnableBegin() const { return _pimpl->_reposToEnable.begin(); } - ServiceInfo::ReposToEnable::const_iterator ServiceInfo::reposToEnableEnd() const { return _pimpl->_reposToEnable.end(); } + ServiceInfo::ReposToEnable::const_iterator ServiceInfo::reposToEnableEnd() const + { return _pimpl->reposToEnableEnd(); } bool ServiceInfo::repoToEnableFind( const std::string & alias_r ) const - { return( _pimpl->_reposToEnable.find( alias_r ) != _pimpl->_reposToEnable.end() ); } + { return _pimpl->repoToEnableFind(alias_r); } void ServiceInfo::addRepoToEnable( const std::string & alias_r ) - { - _pimpl->_reposToEnable.insert( alias_r ); - _pimpl->_reposToDisable.erase( alias_r ); - } + { _pimpl->addRepoToEnable(alias_r); } void ServiceInfo::delRepoToEnable( const std::string & alias_r ) - { _pimpl->_reposToEnable.erase( alias_r ); } + { _pimpl->delRepoToEnable(alias_r); } void ServiceInfo::clearReposToEnable() - { _pimpl->_reposToEnable.clear(); } + { _pimpl->clearReposToEnable(); } + + bool ServiceInfo::reposToDisableEmpty() const + { return _pimpl->reposToDisableEmpty(); } + ServiceInfo::ReposToDisable::size_type ServiceInfo::reposToDisableSize() const + { return _pimpl->reposToDisableSize(); } - bool ServiceInfo::reposToDisableEmpty() const { return _pimpl->_reposToDisable.empty(); } - ServiceInfo::ReposToDisable::size_type ServiceInfo::reposToDisableSize() const { return _pimpl->_reposToDisable.size(); } - ServiceInfo::ReposToDisable::const_iterator ServiceInfo::reposToDisableBegin() const { return _pimpl->_reposToDisable.begin(); } - ServiceInfo::ReposToDisable::const_iterator ServiceInfo::reposToDisableEnd() const { return _pimpl->_reposToDisable.end(); } + ServiceInfo::ReposToDisable::const_iterator ServiceInfo::reposToDisableBegin() const + { return _pimpl->reposToDisableBegin(); } + + ServiceInfo::ReposToDisable::const_iterator ServiceInfo::reposToDisableEnd() const + { return _pimpl->reposToDisableEnd(); } bool ServiceInfo::repoToDisableFind( const std::string & alias_r ) const - { return( _pimpl->_reposToDisable.find( alias_r ) != _pimpl->_reposToDisable.end() ); } + { return _pimpl->repoToDisableFind( alias_r ); } void ServiceInfo::addRepoToDisable( const std::string & alias_r ) - { - _pimpl->_reposToDisable.insert( alias_r ); - _pimpl->_reposToEnable.erase( alias_r ); - } + { return _pimpl->addRepoToDisable(alias_r); } void ServiceInfo::delRepoToDisable( const std::string & alias_r ) - { _pimpl->_reposToDisable.erase( alias_r ); } + { return _pimpl->delRepoToDisable(alias_r); } void ServiceInfo::clearReposToDisable() - { _pimpl->_reposToDisable.clear(); } + { _pimpl->clearReposToDisable(); } + const ServiceInfo::RepoStates & ServiceInfo::repoStates() const + { return _pimpl->repoStates(); } - const ServiceInfo::RepoStates & ServiceInfo::repoStates() const { return _pimpl->_repoStates; } - void ServiceInfo::setRepoStates( RepoStates newStates_r ) { swap( _pimpl->_repoStates, newStates_r ); } + void ServiceInfo::setRepoStates( RepoStates newStates_r ) + { _pimpl->setRepoStates( std::move(newStates_r) ); } + std::ostream & ServiceInfo::dumpAsIniOn( std::ostream & str ) const + { + return _pimpl->dumpAsIniOn(str); + } - std::ostream & operator<<( std::ostream & str, const ServiceInfo::RepoState & obj ) + std::ostream & ServiceInfo::dumpAsXmlOn( std::ostream & str, const std::string & content ) const { - return str - << "enabled=" << obj.enabled << " " - << "autorefresh=" << obj.autorefresh << " " - << "priority=" << obj.priority; + return _pimpl->dumpAsXmlOn(str, content); } - std::ostream & ServiceInfo::dumpAsIniOn( std::ostream & str ) const + zyppng::ServiceInfo &ServiceInfo::ngServiceInfo() { - RepoInfoBase::dumpAsIniOn(str) - << "url = " << hotfix1050625::asString( rawUrl() ) << endl - << "type = " << type() << endl; - - if ( ttl() ) - str << "ttl_sec = " << ttl() << endl; - - if ( lrf() ) - str << "lrf_dat = " << lrf().asSeconds() << endl; - - if ( ! repoStates().empty() ) - { - unsigned cnt = 0U; - for ( const auto & el : repoStates() ) - { - std::string tag( "repo_" ); - tag += str::numstring( ++cnt ); - const RepoState & state( el.second ); - - str << tag << "=" << el.first << endl - << tag << "_enabled=" << state.enabled << endl - << tag << "_autorefresh=" << state.autorefresh << endl; - if ( state.priority != RepoInfo::defaultPriority() ) - str - << tag << "_priority=" << state.priority << endl; - } - } - - if ( ! reposToEnableEmpty() ) - str << "repostoenable = " << str::joinEscaped( reposToEnableBegin(), reposToEnableEnd() ) << endl; - if ( ! reposToDisableEmpty() ) - str << "repostodisable = " << str::joinEscaped( reposToDisableBegin(), reposToDisableEnd() ) << endl; - return str; + return *_pimpl; } - std::ostream & ServiceInfo::dumpAsXmlOn( std::ostream & str, const std::string & content ) const + const zyppng::ServiceInfo &ServiceInfo::ngServiceInfo() const { - str - << "" << endl; - else - str << ">" << endl << content << "" << endl; - - return str; + return *_pimpl; } + zyppng::repo::RepoInfoBase &ServiceInfo::pimpl() + { + return *_pimpl; + } + + const zyppng::repo::RepoInfoBase &ServiceInfo::pimpl() const + { + return *_pimpl; + } std::ostream & operator<<( std::ostream& str, const ServiceInfo &obj ) { return obj.dumpAsIniOn(str); } +} - -/////////////////////////////////////////////////////////////////////////////// -} //namespace zypp -/////////////////////////////////////////////////////////////////////////////// +ZYPP_END_LEGACY_API diff --git a/zypp/ServiceInfo.h b/zypp/ServiceInfo.h index 1df0a9de46..d58eecaf83 100644 --- a/zypp/ServiceInfo.h +++ b/zypp/ServiceInfo.h @@ -19,9 +19,16 @@ #include #include +#include #include #include +namespace zyppng { + class ServiceInfo; +} + +ZYPP_BEGIN_LEGACY_API + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// @@ -33,52 +40,33 @@ namespace zypp /// \note Name and Url are subject to repo variable replacement /// (\see \ref RepoVariablesStringReplacer). /// - class ZYPP_API ServiceInfo : public repo::RepoInfoBase + class ZYPP_API ZYPP_INTERNAL_DEPRECATE ServiceInfo : public repo::RepoInfoBase { public: /** Default ctor creates \ref noService.*/ - ZYPP_INTERNAL_DEPRECATE ServiceInfo(); - - /** - * Creates ServiceInfo with specified alias. - * - * \param alias unique short name of service - */ - ZYPP_INTERNAL_DEPRECATE ServiceInfo( const std::string & alias ); - - /** - * ServiceInfo with alias and its URL - * - * \param alias unique shortname of service - * \param url url to service - */ - ZYPP_INTERNAL_DEPRECATE ServiceInfo( const std::string & alias, const Url& url ); + ServiceInfo(); + ServiceInfo( const zyppng::ServiceInfo &i ); - /** - * Default ctor creates \ref noService. - * \internal - */ - ServiceInfo( zyppng::ContextBaseRef contextRef ) ZYPP_LOCAL; + ServiceInfo(const ServiceInfo &other); + ServiceInfo(ServiceInfo &&other); + ServiceInfo &operator=(const ServiceInfo &other); + ServiceInfo &operator=(ServiceInfo &&other); /** * Creates ServiceInfo with specified alias. * * \param alias unique short name of service - * \internal */ - ServiceInfo( zyppng::ContextBaseRef contextRef, const std::string & alias ) ZYPP_LOCAL; + ServiceInfo( const std::string & alias ); /** * ServiceInfo with alias and its URL * * \param alias unique shortname of service * \param url url to service - * \internal */ - ServiceInfo( zyppng::ContextBaseRef contextRef, const std::string & alias, const Url& url ) ZYPP_LOCAL; - - + ServiceInfo( const std::string & alias, const Url& url ); ~ServiceInfo() override; @@ -183,31 +171,7 @@ namespace zypp void clearReposToDisable(); //@} - /** \name The original repo state as defined by the repoindex.xml upon last refresh. - * - * This state is remembered to detect any user modifications applied to the repos. - * It may not be available for all repos or in plugin services. In this case all - * changes requested by a service refresh are applied unconditionally. - */ - //@{ - struct RepoState - { - bool enabled; - bool autorefresh; - unsigned priority; - - RepoState() - : enabled( false ), autorefresh( true ), priority( RepoInfo::defaultPriority() ) - {} - RepoState( const RepoInfo & repo_r ) - : enabled( repo_r.enabled() ), autorefresh( repo_r.autorefresh() ), priority( repo_r.priority() ) - {} - bool operator==( const RepoState & rhs ) const - { return( enabled==rhs.enabled && autorefresh==rhs.autorefresh && priority==rhs.priority ); } - bool operator!=( const RepoState & rhs ) const - { return ! operator==( rhs ); } - friend std::ostream & operator<<( std::ostream & str, const RepoState & obj ); - }; + using RepoState = ServiceRepoState; using RepoStates = std::map; /** Access the remembered repository states. */ @@ -234,10 +198,17 @@ namespace zypp */ std::ostream & dumpAsXmlOn( std::ostream & str, const std::string & content = "" ) const override; - struct Impl; + + zyppng::ServiceInfo &ngServiceInfo(); + const zyppng::ServiceInfo &ngServiceInfo() const; + private: - RWCOW_pointer _pimpl; + zyppng::repo::RepoInfoBase &pimpl() override; + const zyppng::repo::RepoInfoBase &pimpl() const override; + + std::unique_ptr _pimpl; + bool _ownsPimpl = true; }; /////////////////////////////////////////////////////////////////// @@ -265,5 +236,7 @@ namespace zypp ///////////////////////////////////////////////////////////////// } // namespace zypp -/////////////////////////////////////////////////////////////////// -#endif // ZYPP_SAT_REPOSITORY_H + +ZYPP_END_LEGACY_API + +#endif // ZYPP_SERVICE_H diff --git a/zypp/SrcPackage.cc b/zypp/SrcPackage.cc index 07439ec486..8635760d12 100644 --- a/zypp/SrcPackage.cc +++ b/zypp/SrcPackage.cc @@ -10,12 +10,13 @@ * */ #include +#include /////////////////////////////////////////////////////////////////// namespace zyppintern { using namespace zypp; // in Package.cc - Pathname cachedLocation( const OnMediaLocation & loc_r, const RepoInfo & repo_r ); + Pathname cachedLocation( const OnMediaLocation & loc_r, const zyppng::RepoInfo & repo_r ); } // namespace zyppintern /////////////////////////////////////////////////////////////////// @@ -55,7 +56,12 @@ namespace zypp { return lookupLocation(); } Pathname SrcPackage::cachedLocation() const - { return zyppintern::cachedLocation( location(), repoInfo() ); } + { + const auto &optRepoInfo = ngRepoInfo (); + if ( !optRepoInfo ) + return Pathname(); + return zyppintern::cachedLocation( location(), *optRepoInfo ); + } ///////////////////////////////////////////////////////////////// } // namespace zypp diff --git a/zypp/ZConfig.cc b/zypp/ZConfig.cc index 862af5a4fa..cd5001d26d 100644 --- a/zypp/ZConfig.cc +++ b/zypp/ZConfig.cc @@ -38,6 +38,7 @@ extern "C" #include #include +#include using std::endl; using namespace zypp::filesystem; @@ -46,6 +47,8 @@ using namespace zypp::parser; #undef ZYPP_BASE_LOGGER_LOGGROUP #define ZYPP_BASE_LOGGER_LOGGROUP "zconfig" +#warning "Still need to sync MediaConfig::systemConfig and the one in ZConfig::systemConfig" + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// @@ -500,8 +503,9 @@ namespace zypp , pkgGpgCheck ( indeterminate ) , apply_locks_file ( true ) , pluginsPath ( "/usr/lib/zypp/plugins" ) - , geoipEnabled ( true ) - , geoipHosts { "download.opensuse.org" } + , geoipEnabled ( true ) + , geoipHosts { "download.opensuse.org" } + , _mediaConf ( _parsedZyppConf ) { MIL << "libzypp: " LIBZYPP_VERSION_STRING << endl; if ( PathInfo(_parsedZyppConf).isExist() ) @@ -520,9 +524,6 @@ namespace zypp std::string entry(it->first); std::string value(it->second); - if ( _mediaConf.setConfigValue( section, entry, value ) ) - continue; - //DBG << (*it).first << "=" << (*it).second << endl; if ( section == "main" ) { @@ -558,6 +559,7 @@ namespace zypp { cfg_config_path = Pathname(value); } + else if ( entry == "reposdir" ) { cfg_known_repos_path = Pathname(value); @@ -808,7 +810,7 @@ namespace zypp std::vector geoipHosts; /* Other config singleton instances */ - MediaConfig &_mediaConf = MediaConfig::instance(); + MediaConfig _mediaConf; public: @@ -908,13 +910,20 @@ namespace zypp mutable MultiversionMap _multiversionMap; }; - /////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////// - // - // METHOD NAME : ZConfig::instance - // METHOD TYPE : ZConfig & - // + + const ZConfig &ZConfig::defaults() + { + static ZConfig _conf("/dev/null"); + return _conf; + } + + ZConfig &ZConfig::systemConfig() + { + static ZConfig _sysConf( zypp_detail::autodetectZyppConfPath() ); + return _sysConf; + } + ZConfig & ZConfig::instance() { return zypp_detail::GlobalStateHelper::config(); @@ -1009,24 +1018,14 @@ namespace zypp /////////////////////////////////////////////////////////////////// bool ZConfig::hasUserData() const - { return !_pimpl->userData.empty(); } + { return zyppng::UserData::hasData(); } std::string ZConfig::userData() const - { return _pimpl->userData; } + { return zyppng::UserData::data(); } bool ZConfig::setUserData( const std::string & str_r ) { - for_( ch, str_r.begin(), str_r.end() ) - { - if ( *ch < ' ' && *ch != '\t' ) - { - ERR << "New user data string rejectded: char " << (int)*ch << " at position " << (ch - str_r.begin()) << endl; - return false; - } - } - MIL << "Set user data string to '" << str_r << "'" << endl; - _pimpl->userData = str_r; - return true; + return zyppng::UserData::setData(str_r); } /////////////////////////////////////////////////////////////////// @@ -1258,25 +1257,16 @@ namespace zypp { return _pimpl->apply_locks_file; } Pathname ZConfig::update_dataPath() -#if LEGACY(1735) - const -#endif { return Pathname("/var/adm"); } Pathname ZConfig::update_messagesPath() -#if LEGACY(1735) - const -#endif { return Pathname(update_dataPath()/"update-messages"); } Pathname ZConfig::update_scriptsPath() -#if LEGACY(1735) - const -#endif { return Pathname(update_dataPath()/"update-scripts"); } @@ -1327,6 +1317,16 @@ namespace zypp return _pimpl->cfg_kernel_keep_spec; } + const MediaConfig &ZConfig::mediaConfig() const + { + return _pimpl->_mediaConf; + } + + MediaConfig &ZConfig::mediaConfig() + { + return _pimpl->_mediaConf; + } + /////////////////////////////////////////////////////////////////// std::ostream & ZConfig::about( std::ostream & str ) const diff --git a/zypp/ZConfig.h b/zypp/ZConfig.h index b7fe95620c..6617a80331 100644 --- a/zypp/ZConfig.h +++ b/zypp/ZConfig.h @@ -44,6 +44,7 @@ namespace zypp { ///////////////////////////////////////////////////////////////// class RepoManager; + class MediaConfig; /////////////////////////////////////////////////////////////////// // @@ -74,6 +75,15 @@ namespace zypp { public: + /** A ZConfig instance that has only the default settings, usable as fallback if + * there is no context that can be asked and the system config is not applicable */ + static const ZConfig &defaults(); + + /** + * The system config, parsed from /etc/zypp/zypp.conf. + */ + static ZConfig &systemConfig(); + /** Singleton ctor */ static ZYPP_INTERNAL_DEPRECATE ZConfig & instance(); @@ -391,7 +401,7 @@ namespace zypp void resetPkgGpgCheck(); ///< Reset to the zconfig default //@} // - /** + /**ZConfig * Directory for equivalent vendor definitions (configPath()/vendors.d) * \ingroup g_ZC_CONFIGFILES */ @@ -498,22 +508,6 @@ namespace zypp */ bool apply_locks_file() const; -#if LEGACY(1735) - /** - * Path where the update items are kept (/var/adm) - */ - Pathname update_dataPath() const; - - /** - * Path where the update scripts are stored ( /var/adm/update-scripts ) - */ - Pathname update_scriptsPath() const; - - /** - * Path where the update messages are stored ( /var/adm/update-messages ) - */ - Pathname update_messagesPath() const; -#else /** * Path where the update items are kept (/var/adm) */ @@ -528,7 +522,6 @@ namespace zypp * Path where the update messages are stored ( /var/adm/update-messages ) */ static Pathname update_messagesPath(); -#endif /** \name Command to be invoked to send update messages. */ //@{ @@ -591,6 +584,10 @@ namespace zypp */ std::string multiversionKernels() const; + + const MediaConfig &mediaConfig() const; + MediaConfig &mediaConfig(); + //@} public: diff --git a/zypp/ZYppCallbacks.h b/zypp/ZYppCallbacks.h index 68f4f98ff1..9bdfa04ff3 100644 --- a/zypp/ZYppCallbacks.h +++ b/zypp/ZYppCallbacks.h @@ -25,6 +25,9 @@ #include #include // bsc#1194597: CurlAuthData must be exposed for zypper + +ZYPP_BEGIN_LEGACY_API + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// @@ -1065,4 +1068,6 @@ namespace zypp } // namespace zypp /////////////////////////////////////////////////////////////////// +ZYPP_END_LEGACY_API + #endif // ZYPP_ZYPPCALLBACKS_H diff --git a/zypp/ZYppFactory.cc b/zypp/ZYppFactory.cc index ccc48f03fe..26e43e4ee4 100644 --- a/zypp/ZYppFactory.cc +++ b/zypp/ZYppFactory.cc @@ -35,8 +35,6 @@ extern "C" using std::endl; -namespace zyppintern { void repoVariablesReset(); } // upon re-acquiring the lock... - /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// @@ -89,7 +87,7 @@ namespace zypp ZYpp::ZYpp( const Impl_Ptr & impl_r ) : _pimpl( impl_r ) { - ::zyppintern::repoVariablesReset(); // upon re-acquiring the lock... + zypp_detail::GlobalStateHelper::context ()->clearRepoVariables(); // upon re-acquiring the lock... MIL << "ZYpp is on..." << endl; } diff --git a/zypp/base/ValueTransform.h b/zypp/base/ValueTransform.h index cbda89a4ab..7978f017d1 100644 --- a/zypp/base/ValueTransform.h +++ b/zypp/base/ValueTransform.h @@ -72,6 +72,9 @@ namespace zypp const Transformator & transformator() const { return _transform; } + void setTransformator ( Transformator &&t ) + { _transform = std::move(t); } + private: RawType _raw; Transformator _transform; @@ -83,7 +86,7 @@ namespace zypp /// /// This helper enforces to explicitly state wheter you are using /// the raw or the variable replaced value. Usually you set \c raw - /// and get \c transformed (uness writing \c raw to some config file). + /// and get \c transformed (unless writing \c raw to some config file). /// /// Offers iterating over transformed strings in the list. /////////////////////////////////////////////////////////////////// @@ -156,6 +159,9 @@ namespace zypp const Transformator & transformator() const { return _transform; } + void setTransformator ( Transformator &&t ) + { _transform = std::move(t); } + private: Container _raw; Transformator _transform; diff --git a/zypp/media/CredentialManager.cc b/zypp/media/CredentialManager.cc new file mode 100644 index 0000000000..e046e0b6dc --- /dev/null +++ b/zypp/media/CredentialManager.cc @@ -0,0 +1,98 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +#include "CredentialManager.h" +#include +#include +#include + +namespace zypp::media { + + CredManagerOptions::CredManagerOptions(const Pathname & rootdir) + { + this->globalCredFilePath = rootdir / zypp_detail::GlobalStateHelper::config().mediaConfig().credentialsGlobalFile(); + this->customCredFileDir = rootdir / zypp_detail::GlobalStateHelper::config().mediaConfig().credentialsGlobalDir(); + char * homedir = getenv("HOME"); + if (homedir) + userCredFilePath = rootdir / homedir / CredManagerSettings::userCredFile(); + } + + AuthData_Ptr CredentialManager::findIn(const CredentialManager::CredentialSet & set, + const Url & url, + url::ViewOption vopt) + { return zyppng::media::CredentialManager::findIn( set, url, vopt ); } + + ////////////////////////////////////////////////////////////////////// + // + // CLASS NAME : CredentialManager + // + ////////////////////////////////////////////////////////////////////// + + CredentialManager::CredentialManager( zyppng::media::CredentialManagerRef pimpl ) + : _pimpl( std::move(pimpl) ) + {} + + CredentialManager::CredentialManager( CredManagerOptions opts ) + : _pimpl( zyppng::media::CredentialManager::create(opts) ) + {} + + AuthData_Ptr CredentialManager::getCred(const Url & url) + { return _pimpl->getCred(url); } + + AuthData_Ptr CredentialManager::getCredFromFile(const Pathname & file) + { return _pimpl->getCredFromFile(file); } + + void CredentialManager::addCred(const AuthData & cred) + { return _pimpl->addCred (cred); } + + time_t CredentialManager::timestampForCredDatabase ( const zypp::Url &url ) + { return _pimpl->timestampForCredDatabase(url); } + + void CredentialManager::addGlobalCred(const AuthData & cred) + { return _pimpl->addGlobalCred(cred); } + + void CredentialManager::addUserCred(const AuthData & cred) + { return _pimpl->addUserCred ( cred ); } + + void CredentialManager::saveInGlobal(const AuthData & cred) + { return _pimpl->saveInGlobal (cred); } + + void CredentialManager::saveInUser(const AuthData & cred) + { return _pimpl->saveInUser(cred); } + + void CredentialManager::saveInFile(const AuthData & cred, const Pathname & credFile) + { return _pimpl->saveInFile(cred, credFile); } + + void CredentialManager::clearAll(bool global) + { return _pimpl->clearAll(global); } + + CredentialManager::CredentialIterator CredentialManager::credsGlobalBegin() const + { return _pimpl->credsGlobalBegin(); } + + CredentialManager::CredentialIterator CredentialManager::credsGlobalEnd() const + { return _pimpl->credsGlobalEnd(); } + + CredentialManager::CredentialSize CredentialManager::credsGlobalSize() const + { return _pimpl->credsGlobalSize(); } + + bool CredentialManager::credsGlobalEmpty() const + { return _pimpl->credsGlobalEmpty(); } + + CredentialManager::CredentialIterator CredentialManager::credsUserBegin() const + { return _pimpl->credsUserBegin(); } + + CredentialManager::CredentialIterator CredentialManager::credsUserEnd() const + { return _pimpl->credsUserEnd(); } + + CredentialManager::CredentialSize CredentialManager::credsUserSize() const + { return _pimpl->credsUserSize(); } + + bool CredentialManager::credsUserEmpty() const + { return _pimpl->credsUserEmpty(); } + +} diff --git a/zypp/media/CredentialManager.h b/zypp/media/CredentialManager.h index 61dd4a230f..7e9d21e189 100644 --- a/zypp/media/CredentialManager.h +++ b/zypp/media/CredentialManager.h @@ -1 +1,164 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp-media/auth/CredentialManager + * + */ +#ifndef ZYPP_CREDENTIALMANAGER_H +#define ZYPP_CREDENTIALMANAGER_H + +#include #include +#include +#include + +namespace zyppng::media { + ZYPP_FWD_DECL_TYPE_WITH_REFS(CredentialManager); +} + +namespace zypp::media { + + struct ZYPP_API ZYPP_DEPRECATED CredManagerOptions : public CredManagerSettings + { + CredManagerOptions( const Pathname & rootdir = "" ); + }; + + ////////////////////////////////////////////////////////////////////// + // + // CLASS NAME : CredentialManager + // + /** + * \todo better method names + * \todo delete(AuthData) method + */ + class ZYPP_API ZYPP_DEPRECATED CredentialManager + { + public: + using CredentialSet = std::set; + using CredentialSize = CredentialSet::size_type; + using CredentialIterator = CredentialSet::const_iterator; + + CredentialManager( zyppng::media::CredentialManagerRef pimpl ) ZYPP_LOCAL; + CredentialManager( CredManagerOptions opts = CredManagerOptions() ); + ~CredentialManager() + {} + + public: + /** + * Get credentials for the specified \a url. + * + * If the URL contains also username, it will be used to find the match + * for this user (in case mutliple are available). + * + * \param url URL to find credentials for. + * \return Pointer to retrieved authentication data on success or an empty + * AuthData_Ptr otherwise. + * \todo return a copy instead? + */ + AuthData_Ptr getCred(const Url & url); + + /** + * Read credentials from a file. + */ + AuthData_Ptr getCredFromFile(const Pathname & file); + + /** + * Add new global credentials. + */ + void addGlobalCred(const AuthData & cred); + + /** + * Add new user credentials. + */ + void addUserCred(const AuthData & cred); + + /** + * Add new credentials with user callbacks. + * + * If the cred->url() contains 'credentials' query parameter, the + * credentials will be automatically saved to the specified file using the + * \ref saveInFile() method. + * + * Otherwise a callback will be called asking whether to save to custom + * file, or to global or user's credentials catalog. + * + * \todo Currently no callback is called, credentials are automatically + * saved to user's credentials.cat if no 'credentials' parameter + * has been specified + */ + void addCred(const AuthData & cred); + + /** + * Saves any unsaved credentials added via \ref addUserCred() or + * \a addGlobalCred() methods. + */ + void save(); + + /** + * Saves given \a cred to global credentials file. + * + * \note Use this method to add just one piece of credentials. To add + * multiple items at once, use addGlobalCred() followed + * by save() + */ + void saveInGlobal(const AuthData & cred); + + /** + * Saves given \a cred to user's credentials file. + * + * \note Use this method to add just one piece of credentials. To add + * multiple items at once, use addUserCred() followed + * by save() + */ + void saveInUser(const AuthData & cred); + + /** + * Saves given \a cred to user specified credentials file. + * + * If the credFile path is absolute, it will be saved at that precise + * location. If \a credFile is just a filename, it will be saved + * in \ref CredManagerOptions::customCredFileDir. Otherwise the current + * working directory will be prepended to the file path. + */ + void saveInFile(const AuthData &, const Pathname & credFile); + + /** + * Remove all global or user credentials from memory and disk. + * + * \param global Whether to remove global or user credentials. + */ + void clearAll(bool global = false); + + /*! + * Helper function to find a matching AuthData instance in a CredentialSet + */ + static AuthData_Ptr findIn( const CredentialManager::CredentialSet & set, const Url & url, url::ViewOption vopt ); + + /*! + * Returns the timestamp of the database the given URL creds would be stored + */ + time_t timestampForCredDatabase ( const zypp::Url &url ); + + CredentialIterator credsGlobalBegin() const; + CredentialIterator credsGlobalEnd() const; + CredentialSize credsGlobalSize() const; + bool credsGlobalEmpty() const; + + CredentialIterator credsUserBegin() const; + CredentialIterator credsUserEnd() const; + CredentialSize credsUserSize() const; + bool credsUserEmpty() const; + + struct Impl; + private: + zyppng::media::CredentialManagerRef _pimpl; + }; + +} + +#endif diff --git a/zypp/media/MediaCD.cc b/zypp/media/MediaCD.cc index 0b73935b02..2067e9d2ac 100644 --- a/zypp/media/MediaCD.cc +++ b/zypp/media/MediaCD.cc @@ -127,8 +127,8 @@ namespace zypp ////////////////////////////////////////////////////////////////// - MediaCD::MediaCD( const Url & url_r, const Pathname & attach_point_hint_r ) - : MediaHandler( url_r, attach_point_hint_r, url_r.getPathName(), false ) + MediaCD::MediaCD( zyppng::ContextBaseRef ctx, const Url & url_r, const Pathname & attach_point_hint_r ) + : MediaHandler( std::move(ctx), url_r, attach_point_hint_r, url_r.getPathName(), false ) , _lastdev( -1 ) , _lastdev_tried( -1 ) { diff --git a/zypp/media/MediaCD.h b/zypp/media/MediaCD.h index 3d0b17ac77..5e26f3555a 100644 --- a/zypp/media/MediaCD.h +++ b/zypp/media/MediaCD.h @@ -63,7 +63,8 @@ namespace zypp { public: - MediaCD( const Url & url_r, + MediaCD( zyppng::ContextBaseRef ctx, + const Url & url_r, const Pathname & attach_point_hint_r ); ~MediaCD() override { try { release(); } catch(...) {} } diff --git a/zypp/media/MediaCIFS.cc b/zypp/media/MediaCIFS.cc index 43b4ef4813..0a890fe446 100644 --- a/zypp/media/MediaCIFS.cc +++ b/zypp/media/MediaCIFS.cc @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include @@ -27,9 +27,10 @@ #include #include -#include #include +#include + using std::endl; namespace zypp { @@ -98,9 +99,9 @@ namespace zypp { // // DESCRIPTION : // - MediaCIFS::MediaCIFS( const Url & url_r, - const Pathname & attach_point_hint_r ) - : MediaHandler( url_r, attach_point_hint_r, + MediaCIFS::MediaCIFS(zyppng::ContextBaseRef ctx, const Url & url_r, + const Pathname & attach_point_hint_r ) + : MediaHandler( std::move(ctx), url_r, attach_point_hint_r, stripShare( url_r.getPathName() ), // urlpath WITHOUT share name at attachpoint false ) // does_download { @@ -162,7 +163,7 @@ namespace zypp { std::string mountpoint( attachPoint().asString() ); Mount mount; - CredentialManager cm(CredManagerOptions(ZConfig::instance().repoManagerRoot())); + auto cm = zyppng::media::CredentialManager::create( CredManagerSettings(_zyppContext) ); Mount::Options options( _url.getQueryParam("mountoptions") ); std::string username = _url.getUsername(); @@ -214,7 +215,7 @@ namespace zypp { if ( username.empty() || password.empty() ) { - AuthData_Ptr c = cm.getCred(_url); + AuthData_Ptr c = cm->getCred(_url); if (c) { username = c->username(); @@ -403,10 +404,10 @@ namespace zypp { bool MediaCIFS::authenticate(AuthData & authdata, bool firstTry) const { //! \todo need a way to pass different CredManagerOptions here - CredentialManager cm(CredManagerOptions(ZConfig::instance().repoManagerRoot())); + auto cm = zyppng::media::CredentialManager::create( CredManagerSettings(_zyppContext) ); // get stored credentials - AuthData_Ptr cmcred = cm.getCred(_url); + AuthData_Ptr cmcred = cm->getCred(_url); AuthData_Ptr smbcred; smbcred.reset(new AuthData()); @@ -457,8 +458,8 @@ namespace zypp { // save the credentials cmcred->setUrl(_url); - cm.addCred(*cmcred); - cm.save(); + cm->addCred(*cmcred); + cm->save(); return true; } diff --git a/zypp/media/MediaCIFS.h b/zypp/media/MediaCIFS.h index 22ffcc41f7..430bc77b90 100644 --- a/zypp/media/MediaCIFS.h +++ b/zypp/media/MediaCIFS.h @@ -44,8 +44,9 @@ namespace zypp { bool getDoesFileExist( const Pathname & filename ) const override; public: - MediaCIFS( const Url& url_r, - const Pathname & attach_point_hint_r ); + MediaCIFS( zyppng::ContextBaseRef ctx, + const Url& url_r, + const Pathname & attach_point_hint_r ); ~MediaCIFS() override { try { release(); } catch(...) {} } diff --git a/zypp/media/MediaCurl.cc b/zypp/media/MediaCurl.cc index 79e13ae440..79d44c42ee 100644 --- a/zypp/media/MediaCurl.cc +++ b/zypp/media/MediaCurl.cc @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -43,6 +43,8 @@ #include #include +#include + using std::endl; namespace internal { @@ -344,9 +346,9 @@ Pathname MediaCurl::_cookieFile = "/var/lib/YaST2/cookies"; #define SET_OPTION_LONG(opt,val) SET_OPTION(opt,(long)val) #define SET_OPTION_VOID(opt,val) SET_OPTION(opt,(void*)val) -MediaCurl::MediaCurl( const Url & url_r, - const Pathname & attach_point_hint_r ) - : MediaNetworkCommonHandler( url_r, attach_point_hint_r, +MediaCurl::MediaCurl( zyppng::ContextBaseRef ctx, const Url & url_r, + const Pathname & attach_point_hint_r ) + : MediaNetworkCommonHandler( std::move(ctx), url_r, attach_point_hint_r, "/", // urlpath at attachpoint true ), // does_download _curl( NULL ), @@ -541,8 +543,8 @@ void MediaCurl::setupEasy() && _settings.username().size() && !_settings.password().size() ) { - CredentialManager cm(CredManagerOptions(ZConfig::instance().repoManagerRoot())); - const auto cred = cm.getCred( _url ); + auto cm = zyppng::media::CredentialManager::create( CredManagerSettings(_zyppContext) ); + const auto cred = cm->getCred( _url ); if ( cred && cred->valid() ) { if ( !_settings.username().size() ) _settings.setUsername(cred->username()); @@ -1482,11 +1484,11 @@ CURLcode MediaCurl::executeCurl() const bool MediaCurl::authenticate(const std::string & availAuthTypes, bool firstTry) const { //! \todo need a way to pass different CredManagerOptions here - CredentialManager cm(CredManagerOptions(ZConfig::instance().repoManagerRoot())); + auto cm = zyppng::media::CredentialManager::create( CredManagerSettings(_zyppContext) ); CurlAuthData_Ptr credentials; // get stored credentials - AuthData_Ptr cmcred = cm.getCred(_url); + AuthData_Ptr cmcred = cm->getCred(_url); if (cmcred && firstTry) { @@ -1570,8 +1572,8 @@ bool MediaCurl::authenticate(const std::string & availAuthTypes, bool firstTry) if (!cmcred) { credentials->setUrl(_url); - cm.addCred(*credentials); - cm.save(); + cm->addCred(*credentials); + cm->save(); } return true; diff --git a/zypp/media/MediaCurl.h b/zypp/media/MediaCurl.h index 3ded2e688c..42b6ccf257 100644 --- a/zypp/media/MediaCurl.h +++ b/zypp/media/MediaCurl.h @@ -95,7 +95,8 @@ class MediaCurl : public MediaNetworkCommonHandler public: - MediaCurl( const Url & url_r, + MediaCurl( zyppng::ContextBaseRef ctx, + const Url & url_r, const Pathname & attach_point_hint_r ); ~MediaCurl() override { try { release(); } catch(...) {} } diff --git a/zypp/media/MediaDIR.cc b/zypp/media/MediaDIR.cc index 4f416b5c13..304d01ff3d 100644 --- a/zypp/media/MediaDIR.cc +++ b/zypp/media/MediaDIR.cc @@ -39,9 +39,9 @@ namespace zypp { // as files are not copied. // Thus attach_point_hint_r is ignored. // - MediaDIR::MediaDIR( const Url & url_r, - const Pathname & /*attach_point_hint_r*/ ) - : MediaHandler( url_r, url_r.getPathName(), + MediaDIR::MediaDIR(zyppng::ContextBaseRef ctx, const Url & url_r, + const Pathname & /*attach_point_hint_r*/ ) + : MediaHandler( std::move(ctx), url_r, url_r.getPathName(), "/", // urlpath below attachpoint false ) // does_download { diff --git a/zypp/media/MediaDIR.h b/zypp/media/MediaDIR.h index a3bd8efe29..f1be25b50d 100644 --- a/zypp/media/MediaDIR.h +++ b/zypp/media/MediaDIR.h @@ -41,7 +41,8 @@ namespace zypp { public: - MediaDIR( const Url & url_r, + MediaDIR( zyppng::ContextBaseRef ctx, + const Url & url_r, const Pathname & attach_point_hint_r ); ~MediaDIR() override { try { release(); } catch(...) {} } diff --git a/zypp/media/MediaDISK.cc b/zypp/media/MediaDISK.cc index ac3e79e728..f425c84e6c 100644 --- a/zypp/media/MediaDISK.cc +++ b/zypp/media/MediaDISK.cc @@ -50,9 +50,9 @@ namespace zypp { // // DESCRIPTION : // - MediaDISK::MediaDISK( const Url & url_r, - const Pathname & attach_point_hint_r ) - : MediaHandler( url_r, attach_point_hint_r, + MediaDISK::MediaDISK(zyppng::ContextBaseRef ctx, const Url & url_r, + const Pathname & attach_point_hint_r ) + : MediaHandler( std::move(ctx), url_r, attach_point_hint_r, url_r.getPathName(), // urlpath below attachpoint false ) // does_download { diff --git a/zypp/media/MediaDISK.h b/zypp/media/MediaDISK.h index 9a75554e7e..61e00c224f 100644 --- a/zypp/media/MediaDISK.h +++ b/zypp/media/MediaDISK.h @@ -44,7 +44,8 @@ namespace zypp { public: - MediaDISK( const Url & url_r, + MediaDISK( zyppng::ContextBaseRef ctx, + const Url & url_r, const Pathname & attach_point_hint_r ); ~MediaDISK() override { try { release(); } catch(...) {} } diff --git a/zypp/media/MediaHandler.cc b/zypp/media/MediaHandler.cc index 1e78533ef0..c94660df55 100644 --- a/zypp/media/MediaHandler.cc +++ b/zypp/media/MediaHandler.cc @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -24,9 +23,9 @@ #include #include #include -#include #include -#include + +#include using std::endl; @@ -52,10 +51,11 @@ namespace zypp { // // DESCRIPTION : // -MediaHandler::MediaHandler ( Url url_r, - const Pathname & attach_point_r, - Pathname urlpath_below_attachpoint_r, - const bool does_download_r ) + MediaHandler::MediaHandler (zyppng::ContextBaseRef ctx, + Url url_r, + const Pathname & attach_point_r, + Pathname urlpath_below_attachpoint_r, + const bool does_download_r ) : _mediaSource() , _attachPoint( new AttachPoint()) , _attachPointHint() @@ -64,6 +64,7 @@ MediaHandler::MediaHandler ( Url url_r, , _attach_mtime(0) , _url(std::move( url_r )) , _parentId(0) + , _zyppContext( std::move(ctx) ) { Pathname real_attach_point( getRealPath(attach_point_r.asString())); @@ -321,7 +322,7 @@ MediaHandler::createAttachPoint() const if ( apoint.empty() ) // fallback to config value { - aroot = ZConfig::instance().download_mediaMountdir(); + aroot = ZConfig::systemConfig().download_mediaMountdir(); if ( ! aroot.empty() ) apoint = createAttachPoint( aroot ); } diff --git a/zypp/media/MediaHandler.h b/zypp/media/MediaHandler.h index 1b293ca210..84ff258daf 100644 --- a/zypp/media/MediaHandler.h +++ b/zypp/media/MediaHandler.h @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -31,6 +32,10 @@ #undef ZYPP_BASE_LOGGER_LOGGROUP #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::media" +namespace zyppng { + ZYPP_FWD_DECL_TYPE_WITH_REFS(ContextBase); +} + namespace zypp { namespace media { @@ -117,6 +122,9 @@ class MediaHandler { */ MediaAccessId _parentId; + /** media handle context */ + zyppng::ContextBaseRef _zyppContext; + public: /** @@ -466,7 +474,8 @@ class MediaHandler { * On any error, the attach_point is set to an empty Pathname, * which should lead to E_bad_attachpoint. **/ - MediaHandler ( Url url_r, + MediaHandler ( zyppng::ContextBaseRef ctx, + Url url_r, const Pathname & attach_point_r, Pathname urlpath_below_attachpoint_r, const bool does_download_r ); diff --git a/zypp/media/MediaHandlerFactory.cc b/zypp/media/MediaHandlerFactory.cc index cb1a5c8508..c9d2f1756e 100644 --- a/zypp/media/MediaHandlerFactory.cc +++ b/zypp/media/MediaHandlerFactory.cc @@ -47,8 +47,12 @@ namespace zypp::media { return {}; } - std::unique_ptr MediaHandlerFactory::createHandler( const Url &o_url, const Pathname &preferred_attach_point ) + std::unique_ptr MediaHandlerFactory::createHandler( zyppng::ContextBaseRef ctx, const Url &o_url, const Pathname &preferred_attach_point ) { + if ( !ctx ) { + MIL << "A MediaHandler always needs a context" << std::endl; + ZYPP_THROW(MediaException("MediaHandler always needs a valid Context.")); + } if(!o_url.isValid()) { MIL << "Url is not valid" << std::endl; ZYPP_THROW(MediaBadUrlException(o_url)); @@ -66,27 +70,27 @@ namespace zypp::media { std::unique_ptr _handler; switch(*hdlType) { case MediaCDType: { - _handler = std::make_unique (url,preferred_attach_point); + _handler = std::make_unique (std::move(ctx), url,preferred_attach_point); break; } case MediaNFSType: { - _handler = std::make_unique (url,preferred_attach_point); + _handler = std::make_unique (std::move(ctx), url,preferred_attach_point); break; } case MediaISOType: { - _handler = std::make_unique (url,preferred_attach_point); + _handler = std::make_unique (std::move(ctx), url,preferred_attach_point); break; } case MediaFileType: { - _handler = std::make_unique (url,preferred_attach_point); + _handler = std::make_unique (std::move(ctx), url,preferred_attach_point); break; } case MediaDISKType: { - _handler = std::make_unique (url,preferred_attach_point); + _handler = std::make_unique (std::move(ctx), url,preferred_attach_point); break; } case MediaCIFSType: { - _handler = std::make_unique (url,preferred_attach_point); + _handler = std::make_unique (std::move(ctx), url,preferred_attach_point); break; } case MediaCURLType: { @@ -126,15 +130,15 @@ namespace zypp::media { switch ( which ) { default: case multicurl: - handler = std::make_unique( url, preferred_attach_point ); + handler = std::make_unique( std::move(ctx), url, preferred_attach_point ); break; case network: - handler = std::make_unique( url, preferred_attach_point ); + handler = std::make_unique( std::move(ctx), url, preferred_attach_point ); break; case curl: - handler = std::make_unique( url, preferred_attach_point ); + handler = std::make_unique( std::move(ctx), url, preferred_attach_point ); break; } // Set up the handler diff --git a/zypp/media/MediaHandlerFactory.h b/zypp/media/MediaHandlerFactory.h index 12f90e177b..37155f6885 100644 --- a/zypp/media/MediaHandlerFactory.h +++ b/zypp/media/MediaHandlerFactory.h @@ -1,11 +1,15 @@ #ifndef MEDIAHANDLERFACTORY_H #define MEDIAHANDLERFACTORY_H +#include #include #include #include #include +namespace zyppng { + ZYPP_FWD_DECL_TYPE_WITH_REFS(ContextBase); +} namespace zypp::media { @@ -27,7 +31,7 @@ namespace zypp::media { }; MediaHandlerFactory(); - static std::unique_ptr createHandler (const Url& o_url, const Pathname & preferred_attach_point); + static std::unique_ptr createHandler ( zyppng::ContextBaseRef ctx, const Url& o_url, const Pathname & preferred_attach_point); static std::optional handlerType( const Url &url ); }; diff --git a/zypp/media/MediaISO.cc b/zypp/media/MediaISO.cc index 4cadffece3..caeb5a5bb3 100644 --- a/zypp/media/MediaISO.cc +++ b/zypp/media/MediaISO.cc @@ -41,9 +41,10 @@ namespace zypp // filesystem: Optional, defaults to "auto". // /////////////////////////////////////////////////////////////////// - MediaISO::MediaISO(const Url &url_r, + MediaISO::MediaISO(zyppng::ContextBaseRef ctx, const Url &url_r, const Pathname &attach_point_hint_r) - : MediaHandler(url_r, attach_point_hint_r, + : MediaHandler(std::move(ctx), + url_r, attach_point_hint_r, url_r.getPathName(), // urlpath below attachpoint false) // does_download { @@ -108,7 +109,7 @@ namespace zypp MediaManager manager; - _parentId = manager.open(src, _url.getQueryParam("mnt")); + _parentId = manager.open( _zyppContext, src, _url.getQueryParam("mnt")); } // --------------------------------------------------------------- diff --git a/zypp/media/MediaISO.h b/zypp/media/MediaISO.h index c83e814e8d..1782958523 100644 --- a/zypp/media/MediaISO.h +++ b/zypp/media/MediaISO.h @@ -52,10 +52,11 @@ namespace zypp public: - MediaISO(const Url &url_r, + MediaISO(zyppng::ContextBaseRef ctx, + const Url &url_r, const Pathname &attach_point_hint_r); - + ~MediaISO() override; bool diff --git a/zypp/media/MediaManager.cc b/zypp/media/MediaManager.cc index e728d9443a..08ed9787b6 100644 --- a/zypp/media/MediaManager.cc +++ b/zypp/media/MediaManager.cc @@ -25,6 +25,7 @@ #include #include #include +#include ////////////////////////////////////////////////////////////////////// namespace zypp @@ -61,9 +62,9 @@ namespace zypp : desired(m.desired), verifier(std::move(m.verifier)), _handler(std::move(m._handler)) {} - static ManagedMedia makeManagedMedia ( const Url &o_url, const Pathname &preferred_attach_point, const MediaVerifierRef &v ) + static ManagedMedia makeManagedMedia ( zyppng::ContextBaseRef &&ctx, const Url &o_url, const Pathname &preferred_attach_point, const MediaVerifierRef &v ) { - auto handler = MediaHandlerFactory::createHandler( o_url, preferred_attach_point ); + auto handler = MediaHandlerFactory::createHandler( std::move(ctx), o_url, preferred_attach_point ); if ( !handler ) { ERR << "Failed to create media handler" << std::endl; ZYPP_THROW( MediaSystemException(o_url, "Failed to create media handler")); @@ -314,10 +315,15 @@ namespace zypp // --------------------------------------------------------------- MediaAccessId MediaManager::open(const Url &url, const Pathname &preferred_attach_point) + { + return open( zypp_detail::GlobalStateHelper::context(), url, preferred_attach_point ); + } + + MediaAccessId MediaManager::open( zyppng::ContextBaseRef ctx, const Url &url, const Pathname &preferred_attach_point ) { // create new access handler for it MediaVerifierRef verifier( new NoVerifier()); - ManagedMedia tmp = ManagedMedia::makeManagedMedia( url, preferred_attach_point, verifier ); + ManagedMedia tmp = ManagedMedia::makeManagedMedia( std::move(ctx), url, preferred_attach_point, verifier ); MediaAccessId nextId = m_impl->nextAccessId(); diff --git a/zypp/media/MediaManager.h b/zypp/media/MediaManager.h index f1fa81a349..d2155f484b 100644 --- a/zypp/media/MediaManager.h +++ b/zypp/media/MediaManager.h @@ -24,6 +24,9 @@ #include +namespace zyppng { + ZYPP_FWD_DECL_TYPE_WITH_REFS(ContextBase); +} namespace zypp::media { @@ -493,7 +496,32 @@ namespace zypp::media * \throws MediaException */ MediaAccessId - open(const Url &url, const Pathname & preferred_attach_point = ""); + open( const Url &url, const Pathname & preferred_attach_point = "" ) ZYPP_INTERNAL_DEPRECATE; + + + /** + * Opens the media access for specified with the url. + * + * If the \p preferred_attach_point parameter does not + * point to a usable attach point directory, the media + * manager automatically creates a temporary attach + * point in a default directory. This default directory + * can be changed using setAttachPrefix() function. + * + * Remember to close() each id you've opened and not + * need any more. It is like a new and delete! + * + * \param ctx, the zyppng context used for settings for the created MediaHandler + * \param url The \ref MediaAccessUrl. + * \param preferred_attach_point The preferred, already + * existing directory, where the media should be + * attached. + * \return a new media access id. + * \throws std::bad_alloc + * \throws MediaException + */ + MediaAccessId + open( zyppng::ContextBaseRef ctx, const Url &url, const Pathname & preferred_attach_point = ""); /** * Close the media access with specified id. diff --git a/zypp/media/MediaMultiCurl.cc b/zypp/media/MediaMultiCurl.cc index 8cddbb3c04..5ac5fac144 100644 --- a/zypp/media/MediaMultiCurl.cc +++ b/zypp/media/MediaMultiCurl.cc @@ -143,7 +143,7 @@ class multifetchworker : private MediaCurl, public zyppng::CurlMultiPartDataRece friend class multifetchrequest; public: - multifetchworker(int no, multifetchrequest &request, const Url &url); + multifetchworker(zyppng::ContextBaseRef ctx, int no, multifetchrequest &request, const Url &url); multifetchworker(const multifetchworker &) = delete; multifetchworker(multifetchworker &&) = delete; multifetchworker &operator=(const multifetchworker &) = delete; @@ -439,8 +439,8 @@ multifetchworker::headerfunction( char *p, size_t bytes ) return bytes; } -multifetchworker::multifetchworker(int no, multifetchrequest &request, const Url &url) -: MediaCurl(url, Pathname()) +multifetchworker::multifetchworker( zyppng::ContextBaseRef ctx, int no, multifetchrequest &request, const Url &url) +: MediaCurl(std::move(ctx), url, Pathname()) , _workerno( no ) , _maxspeed( request._maxspeed ) , _request ( &request ) @@ -1048,7 +1048,7 @@ multifetchrequest::run(std::vector &urllist) if ((int)_activeworkers < _maxworkers && urliter != urllist.end() && _workers.size() < MAXURLS) { // spawn another worker! - _workers.push_back(std::make_unique(workerno++, *this, *urliter)); + _workers.push_back(std::make_unique( _context->_zyppContext, workerno++, *this, *urliter)); auto &worker = _workers.back(); if (worker->_state != WORKER_BROKEN) { @@ -1369,8 +1369,8 @@ inline zypp::ByteCount multifetchrequest::makeBlksize ( uint maxConns, size_t fi ////////////////////////////////////////////////////////////////////// -MediaMultiCurl::MediaMultiCurl(const Url &url_r, const Pathname & attach_point_hint_r) - : MediaCurl(url_r, attach_point_hint_r) +MediaMultiCurl::MediaMultiCurl(zyppng::ContextBaseRef ctx, const Url &url_r, const Pathname & attach_point_hint_r) + : MediaCurl( std::move(ctx), url_r, attach_point_hint_r) { MIL << "MediaMultiCurl::MediaMultiCurl(" << url_r << ", " << attach_point_hint_r << ")" << endl; _multi = 0; @@ -1582,7 +1582,7 @@ void MediaMultiCurl::doGetFileCopy( const OnMediaLocation &srcFile , const Pathn if ( ismetalink != MetaDataType::None ) { bool userabort = false; - Pathname failedFile = ZConfig::instance().repoCachePath() / "MultiCurl.failed"; + Pathname failedFile = ZConfig::systemConfig().repoCachePath() / "MultiCurl.failed"; file = nullptr; // explicitly close destNew before the parser reads it. try { diff --git a/zypp/media/MediaMultiCurl.h b/zypp/media/MediaMultiCurl.h index 42f335376b..8aae5e74a8 100644 --- a/zypp/media/MediaMultiCurl.h +++ b/zypp/media/MediaMultiCurl.h @@ -42,7 +42,7 @@ class MediaMultiCurl : public MediaCurl { friend class multifetchrequest; friend class multifetchworker; - MediaMultiCurl(const Url &url_r, const Pathname & attach_point_hint_r); + MediaMultiCurl( zyppng::ContextBaseRef ctx, const Url &url_r, const Pathname & attach_point_hint_r); ~MediaMultiCurl() override; void doGetFileCopy( const OnMediaLocation & srcFile, const Pathname & targetFilename, callback::SendReport & _report, RequestOptions options = OPTION_NONE ) const override; diff --git a/zypp/media/MediaNFS.cc b/zypp/media/MediaNFS.cc index b59e6a7cde..a6e1cb3861 100644 --- a/zypp/media/MediaNFS.cc +++ b/zypp/media/MediaNFS.cc @@ -39,9 +39,10 @@ namespace zypp { // // DESCRIPTION : // - MediaNFS::MediaNFS( const Url & url_r, - const Pathname & attach_point_hint_r ) - : MediaHandler( url_r, attach_point_hint_r, + MediaNFS::MediaNFS( zyppng::ContextBaseRef ctx, + const Url & url_r, + const Pathname & attach_point_hint_r ) + : MediaHandler( std::move(ctx), url_r, attach_point_hint_r, "/", // urlpath at attachpoint false ) // does_download { diff --git a/zypp/media/MediaNFS.h b/zypp/media/MediaNFS.h index 208b0e5719..d79bd282d6 100644 --- a/zypp/media/MediaNFS.h +++ b/zypp/media/MediaNFS.h @@ -50,7 +50,8 @@ namespace zypp { public: - MediaNFS( const Url& url_r, + MediaNFS( zyppng::ContextBaseRef ctx, + const Url& url_r, const Pathname & attach_point_hint_r ); ~MediaNFS() override { try { release(); } catch(...) {} } diff --git a/zypp/media/MediaNetwork.cc b/zypp/media/MediaNetwork.cc index f50bd1e89b..43c7dff670 100644 --- a/zypp/media/MediaNetwork.cc +++ b/zypp/media/MediaNetwork.cc @@ -30,10 +30,11 @@ #include #include -#include +#include #include #include +#include using std::endl; @@ -151,7 +152,7 @@ namespace internal { MIL << "Initializing internal::SharedData for MediaNetwork" << std::endl; _dispatcher = zyppng::ThreadData::current().ensureDispatcher(); _downloader = std::make_shared(); - _downloader->requestDispatcher()->setMaximumConcurrentConnections( zypp::MediaConfig::instance().download_max_concurrent_connections() ); + _downloader->requestDispatcher()->setMaximumConcurrentConnections( zypp::ZConfig::systemConfig().download_max_concurrent_connections() ); } }; @@ -164,9 +165,9 @@ namespace zypp { namespace media { - MediaNetwork::MediaNetwork( const Url & url_r, - const Pathname & attach_point_hint_r ) - : MediaNetworkCommonHandler( url_r, attach_point_hint_r, + MediaNetwork::MediaNetwork(zyppng::ContextBaseRef ctx, const Url & url_r, + const Pathname & attach_point_hint_r ) + : MediaNetworkCommonHandler( std::move(ctx), url_r, attach_point_hint_r, "/", // urlpath at attachpoint true ) // does_download { @@ -286,11 +287,11 @@ namespace zypp { const auto &authRequiredSlot = [&]( zyppng::Download &req, zyppng::NetworkAuthData &auth, const std::string &availAuth ){ //! \todo need a way to pass different CredManagerOptions here - CredentialManager cm(CredManagerOptions(ZConfig::instance().repoManagerRoot())); + auto cm = zyppng::media::CredentialManager::create( CredManagerSettings(_zyppContext) ); CurlAuthData_Ptr credentials; // get stored credentials - AuthData_Ptr cmcred = cm.getCred(_url); + AuthData_Ptr cmcred = cm->getCred(_url); if ( cmcred && auth.lastDatabaseUpdate() < cmcred->lastDatabaseUpdate() ) { credentials.reset(new CurlAuthData(*cmcred)); DBG << "got stored credentials:" << endl << *credentials << endl; @@ -351,8 +352,8 @@ namespace zypp { auth = *credentials; if (!cmcred) { credentials->setUrl(_url); - cm.addCred(*credentials); - cm.save(); + cm->addCred(*credentials); + cm->save(); } }; diff --git a/zypp/media/MediaNetwork.h b/zypp/media/MediaNetwork.h index 6a37c46ca6..2b3e440c4c 100644 --- a/zypp/media/MediaNetwork.h +++ b/zypp/media/MediaNetwork.h @@ -64,8 +64,9 @@ namespace zypp { public: - MediaNetwork( const Url & url_r, - const Pathname & attach_point_hint_r ); + MediaNetwork( zyppng::ContextBaseRef ctx, + const Url & url_r, + const Pathname & attach_point_hint_r ); ~MediaNetwork() override { try { release(); } catch(...) {} } diff --git a/zypp/media/MediaNetworkCommonHandler.cc b/zypp/media/MediaNetworkCommonHandler.cc index 25a32405d7..402d7359be 100644 --- a/zypp/media/MediaNetworkCommonHandler.cc +++ b/zypp/media/MediaNetworkCommonHandler.cc @@ -24,7 +24,7 @@ namespace zypp::media zypp::Url MediaNetworkCommonHandler::findGeoIPRedirect ( const zypp::Url &url ) { try { - const auto &conf = ZConfig::instance(); + const auto &conf = ZConfig::systemConfig(); if ( !conf.geoipEnabled() ) { MIL << "GeoIp rewrites disabled via ZConfig." << std::endl; return Url(); diff --git a/zypp/media/MediaNetworkCommonHandler.h b/zypp/media/MediaNetworkCommonHandler.h index 514e59cf54..f6487bcec1 100644 --- a/zypp/media/MediaNetworkCommonHandler.h +++ b/zypp/media/MediaNetworkCommonHandler.h @@ -30,11 +30,12 @@ namespace zypp class MediaNetworkCommonHandler : public MediaHandler { public: - MediaNetworkCommonHandler( const Url & url_r, + MediaNetworkCommonHandler( zyppng::ContextBaseRef ctx, + const Url & url_r, const Pathname & attach_point_r, const Pathname & urlpath_below_attachpoint_r, const bool does_download_r ) - : MediaHandler( url_r, attach_point_r, urlpath_below_attachpoint_r, does_download_r ) + : MediaHandler( std::move(ctx), url_r, attach_point_r, urlpath_below_attachpoint_r, does_download_r ) , _redirTarget( findGeoIPRedirect(url_r) ) {} diff --git a/zypp/media/MediaPlugin.cc b/zypp/media/MediaPlugin.cc index 48ba094fff..076f3a6bf0 100644 --- a/zypp/media/MediaPlugin.cc +++ b/zypp/media/MediaPlugin.cc @@ -28,8 +28,8 @@ namespace zypp namespace media { ////////////////////////////////////////////////////////////////// - MediaPlugin::MediaPlugin( const Url & url_r, const Pathname & attach_point_hint_r ) - : MediaHandler( url_r, attach_point_hint_r, /*path below attachpoint*/"/", /*does_download*/false ) + MediaPlugin::MediaPlugin(zyppng::ContextBaseRef ctx, const Url & url_r, const Pathname & attach_point_hint_r ) + : MediaHandler( std::move(ctx), url_r, attach_point_hint_r, /*path below attachpoint*/"/", /*does_download*/false ) { MIL << "MediaPlugin::MediaPlugin(" << url_r << ", " << attach_point_hint_r << ")" << endl; } diff --git a/zypp/media/MediaPlugin.h b/zypp/media/MediaPlugin.h index 998e1ef9ff..d9d6869373 100644 --- a/zypp/media/MediaPlugin.h +++ b/zypp/media/MediaPlugin.h @@ -29,7 +29,7 @@ namespace zypp class MediaPlugin : public MediaHandler { public: - MediaPlugin( const Url & url_r, const Pathname & attach_point_hint_r ); + MediaPlugin( zyppng::ContextBaseRef ctx, const Url & url_r, const Pathname & attach_point_hint_r ); ~MediaPlugin() override { try { release(); } catch(...) {} } diff --git a/zypp/media/MediaPriority.cc b/zypp/media/MediaPriority.cc index 52f842556c..0ad2b79c88 100644 --- a/zypp/media/MediaPriority.cc +++ b/zypp/media/MediaPriority.cc @@ -44,27 +44,27 @@ namespace zypp #define RETURN_IF(scheme,value) \ if ( ::strcmp( scheme+1, scheme_r.c_str()+1 ) == 0 ) return value; case 'c': - RETURN_IF( "cd", ZConfig::instance().download_media_prefer_download() ? 1 : 2 ); + RETURN_IF( "cd", ZConfig::systemConfig().download_media_prefer_download() ? 1 : 2 ); RETURN_IF( "cifs", 3 ); break; case 'd': - RETURN_IF( "dvd", ZConfig::instance().download_media_prefer_download() ? 1 : 2 ); + RETURN_IF( "dvd", ZConfig::systemConfig().download_media_prefer_download() ? 1 : 2 ); RETURN_IF( "dir", 4 ); break; case 'f': RETURN_IF( "file", 4 ); - RETURN_IF( "ftp", ZConfig::instance().download_media_prefer_download() ? 2 : 1); + RETURN_IF( "ftp", ZConfig::systemConfig().download_media_prefer_download() ? 2 : 1); break; case 't': - RETURN_IF( "tftp", ZConfig::instance().download_media_prefer_download() ? 2 : 1); + RETURN_IF( "tftp", ZConfig::systemConfig().download_media_prefer_download() ? 2 : 1); break; case 'h': - RETURN_IF( "http", ZConfig::instance().download_media_prefer_download() ? 2 : 1 ); - RETURN_IF( "https", ZConfig::instance().download_media_prefer_download() ? 2 : 1 ); + RETURN_IF( "http", ZConfig::systemConfig().download_media_prefer_download() ? 2 : 1 ); + RETURN_IF( "https", ZConfig::systemConfig().download_media_prefer_download() ? 2 : 1 ); RETURN_IF( "hd", 4 ); break; @@ -74,7 +74,7 @@ namespace zypp break; case 's': - RETURN_IF( "sftp", ZConfig::instance().download_media_prefer_download() ? 2 : 1 ); + RETURN_IF( "sftp", ZConfig::systemConfig().download_media_prefer_download() ? 2 : 1 ); RETURN_IF( "smb", 3 ); break; #undef RETURN_IF diff --git a/zypp/media/UrlResolverPlugin.cc b/zypp/media/UrlResolverPlugin.cc index 6bf7605a00..09a86929ce 100644 --- a/zypp/media/UrlResolverPlugin.cc +++ b/zypp/media/UrlResolverPlugin.cc @@ -40,7 +40,7 @@ namespace zypp Url url(o_url); std::string name = url.getPathName(); - Pathname plugin_path = (ZConfig::instance().pluginsPath()/"urlresolver")/name; + Pathname plugin_path = (ZConfig::systemConfig().pluginsPath()/"urlresolver")/name; if (PathInfo(plugin_path).isExist()) { PluginScript scr; scr.open(plugin_path); diff --git a/zypp/misc/DefaultLoadSystem.cc b/zypp/misc/DefaultLoadSystem.cc deleted file mode 100644 index 751a9dfd08..0000000000 --- a/zypp/misc/DefaultLoadSystem.cc +++ /dev/null @@ -1,114 +0,0 @@ -/*---------------------------------------------------------------------\ -| ____ _ __ __ ___ | -| |__ / \ / / . \ . \ | -| / / \ V /| _/ _/ | -| / /__ | | | | | | | -| /_____||_| |_| |_| | -| | -\---------------------------------------------------------------------*/ -/** \file zypp/misc/DefaultLoadSystem.cc - * -*/ -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include - -using std::endl; - -#undef ZYPP_BASE_LOGGER_LOGGROUP -#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::misc" - -/////////////////////////////////////////////////////////////////// -namespace zypp -{ ///////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////// - namespace misc - { ///////////////////////////////////////////////////////////////// - - void defaultLoadSystem( const Pathname & sysRoot_r, LoadSystemFlags flags_r ) - { - if ( not flags_r && geteuid() != 0 ) { - flags_r |= LS_NOREFRESH; - } - MIL << str::form( "*** Load system at '%s' (%lx)", sysRoot_r.c_str(), (unsigned long)flags_r ) << endl; - - if ( ! PathInfo( sysRoot_r ).isDir() ) - ZYPP_THROW( Exception(str::form("sysRoot_r argument needs to be a directory. (%s)", sysRoot_r.c_str())) ); - - if ( ZYppFactory::instance().haveZYpp() ) - ZYPP_THROW( Exception("ZYpp instance is already created. (Call this method earlier.)") ); - - if ( flags_r.testFlag( LS_READONLY ) ) - zypp_readonly_hack::IWantIt (); - - sat::Pool satpool( sat::Pool::instance() ); - - if ( 1 ) - { - MIL << "*** load target '" << Repository::systemRepoAlias() << "'\t" << endl; - getZYpp()->initializeTarget( sysRoot_r ); - getZYpp()->target()->load(); - MIL << satpool.systemRepo() << endl; - } - - if ( not flags_r.testFlag( LS_NOREPOS ) ) - { - RepoManager repoManager( sysRoot_r ); - RepoInfoList repos = repoManager.knownRepositories(); - for_( it, repos.begin(), repos.end() ) - { - RepoInfo & nrepo( *it ); - - if ( ! nrepo.enabled() ) - continue; - - if ( ! flags_r.testFlag( LS_NOREFRESH ) ) - { - if ( repoManager.isCached( nrepo ) - && ( nrepo.type() == repo::RepoType::RPMPLAINDIR // refreshes always - || repoManager.checkIfToRefreshMetadata( nrepo, nrepo.url() ) == RepoManager::REFRESH_NEEDED ) ) - { - MIL << str::form( "*** clean cache for repo '%s'\t", nrepo.name().c_str() ) << endl; - repoManager.cleanCache( nrepo ); - MIL << str::form( "*** refresh repo '%s'\t", nrepo.name().c_str() ) << endl; - repoManager.refreshMetadata( nrepo ); - } - } - - if ( ! repoManager.isCached( nrepo ) ) - { - MIL << str::form( "*** build cache for repo '%s'\t", nrepo.name().c_str() ) << endl; - repoManager.buildCache( nrepo ); - } - - MIL << str::form( "*** load repo '%s'\t", nrepo.name().c_str() ) << std::flush; - try - { - repoManager.loadFromCache( nrepo ); - MIL << satpool.reposFind( nrepo.alias() ) << endl; - } - catch ( const Exception & exp ) - { - ERR << "*** load repo failed: " << exp.asString() + "\n" + exp.historyAsString() << endl; - ZYPP_RETHROW ( exp ); - } - } - } - MIL << str::form( "*** Read system at '%s'", sysRoot_r.c_str() ) << endl; - } - - ///////////////////////////////////////////////////////////////// - } // namespace misc - /////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////// -} // namespace zypp -/////////////////////////////////////////////////////////////////// diff --git a/zypp/misc/DefaultLoadSystem.h b/zypp/misc/DefaultLoadSystem.h deleted file mode 100644 index faa3b0fe1c..0000000000 --- a/zypp/misc/DefaultLoadSystem.h +++ /dev/null @@ -1,64 +0,0 @@ -/*---------------------------------------------------------------------\ -| ____ _ __ __ ___ | -| |__ / \ / / . \ . \ | -| / / \ V /| _/ _/ | -| / /__ | | | | | | | -| /_____||_| |_| |_| | -| | -\---------------------------------------------------------------------*/ -/** \file zypp/misc/DefaultLoadSystem.h - * -*/ -#ifndef ZYPP_MISC_DEFAULTLOADSYSTEM_H -#define ZYPP_MISC_DEFAULTLOADSYSTEM_H - -#include - -#include -#include - -/////////////////////////////////////////////////////////////////// -namespace zypp -{ ///////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////// - namespace misc - { ///////////////////////////////////////////////////////////////// - - /** - * Bits for tuning \ref defaultLoadSystem. - * - * Use \ref LoadSystemFlags as a type-safe way of - * storing OR-combinations. - */ - enum LoadSystemFlag - { - LS_READONLY = (1 << 0), //!< // Create readonly ZYpp instance. - LS_NOREFRESH = (1 << 1), //!< // Don't refresh existing repos. - LS_NOREPOS = (1 << 2), //!< // Don't loag existing repos (just Target). - }; - - /** \relates LoadSystemFlag Type-safe way of storing OR-combinations. */ - ZYPP_DECLARE_FLAGS_AND_OPERATORS( LoadSystemFlags, LoadSystemFlag ); - - /** - * Create the ZYpp instance and load target and enabled repositories. - * - * \see LoadSystemFlag for options. - * - * \throws Exception on error - * - * \todo properly handle service refreshs - */ - void defaultLoadSystem( const Pathname & sysRoot_r = "/", LoadSystemFlags flags_r = LoadSystemFlags() ); - - /** \overload */ - inline void defaultLoadSystem( LoadSystemFlags flags_r ) - { defaultLoadSystem( "/", flags_r ); } - - ///////////////////////////////////////////////////////////////// - } // namespace misc - /////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////// -} // namespace zypp -/////////////////////////////////////////////////////////////////// -#endif // ZYPP_MISC_DEFAULTLOADSYSTEM_H diff --git a/zypp/misc/TestcaseSetup.cc b/zypp/misc/TestcaseSetup.cc index 0766b9fa03..8dcd2b3f36 100644 --- a/zypp/misc/TestcaseSetup.cc +++ b/zypp/misc/TestcaseSetup.cc @@ -2,6 +2,7 @@ namespace zypp::misc::testcase { + ZYPP_BEGIN_LEGACY_API RepoData::RepoData() : _pimpl( new RepoDataImpl ) {} @@ -257,4 +258,5 @@ namespace zypp::misc::testcase return *_pimpl; } + ZYPP_END_LEGACY_API } diff --git a/zypp/misc/TestcaseSetup.h b/zypp/misc/TestcaseSetup.h index 0230f39d39..3c3519ee22 100644 --- a/zypp/misc/TestcaseSetup.h +++ b/zypp/misc/TestcaseSetup.h @@ -27,6 +27,8 @@ #include #include +ZYPP_BEGIN_LEGACY_API + namespace zypp { class RepoManager; } @@ -132,5 +134,5 @@ namespace zypp::misc::testcase } - +ZYPP_END_LEGACY_API #endif // ZYPP_MISC_TESTCASESETUPIMPL_H diff --git a/zypp/ng/context_fwd.h b/zypp/ng/context_fwd.h index 574d68d7f0..91799cfe61 100644 --- a/zypp/ng/context_fwd.h +++ b/zypp/ng/context_fwd.h @@ -16,6 +16,7 @@ namespace zyppng { struct SyncTag; struct AsyncTag; + ZYPP_FWD_DECL_TYPE_WITH_REFS ( ContextBase ); ZYPP_FWD_DECL_TEMPL_TYPE_WITH_REFS_ARG1( Context, Tag ); using AsyncContext = Context; diff --git a/zypp/ng/contextbase.cc b/zypp/ng/contextbase.cc index 410911706c..0d79d132ff 100644 --- a/zypp/ng/contextbase.cc +++ b/zypp/ng/contextbase.cc @@ -10,16 +10,12 @@ namespace zyppng { ContextBase::ContextBase() : _tmpDir( zypp::filesystem::TmpPath::defaultLocation(), "zypp." ) + , _repoVarCache( *this ) { } ContextBase::~ContextBase() { } - zypp::Pathname ContextBase::defaultConfigPath() - { - return "/etc/zypp/zypp.conf"; - } - zypp::Pathname ContextBase::contextRoot() const { // this is a programming error, the C API will hide the 2 step create and init process. @@ -176,6 +172,14 @@ namespace zyppng { return *_config; } + zypp::MediaConfig &ContextBase::mediaConfig() + { + assertInitialized(); + // config loaded on demand if queried before initializing the target + if ( !_config ) loadConfig ( *_settings->configPath ).unwrap(); + return _config->mediaConfig(); + } + zypp::Pathname ContextBase::tmpPath() const { return _tmpDir.path(); @@ -186,4 +190,24 @@ namespace zyppng { return _target; } + const std::string *ContextBase::resolveRepoVar(const std::string &var) + { + return _repoVarCache.lookup(var); + } + + repo::RepoVarsMap &ContextBase::repoVarCache() + { + return _repoVarCache; + } + + const repo::RepoVarsMap &ContextBase::repoVarCache() const + { + return _repoVarCache; + } + + void ContextBase::clearRepoVariables() + { + _repoVarCache.clear(); + } + } diff --git a/zypp/ng/contextbase.h b/zypp/ng/contextbase.h index db6559ec69..4823dc4e98 100644 --- a/zypp/ng/contextbase.h +++ b/zypp/ng/contextbase.h @@ -11,7 +11,8 @@ #include #include -#include +#include +#include namespace zypp { DEFINE_PTR_TYPE(KeyRing); @@ -38,7 +39,7 @@ namespace zyppng { std::optional configPath; }; - class ContextBase : public UserInterface + class ContextBase : public MediaContext { public: ~ContextBase() override; @@ -47,13 +48,10 @@ namespace zyppng { ContextBase &operator=(const ContextBase &) = delete; ContextBase &operator=(ContextBase &&) = delete; - - static zypp::Pathname defaultConfigPath(); - /*! * Returns the root path of the context */ - zypp::Pathname contextRoot() const; + zypp::Pathname contextRoot() const override; /*! * Gets the zypp lock, loads the config and sets up keyring @@ -75,9 +73,26 @@ namespace zyppng { KeyRingRef keyRing (); zypp::ZConfig &config(); + zypp::MediaConfig &mediaConfig() override; zypp::Pathname tmpPath() const; TargetRef target() const; + + /*! + * Tries to resolve the variable \a var from the repoCache, + * returns a pointer to the found value or nullptr if the variable + * is not known. + */ + const std::string * resolveRepoVar( const std::string & var ); + + repo::RepoVarsMap &repoVarCache(); + const repo::RepoVarsMap &repoVarCache() const; + + /*! + * Resets all cached repo variables + */ + void clearRepoVariables(); + /*! * Signal emitted during context close, e.g. unloading the target. * All classes depending on the context can connect to it to clean up. @@ -111,6 +126,11 @@ namespace zyppng { } private: + + /** + * \todo move CredentialManager here + */ + std::optional _settings; bool _legacyMode = false; // set by legacyInit. Will disable locking inside the context, Zypp and ZyppFactory take care of that @@ -130,6 +150,7 @@ namespace zyppng { TargetRef _target; zypp::ZyppContextLockRef _myLock; + repo::RepoVarsMap _repoVarCache; }; diff --git a/zypp/ng/fusionpool.h b/zypp/ng/fusionpool.h index 8457d74274..337eb46be6 100644 --- a/zypp/ng/fusionpool.h +++ b/zypp/ng/fusionpool.h @@ -257,7 +257,7 @@ namespace zyppng { /*! * Loads the given RepoInfo associated with a solvFile into the Pool. */ - expected addRepository ( zypp::RepoInfo info, zypp::Pathname solvFilePath ) + expected addRepository ( RepoInfo info, zypp::Pathname solvFilePath ) { return expected::error( ZYPP_EXCPT_PTR( zypp::Exception("Not implemented")) ); } diff --git a/zypp/parser/RepoFileReader.cc b/zypp/ng/parser/RepoFileReader.cc similarity index 71% rename from zypp/parser/RepoFileReader.cc rename to zypp/ng/parser/RepoFileReader.cc index 131e86ffc7..9daf8e911a 100644 --- a/zypp/parser/RepoFileReader.cc +++ b/zypp/ng/parser/RepoFileReader.cc @@ -6,24 +6,25 @@ | /_____||_| |_| |_| | | | \---------------------------------------------------------------------*/ -/** \file zypp/repo/RepoFileReader.cc +/** \file zypp/ng/repo/RepoFileReader.cc * */ + +#include "RepoFileReader.h" #include #include #include #include +#include #include #include #include - #include -#include using std::endl; /////////////////////////////////////////////////////////////////// -namespace zypp +namespace zyppng { /////////////////////////////////////////////////////////////////// namespace parser @@ -35,10 +36,10 @@ namespace zypp /// \class RepoFileParser /// \brief Modified \ref IniDict to allow parsing multiple 'baseurl=' entries /////////////////////////////////////////////////////////////////// - class RepoFileParser : public IniDict + class RepoFileParser : public zypp::parser::IniDict { public: - RepoFileParser( const InputStream & is_r ) + RepoFileParser( const zypp::InputStream & is_r ) { read( is_r ); } using IniDict::consume; // don't hide overloads we don't redefine here @@ -93,40 +94,40 @@ namespace zypp break; case MultiLine::none: - IniDict::garbageLine( section_r, line_r ); // throw + zypp::parser::IniDict::garbageLine( section_r, line_r ); // throw break; } } - std::list & baseurls( const std::string & section_r ) + std::list & baseurls( const std::string & section_r ) { return _baseurls[section_r]; } - std::list & gpgkeys( const std::string & section_r ) + std::list & gpgkeys( const std::string & section_r ) { return _gpgkeys[section_r]; } - std::list & mirrorlist( const std::string & section_r ) + std::list & mirrorlist( const std::string & section_r ) { return _mirrorlist[section_r]; } - std::list & metalink( const std::string & section_r ) + std::list & metalink( const std::string & section_r ) { return _metalink[section_r]; } private: - void storeUrl( std::list & store_r, const std::string & line_r ) + void storeUrl( std::list & store_r, const std::string & line_r ) { // #285: Fedora/dnf allows WS separated urls (and an optional comma) - strv::splitRx( line_r, "[,[:blank:]]*[[:blank:]][,[:blank:]]*", [&store_r]( std::string_view w ) { + zypp::strv::splitRx( line_r, "[,[:blank:]]*[[:blank:]][,[:blank:]]*", [&store_r]( std::string_view w ) { if ( ! w.empty() ) - store_r.push_back( Url(std::string(w)) ); + store_r.push_back( zypp::Url(std::string(w)) ); }); } enum class MultiLine { none, baseurl, gpgkey, mirrorlist, metalink }; MultiLine _inMultiline = MultiLine::none; - std::map> _baseurls; - std::map> _gpgkeys; - std::map> _mirrorlist; - std::map> _metalink; + std::map> _baseurls; + std::map> _gpgkeys; + std::map> _mirrorlist; + std::map> _metalink; }; } //namespace @@ -136,14 +137,15 @@ namespace zypp * \short List of RepoInfo's from a file. * \param file pathname of the file to read. */ - static void repositories_in_stream( const InputStream &is, + static void repositories_in_stream( ContextBaseRef ctx, + const zypp::InputStream &is, const RepoFileReader::ProcessRepo &callback, - const ProgressData::ReceiverFnc &progress ) + const zypp::ProgressData::ReceiverFnc &progress ) try { RepoFileParser dict(is); for_( its, dict.sectionsBegin(), dict.sectionsEnd() ) { - RepoInfo info(nullptr); // context is initialized by caller + RepoInfo info(ctx); info.setAlias(*its); std::string proxy; std::string proxyport; @@ -154,23 +156,23 @@ namespace zypp if (it->first == "name" ) info.setName(it-> second); else if ( it->first == "enabled" ) - info.setEnabled( str::strToTrue( it->second ) ); + info.setEnabled( zypp::str::strToTrue( it->second ) ); else if ( it->first == "priority" ) - info.setPriority( str::strtonum( it->second ) ); + info.setPriority( zypp::str::strtonum( it->second ) ); else if ( it->first == "path" ) - info.setPath( Pathname(it->second) ); + info.setPath( zypp::Pathname(it->second) ); else if ( it->first == "type" ) ; // bsc#1177427 et.al.: type in a .repo file is legacy - ignore it and let RepoManager probe else if ( it->first == "autorefresh" ) - info.setAutorefresh( str::strToTrue( it->second ) ); + info.setAutorefresh( zypp::str::strToTrue( it->second ) ); else if ( it->first == "gpgcheck" ) - info.setGpgCheck( str::strToTriBool( it->second ) ); + info.setGpgCheck( zypp::str::strToTriBool( it->second ) ); else if ( it->first == "repo_gpgcheck" ) - info.setRepoGpgCheck( str::strToTrue( it->second ) ); + info.setRepoGpgCheck( zypp::str::strToTrue( it->second ) ); else if ( it->first == "pkg_gpgcheck" ) - info.setPkgGpgCheck( str::strToTrue( it->second ) ); + info.setPkgGpgCheck( zypp::str::strToTrue( it->second ) ); else if ( it->first == "keeppackages" ) - info.setKeepPackages( str::strToTrue( it->second ) ); + info.setKeepPackages( zypp::str::strToTrue( it->second ) ); else if ( it->first == "service" ) info.setService( it->second ); else if ( it->first == "proxy" ) @@ -178,9 +180,9 @@ namespace zypp // Translate it into baseurl queryparams // NOTE: The hack here does not add proxy to mirrorlist urls but the // original code worked without complains, so keep it for now. - static const str::regex ex( ":[0-9]+$" ); // portspec - str::smatch what; - if ( str::regex_match( it->second, what, ex ) ) + static const zypp::str::regex ex( ":[0-9]+$" ); // portspec + zypp::str::smatch what; + if ( zypp::str::regex_match( it->second, what, ex ) ) { proxy = it->second.substr( 0, it->second.size() - what[0].size() ); proxyport = what[0].substr( 1 ); @@ -222,7 +224,7 @@ namespace zypp // ZYPP_THROW(AbortRequestException()); } } - catch ( Exception & ex ) { + catch ( zypp::Exception & ex ) { ex.addHistory( "Parsing .repo file "+is.name() ); ZYPP_RETHROW( ex ); } @@ -233,20 +235,24 @@ namespace zypp // /////////////////////////////////////////////////////////////////// - RepoFileReader::RepoFileReader( const Pathname & repo_file, + RepoFileReader::RepoFileReader( ContextBaseRef context, + const zypp::Pathname & repo_file, ProcessRepo callback, - const ProgressData::ReceiverFnc &progress ) - : _callback(std::move(callback)) + const zypp::ProgressData::ReceiverFnc &progress ) + : _context( std::move(context) ) + , _callback(std::move(callback)) { - repositories_in_stream(InputStream(repo_file), _callback, progress); + repositories_in_stream(_context, zypp::InputStream(repo_file), _callback, progress); } - RepoFileReader::RepoFileReader( const InputStream &is, + RepoFileReader::RepoFileReader( ContextBaseRef context, + const zypp::InputStream &is, ProcessRepo callback, - const ProgressData::ReceiverFnc &progress ) - : _callback(std::move(callback)) + const zypp::ProgressData::ReceiverFnc &progress ) + : _context( std::move(context) ) + , _callback(std::move(callback)) { - repositories_in_stream(is, _callback, progress); + repositories_in_stream(_context, is, _callback, progress); } RepoFileReader::~RepoFileReader() diff --git a/zypp/parser/RepoFileReader.h b/zypp/ng/parser/RepoFileReader.h similarity index 85% rename from zypp/parser/RepoFileReader.h rename to zypp/ng/parser/RepoFileReader.h index e97c86790b..663ead3564 100644 --- a/zypp/parser/RepoFileReader.h +++ b/zypp/ng/parser/RepoFileReader.h @@ -6,7 +6,7 @@ | /_____||_| |_| |_| | | | \---------------------------------------------------------------------*/ -/** \file zypp/repo/RepoFileReader.h +/** \file zypp/ng/parser/RepoFileReader.h * */ #ifndef ZYPP_REPO_REPOFILEREADER_H @@ -18,9 +18,10 @@ #include #include #include +#include /////////////////////////////////////////////////////////////////// -namespace zypp +namespace zyppng { ///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// namespace parser @@ -61,7 +62,7 @@ namespace zypp * Return false from the callback to get a \ref AbortRequestException * to be thrown and the processing to be cancelled. */ - using ProcessRepo = function; + using ProcessRepo = std::function; /** Implementation */ class Impl; @@ -70,6 +71,7 @@ namespace zypp /** * \short Constructor. Creates the reader and start reading. * + * \param context The zypp context this RepoFileReader should evaluate in * \param repo_file A valid .repo file * \param callback Callback that will be called for each repository. * \param progress Optional progress function. \see ProgressData @@ -78,9 +80,10 @@ namespace zypp * \throws Exception If a error occurs at reading / parsing * */ - RepoFileReader( const Pathname & repo_file, + RepoFileReader( ContextBaseRef context, + const zypp::Pathname & repo_file, ProcessRepo callback, - const ProgressData::ReceiverFnc &progress = ProgressData::ReceiverFnc() ); + const zypp::ProgressData::ReceiverFnc &progress = zypp::ProgressData::ReceiverFnc() ); /** * \short Constructor. Creates the reader and start reading. @@ -93,15 +96,17 @@ namespace zypp * \throws Exception If a error occurs at reading / parsing * */ - RepoFileReader( const InputStream &is, + RepoFileReader( ContextBaseRef context, + const zypp::InputStream &is, ProcessRepo callback, - const ProgressData::ReceiverFnc &progress = ProgressData::ReceiverFnc() ); + const zypp::ProgressData::ReceiverFnc &progress = zypp::ProgressData::ReceiverFnc() ); /** * Dtor */ ~RepoFileReader(); private: + ContextBaseRef _context; ProcessRepo _callback; }; /////////////////////////////////////////////////////////////////// diff --git a/zypp/ng/parser/repoindexfilereader.cc b/zypp/ng/parser/repoindexfilereader.cc new file mode 100644 index 0000000000..9601cd078a --- /dev/null +++ b/zypp/ng/parser/repoindexfilereader.cc @@ -0,0 +1,255 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/ng/parser/repoindexfilereader.cc + * Implementation of repoindex.xml file reader. + */ + +#include "repoindexfilereader.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + + +#undef ZYPP_BASE_LOGGER_LOGGROUP +#define ZYPP_BASE_LOGGER_LOGGROUP "parser" + +using std::endl; + +namespace zyppng +{ + namespace parser + { + class RepoIndexVarReplacer + { + public: + RepoIndexVarReplacer() = default; + ~RepoIndexVarReplacer() = default; + RepoIndexVarReplacer(const RepoIndexVarReplacer &) = delete; + RepoIndexVarReplacer(RepoIndexVarReplacer &&) = delete; + RepoIndexVarReplacer &operator=(const RepoIndexVarReplacer &) = delete; + RepoIndexVarReplacer &operator=(RepoIndexVarReplacer &&) = delete; + /** */ + void setVar( const std::string & key_r, const std::string & val_r ) + { + //MIL << "*** Inject " << key_r << " = " << val_r; + _vars[key_r] = replace( val_r ); + //MIL << " (" << _vars[key_r] << ")" << endl; + } + + std::string replace( const std::string & val_r ) const + { + std::string::size_type vbeg = val_r.find( "%{", 0 ); + if ( vbeg == std::string::npos ) + return val_r; + + zypp::str::Str ret; + std::string::size_type cbeg = 0; + for( ; vbeg != std::string::npos; vbeg = val_r.find( "%{", vbeg ) ) + { + std::string::size_type nbeg = vbeg+2; + std::string::size_type nend = val_r.find( '}', nbeg ); + if ( nend == std::string::npos ) + { + WAR << "Incomplete variable in '" << val_r << "'" << endl; + break; + } + const auto & iter = _vars.find( val_r.substr( nbeg, nend-nbeg ) ); + if ( iter != _vars.end() ) + { + if ( cbeg < vbeg ) + ret << val_r.substr( cbeg, vbeg-cbeg ); + ret << iter->second; + cbeg = nend+1; + } + else + WAR << "Undefined variable %{" << val_r.substr( nbeg, nend-nbeg ) << "} in '" << val_r << "'" << endl; + vbeg = nend+1; + } + if ( cbeg < val_r.size() ) + ret << val_r.substr( cbeg ); + + return ret; + } + private: + std::unordered_map _vars; + }; + + bool RepoIndexFileReader::getAttrValue( const std::string & key_r, zypp::xml::Reader & reader_r, std::string & value_r ) + { + const zypp::xml::XmlString & s( reader_r->getAttribute( key_r ) ); + if ( s.get() ) + { + value_r = _replacer->replace( s.asString() ); + return !value_r.empty(); + } + value_r.clear(); + return false; + } + + + // -------------------------------------------------------------------------- + + /* + * xpath and multiplicity of processed nodes are included in the code + * for convenience: + * + * // xpath: (?|*|+) + * + * if multiplicity is ommited, then the node has multiplicity 'one'. + */ + + // -------------------------------------------------------------------------- + + bool RepoIndexFileReader::consumeNode( zypp::xml::Reader & reader_r ) + { + if ( reader_r->nodeType() == XML_READER_TYPE_ELEMENT ) + { + // xpath: /repoindex + if ( reader_r->name() == "repoindex" ) + { + while ( reader_r.nextNodeAttribute() ) + { + const std::string & name( reader_r->localName().asString() ); + const std::string & value( reader_r->value().asString() ); + _replacer->setVar( name, value ); + // xpath: /repoindex@ttl + if ( name == "ttl" ) + _ttl = zypp::str::strtonum(value); + } + return true; + } + + // xpath: /repoindex/data (+) + if ( reader_r->name() == "repo" ) + { + RepoInfo info(_zyppCtx); + // Set some defaults that are not contained in the repo information + info.setAutorefresh( true ); + info.setEnabled(false); + + std::string attrValue; + + // required alias + // mandatory, so we can allow it in var replacement without reset + if ( getAttrValue( "alias", reader_r, attrValue ) ) + { + info.setAlias( attrValue ); + _replacer->setVar( "alias", attrValue ); + } + else + throw zypp::parser::ParseException(zypp::str::form(_("Required attribute '%s' is missing."), "alias")); + + // required url + // SLES HACK: or path, but beware of the hardcoded '/repo' prefix! + { + std::string urlstr; + std::string pathstr; + getAttrValue( "url", reader_r, urlstr ); + getAttrValue( "path", reader_r, pathstr ); + if ( urlstr.empty() ) + { + if ( pathstr.empty() ) + throw zypp::parser::ParseException(zypp::str::form(_("One or both of '%s' or '%s' attributes is required."), "url", "path")); + else + info.setPath( zypp::Pathname("/repo") / pathstr ); + } + else + { + if ( pathstr.empty() ) + info.setBaseUrl( zypp::Url(urlstr) ); + else + { + zypp::Url url( urlstr ); + url.setPathName( zypp::Pathname(url.getPathName()) / "repo" / pathstr ); + info.setBaseUrl( url ); + } + } + } + + // optional name + if ( getAttrValue( "name", reader_r, attrValue ) ) + info.setName( attrValue ); + + // optional targetDistro + if ( getAttrValue( "distro_target", reader_r, attrValue ) ) + info.setTargetDistribution( attrValue ); + + // optional priority + if ( getAttrValue( "priority", reader_r, attrValue ) ) + info.setPriority( zypp::str::strtonum( attrValue ) ); + + + // optional enabled + if ( getAttrValue( "enabled", reader_r, attrValue ) ) + info.setEnabled( zypp::str::strToBool( attrValue, info.enabled() ) ); + + // optional autorefresh + if ( getAttrValue( "autorefresh", reader_r, attrValue ) ) + info.setAutorefresh( zypp::str::strToBool( attrValue, info.autorefresh() ) ); + + DBG << info << endl; + + // ignore the rest + _callback(info); + return true; + } + } + + return true; + } + + + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : RepoindexFileReader + // + /////////////////////////////////////////////////////////////////// + + RepoIndexFileReader::RepoIndexFileReader( ContextBaseRef ctx, zypp::Pathname repoindex_file, ProcessResource callback ) + : _zyppCtx( std::move(ctx) ) + , _callback( std::move(callback) ) + , _replacer( std::make_unique() ) + { run( zypp::InputStream(std::move(repoindex_file)) ); } + + RepoIndexFileReader::RepoIndexFileReader( ContextBaseRef ctx, const zypp::InputStream &is, ProcessResource callback ) + : _zyppCtx( std::move(ctx) ) + , _callback( std::move(callback) ) + , _replacer( std::make_unique() ) + { run( is ); } + + RepoIndexFileReader::~RepoIndexFileReader() + {} + + zypp::Date::Duration RepoIndexFileReader::ttl() const { return _ttl; } + + void RepoIndexFileReader::run( const zypp::InputStream &is ) + { + zypp::xml::Reader reader( is ); + MIL << "Reading " << is.path() << endl; + reader.foreachNode( [this]( auto &reader ) { return consumeNode (reader); } ); + } + + } // ns parser +} // ns zypp + +// vim: set ts=2 sts=2 sw=2 et ai: diff --git a/zypp/parser/RepoindexFileReader.h b/zypp/ng/parser/repoindexfilereader.h similarity index 53% rename from zypp/parser/RepoindexFileReader.h rename to zypp/ng/parser/repoindexfilereader.h index 9171d2d530..19a979bb98 100644 --- a/zypp/parser/RepoindexFileReader.h +++ b/zypp/ng/parser/repoindexfilereader.h @@ -9,22 +9,28 @@ /** \file zypp/parser/RepoindexFileReader.h * Interface of repoindex.xml file reader. */ -#ifndef zypp_source_yum_RepoindexFileReader_H -#define zypp_source_yum_RepoindexFileReader_H +#ifndef ZYPP_NG_PARSER_REPOINDEXFILEREADER_H_INCLUDED +#define ZYPP_NG_PARSER_REPOINDEXFILEREADER_H_INCLUDED #include -#include #include #include #include #include -namespace zypp +#include + +namespace zypp::xml { + class Reader; +} + +namespace zyppng { class RepoInfo; namespace parser { + class RepoIndexVarReplacer; /** * Reads through a repoindex.xml file and collects repositories. @@ -41,7 +47,7 @@ namespace zypp * bind( &SomeClass::callbackfunc, &SomeClassInstance, _1) ); * \endcode */ - class ZYPP_API RepoindexFileReader : private base::NonCopyable + class RepoIndexFileReader { public: /** @@ -49,17 +55,17 @@ namespace zypp * First parameter is a \ref RepoInfo object with the resource * FIXME return value is ignored */ - using ProcessResource = function; - - /** - * CTOR. Creates also \ref xml::Reader and starts reading. - * - * \param repoindexFile is the repoindex.xml file you want to read - * \param callback is a function. - * - * \see RepoindexFileReader::ProcessResource - */ - RepoindexFileReader(Pathname repoindexFile, + using ProcessResource = std::function; + /** + * CTOR. Creates also \ref xml::Reader and starts reading. + * + * \param repoindexFile is the repoindex.xml file you want to read + * \param callback is a function. + * + * \see RepoIndexFileReader::ProcessResource + */ + RepoIndexFileReader( ContextBaseRef ctx, + zypp::Pathname repoindexFile, ProcessResource callback); /** @@ -68,28 +74,41 @@ namespace zypp * \param is a valid input stream * \param callback Callback that will be called for each repository. * - * \see RepoindexFileReader::ProcessResource + * \see RepoIndexFileReader::ProcessResource */ - RepoindexFileReader( const InputStream &is, + RepoIndexFileReader( ContextBaseRef ctx, + const zypp::InputStream &is, ProcessResource callback ); /** * DTOR */ - ~RepoindexFileReader(); + ~RepoIndexFileReader(); + + RepoIndexFileReader(const RepoIndexFileReader &) = delete; + RepoIndexFileReader(RepoIndexFileReader &&) = delete; + RepoIndexFileReader &operator=(const RepoIndexFileReader &) = delete; + RepoIndexFileReader &operator=(RepoIndexFileReader &&) = delete; + /** Metadata TTL (repoindex.xml:xpath:/repoindex@ttl or 0). */ - Date::Duration ttl() const; + zypp::Date::Duration ttl() const; private: - class Impl; - RW_pointer > _pimpl; + void run( const zypp::InputStream &is ); + bool consumeNode( zypp::xml::Reader & reader_r ); + bool getAttrValue( const std::string & key_r, zypp::xml::Reader & reader_r, std::string & value_r ); + + private: + ContextBaseRef _zyppCtx; + /** Function for processing collected data. Passed-in through constructor. */ + ProcessResource _callback; + std::unique_ptr _replacer; + zypp::DefaultIntegral _ttl; }; } // ns parser } // ns zypp -#endif /*zypp_source_yum_RepoindexFileReader_H*/ - -// vim: set ts=2 sts=2 sw=2 et ai: +#endif /*ZYPP_NG_PARSER_REPOINDEXFILEREADER_H_INCLUDED*/ diff --git a/zypp/parser/ServiceFileReader.cc b/zypp/ng/parser/servicefilereader.cc similarity index 72% rename from zypp/parser/ServiceFileReader.cc rename to zypp/ng/parser/servicefilereader.cc index b71740cffd..c49f36df19 100644 --- a/zypp/parser/ServiceFileReader.cc +++ b/zypp/ng/parser/servicefilereader.cc @@ -9,6 +9,8 @@ /** \file zypp/parser/RepoFileReader.cc * */ + +#include "servicefilereader.h" #include #include #include @@ -17,14 +19,13 @@ #include #include -#include -#include +#include using std::endl; using zypp::parser::IniDict; /////////////////////////////////////////////////////////////////// -namespace zypp +namespace zyppng { ///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// namespace parser @@ -33,28 +34,28 @@ namespace zypp class ServiceFileReader::Impl { public: - static void parseServices( const Pathname & file, + static void parseServices( zyppng::ContextBaseRef ctx, const zypp::Pathname & file, const ServiceFileReader::ProcessService & callback ); }; - void ServiceFileReader::Impl::parseServices( const Pathname & file, + void ServiceFileReader::Impl::parseServices( zyppng::ContextBaseRef ctx, const zypp::Pathname & file, const ServiceFileReader::ProcessService & callback/*, const ProgressData::ReceiverFnc &progress*/ ) try { - InputStream is(file); + zypp::InputStream is(file); if( is.stream().fail() ) { - ZYPP_THROW(Exception("Failed to open service file")); + ZYPP_THROW(zypp::Exception("Failed to open service file")); } - parser::IniDict dict(is); - for ( parser::IniDict::section_const_iterator its = dict.sectionsBegin(); + zypp::parser::IniDict dict(is); + for ( zypp::parser::IniDict::section_const_iterator its = dict.sectionsBegin(); its != dict.sectionsEnd(); ++its ) { MIL << (*its) << endl; - ServiceInfo service(*its); + zyppng::ServiceInfo service(ctx, *its); std::map> repoStates; // > for ( IniDict::entry_const_iterator it = dict.entriesBegin(*its); @@ -65,21 +66,21 @@ namespace zypp if ( it->first == "name" ) service.setName( it->second ); else if ( it->first == "url" && ! it->second.empty() ) - service.setUrl( Url (it->second) ); + service.setUrl( zypp::Url (it->second) ); else if ( it->first == "enabled" ) - service.setEnabled( str::strToTrue( it->second ) ); + service.setEnabled( zypp::str::strToTrue( it->second ) ); else if ( it->first == "autorefresh" ) - service.setAutorefresh( str::strToTrue( it->second ) ); + service.setAutorefresh( zypp::str::strToTrue( it->second ) ); else if ( it->first == "type" ) - service.setType( repo::ServiceType(it->second) ); + service.setType( zypp::repo::ServiceType(it->second) ); else if ( it->first == "ttl_sec" ) - service.setTtl( str::strtonum(it->second) ); + service.setTtl( zypp::str::strtonum(it->second) ); else if ( it->first == "lrf_dat" ) - service.setLrf( Date( it->second ) ); + service.setLrf( zypp::Date( it->second ) ); else if ( it->first == "repostoenable" ) { std::vector aliases; - str::splitEscaped( it->second, std::back_inserter(aliases) ); + zypp::str::splitEscaped( it->second, std::back_inserter(aliases) ); for_( ait, aliases.begin(), aliases.end() ) { service.addRepoToEnable( *ait ); @@ -88,28 +89,28 @@ namespace zypp else if ( it->first == "repostodisable" ) { std::vector aliases; - str::splitEscaped( it->second, std::back_inserter(aliases) ); + zypp::str::splitEscaped( it->second, std::back_inserter(aliases) ); for_( ait, aliases.begin(), aliases.end() ) { service.addRepoToDisable( *ait ); } } - else if ( str::startsWith( it->first, "repo_" ) ) + else if ( zypp::str::startsWith( it->first, "repo_" ) ) { - static str::regex rxexpr( "([0-9]+)(_(.*))?" ); - str::smatch what; - if ( str::regex_match( it->first.c_str()+5/*repo_*/, what, rxexpr ) ) + static zypp::str::regex rxexpr( "([0-9]+)(_(.*))?" ); + zypp::str::smatch what; + if ( zypp::str::regex_match( it->first.c_str()+5/*repo_*/, what, rxexpr ) ) { std::string tag( what[1] ); if ( what.size() > 3 ) { // attribute if ( what[3] == "enabled" ) - repoStates[tag].second.enabled = str::strToBool( it->second, repoStates[tag].second.enabled ); + repoStates[tag].second.enabled = zypp::str::strToBool( it->second, repoStates[tag].second.enabled ); else if ( what[3] == "autorefresh" ) - repoStates[tag].second.autorefresh = str::strToBool( it->second, repoStates[tag].second.autorefresh ); + repoStates[tag].second.autorefresh = zypp::str::strToBool( it->second, repoStates[tag].second.autorefresh ); else if ( what[3] == "priority" ) - str::strtonum( it->second, repoStates[tag].second.priority ); + zypp::str::strtonum( it->second, repoStates[tag].second.priority ); else ERR << "Unknown attribute " << it->first << " ignored" << endl; } @@ -145,10 +146,10 @@ namespace zypp // add it to the list. if ( !callback(service) ) - ZYPP_THROW(AbortRequestException()); + ZYPP_THROW(zypp::AbortRequestException()); } } - catch ( Exception & ex ) { + catch ( zypp::Exception & ex ) { ex.addHistory( "Parsing .service file "+file.asString() ); ZYPP_RETHROW( ex ); } @@ -159,11 +160,13 @@ namespace zypp // /////////////////////////////////////////////////////////////////// - ServiceFileReader::ServiceFileReader( const Pathname & repo_file, + ServiceFileReader::ServiceFileReader( + zyppng::ContextBaseRef ctx, + const zypp::Pathname & repo_file, const ProcessService & callback/*, const ProgressData::ReceiverFnc &progress */) { - Impl::parseServices(repo_file, callback/*, progress*/); + Impl::parseServices(ctx, repo_file, callback/*, progress*/); //MIL << "Done" << endl; } diff --git a/zypp/parser/ServiceFileReader.h b/zypp/ng/parser/servicefilereader.h similarity index 90% rename from zypp/parser/ServiceFileReader.h rename to zypp/ng/parser/servicefilereader.h index 16d467a9d4..d76bce4647 100644 --- a/zypp/parser/ServiceFileReader.h +++ b/zypp/ng/parser/servicefilereader.h @@ -18,8 +18,10 @@ #include #include +#include + /////////////////////////////////////////////////////////////////// -namespace zypp +namespace zyppng { ///////////////////////////////////////////////////////////////// class ServiceInfo; @@ -52,7 +54,7 @@ namespace zypp * Return false from the callback to get a \ref AbortRequestException * to be thrown and the processing to be cancelled. */ - using ProcessService = function; + using ProcessService = std::function; /** Implementation */ class Impl; @@ -68,8 +70,9 @@ namespace zypp * \throws Exception If a error occurs at reading / parsing * */ - ServiceFileReader( const Pathname & serviceFile, - const ProcessService & callback); + ServiceFileReader( zyppng::ContextBaseRef ctx, + const zypp::Pathname & serviceFile, + const ProcessService & callback); /** * Dtor diff --git a/zypp/ng/repo/downloader.cc b/zypp/ng/repo/downloader.cc index 65fb9efa05..41ce3478a3 100644 --- a/zypp/ng/repo/downloader.cc +++ b/zypp/ng/repo/downloader.cc @@ -28,19 +28,19 @@ namespace zyppng::repo { using namespace zyppng::operators; template - DownloadContext::DownloadContext(ContextRefType zyppContext, const zypp::RepoInfo &info, const zypp::Pathname &destDir ) + DownloadContext::DownloadContext(ContextRefType zyppContext, const RepoInfo &info, const zypp::Pathname &destDir ) : CacheProviderContext( typename CacheProviderContext::private_constr_t{}, std::move(zyppContext), destDir ) , _repoinfo(info) {} template - const zypp::RepoInfo &DownloadContext::repoInfo() const { return _repoinfo; } + const RepoInfo &DownloadContext::repoInfo() const { return _repoinfo; } template const zypp::filesystem::Pathname &DownloadContext::deltaDir() const { return _deltaDir; } template - zypp::RepoInfo &DownloadContext::repoInfo() { return _repoinfo; } + RepoInfo &DownloadContext::repoInfo() { return _repoinfo; } template std::vector &DownloadContext::files() { return _files; } diff --git a/zypp/ng/repo/downloader.h b/zypp/ng/repo/downloader.h index b75f7ad4cd..5c5f9c0987 100644 --- a/zypp/ng/repo/downloader.h +++ b/zypp/ng/repo/downloader.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include @@ -37,12 +37,12 @@ namespace zyppng::repo { using ProvideType = typename ContextType::ProvideType; using MediaHandle = typename ProvideType::MediaHandle; - DownloadContext( ContextRefType zyppContext, const zypp::RepoInfo &info, const zypp::Pathname &destDir ); + DownloadContext( ContextRefType zyppContext, const RepoInfo &info, const zypp::Pathname &destDir ); - const zypp::RepoInfo &repoInfo () const; + const RepoInfo &repoInfo () const; const zypp::Pathname &deltaDir () const; - zypp::RepoInfo &repoInfo(); + RepoInfo &repoInfo(); std::vector &files(); const std::optional &pluginRepoverification() const; @@ -56,7 +56,7 @@ namespace zyppng::repo { void setDeltaDir(const zypp::Pathname &newDeltaDir); private: - zypp::RepoInfo _repoinfo; + RepoInfo _repoinfo; zypp::Pathname _deltaDir; std::vector _files; ///< Files downloaded std::optional _pluginRepoverification; ///< \see \ref plugin-repoverification diff --git a/zypp/repo/PluginServices.cc b/zypp/ng/repo/pluginservices.cc similarity index 68% rename from zypp/repo/PluginServices.cc rename to zypp/ng/repo/pluginservices.cc index 696c98d4fd..565b83b678 100644 --- a/zypp/repo/PluginServices.cc +++ b/zypp/ng/repo/pluginservices.cc @@ -6,6 +6,9 @@ | /_____||_| |_| |_| | | | \---------------------------------------------------------------------*/ + +#include "pluginservices.h" + #include #include #include @@ -14,16 +17,15 @@ #include #include -#include -#include -#include +#include +#include #include using std::endl; using std::stringstream; /////////////////////////////////////////////////////////////////// -namespace zypp +namespace zyppng { ///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// namespace repo @@ -32,33 +34,34 @@ namespace zypp class PluginServices::Impl { public: - static void loadServices( const Pathname &path, - const PluginServices::ProcessService &callback ); + static void loadServices(ContextBaseRef ctx, const zypp::Pathname &path, + const PluginServices::ProcessService &callback ); }; - void PluginServices::Impl::loadServices( const Pathname &path, + void PluginServices::Impl::loadServices( ContextBaseRef ctx, + const zypp::Pathname &path, const PluginServices::ProcessService & callback/*, const ProgressData::ReceiverFnc &progress*/ ) { - std::list entries; - if (PathInfo(path).isExist()) + std::list entries; + if (zypp::PathInfo(path).isExist()) { - if ( filesystem::readdir( entries, path, false ) != 0 ) + if ( zypp::filesystem::readdir( entries, path, false ) != 0 ) { // TranslatorExplanation '%s' is a pathname - ZYPP_THROW(Exception(str::form(_("Failed to read directory '%s'"), path.c_str()))); + ZYPP_THROW(zypp::Exception(zypp::str::form(_("Failed to read directory '%s'"), path.c_str()))); } //str::regex allowedServiceExt("^\\.service(_[0-9]+)?$"); for_(it, entries.begin(), entries.end() ) { - ServiceInfo service_info; + ServiceInfo service_info(ctx); service_info.setAlias((*it).basename()); - Url url; + zypp::Url url; url.setPathName((*it).asString()); url.setScheme("file"); service_info.setUrl(url); - service_info.setType(ServiceType::PLUGIN); + service_info.setType(zypp::repo::ServiceType::PLUGIN); service_info.setAutorefresh( true ); DBG << "Plugin Service: " << service_info << endl; callback(service_info); @@ -67,11 +70,11 @@ namespace zypp } } - PluginServices::PluginServices( const Pathname &path, - const ProcessService & callback/*, - const ProgressData::ReceiverFnc &progress */) + PluginServices::PluginServices(ContextBaseRef ctx, const zypp::Pathname &path, + const ProcessService & callback/*, + const ProgressData::ReceiverFnc &progress */) { - Impl::loadServices(path, callback/*, progress*/); + Impl::loadServices(ctx, path, callback/*, progress*/); } PluginServices::~PluginServices() diff --git a/zypp/repo/PluginServices.h b/zypp/ng/repo/pluginservices.h similarity index 91% rename from zypp/repo/PluginServices.h rename to zypp/ng/repo/pluginservices.h index 910ce897a6..8635300053 100644 --- a/zypp/repo/PluginServices.h +++ b/zypp/ng/repo/pluginservices.h @@ -13,11 +13,11 @@ #include #include -#include #include +#include /////////////////////////////////////////////////////////////////// -namespace zypp +namespace zyppng { ///////////////////////////////////////////////////////////////// class ServiceInfo; @@ -37,13 +37,14 @@ namespace zypp * Return false from the callback to get a \ref AbortRequestException * to be thrown and the processing to be cancelled. */ - using ProcessService = function; + using ProcessService = std::function; /** Implementation */ class Impl; public: - PluginServices(const Pathname &path, + PluginServices( ContextBaseRef ctx, + const zypp::Pathname &path, const ProcessService & callback); /** diff --git a/zypp/ng/repo/refresh.cc b/zypp/ng/repo/refresh.cc index 393e6d0ff2..eb97dcea56 100644 --- a/zypp/ng/repo/refresh.cc +++ b/zypp/ng/repo/refresh.cc @@ -16,7 +16,7 @@ namespace zyppng::repo { template - RefreshContext::RefreshContext( private_constr_t, Ref &&zyppContext, zypp::RepoInfo &&info, zypp::Pathname &&rawCachePath, zypp::filesystem::TmpDir &&tempDir, RepoManagerRef &&repoManager ) + RefreshContext::RefreshContext( private_constr_t, Ref &&zyppContext, RepoInfo &&info, zypp::Pathname &&rawCachePath, zypp::filesystem::TmpDir &&tempDir, RepoManagerRef &&repoManager ) : _zyppContext( std::move(zyppContext) ) , _repoManager( std::move(repoManager) ) , _repoInfo( std::move(info) ) @@ -25,7 +25,7 @@ namespace zyppng::repo { {} template - expected> RefreshContext::create( Ref zyppContext, zypp::RepoInfo info, RepoManagerRef repoManager ) + expected> RefreshContext::create( Ref zyppContext, RepoInfo info, RepoManagerRef repoManager ) { using namespace operators; using CtxType = RefreshContext; @@ -84,13 +84,13 @@ namespace zyppng::repo { } template - const zypp::RepoInfo &RefreshContext::repoInfo() const + const RepoInfo &RefreshContext::repoInfo() const { return _repoInfo; } template - zypp::RepoInfo &RefreshContext::repoInfo() + RepoInfo &RefreshContext::repoInfo() { return _repoInfo; } diff --git a/zypp/ng/repo/refresh.h b/zypp/ng/repo/refresh.h index 326fd868b8..632be87314 100644 --- a/zypp/ng/repo/refresh.h +++ b/zypp/ng/repo/refresh.h @@ -46,8 +46,8 @@ namespace zyppng::repo { using MediaHandle = typename ProvideType::MediaHandle; using PluginRepoverification = zypp_private::repo::PluginRepoverification; - static expected> create( Ref zyppContext, zypp::RepoInfo info, RepoManagerRef repoManager ); - ZYPP_DECL_PRIVATE_CONSTR_ARGS(RefreshContext, Ref &&zyppContext, zypp::RepoInfo &&info, zypp::Pathname &&rawCachePath, zypp::filesystem::TmpDir &&tempDir, RepoManagerRef &&repoManager ); + static expected> create( Ref zyppContext, RepoInfo info, RepoManagerRef repoManager ); + ZYPP_DECL_PRIVATE_CONSTR_ARGS(RefreshContext, Ref &&zyppContext, RepoInfo &&info, zypp::Pathname &&rawCachePath, zypp::filesystem::TmpDir &&tempDir, RepoManagerRef &&repoManager ); ~RefreshContext() override; @@ -81,8 +81,8 @@ namespace zyppng::repo { * the workflow is free to change data in this \ref zypp::RepoInfo , so calling * code should take care to use it once the workflow has finished. */ - const zypp::RepoInfo &repoInfo () const; - zypp::RepoInfo &repoInfo (); + const RepoInfo &repoInfo () const; + RepoInfo &repoInfo (); /*! * Reference to the \ref zyppng::RepoManager that initiated the refresh @@ -121,7 +121,7 @@ namespace zyppng::repo { private: Ref _zyppContext; RepoManagerRef _repoManager; - zypp::RepoInfo _repoInfo; + RepoInfo _repoInfo; zypp::Pathname _rawCachePath; zypp::filesystem::TmpDir _tmpDir; repo::RawMetadataRefreshPolicy _policy = RawMetadataRefreshPolicy::RefreshIfNeeded; diff --git a/zypp/ng/repo/repoinfobase.cc b/zypp/ng/repo/repoinfobase.cc new file mode 100644 index 0000000000..8753ccc83c --- /dev/null +++ b/zypp/ng/repo/repoinfobase.cc @@ -0,0 +1,180 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/repo/RepoInfoBase.cc + * + */ +#include +#include + +#include "repoinfobase.h" + +#include +#include + +#include +#include +#include + +#include + +using std::endl; + +namespace zyppng::repo { + + RepoInfoBaseSharedData::RepoInfoBaseSharedData( zyppng::ContextBaseRef &&context ) + : _ctx( std::move(context) ) + , _enabled( zypp::indeterminate ) + , _autorefresh( zypp::indeterminate ) + { + RepoInfoBaseSharedData::bindVariables(); + } + + RepoInfoBaseSharedData::RepoInfoBaseSharedData( zyppng::ContextBaseRef &&context, const std::string & alias_r ) + : _ctx( std::move(context) ) + , _enabled( zypp::indeterminate ) + , _autorefresh( zypp::indeterminate ) + { + RepoInfoBaseSharedData::bindVariables(); + setAlias( alias_r ); + } + + void RepoInfoBaseSharedData::bindVariables() + { + if ( _ctx ) { + _name.setTransformator( RepoVariablesStringReplacer( zypp::repo::RepoVarRetriever( *_ctx.get() ) ) ); + } else { + _name.setTransformator( RepoVariablesStringReplacer( nullptr ) ); + } + } + + + void RepoInfoBaseSharedData::setAlias( const std::string & alias_r ) + { + _alias = _escaped_alias = alias_r; + // replace slashes with underscores + zypp::str::replaceAll( _escaped_alias, "/", "_" ); + } + + void RepoInfoBaseSharedData::switchContext(ContextBaseRef ctx) + { + if ( ctx != _ctx ) { + _ctx = std::move(ctx); + bindVariables(); + } + } + + RepoInfoBaseSharedData * RepoInfoBaseSharedData::clone() const + { + auto *n = new RepoInfoBaseSharedData( *this ); + n->bindVariables (); + return n; + } + + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : RepoInfoBase + // + /////////////////////////////////////////////////////////////////// + + RepoInfoBase::RepoInfoBase( RepoInfoBaseSharedData &pimpl ) : _pimpl( &pimpl ) + {} + + zyppng::ContextBaseRef RepoInfoBase::context() const + { return _pimpl->_ctx; } + + RepoInfoBase::~RepoInfoBase() + {} + + void RepoInfoBase::setEnabled( bool enabled ) + { _pimpl->_enabled = enabled; } + + void RepoInfoBase::setAutorefresh( bool autorefresh ) + { _pimpl->_autorefresh = autorefresh; } + + void RepoInfoBase::setAlias( const std::string &alias ) + { _pimpl->setAlias(alias); } + + void RepoInfoBase::setName( const std::string &name ) + { _pimpl->_name.raw() = name; } + + void RepoInfoBase::setFilepath( const zypp::Pathname &filepath ) + { _pimpl->_filepath = filepath; } + + // true by default (if not set by setEnabled()) + bool RepoInfoBase::enabled() const + { return indeterminate(_pimpl->_enabled) ? true : (bool) _pimpl->_enabled; } + + // false by default (if not set by setAutorefresh()) + bool RepoInfoBase::autorefresh() const + { return indeterminate(_pimpl->_autorefresh) ? false : (bool) _pimpl->_autorefresh; } + + const std::string &RepoInfoBase::alias() const + { return _pimpl->_alias; } + + const std::string &RepoInfoBase::escaped_alias() const + { return _pimpl->_escaped_alias; } + + std::string RepoInfoBase::name() const + { + if ( rawName().empty() ) + return alias(); + return repo::RepoVariablesStringReplacer()( rawName() ); + } + + const std::string &RepoInfoBase::rawName() const + { return _pimpl->_name.raw(); } + + std::string RepoInfoBase::label() const + { + if ( _pimpl->_ctx && _pimpl->_ctx->config().repoLabelIsAlias() ) + return alias(); + return name(); + } + + const zypp::Pathname &RepoInfoBase::filepath() const + { return _pimpl->_filepath; } + + + std::ostream & RepoInfoBase::dumpOn( std::ostream & str ) const + { + str << "--------------------------------------" << std::endl; + str << "- alias : " << alias() << std::endl; + if ( ! rawName().empty() ) + str << "- name : " << rawName() << std::endl; + str << "- enabled : " << enabled() << std::endl; + str << "- autorefresh : " << autorefresh() << std::endl; + + return str; + } + + std::ostream & RepoInfoBase::dumpAsIniOn( std::ostream & str ) const + { + // we save the original data without variable replacement + str << "[" << alias() << "]" << endl; + if ( ! rawName().empty() ) + str << "name=" << rawName() << endl; + str << "enabled=" << (enabled() ? "1" : "0") << endl; + str << "autorefresh=" << (autorefresh() ? "1" : "0") << endl; + + return str; + } + + std::ostream & RepoInfoBase::dumpAsXmlOn( std::ostream & str, const std::string & content ) const + { + return str << "" << endl; + } + + std::ostream & operator<<( std::ostream & str, const RepoInfoBase & obj ) + { + return obj.dumpOn(str); + } + +} //namespace zyppng::repo diff --git a/zypp/ng/repo/repoinfobase.h b/zypp/ng/repo/repoinfobase.h new file mode 100644 index 0000000000..7a09e953e6 --- /dev/null +++ b/zypp/ng/repo/repoinfobase.h @@ -0,0 +1,192 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +#ifndef ZYPP_NG_REPO_REPOINFOBASE_H_INCLUDED +#define ZYPP_NG_REPO_REPOINFOBASE_H_INCLUDED + +#include + +#include +#include +#include +#include +#include + + +namespace zyppng::repo +{ + + /** + * \short Base class implementing common features of \ref RepoInfo and + * \ref ServiceInfo. + * + * \note Name is subject to repo variable replacement + * (\see \ref RepoVariablesStringReplacer). + */ + class RepoInfoBase + { + friend std::ostream & operator<<( std::ostream & str, const RepoInfoBase & obj ); + + public: + + virtual ~RepoInfoBase(); + + protected: + RepoInfoBase(const RepoInfoBase &) = default; + RepoInfoBase(RepoInfoBase &&) noexcept = default; + RepoInfoBase &operator=(const RepoInfoBase &) = default; + RepoInfoBase &operator=(RepoInfoBase &&) noexcept = default; + + public: + + /** + * Returns the associated context of the RepoInfo + */ + zyppng::ContextBaseRef context() const; + + /** + * unique identifier for this source. If not specified + * It should be generated from the base url. + * + * Normally, in a .repo file the section name is used + * ( [somerepo] ) + */ + const std::string &alias() const; + + /** + * Same as alias(), just escaped in a way to be a valid file name. + */ + const std::string &escaped_alias() const; + + /** + * \short Repository name + * + * Short label or description of the repository. Defaults to \ref alias. + * Subject to repo variable replacement (\see \ref RepoVariablesStringReplacer). + * ie: "SUSE Linux 10.2 updates" + */ + std::string name() const; + + /** The raw metadata name (no default, no variables replaced). */ + const std::string &rawName() const; + + /** + * \short Label for use in messages for the user interface. + * + * Returns an alias or name, according to ZConfig::repoLabelIsAlias(). + */ + std::string label() const; + + /** User string: \ref label (alias or name) */ + std::string asUserString() const + { return label(); } + + /** + * If enabled is false, then this repository must be ignored as if does + * not exists, except when checking for duplicate alias. + */ + bool enabled() const; + + /** + * If true, the repostory must be refreshed before creating resolvables + * from it + */ + bool autorefresh() const; + + /** + * \short File where this repo was read from + * + * \note could be an empty pathname for repo + * infos created in memory. + */ + const zypp::Pathname &filepath() const; + + + public: + + /** + * set the repository alias \see alias + * \param alias + */ + void setAlias( const std::string &alias ); + + /** + * set the repository name \see name + * \param name + */ + void setName( const std::string &name ); + + /** + * enable or disable the repository \see enabled + * \param enabled + */ + void setEnabled( bool enabled ); + + /** + * enable or disable autorefresh \see autorefresh + * \param enabled + */ + void setAutorefresh( bool autorefresh ); + + /** + * \short set the path to the .repo file + * + * The path to the .repo file where this repository + * was defined, or empty if nowhere. + * + * \param path File path + */ + void setFilepath( const zypp::Pathname &filename ); + + /** + * Write a human-readable representation of this RepoInfoBase object + * into the \a str stream. Useful for logging. + */ + virtual std::ostream & dumpOn( std::ostream & str ) const; + + /** + * Write this RepoInfoBase object into \a str in a .repo (ini) file format. + * Raw values, no variable replacement. + */ + virtual std::ostream & dumpAsIniOn( std::ostream & str ) const; + + /** + * Write an XML representation of this object with content (if available). + * Repo variables replaced. + */ + virtual std::ostream & dumpAsXmlOn( std::ostream & str, const std::string & content = "" ) const; + + protected: + RepoInfoBase( RepoInfoBaseSharedData &pimpl ); + + // support rw_cow copying for derived types + RepoInfoBase( const zypp::RWCOW_pointer &other ); + + /** Pointer to implementation */ + zypp::RWCOW_pointer _pimpl; + }; + /////////////////////////////////////////////////////////////////// + + /** \relates RepoInfoBase */ + inline bool operator==( const RepoInfoBase & lhs, const RepoInfoBase & rhs ) + { return ( lhs.context() == rhs.context() && lhs.alias() == rhs.alias()); } + + /** \relates RepoInfoBase */ + inline bool operator!=( const RepoInfoBase & lhs, const RepoInfoBase & rhs ) + { return (lhs.context() != rhs.context() || lhs.alias() != rhs.alias()); } + + inline bool operator<( const RepoInfoBase & lhs, const RepoInfoBase & rhs ) + { return lhs.alias() < rhs.alias(); } + + /** \relates RepoInfoBase Stream output */ + std::ostream & operator<<( std::ostream & str, const RepoInfoBase & obj ); + + + } // namespace zyppng::repo + +#endif /*ZYPP_NG_REPO_REPOINFOBASE_H_INCLUDED*/ diff --git a/zypp/ng/repo/repoinfobaseshareddata.cc b/zypp/ng/repo/repoinfobaseshareddata.cc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/zypp/ng/repo/repoinfobaseshareddata.h b/zypp/ng/repo/repoinfobaseshareddata.h new file mode 100644 index 0000000000..d19e86bd79 --- /dev/null +++ b/zypp/ng/repo/repoinfobaseshareddata.h @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/repo/detail/RepoInfoBaseImpl.h + * +*/ + +#ifndef ZYPP_NG_REPOINFOBASESHAREDDATA_INCLUDED +#define ZYPP_NG_REPOINFOBASESHAREDDATA_INCLUDED + +#include +#include +#include +#include + +namespace zyppng::repo +{ + + /*! + * \brief Contains shared data for Service and RepoInfo types + */ + struct RepoInfoBaseSharedData + { + RepoInfoBaseSharedData(const RepoInfoBaseSharedData &) = default; + RepoInfoBaseSharedData(RepoInfoBaseSharedData &&) = delete; + RepoInfoBaseSharedData &operator=(const RepoInfoBaseSharedData &) = default; + RepoInfoBaseSharedData &operator=(RepoInfoBaseSharedData &&) = delete; + + RepoInfoBaseSharedData( zyppng::ContextBaseRef &&context ); + RepoInfoBaseSharedData( zyppng::ContextBaseRef &&context, const std::string & alias_r ); + + virtual ~RepoInfoBaseSharedData() = default; + + public: + zyppng::ContextBaseRef _ctx; + zypp::TriBool _enabled; + zypp::TriBool _autorefresh; + std::string _alias; + std::string _escaped_alias; + RepoVariablesReplacedString _name; + zypp::Pathname _filepath; + + public: + void setAlias( const std::string & alias_r ); + void switchContext( ContextBaseRef ctx ); + + protected: + virtual void bindVariables(); + + private: + friend RepoInfoBaseSharedData * zypp::rwcowClone( const RepoInfoBaseSharedData * rhs ); + + /** clone for RWCOW_pointer */ + virtual RepoInfoBaseSharedData *clone() const; + }; +} + +#endif //ZYPP_NG_REPOINFOBASESHAREDDATA_INCLUDED diff --git a/zypp-glib/private/repomanageroptions_p.h b/zypp/ng/repo/repovariables.cc similarity index 59% rename from zypp-glib/private/repomanageroptions_p.h rename to zypp/ng/repo/repovariables.cc index b35ff057a6..3ee8e16df3 100644 --- a/zypp-glib/private/repomanageroptions_p.h +++ b/zypp/ng/repo/repovariables.cc @@ -6,16 +6,11 @@ | /_____||_| |_| |_| | | | \---------------------------------------------------------------------*/ -#ifndef ZYPP_GLIB_PRIVATE_REPO_MANAGER_OPTIONS_P_H -#define ZYPP_GLIB_PRIVATE_REPO_MANAGER_OPTIONS_P_H +#include "repovariables.h" -#include -#include +#include -struct _ZyppRepoManagerOptions { - zypp::RepoManagerOptions _opts; -}; - -ZyppRepoManagerOptions *zypp_repo_manager_options_new( const zypp::RepoManagerOptions &rO ); - -#endif // ZYPP_GLIB_PRIVATE_REPO_MANAGER_OPTIONS_P_H +namespace zyppng { + namespace repo { + } +} diff --git a/zypp/ng/repo/repovariables.h b/zypp/ng/repo/repovariables.h new file mode 100644 index 0000000000..6ef74f1d35 --- /dev/null +++ b/zypp/ng/repo/repovariables.h @@ -0,0 +1,53 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +#ifndef ZYPP_NG_REPO_REPOVARIABLES_H_INCLUDED +#define ZYPP_NG_REPO_REPOVARIABLES_H_INCLUDED + +#include +#include +#include +#include + +namespace zyppng { + + namespace repo { + + /* + * Since we need the RepoVar replacer as part of the public zypp API + * ( because of RepoInfo returning it as part of a iterator type ) they are + * defined in zypp::repo and only pulled into the zyppng namespace via using declarations. + * Once we can drop legacy APIs, or find a better way, this can be changed. + */ + using RepoVarRetrieverFunctor = zypp::repo::RepoVarRetrieverFunctor; + + template + using RepoVarRetriever = zypp::repo::RepoVarRetriever; + + using RepoVariablesStringReplacer = zypp::repo::RepoVariablesStringReplacerNg; + using RepoVariablesUrlReplacer = zypp::repo::RepoVariablesUrlReplacerNg; + +} // namespace repo + +/** \relates RepoVariablesStringReplacer Helper managing repo variables replaced strings */ +using RepoVariablesReplacedString = zypp::base::ValueTransform; + +/** \relates RepoVariablesStringReplacer Helper managing repo variables replaced string lists */ +using RepoVariablesReplacedStringList = zypp::base::ContainerTransform, repo::RepoVariablesStringReplacer>; + +/** \relates RepoVariablesUrlReplacer Helper managing repo variables replaced urls */ +using RepoVariablesReplacedUrl = zypp::base::ValueTransform; + +/** \relates RepoVariablesUrlReplacer Helper managing repo variables replaced url lists */ +using RepoVariablesReplacedUrlList = zypp::base::ContainerTransform, repo::RepoVariablesUrlReplacer>; + + + +} + +#endif //ZYPP_NG_REPO_REPOVARIABLES_H_INCLUDED diff --git a/zypp/ng/repo/repovariablescache.cc b/zypp/ng/repo/repovariablescache.cc new file mode 100644 index 0000000000..707d8aa5d1 --- /dev/null +++ b/zypp/ng/repo/repovariablescache.cc @@ -0,0 +1,157 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ + +#include "repovariablescache.h" + +#include + +#include +#include + +namespace zyppng::repo { + + namespace env + { + /** Use faked releasever (e.g. for 'zupper dup' to next distro version */ + inline std::string ZYPP_REPO_RELEASEVER() + { + const char * env = getenv("ZYPP_REPO_RELEASEVER"); + return( env ? env : "" ); + } + } + + RepoVarsMap::RepoVarsMap(ContextBase &myContext) : _myCtx(myContext) + { } + + const std::string *RepoVarsMap::lookup(const std::string &name_r) { + if (empty()) // at init / after reset + { + // load user definitions from vars.d + + // @TODO-NG check if _myCtx.contextRoot() is correct, before this used the config() repomanager root + zypp::filesystem::dirForEach( _myCtx.contextRoot() / + _myCtx.config().varsPath(), + zypp::filesystem::matchNoDots(), + std::bind(&RepoVarsMap::parse, this, std::placeholders::_1, std::placeholders::_2)); + // releasever_major/_minor are per default derived from releasever. + // If releasever is userdefined, inject missing _major/_minor too. + deriveFromReleasever("releasever", + /*dont't overwrite user defined values*/ false); + + dumpOn(DBG); + // add builtin vars except for releasever{,_major,_minor} (see + // checkOverride) + { + const zypp::Arch &arch( _myCtx.config().systemArchitecture() ); + { + std::string &var(operator[]("arch")); + if (var.empty()) + var = arch.asString(); + } + { + std::string &var(operator[]("basearch")); + if (var.empty()) + var = arch.baseArch().asString(); + } + } + } + + const std::string *ret = checkOverride(name_r); + if (!ret) { + // get value from map + iterator it = find(name_r); + if (it != end()) + ret = &(it->second); + } + + return ret; + } + std::ostream &RepoVarsMap::dumpOn(std::ostream &str) const { + for (auto &&kv : *this) { + str << '{' << kv.first << '=' << kv.second << '}' << std::endl; + } + return str; + } + bool RepoVarsMap::parse(const zypp::Pathname &dir_r, const std::string &str_r) { + std::ifstream file((dir_r / str_r).c_str()); + operator[](str_r) = zypp::str::getline(file, /*trim*/ false); + return true; + } + void RepoVarsMap::deriveFromReleasever(const std::string &stem_r, + bool overwrite_r) { + if (count(stem_r)) // releasever is defined.. + { + const std::string &stem_major(stem_r + "_major"); + const std::string &stem_minor(stem_r + "_minor"); + if (overwrite_r) + splitReleaseverTo(operator[](stem_r), &operator[](stem_major), + &operator[](stem_minor)); + else + splitReleaseverTo(operator[](stem_r), + count(stem_major) ? nullptr : &operator[](stem_major), + count(stem_minor) ? nullptr + : &operator[](stem_minor)); + } + } + void RepoVarsMap::splitReleaseverTo(const std::string &releasever_r, + std::string *major_r, + std::string *minor_r) const { + if (major_r || minor_r) { + std::string::size_type pos = releasever_r.find('.'); + if (pos == std::string::npos) { + if (major_r) + *major_r = releasever_r; + if (minor_r) + minor_r->clear(); + } else { + if (major_r) + *major_r = releasever_r.substr(0, pos); + if (minor_r) + *minor_r = releasever_r.substr(pos + 1); + } + } + } + const std::string *RepoVarsMap::checkOverride(const std::string &name_r) { + /////////////////////////////////////////////////////////////////// + // Always check for changing releasever{,_major,_minor} (bnc#943563) + if (zypp::str::startsWith(name_r, "releasever") && + (name_r.size() == 10 || strcmp(name_r.c_str() + 10, "_minor") == 0 || + strcmp(name_r.c_str() + 10, "_major") == 0)) { + std::string val(env::ZYPP_REPO_RELEASEVER()); + if (!val.empty()) { + // $ZYPP_REPO_RELEASEVER always overwrites any defined value + if (val != operator[]("$releasever")) { + operator[]("$releasever") = std::move(val); + deriveFromReleasever("$releasever", + /*overwrite previous values*/ true); + } + return &operator[]("$" + name_r); + } else if (!count(name_r)) { + // No user defined value, so we follow the target + zypp::Target_Ptr trg(_myCtx.target()); + if (trg) + val = trg->distributionVersion(); + else + val = zypp::Target::distributionVersion( _myCtx.contextRoot() ); + + if (val != operator[]("$_releasever")) { + operator[]("$_releasever") = std::move(val); + deriveFromReleasever("$_releasever", + /*overwrite previous values*/ true); + } + return &operator[]("$_" + name_r); + } + // else: + return nullptr; // get user value from map + } + /////////////////////////////////////////////////////////////////// + + return nullptr; // get user value from map + } +} // namespace zyppng::repo diff --git a/zypp/ng/repo/repovariablescache.h b/zypp/ng/repo/repovariablescache.h new file mode 100644 index 0000000000..fd4b6e41fa --- /dev/null +++ b/zypp/ng/repo/repovariablescache.h @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +#ifndef ZYPP_NG_REPO_REPOVARIABLES_CACHE_H_INCLUDED +#define ZYPP_NG_REPO_REPOVARIABLES_CACHE_H_INCLUDED + +#include +#include +#include +#include + +namespace zyppng { + class ContextBase; +} + +namespace zyppng::repo { + + class RepoVarsMap : public std::map + { + public: + + ~RepoVarsMap() = default; + RepoVarsMap(const RepoVarsMap &) = delete; + RepoVarsMap(RepoVarsMap &&) = delete; + RepoVarsMap &operator=(const RepoVarsMap &) = delete; + RepoVarsMap &operator=(RepoVarsMap &&) = delete; + + const std::string *lookup(const std::string &name_r); + + std::ostream &dumpOn(std::ostream &str) const; + + private: + friend class zyppng::ContextBase; // only context may create a cache + + RepoVarsMap(ContextBase &myContext); + /** Get first line from file */ + bool parse( const zypp::Pathname &dir_r, const std::string &str_r ); + + /** Derive \c releasever_major/_minor from \c releasever, keeping or overwrititing existing values. */ + void deriveFromReleasever(const std::string &stem_r, bool overwrite_r); + + /** Split \c releasever at \c '.' and store major/minor parts as requested. */ + void splitReleaseverTo(const std::string &releasever_r, + std::string *major_r, std::string *minor_r) const; + + /** Check for conditions overwriting the (user) defined values. */ + const std::string *checkOverride(const std::string &name_r); + + ContextBase &_myCtx; // the context this Cache is owned by + }; + + +} + + + +#endif // ZYPP_NG_REPO_REPOVARIABLES_CACHE_H_INCLUDED + diff --git a/zypp/ng/repo/workflows/repodownloaderwf.cc b/zypp/ng/repo/workflows/repodownloaderwf.cc index cea2e8a7b2..cb366ff154 100644 --- a/zypp/ng/repo/workflows/repodownloaderwf.cc +++ b/zypp/ng/repo/workflows/repodownloaderwf.cc @@ -237,7 +237,7 @@ namespace zyppng { auto key = zypp::PublicKey::noThrow( _dlContext->files().back() ); if ( not key.fileProvidesKey( keyid ) ) { - const auto &str = zypp::str::Str() << "Keyhint " << file << " does not contain a key with id " << keyid << ". Skipping it."; + const std::string str = zypp::str::Str() << "Keyhint " << file << " does not contain a key with id " << keyid << ". Skipping it."; WAR << str << std::endl; return makeReadyResult(expected::error( std::make_exception_ptr( zypp::Exception(str)) )); } diff --git a/zypp/ng/repo/workflows/repomanagerwf.cc b/zypp/ng/repo/workflows/repomanagerwf.cc index c57a0d35fb..5340d634b7 100644 --- a/zypp/ng/repo/workflows/repomanagerwf.cc +++ b/zypp/ng/repo/workflows/repomanagerwf.cc @@ -215,9 +215,9 @@ namespace zyppng::RepoManagerWorkflow { { using namespace zyppng::operators; return ctx->provider()->provide( repoFileUrl, ProvideFileSpec() ) - | and_then([repoFileUrl]( auto local ){ + | and_then([ctx, repoFileUrl]( auto local ){ DBG << "reading repo file " << repoFileUrl << ", local path: " << local.file() << std::endl; - return repositories_in_file( local.file() ); + return repositories_in_file( ctx, local.file() ); }); } } @@ -552,7 +552,7 @@ namespace zyppng::RepoManagerWorkflow { { Repo2SolvOp() { } - static AsyncOpRef> run( zypp::RepoInfo repo, zypp::ExternalProgram::Arguments args ) { + static AsyncOpRef> run( RepoInfo repo, zypp::ExternalProgram::Arguments args ) { MIL << "Starting repo2solv for repo " << repo.alias () << std::endl; auto me = std::make_shared>(); me->_repo = std::move(repo); @@ -594,14 +594,14 @@ namespace zyppng::RepoManagerWorkflow { private: ProcessRef _proc; - zypp::RepoInfo _repo; + RepoInfo _repo {nullptr}; std::string _errdetail; }; template <> struct Repo2SolvOp { - static expected run( zypp::RepoInfo repo, zypp::ExternalProgram::Arguments args ) { + static expected run( RepoInfo repo, zypp::ExternalProgram::Arguments args ) { zypp::ExternalProgram prog( args, zypp::ExternalProgram::Stderr_To_Stdout ); std::string errdetail; @@ -822,7 +822,7 @@ namespace zyppng::RepoManagerWorkflow { } private: - MaybeAsyncRef>> mountIfRequired ( zypp::repo::RepoType repokind, zypp::RepoInfo info ) { + MaybeAsyncRef>> mountIfRequired ( zypp::repo::RepoType repokind, RepoInfo info ) { if ( repokind != zypp::repo::RepoType::RPMPLAINDIR ) return makeReadyResult( make_expected_success( std::optional() )); @@ -879,7 +879,7 @@ namespace zyppng::RepoManagerWorkflow { ProgressObserver::setup( _myProgress, zypp::str::form(_("Adding repository '%s'"), _info.label().c_str()) ); ProgressObserver::start( _myProgress ); - if ( _repoMgrRef->repos().find(_info) != _repoMgrRef->repos().end() ) + if ( _repoMgrRef->repos().find(_info.alias()) != _repoMgrRef->repos().end() ) return makeReadyResult( expected::error( ZYPP_EXCPT_PTR(zypp::repo::RepoAlreadyExistsException(_info)) ) ); // check the first url for now @@ -948,7 +948,7 @@ namespace zyppng::RepoManagerWorkflow { MaybeAsyncRef> execute() { using namespace zyppng::operators; - return mtry( zypp::repo::RepoVariablesUrlReplacer(), _url ) + return mtry( zypp::repo::RepoVariablesUrlReplacerNg( zypp::repo::RepoVarRetriever( *_repoMgrRef->zyppContext() ) ), _url ) | and_then([this]( zypp::Url repoFileUrl ) { return readRepoFile( _repoMgrRef->zyppContext(), std::move(repoFileUrl) ); } ) | and_then([this]( std::list repos ) { @@ -959,9 +959,9 @@ namespace zyppng::RepoManagerWorkflow { // look if the alias is in the known repos. for_ ( kit, _repoMgrRef->repoBegin(), _repoMgrRef->repoEnd() ) { - if ( (*it).alias() == (*kit).alias() ) + if ( (*it).alias() == kit->first ) { - ERR << "To be added repo " << (*it).alias() << " conflicts with existing repo " << (*kit).alias() << std::endl; + ERR << "To be added repo " << (*it).alias() << " conflicts with existing repo " << kit->first << std::endl; return expected::error(ZYPP_EXCPT_PTR(zypp::repo::RepoAlreadyExistsException(*it))); } } @@ -1006,7 +1006,7 @@ namespace zyppng::RepoManagerWorkflow { it->setFilepath(repofile); it->setMetadataPath( *rawCachePath ); it->setPackagesPath( *pckCachePath ); - _repoMgrRef->reposManip().insert(*it); + _repoMgrRef->reposManip().insert( std::make_pair(it->alias(), *it)); zypp::HistoryLog( _repoMgrRef->options().rootDir).addRepository(*it); } diff --git a/zypp/ng/repo/workflows/rpmmd.cc b/zypp/ng/repo/workflows/rpmmd.cc index a1f65e6b4b..5316a288bc 100644 --- a/zypp/ng/repo/workflows/rpmmd.cc +++ b/zypp/ng/repo/workflows/rpmmd.cc @@ -100,7 +100,7 @@ namespace zyppng::RpmmdWorkflows { using ProvideRes = typename ProvideType::Res; DlLogic( DlContextRefType ctx, MediaHandle &&mediaHandle, ProgressObserverRef &&progressObserver ) - : zypp::repo::yum::RepomdFileCollector( ctx->destDir() ) + : zypp::repo::yum::RepomdFileCollector( ctx->zyppContext(), ctx->destDir() ) , _ctx( std::move(ctx)) , _mediaHandle(std::move(mediaHandle)) , _progressObserver(std::move(progressObserver)) @@ -155,7 +155,7 @@ namespace zyppng::RpmmdWorkflows { private: - const zypp::RepoInfo &repoInfo() const override { + const zyppng::RepoInfo &repoInfo() const override { return _ctx->repoInfo(); } diff --git a/zypp/ng/repo/workflows/serviceswf.cc b/zypp/ng/repo/workflows/serviceswf.cc index 139f5fcad3..6ea56d7e96 100644 --- a/zypp/ng/repo/workflows/serviceswf.cc +++ b/zypp/ng/repo/workflows/serviceswf.cc @@ -16,8 +16,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -66,7 +66,7 @@ namespace zyppng::RepoServicesWorkflow { {} - MaybeAsyncRef >> execute() { + MaybeAsyncRef >> execute() { using namespace zyppng::operators; @@ -81,10 +81,10 @@ namespace zyppng::RepoServicesWorkflow { | and_then( [this]( auto provideResult ) { try { - zypp::RepoInfoList repos; - auto callback = [&]( const zypp::RepoInfo &r) { repos.push_back(r); return true; }; + RepoInfoList repos; + auto callback = [&]( const RepoInfo &r) { repos.push_back(r); return true; }; - zypp::parser::RepoindexFileReader reader( provideResult.file(), callback); + parser::RepoIndexFileReader reader( _ctx, provideResult.file(), callback); _service.setProbedTtl( reader.ttl() ); // hack! Modifying the const Service to set parsed TTL return make_expected_success( std::make_pair( _service, std::move(repos) ) ); @@ -95,7 +95,7 @@ namespace zyppng::RepoServicesWorkflow { ZYPP_CAUGHT ( e ); zypp::repo::ServicePluginInformalException ex ( e.msg() ); ex.remember( e ); - return expected>::error( ZYPP_EXCPT_PTR( ex ) ); + return expected>::error( ZYPP_EXCPT_PTR( ex ) ); } }); } @@ -118,7 +118,7 @@ namespace zyppng::RepoServicesWorkflow { using ZyppContextType = std::conditional_t, AsyncContext, SyncContext >; using ZyppContextRefType = Ref; using RepoMgrRefType = RepoManagerRef; - using Ret = expected>; + using Ret = expected>; FetchPluginServiceLogic( ZyppContextRefType &&ctx, zypp::Pathname &&root_r, ServiceInfo &&service, ProgressObserverRef &&myProgress ) : _ctx( std::move(ctx) ) @@ -147,11 +147,11 @@ namespace zyppng::RepoServicesWorkflow { } try { - zypp::RepoInfoList repos; - auto callback = [&]( const zypp::RepoInfo &r) { repos.push_back(r); return true; }; + RepoInfoList repos; + auto callback = [&]( const RepoInfo &r) { repos.push_back(r); return true; }; std::stringstream buffer( _stdoutBuf ); - zypp::parser::RepoFileReader parser( buffer, callback ); + parser::RepoFileReader parser( _ctx, buffer, callback ); return make_expected_success( std::make_pair( _service, std::move(repos) ) ); } catch (...) { @@ -170,7 +170,7 @@ namespace zyppng::RepoServicesWorkflow { }; - struct SyncFetchPluginService : FetchPluginServiceLogic >>> + struct SyncFetchPluginService : FetchPluginServiceLogic >>> { using FetchPluginServiceLogic::FetchPluginServiceLogic; expected runPlugin( std::string command ) { @@ -200,7 +200,7 @@ namespace zyppng::RepoServicesWorkflow { } }; - struct ASyncFetchPluginService : FetchPluginServiceLogic >>> + struct ASyncFetchPluginService : FetchPluginServiceLogic >>> { using FetchPluginServiceLogic::FetchPluginServiceLogic; AsyncOpRef> runPlugin( std::string command ) { @@ -244,20 +244,20 @@ namespace zyppng::RepoServicesWorkflow { } - AsyncOpRef>> fetchRepoListfromService( AsyncContextRef ctx, zypp::Pathname root_r, ServiceInfo service, ProgressObserverRef myProgress ) + AsyncOpRef>> fetchRepoListfromService( AsyncContextRef ctx, zypp::Pathname root_r, ServiceInfo service, ProgressObserverRef myProgress ) { if ( service.type() == zypp::repo::ServiceType::PLUGIN ) return ASyncFetchPluginService::run( std::move(ctx), std::move(root_r), std::move(service), std::move(myProgress) ); else - return SimpleExecutor >>>::run( std::move(ctx), std::move(root_r), std::move(service), std::move(myProgress) ); + return SimpleExecutor >>>::run( std::move(ctx), std::move(root_r), std::move(service), std::move(myProgress) ); } - expected> fetchRepoListfromService( SyncContextRef ctx, zypp::Pathname root_r, ServiceInfo service, ProgressObserverRef myProgress ) + expected> fetchRepoListfromService( SyncContextRef ctx, zypp::Pathname root_r, ServiceInfo service, ProgressObserverRef myProgress ) { if ( service.type() == zypp::repo::ServiceType::PLUGIN ) return SyncFetchPluginService::run( std::move(ctx), std::move(root_r), std::move(service), std::move(myProgress) ); else - return SimpleExecutor >>>::run( std::move(ctx), std::move(root_r), std::move(service), std::move(myProgress) ); + return SimpleExecutor >>>::run( std::move(ctx), std::move(root_r), std::move(service), std::move(myProgress) ); } @@ -329,7 +329,7 @@ namespace zyppng::RepoServicesWorkflow { using RepoMgrRefType = RepoManagerRef; using Ret = expected; - RefreshServiceLogic( RepoMgrRefType &&repoMgr, zypp::ServiceInfo &&info, zypp::RepoManagerFlags::RefreshServiceOptions options ) + RefreshServiceLogic( RepoMgrRefType &&repoMgr, ServiceInfo &&info, zypp::RepoManagerFlags::RefreshServiceOptions options ) : _repoMgr( std::move(repoMgr) ) , _service( std::move(info) ) , _options(options) @@ -393,7 +393,7 @@ namespace zyppng::RepoServicesWorkflow { // to ServiceRepos. return fetchRepoListfromService( _repoMgr->zyppContext(), _repoMgr->options().rootDir, _service, nullptr ); } ) - | [this]( expected> serviceReposExp ) { + | [this]( expected> serviceReposExp ) { if ( !serviceReposExp ) { try { @@ -408,7 +408,7 @@ namespace zyppng::RepoServicesWorkflow { } } - std::pair serviceRepos = serviceReposExp.is_valid() ? std::move( serviceReposExp.get() ) : std::make_pair( _service, RepoInfoList{} ); + std::pair serviceRepos = serviceReposExp.is_valid() ? std::move( serviceReposExp.get() ) : std::make_pair( _service, RepoInfoList{} ); // get target distro identifier std::string servicesTargetDistro = _repoMgr->options().servicesTargetDistro; @@ -515,7 +515,7 @@ namespace zyppng::RepoServicesWorkflow { //////////////////////////////////////////////////////////////////////////// // create missing repositories and modify existing ones if needed... - zypp::UrlCredentialExtractor urlCredentialExtractor( _repoMgr->options().rootDir ); // To collect any credentials stored in repo URLs + zypp::UrlCredentialExtractor urlCredentialExtractor( _repoMgr->zyppContext() ); // To collect any credentials stored in repo URLs for_( it, collector.repos.begin(), collector.repos.end() ) { // User explicitly requested the repo being enabled? @@ -724,7 +724,7 @@ namespace zyppng::RepoServicesWorkflow { RepoMgrRefType _repoMgr; - zypp::ServiceInfo _service; + ServiceInfo _service; zypp::RepoManagerFlags::RefreshServiceOptions _options; // NOTE: It might be necessary to modify and rewrite the service info. diff --git a/zypp/ng/repo/workflows/serviceswf.h b/zypp/ng/repo/workflows/serviceswf.h index 090d14b5f2..5bb7dfe39f 100644 --- a/zypp/ng/repo/workflows/serviceswf.h +++ b/zypp/ng/repo/workflows/serviceswf.h @@ -26,14 +26,14 @@ namespace zyppng { ZYPP_FWD_DECL_TYPE_WITH_REFS (ProgressObserver); namespace RepoServicesWorkflow { - AsyncOpRef>> fetchRepoListfromService( AsyncContextRef ctx, zypp::Pathname root_r, ServiceInfo service, ProgressObserverRef myProgress = nullptr ); - expected> fetchRepoListfromService( SyncContextRef ctx, zypp::Pathname root_r, ServiceInfo service, ProgressObserverRef myProgress = nullptr ); + AsyncOpRef>> fetchRepoListfromService( AsyncContextRef ctx, zypp::Pathname root_r, ServiceInfo service, ProgressObserverRef myProgress = nullptr ); + expected> fetchRepoListfromService( SyncContextRef ctx, zypp::Pathname root_r, ServiceInfo service, ProgressObserverRef myProgress = nullptr ); AsyncOpRef > probeServiceType( AsyncContextRef ctx, const zypp::Url &url ); expected probeServiceType ( SyncContextRef ctx, const zypp::Url &url ); - AsyncOpRef> refreshService ( AsyncRepoManagerRef repoMgr, zypp::ServiceInfo info, zypp::RepoManagerFlags::RefreshServiceOptions options ); - expected refreshService ( SyncRepoManagerRef repoMgr, zypp::ServiceInfo info, zypp::RepoManagerFlags::RefreshServiceOptions options ); + AsyncOpRef> refreshService ( AsyncRepoManagerRef repoMgr, ServiceInfo info, zypp::RepoManagerFlags::RefreshServiceOptions options ); + expected refreshService ( SyncRepoManagerRef repoMgr, ServiceInfo info, zypp::RepoManagerFlags::RefreshServiceOptions options ); } } // namespace zyppng; diff --git a/zypp/ng/repo/workflows/susetags.cc b/zypp/ng/repo/workflows/susetags.cc index ff88c92cdc..61aaaa1d1f 100644 --- a/zypp/ng/repo/workflows/susetags.cc +++ b/zypp/ng/repo/workflows/susetags.cc @@ -308,7 +308,7 @@ namespace zyppng::SuseTagsWorkflows { private: - const zypp::RepoInfo &repoInfo() const { + const RepoInfo &repoInfo() const { return _ctx->repoInfo(); } diff --git a/zypp/ng/repoinfo.cc b/zypp/ng/repoinfo.cc new file mode 100644 index 0000000000..279e1c4e77 --- /dev/null +++ b/zypp/ng/repoinfo.cc @@ -0,0 +1,989 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/ng/repoinfo.cc + * +*/ + +#include "repoinfo.h" + +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "repoinfoshareddata.h" +#include "zypp/repo/SUSEMediaVerifier.h" + +using std::endl; +using zypp::xml::escape; + +namespace zyppng { + + namespace + { + zypp::repo::RepoType probeCache( const zypp::Pathname & path_r ) + { + zypp::repo::RepoType ret = zypp::repo::RepoType::NONE; + if ( zypp::PathInfo(path_r).isDir() ) + { + if ( zypp::PathInfo(path_r/"/repodata/repomd.xml").isFile() ) + { ret = zypp::repo::RepoType::RPMMD; } + else if ( zypp::PathInfo(path_r/"/content").isFile() ) + { ret = zypp::repo::RepoType::YAST2; } + else if ( zypp::PathInfo(path_r/"/cookie").isFile() ) + { ret = zypp::repo::RepoType::RPMPLAINDIR; } + } + DBG << "Probed cached type " << ret << " at " << path_r << endl; + return ret; + } + } // + + RepoInfoSharedData::RepoInfoSharedData( zyppng::ContextBaseRef &&context ) + : RepoInfoBaseSharedData( std::move(context) ) + , _rawGpgCheck( zypp::indeterminate ) + , _rawRepoGpgCheck( zypp::indeterminate ) + , _rawPkgGpgCheck( zypp::indeterminate ) + , _validRepoSignature( zypp::indeterminate ) + , _type(zypp::repo::RepoType::NONE_e) + , keeppackages(zypp::indeterminate) + , _mirrorListForceMetalink(false) + , emptybaseurls(false) + { RepoInfoSharedData::bindVariables(); } + + void RepoInfoSharedData::bindVariables() + { + repo::RepoInfoBaseSharedData::bindVariables(); + if ( _ctx ) { + _mirrorListUrl.setTransformator( repo::RepoVariablesUrlReplacer( zypp::repo::RepoVarRetriever( *_ctx.get() ) ) ); + _baseUrls.setTransformator( repo::RepoVariablesUrlReplacer( zypp::repo::RepoVarRetriever( *_ctx.get() ) ) ); + _gpgKeyUrls.setTransformator( repo::RepoVariablesUrlReplacer( zypp::repo::RepoVarRetriever( *_ctx.get() ) ) ); + } else { + _mirrorListUrl.setTransformator( repo::RepoVariablesUrlReplacer( nullptr ) ); + _baseUrls.setTransformator( repo::RepoVariablesUrlReplacer( nullptr ) ); + _gpgKeyUrls.setTransformator( repo::RepoVariablesUrlReplacer( nullptr ) ); + } + } + + void RepoInfoSharedData::setType(const zypp::repo::RepoType &t) + { _type = t; } + + void RepoInfoSharedData::setProbedType(const zypp::repo::RepoType &t) const + { + if (_type == zypp::repo::RepoType::NONE && + t != zypp::repo::RepoType::NONE) { + const_cast(this)->_type = t; + } + } + zypp::repo::RepoType RepoInfoSharedData::type() const + { + if (_type == zypp::repo::RepoType::NONE) + setProbedType(probeCache(metadataPath() / path)); + + return _type; + } + + /** Path to a license tarball in case it exists in the repo. */ + zypp::Pathname RepoInfoSharedData::licenseTgz(const std::string &name_r) const + { + zypp::Pathname ret; + if (!metadataPath().empty()) { + std::string licenseStem("license"); + if (!name_r.empty()) { + licenseStem += "-"; + licenseStem += name_r; + } + + zypp::filesystem::Glob g; + // TODO: REPOMD: this assumes we know the name of the tarball. In fact + // we'd need to get the file from repomd.xml () + g.add(metadataPath() / path / ("repodata/*" + licenseStem + ".tar.gz")); + if (g.empty()) + g.add(metadataPath() / path / (licenseStem + ".tar.gz")); + + if (!g.empty()) + ret = *g.begin(); + } + return ret; + } + + const RepoVariablesReplacedUrlList & RepoInfoSharedData::baseUrls() const + { + const zypp::Url &mlurl(_mirrorListUrl.transformed()); // Variables replaced! + if (_baseUrls.empty() && !mlurl.asString().empty()) { + emptybaseurls = true; + DBG << "MetadataPath: " << metadataPath() << endl; + zypp::repo::RepoMirrorList rmurls(_ctx, mlurl, metadataPath(), + _mirrorListForceMetalink); + _baseUrls.raw().insert(_baseUrls.raw().end(), rmurls.getUrls().begin(), + rmurls.getUrls().end()); + } + return _baseUrls; + } + + RepoVariablesReplacedUrlList &RepoInfoSharedData::baseUrls() + { + return _baseUrls; + } + + bool RepoInfoSharedData::baseurl2dump() const + { + return !emptybaseurls && !_baseUrls.empty(); + } + + const RepoVariablesReplacedUrlList &RepoInfoSharedData::gpgKeyUrls() const + { + return _gpgKeyUrls; + } + + RepoVariablesReplacedUrlList &RepoInfoSharedData::gpgKeyUrls() + { + return _gpgKeyUrls; + } + + const std::set &RepoInfoSharedData::contentKeywords() const + { + hasContent() /*init if not yet done*/; + return _keywords.second; + } + + void RepoInfoSharedData::addContent(const std::string &keyword_r) + { + _keywords.second.insert(keyword_r); + if (!hasContent()) + _keywords.first = true; + } + + bool RepoInfoSharedData::hasContent() const + { + if (!_keywords.first && !metadataPath().empty()) { + // HACK directly check master index file until RepoManager offers + // some content probing and zypper uses it. + ///////////////////////////////////////////////////////////////// + MIL << "Empty keywords...." << metadataPath() << endl; + zypp::Pathname master; + if (zypp::PathInfo((master = metadataPath() / "/repodata/repomd.xml")) + .isFile()) { + // MIL << "GO repomd.." << endl; + zypp::xml::Reader reader(master); + while (reader.seekToNode(2, "content")) { + _keywords.second.insert(reader.nodeText().asString()); + reader.seekToEndNode(2, "content"); + } + _keywords.first = true; // valid content in _keywords even if empty + } else if (zypp::PathInfo((master = metadataPath() / "/content")).isFile()) { + // MIL << "GO content.." << endl; + zypp::iostr::forEachLine( + zypp::InputStream(master), + [this](int num_r, const std::string &line_r) -> bool { + if (zypp::str::startsWith(line_r, "REPOKEYWORDS")) { + std::vector words; + if (zypp::str::split(line_r, std::back_inserter(words)) > 1 && + words[0].length() == 12 /*"REPOKEYWORDS"*/) { + this->_keywords.second.insert(++words.begin(), words.end()); + } + return true; // mult. occurrances are ok. + } + return (!zypp::str::startsWith( + line_r, "META ")); // no need to parse into META section. + }); + _keywords.first = true; // valid content in _keywords even if empty + } + ///////////////////////////////////////////////////////////////// + } + return _keywords.first; + } + + bool RepoInfoSharedData::hasContent(const std::string &keyword_r) const + { + return (hasContent() && + _keywords.second.find(keyword_r) != _keywords.second.end()); + } + + zypp::TriBool RepoInfoSharedData::internalValidRepoSignature() const + { + if (!zypp::indeterminate(_validRepoSignature)) + return _validRepoSignature; + // check metadata: + if (!metadataPath().empty()) { + // A missing ".repo_gpgcheck" might be plaindir(no Downloader) or not yet + // refreshed signed repo! + zypp::TriBool linkval = triBoolFromPath(metadataPath() / ".repo_gpgcheck"); + return linkval; + } + return zypp::indeterminate; + } + + void RepoInfoSharedData::internalSetValidRepoSignature( zypp::TriBool value_r) + { + if (zypp::PathInfo(metadataPath()).isDir()) { + zypp::Pathname gpgcheckFile(metadataPath() / ".repo_gpgcheck"); + if (zypp::PathInfo(gpgcheckFile).isExist()) { + zypp::TriBool linkval(zypp::indeterminate); + if (triBoolFromPath(gpgcheckFile, linkval) && linkval == value_r) + return; // existing symlink fits value_r + else + zypp::filesystem::unlink(gpgcheckFile); // will write a new one + } + zypp::filesystem::symlink(zypp::asString(value_r), gpgcheckFile); + } + _validRepoSignature = value_r; + } + + bool RepoInfoSharedData::internalUnsignedConfirmed() const + { + zypp::TriBool linkval( + true); // want to see it being switched to zypp::indeterminate + return triBoolFromPath(metadataPath() / ".repo_gpgcheck", linkval) && + zypp::indeterminate(linkval); + } + + bool RepoInfoSharedData::triBoolFromPath(const zypp::Pathname &path_r, zypp::TriBool &ret_r) const + { + static const zypp::Pathname truePath("true"); + static const zypp::Pathname falsePath("false"); + static const zypp::Pathname indeterminatePath("zypp::indeterminate"); + + // Quiet readlink; + static const ssize_t bufsiz = 63; + static char buf[bufsiz + 1]; + ssize_t ret = ::readlink(path_r.c_str(), buf, bufsiz); + buf[ret == -1 ? 0 : ret] = '\0'; + + zypp::Pathname linkval(buf); + + bool known = true; + if (linkval == truePath) + ret_r = true; + else if (linkval == falsePath) + ret_r = false; + else if (linkval == indeterminatePath) + ret_r = zypp::indeterminate; + else + known = false; + return known; + } + + zypp::TriBool RepoInfoSharedData::triBoolFromPath(const zypp::Pathname &path_r) const + { + zypp::TriBool ret(zypp::indeterminate); + triBoolFromPath(path_r, ret); + return ret; + } + + bool RepoInfoSharedData::cfgGpgCheck() const + { + const zypp::ZConfig *zConf = nullptr; + if (!this->_ctx) { + MIL << "RepoInfo has no context, returning default setting for " + "cfgRepoGpgCheck!" + << std::endl; + zConf = &zypp::ZConfig::defaults(); + } else { + zConf = &this->_ctx->config(); + } + return zypp::indeterminate(_rawGpgCheck) ? zConf->gpgCheck() + : (bool)_rawGpgCheck; + } + + zypp::TriBool RepoInfoSharedData::cfgRepoGpgCheck() const + { + const zypp::ZConfig *zConf = nullptr; + if (!this->_ctx) { + MIL << "RepoInfo has no context, returning default setting for " + "cfgRepoGpgCheck!" + << std::endl; + zConf = &zypp::ZConfig::defaults(); + } else { + zConf = &this->_ctx->config(); + } + return zypp::indeterminate(_rawGpgCheck) && + zypp::indeterminate(_rawRepoGpgCheck) + ? zConf->repoGpgCheck() + : _rawRepoGpgCheck; + } + + zypp::TriBool RepoInfoSharedData::cfgPkgGpgCheck() const + { + const zypp::ZConfig *zConf = nullptr; + if (!this->_ctx) { + MIL << "RepoInfo has no context, returning default setting for " + "cfgRepoGpgCheck!" + << std::endl; + zConf = &zypp::ZConfig::defaults(); + } else { + zConf = &this->_ctx->config(); + } + return zypp::indeterminate(_rawGpgCheck) && + zypp::indeterminate(_rawPkgGpgCheck) + ? zConf->pkgGpgCheck() + : _rawPkgGpgCheck; + } + + void RepoInfoSharedData::solvPath(zypp::Pathname new_r) { + _slvPath = std::move(new_r); + } + + void RepoInfoSharedData::metadataPath(zypp::Pathname new_r) { + _metadataPath = std::move(new_r); + } + + void RepoInfoSharedData::packagesPath(zypp::Pathname new_r) { + _packagesPath = std::move(new_r); + } + + bool RepoInfoSharedData::usesAutoMetadataPaths() const + { + return zypp::str::hasSuffix(_metadataPath.asString(), "/%AUTO%"); + } + + zypp::Pathname RepoInfoSharedData::solvPath() const + { + if (usesAutoMetadataPaths()) + return _metadataPath.dirname() / "%SLV%"; + return _slvPath; + } + + zypp::Pathname RepoInfoSharedData::metadataPath() const + { + if (usesAutoMetadataPaths()) + return _metadataPath.dirname() / "%RAW%"; + return _metadataPath; + } + + zypp::Pathname RepoInfoSharedData::packagesPath() const + { + if (_packagesPath.empty() && usesAutoMetadataPaths()) + return _metadataPath.dirname() / "%PKG%"; + return _packagesPath; + } + + RepoInfoSharedData *RepoInfoSharedData::clone() const + { + auto *n = new RepoInfoSharedData(*this); + n->bindVariables (); + return n; + } + + /////////////////////////////////////////////////////////////////// + + /** \relates RepoInfo::Impl Stream output */ + inline std::ostream & operator<<( std::ostream & str, const RepoInfo::Impl & obj ) + { + return str << "RepoInfo::Impl"; + } + + RepoInfo::RepoInfo( zyppng::ContextBaseRef context ) + : RepoInfoBase( *( new RepoInfoSharedData( std::move(context) ) ) ) + {} + + RepoInfo::~RepoInfo() + {} + + unsigned RepoInfo::priority() const + { return pimpl()->priority; } + + const std::optional &RepoInfo::nullRepo() + { + static std::optional _nullRepo; + return _nullRepo; + } + + unsigned RepoInfo::defaultPriority() + { return RepoInfoSharedData::defaultPriority; } + + unsigned RepoInfo::noPriority() + { return RepoInfoSharedData::noPriority; } + + void RepoInfo::setPriority( unsigned newval_r ) + { pimpl()->priority = newval_r ? newval_r : RepoInfoSharedData::defaultPriority; } + + bool RepoInfo::gpgCheck() const + { return pimpl()->cfgGpgCheck(); } + + void RepoInfo::setGpgCheck( zypp::TriBool value_r ) + { pimpl()->rawGpgCheck( value_r ); } + + bool RepoInfo::repoGpgCheck() const + { return gpgCheck() || bool(pimpl()->cfgRepoGpgCheck()); } + + bool RepoInfo::repoGpgCheckIsMandatory() const + { + bool ret = ( gpgCheck() && indeterminate(pimpl()->cfgRepoGpgCheck()) ) || bool(pimpl()->cfgRepoGpgCheck()); + if ( ret && pimpl()->internalUnsignedConfirmed() ) // relax if unsigned repo was confirmed in the past + ret = false; + return ret; + } + + void RepoInfo::setRepoGpgCheck( zypp::TriBool value_r ) + { pimpl()->rawRepoGpgCheck( value_r ); } + + + bool RepoInfo::pkgGpgCheck() const + { return bool(pimpl()->cfgPkgGpgCheck()) || ( gpgCheck() && !bool(validRepoSignature())/*enforced*/ ) ; } + + bool RepoInfo::pkgGpgCheckIsMandatory() const + { return bool(pimpl()->cfgPkgGpgCheck()) || ( gpgCheck() && indeterminate(pimpl()->cfgPkgGpgCheck()) && !bool(validRepoSignature())/*enforced*/ ); } + + void RepoInfo::setPkgGpgCheck( zypp::TriBool value_r ) + { pimpl()->rawPkgGpgCheck( value_r ); } + + + void RepoInfo::getRawGpgChecks( zypp::TriBool & g_r, zypp::TriBool & r_r, zypp::TriBool & p_r ) const + { + g_r = pimpl()->rawGpgCheck(); + r_r = pimpl()->rawRepoGpgCheck(); + p_r = pimpl()->rawPkgGpgCheck(); + } + + void RepoInfo::setContext( zyppng::ContextBaseRef context ) + { + pimpl()->switchContext(context); + } + + RepoInfoSharedData *RepoInfo::pimpl() + { + return static_cast(_pimpl.get()); + } + + const RepoInfoSharedData *RepoInfo::pimpl() const + { + return static_cast( _pimpl.get() ); + } + + zypp::TriBool RepoInfo::validRepoSignature() const + { + zypp::TriBool ret( pimpl()->internalValidRepoSignature() ); + if ( ret && !repoGpgCheck() ) ret = false; // invalidate any old signature if repoGpgCheck is off + return ret; + } + + void RepoInfo::setValidRepoSignature( zypp::TriBool value_r ) + { pimpl()->internalSetValidRepoSignature( value_r ); } + + /////////////////////////////////////////////////////////////////// + namespace + { + inline bool changeGpgCheckTo( zypp::TriBool & lhs, zypp::TriBool rhs ) + { if ( ! sameTriboolState( lhs, rhs ) ) { lhs = rhs; return true; } return false; } + + inline bool changeGpgCheckTo( zypp::TriBool ogpg[3], zypp::TriBool g, zypp::TriBool r, zypp::TriBool p ) + { + bool changed = false; + if ( changeGpgCheckTo( ogpg[0], g ) ) changed = true; + if ( changeGpgCheckTo( ogpg[1], r ) ) changed = true; + if ( changeGpgCheckTo( ogpg[2], p ) ) changed = true; + return changed; + } + } // namespace + /////////////////////////////////////////////////////////////////// + bool RepoInfo::setGpgCheck( GpgCheck mode_r ) + { + zypp::TriBool ogpg[3]; // Gpg RepoGpg PkgGpg + getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] ); + + bool changed = false; + switch ( mode_r ) + { + case GpgCheck::On: + changed = changeGpgCheckTo( ogpg, true, zypp::indeterminate, zypp::indeterminate ); + break; + case GpgCheck::Strict: + changed = changeGpgCheckTo( ogpg, true, true, true ); + break; + case GpgCheck::AllowUnsigned: + changed = changeGpgCheckTo( ogpg, true, false, false ); + break; + case GpgCheck::AllowUnsignedRepo: + changed = changeGpgCheckTo( ogpg, true, false, zypp::indeterminate ); + break; + case GpgCheck::AllowUnsignedPackage: + changed = changeGpgCheckTo( ogpg, true, zypp::indeterminate, false ); + break; + case GpgCheck::Default: + changed = changeGpgCheckTo( ogpg, zypp::indeterminate, zypp::indeterminate, zypp::indeterminate ); + break; + case GpgCheck::Off: + changed = changeGpgCheckTo( ogpg, false, zypp::indeterminate, zypp::indeterminate ); + break; + case GpgCheck::indeterminate: // no change + break; + } + + if ( changed ) + { + setGpgCheck ( ogpg[0] ); + setRepoGpgCheck( ogpg[1] ); + setPkgGpgCheck ( ogpg[2] ); + } + return changed; + } + + void RepoInfo::setMirrorListUrl( const zypp::Url & url_r ) // Raw + { pimpl()->_mirrorListUrl.raw() = url_r; pimpl()->_mirrorListForceMetalink = false; } + + void RepoInfo::setMirrorListUrls( url_set urls ) // Raw + { setMirrorListUrl( urls.empty() ? zypp::Url() : urls.front() ); } + + void RepoInfo::setMetalinkUrl( const zypp::Url & url_r ) // Raw + { pimpl()->_mirrorListUrl.raw() = url_r; pimpl()->_mirrorListForceMetalink = true; } + + void RepoInfo::setMetalinkUrls( url_set urls ) // Raw + { setMetalinkUrl( urls.empty() ? zypp::Url() : urls.front() ); } + + void RepoInfo::setGpgKeyUrls( url_set urls ) + { pimpl()->gpgKeyUrls().raw().swap( urls ); } + + void RepoInfo::setGpgKeyUrl( const zypp::Url & url_r ) + { + pimpl()->gpgKeyUrls().raw().clear(); + pimpl()->gpgKeyUrls().raw().push_back( url_r ); + } + + void RepoInfo::addBaseUrl( zypp::Url url_r ) + { + for ( const auto & url : pimpl()->baseUrls().raw() ) // Raw unique! + if ( url == url_r ) + return; + pimpl()->baseUrls().raw().push_back( std::move(url_r) ); + } + + void RepoInfo::setBaseUrl( zypp::Url url_r ) + { + pimpl()->baseUrls().raw().clear(); + pimpl()->baseUrls().raw().push_back( std::move(url_r) ); + } + + void RepoInfo::setBaseUrls( url_set urls ) + { pimpl()->baseUrls().raw().swap( urls ); } + + void RepoInfo::setPath( const zypp::Pathname &path ) + { pimpl()->path = path; } + + void RepoInfo::setType( const zypp::repo::RepoType &t ) + { pimpl()->setType( t ); } + + void RepoInfo::setProbedType( const zypp::repo::RepoType &t ) const + { pimpl()->setProbedType( t ); } + + void RepoInfo::setMetadataPath( const zypp::Pathname &path ) + { pimpl()->metadataPath( path ); } + + void RepoInfo::setPackagesPath( const zypp::Pathname &path ) + { pimpl()->packagesPath( path ); } + + void RepoInfo::setSolvCachePath(const zypp::Pathname &path) + { pimpl()->solvPath (path); } + + void RepoInfo::setKeepPackages( bool keep ) + { pimpl()->keeppackages = keep; } + + void RepoInfo::setService( const std::string& name ) + { pimpl()->service = name; } + + void RepoInfo::setTargetDistribution( const std::string & targetDistribution ) + { pimpl()->targetDistro = targetDistribution; } + + bool RepoInfo::keepPackages() const + { return indeterminate(pimpl()->keeppackages) ? false : (bool)pimpl()->keeppackages; } + + zypp::Pathname RepoInfo::metadataPath() const + { return pimpl()->metadataPath(); } + + zypp::Pathname RepoInfo::packagesPath() const + { return pimpl()->packagesPath(); } + + zypp::Pathname RepoInfo::solvCachePath() const + { return pimpl()->solvPath(); } + + bool RepoInfo::usesAutoMetadataPaths() const + { return pimpl()->usesAutoMetadataPaths(); } + + zypp::repo::RepoType RepoInfo::type() const + { return pimpl()->type(); } + + zypp::Url RepoInfo::mirrorListUrl() const // Variables replaced! + { return pimpl()->_mirrorListUrl.transformed(); } + + zypp::Url RepoInfo::rawMirrorListUrl() const // Raw + { return pimpl()->_mirrorListUrl.raw(); } + + bool RepoInfo::gpgKeyUrlsEmpty() const + { return pimpl()->gpgKeyUrls().empty(); } + + RepoInfo::urls_size_type RepoInfo::gpgKeyUrlsSize() const + { return pimpl()->gpgKeyUrls().size(); } + + RepoInfo::url_set RepoInfo::gpgKeyUrls() const // Variables replaced! + { return pimpl()->gpgKeyUrls().transformed(); } + + RepoInfo::url_set RepoInfo::rawGpgKeyUrls() const // Raw + { return pimpl()->gpgKeyUrls().raw(); } + + zypp::Url RepoInfo::gpgKeyUrl() const // Variables replaced! + { return( pimpl()->gpgKeyUrls().empty() ? zypp::Url() : *pimpl()->gpgKeyUrls().transformedBegin() ); } + + zypp::Url RepoInfo::rawGpgKeyUrl() const // Raw + { return( pimpl()->gpgKeyUrls().empty() ? zypp::Url() : *pimpl()->gpgKeyUrls().rawBegin() ) ; } + + RepoInfo::url_set RepoInfo::baseUrls() const // Variables replaced! + { return pimpl()->baseUrls().transformed(); } + + RepoInfo::url_set RepoInfo::rawBaseUrls() const // Raw + { return pimpl()->baseUrls().raw(); } + + zypp::Pathname RepoInfo::path() const + { return pimpl()->path; } + + std::string RepoInfo::service() const + { return pimpl()->service; } + + std::string RepoInfo::targetDistribution() const + { return pimpl()->targetDistro; } + + zypp::Url RepoInfo::rawUrl() const + { return( pimpl()->baseUrls().empty() ? zypp::Url() : *pimpl()->baseUrls().rawBegin() ); } + + RepoInfo::urls_const_iterator RepoInfo::baseUrlsBegin() const + { return pimpl()->baseUrls().transformedBegin(); } + + RepoInfo::urls_const_iterator RepoInfo::baseUrlsEnd() const + { return pimpl()->baseUrls().transformedEnd(); } + + RepoInfo::urls_size_type RepoInfo::baseUrlsSize() const + { return pimpl()->baseUrls().size(); } + + bool RepoInfo::baseUrlsEmpty() const + { return pimpl()->baseUrls().empty(); } + + bool RepoInfo::baseUrlSet() const + { return pimpl()->baseurl2dump(); } + + const std::set & RepoInfo::contentKeywords() const + { return pimpl()->contentKeywords(); } + + void RepoInfo::addContent( const std::string & keyword_r ) + { pimpl()->addContent( keyword_r ); } + + bool RepoInfo::hasContent() const + { return pimpl()->hasContent(); } + + bool RepoInfo::hasContent( const std::string & keyword_r ) const + { return pimpl()->hasContent( keyword_r ); } + + /////////////////////////////////////////////////////////////////// + + bool RepoInfo::hasLicense() const + { return hasLicense( std::string() ); } + + bool RepoInfo::hasLicense( const std::string & name_r ) const + { return !pimpl()->licenseTgz( name_r ).empty(); } + + + bool RepoInfo::needToAcceptLicense() const + { return needToAcceptLicense( std::string() ); } + + bool RepoInfo::needToAcceptLicense( const std::string & name_r ) const + { + const zypp::Pathname & licenseTgz( pimpl()->licenseTgz( name_r ) ); + if ( licenseTgz.empty() ) + return false; // no licenses at all + + zypp::ExternalProgram::Arguments cmd; + cmd.push_back( "tar" ); + cmd.push_back( "-t" ); + cmd.push_back( "-z" ); + cmd.push_back( "-f" ); + cmd.push_back( licenseTgz.asString() ); + zypp::ExternalProgram prog( cmd, zypp::ExternalProgram::Stderr_To_Stdout ); + + bool accept = true; + static const std::string noAcceptanceFile = "no-acceptance-needed\n"; + for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) + { + if ( output == noAcceptanceFile ) + { + accept = false; + } + } + prog.close(); + MIL << "License(" << name_r << ") in " << name() << " has to be accepted: " << (accept?"true":"false" ) << endl; + return accept; + } + + std::string RepoInfo::getLicense( const zypp::Locale & lang_r ) const + { return getLicense( std::string(), lang_r ); } + + std::string RepoInfo::getLicense( const std::string & name_r, const zypp::Locale & lang_r ) const + { + zypp::LocaleSet avlocales( getLicenseLocales( name_r ) ); + if ( avlocales.empty() ) + return std::string(); + + zypp::Locale getLang( zypp::Locale::bestMatch( avlocales, lang_r ) ); + if ( !getLang && avlocales.find( zypp::Locale::noCode ) == avlocales.end() ) + { + WAR << "License(" << name_r << ") in " << name() << " contains no fallback text!" << endl; + // Using the fist locale instead of returning no text at all. + // So the user might recognize that there is a license, even if they + // can't read it. + getLang = *avlocales.begin(); + } + + // now extract the license file. + static const std::string licenseFileFallback( "license.txt" ); + std::string licenseFile( !getLang ? licenseFileFallback + : zypp::str::form( "license.%s.txt", getLang.c_str() ) ); + + zypp::ExternalProgram::Arguments cmd; + cmd.push_back( "tar" ); + cmd.push_back( "-x" ); + cmd.push_back( "-z" ); + cmd.push_back( "-O" ); + cmd.push_back( "-f" ); + cmd.push_back( pimpl()->licenseTgz( name_r ).asString() ); // if it not exists, avlocales was empty. + cmd.push_back( licenseFile ); + + std::string ret; + zypp::ExternalProgram prog( cmd, zypp::ExternalProgram::Discard_Stderr ); + for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) + { + ret += output; + } + prog.close(); + return ret; + } + + zypp::LocaleSet RepoInfo::getLicenseLocales() const + { return getLicenseLocales( std::string() ); } + + zypp::LocaleSet RepoInfo::getLicenseLocales( const std::string & name_r ) const + { + const zypp::Pathname & licenseTgz( pimpl()->licenseTgz( name_r ) ); + if ( licenseTgz.empty() ) + return zypp::LocaleSet(); + + zypp::ExternalProgram::Arguments cmd; + cmd.push_back( "tar" ); + cmd.push_back( "-t" ); + cmd.push_back( "-z" ); + cmd.push_back( "-f" ); + cmd.push_back( licenseTgz.asString() ); + + zypp::LocaleSet ret; + zypp::ExternalProgram prog( cmd, zypp::ExternalProgram::Stderr_To_Stdout ); + for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) + { + static const zypp::C_Str license( "license." ); + static const zypp::C_Str dotTxt( ".txt\n" ); + if ( zypp::str::hasPrefix( output, license ) && zypp::str::hasSuffix( output, dotTxt ) ) + { + if ( output.size() <= license.size() + dotTxt.size() ) // license.txt + ret.insert( zypp::Locale() ); + else + ret.insert( zypp::Locale( std::string( output.c_str()+license.size(), output.size()- license.size() - dotTxt.size() ) ) ); + } + } + prog.close(); + return ret; + } + + /////////////////////////////////////////////////////////////////// + + std::ostream & RepoInfo::dumpOn( std::ostream & str ) const + { + RepoInfoBase::dumpOn(str); + if ( pimpl()->baseurl2dump() ) + { + for ( const auto & url : pimpl()->baseUrls().raw() ) + { + str << "- url : " << url << std::endl; + } + } + + // print if non empty value + auto strif( [&] ( const std::string & tag_r, const std::string & value_r ) { + if ( ! value_r.empty() ) + str << tag_r << value_r << std::endl; + }); + + strif( (pimpl()->_mirrorListForceMetalink ? "- metalink : " : "- mirrorlist : "), rawMirrorListUrl().asString() ); + strif( "- path : ", path().asString() ); + str << "- type : " << type() << std::endl; + str << "- priority : " << priority() << std::endl; + + // Yes No Default(Y) Default(N) +#define OUTS(T,B) ( indeterminate(T) ? (std::string("D(")+(B?"Y":"N")+")") : ((bool)T?"Y":"N") ) + str << "- gpgcheck : " << OUTS(pimpl()->rawGpgCheck(),gpgCheck()) + << " repo" << OUTS(pimpl()->rawRepoGpgCheck(),repoGpgCheck()) << (repoGpgCheckIsMandatory() ? "* ": " " ) + << "sig" << zypp::asString( validRepoSignature(), "?", "Y", "N" ) + << " pkg" << OUTS(pimpl()->rawPkgGpgCheck(),pkgGpgCheck()) << (pkgGpgCheckIsMandatory() ? "* ": " " ) + << std::endl; +#undef OUTS + + for ( const auto & url : pimpl()->gpgKeyUrls().raw() ) + { + str << "- gpgkey : " << url << std::endl; + } + + if ( ! indeterminate(pimpl()->keeppackages) ) + str << "- keeppackages: " << keepPackages() << std::endl; + + strif( "- service : ", service() ); + strif( "- targetdistro: ", targetDistribution() ); + strif( "- filePath: ", filepath().asString() ); + strif( "- metadataPath: ", metadataPath().asString() ); + strif( "- packagesPath: ", packagesPath().asString() ); + + return str; + } + + std::ostream & RepoInfo::dumpAsIniOn( std::ostream & str ) const + { + RepoInfoBase::dumpAsIniOn(str); + + if ( pimpl()->baseurl2dump() ) + { + str << "baseurl="; + std::string indent; + for ( const auto & url : pimpl()->baseUrls().raw() ) + { + str << indent << zypp::hotfix1050625::asString( url ) << endl; + if ( indent.empty() ) indent = " "; // "baseurl=" + } + } + + if ( ! pimpl()->path.empty() ) + str << "path="<< path() << endl; + + if ( ! (rawMirrorListUrl().asString().empty()) ) + str << (pimpl()->_mirrorListForceMetalink ? "metalink=" : "mirrorlist=") << zypp::hotfix1050625::asString( rawMirrorListUrl() ) << endl; + + if ( type() != zypp::repo::RepoType::NONE ) + str << "type=" << type().asString() << endl; + + if ( priority() != defaultPriority() ) + str << "priority=" << priority() << endl; + + if ( ! indeterminate(pimpl()->rawGpgCheck()) ) + str << "gpgcheck=" << (pimpl()->rawGpgCheck() ? "1" : "0") << endl; + + if ( ! indeterminate(pimpl()->rawRepoGpgCheck()) ) + str << "repo_gpgcheck=" << (pimpl()->rawRepoGpgCheck() ? "1" : "0") << endl; + + if ( ! indeterminate(pimpl()->rawPkgGpgCheck()) ) + str << "pkg_gpgcheck=" << (pimpl()->rawPkgGpgCheck() ? "1" : "0") << endl; + + { + std::string indent( "gpgkey="); + for ( const auto & url : pimpl()->gpgKeyUrls().raw() ) + { + str << indent << url << endl; + if ( indent[0] != ' ' ) + indent = " "; + } + } + + if (!indeterminate(pimpl()->keeppackages)) + str << "keeppackages=" << keepPackages() << endl; + + if( ! service().empty() ) + str << "service=" << service() << endl; + + return str; + } + + std::ostream & RepoInfo::dumpAsXmlOn( std::ostream & str, const std::string & content ) const + { + std::string tmpstr; + str + << "rawGpgCheck()) ) + str << " raw_gpgcheck=\"" << (pimpl()->rawGpgCheck() ? "1" : "0") << "\""; + if ( ! indeterminate(pimpl()->rawRepoGpgCheck()) ) + str << " raw_repo_gpgcheck=\"" << (pimpl()->rawRepoGpgCheck() ? "1" : "0") << "\""; + if ( ! indeterminate(pimpl()->rawPkgGpgCheck()) ) + str << " raw_pkg_gpgcheck=\"" << (pimpl()->rawPkgGpgCheck() ? "1" : "0") << "\""; + if (!(tmpstr = gpgKeyUrl().asString()).empty()) + if (!(tmpstr = gpgKeyUrl().asString()).empty()) + str << " gpgkey=\"" << escape(tmpstr) << "\""; + if (!(tmpstr = mirrorListUrl().asString()).empty()) + str << (pimpl()->_mirrorListForceMetalink ? " metalink=\"" : " mirrorlist=\"") << escape(tmpstr) << "\""; + str << ">" << endl; + + if ( pimpl()->baseurl2dump() ) + { + for_( it, baseUrlsBegin(), baseUrlsEnd() ) // !transform iterator replaces variables + str << "" << escape((*it).asString()) << "" << endl; + } + + str << "" << endl; + return str; + } + + + std::ostream & operator<<( std::ostream & str, const RepoInfo & obj ) + { + return obj.dumpOn(str); + } + + bool RepoInfo::requireStatusWithMediaFile () const + { + // We skip the check for downloading media unless a local copy of the + // media file exists and states that there is more than one medium. + bool canSkipMediaCheck = std::all_of( baseUrlsBegin(), baseUrlsEnd(), []( const zypp::Url &url ) { return url.schemeIsDownloading(); }); + if ( canSkipMediaCheck ) { + const auto &mDataPath = metadataPath(); + if ( not mDataPath.empty() ) { + zypp::PathInfo mediafile { mDataPath/"media.1/media" }; + if ( mediafile.isExist() ) { + zypp::repo::SUSEMediaVerifier lverifier { mediafile.path() }; + if ( lverifier && lverifier.totalMedia() > 1 ) { + canSkipMediaCheck = false; + } + } + } + } + if ( canSkipMediaCheck ) + DBG << "Can SKIP media.1/media check for status calc of repo " << alias() << endl; + return not canSkipMediaCheck; + } +} // namespace zyppng diff --git a/zypp/ng/repoinfo.h b/zypp/ng/repoinfo.h new file mode 100644 index 0000000000..50825870ec --- /dev/null +++ b/zypp/ng/repoinfo.h @@ -0,0 +1,598 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/RepoInfo.h + * +*/ +#ifndef ZYPP_NG_REPOINFO_INCLUDED +#define ZYPP_NG_REPOINFO_INCLUDED + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +/////////////////////////////////////////////////////////////////// +namespace zyppng +{ ///////////////////////////////////////////////////////////////// + + class RepoInfoSharedData; + + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : RepoInfo + // + /** + * \short What is known about a repository + * + * The class RepoInfo represents everything that + * is known about a software repository. + * + * It can be used to store information about known + * sources. + * + * This class tries to be compatible with the + * concept of a .repo file used by YUM and + * also available in the openSUSE build service. + * See man yum.conf. + * + * Example file + * + * \code + * [ruby] + * name=Ruby repository (openSUSE_10.2) + * type=rpm-md + * baseurl=http://software.opensuse.org/download/ruby/openSUSE_10.2/ + * http://some.opensuse.mirror/ruby/openSUSE_10.2/ + * gpgcheck=1 + * gpgkey=http://software.opensuse.org/openSUSE-Build-Service.asc + * enabled=1 + * priority=10 + * \endcode + * + * \note A RepoInfo is a hint about how + * to create a Repository. + * + * \note Name, baseUrls and mirrorUrl are subject to repo variable replacement + * (\see \ref RepoVariablesStringReplacer). + */ + class RepoInfo : public repo::RepoInfoBase + { + friend std::ostream & operator<<( std::ostream & str, const RepoInfo & obj ); + + public: + + // nullable -> ContextFactory::defaultContext() ? + RepoInfo ( zyppng::ContextBaseRef context ) ZYPP_LOCAL; + ~RepoInfo() override; + + RepoInfo(const RepoInfo &) = default; + RepoInfo(RepoInfo &&) = default; + RepoInfo &operator=(const RepoInfo &) = default; + RepoInfo &operator=(RepoInfo &&) = default; + + public: + + static const std::optional &nullRepo(); + + /** + * The default priority (\c 99). + */ + static unsigned defaultPriority(); + /** + * The least priority (unsigned(-1)). + */ + static unsigned noPriority(); + /** + * Repository priority for solver. + * Some number between \c 1 (highest priority) and \c 99 (\ref defaultPriority). + */ + unsigned priority() const; + /** + * Set repository priority for solver. + * A \c newval_r of \c 0 sets the default priority. + * \see \ref priority. + */ + void setPriority( unsigned newval_r ); + + using url_set = std::list; + using urls_size_type = url_set::size_type; + using urls_const_iterator = zypp::transform_iterator; + /** + * whether repository urls are available + */ + bool baseUrlsEmpty() const; + /** + * Whether there are manualy configured repository urls. + * If \c false, a mirrorlist might be used. + */ + bool baseUrlSet() const; + /** + * number of repository urls + */ + urls_size_type baseUrlsSize() const; + /** + * iterator that points at begin of repository urls + */ + urls_const_iterator baseUrlsBegin() const; + /** + * iterator that points at end of repository urls + */ + urls_const_iterator baseUrlsEnd() const; + + /** + * Pars pro toto: The first repository url + */ + zypp::Url url() const + { return( baseUrlsEmpty() ? zypp::Url() : *baseUrlsBegin()); } + /** + * Pars pro toto: The first repository raw url (no variables replaced) + */ + zypp::Url rawUrl() const; + + /** + * The complete set of repository urls + * + * These are either the configured baseurls, or if empty, the downloaded + * mirror list (\see \ref mirrorListUrl) + */ + url_set baseUrls() const; + /** + * The complete set of raw repository urls (no variables replaced) + */ + url_set rawBaseUrls() const; + + /** + * Add a base url. \see baseUrls + * \param url The base url for the repository. + * + * To recreate the base URLs list, use \ref setBaseUrl(const Url &) followed + * by addBaseUrl(). + */ + void addBaseUrl( zypp::Url url ); + /** + * Clears current base URL list and adds \a url. + */ + void setBaseUrl( zypp::Url url ); + /** + * Clears current base URL list and adds an \ref url_set. + */ + void setBaseUrls( url_set urls ); + + /** + * \short Repository path + * + * Pathname relative to the base Url where the product/repository + * is located + * + * For media containing more than one product, or repositories not + * located at the root of the media it is important to know the path + * to the product directory relative to the media root. So a media + * verifier can be set for that media. You may also read it as + * baseUrl = url to mount and path = path on the + * mounted media. + * + * It is not mandatory, and the default is \c /. + * + * \note As a repository can have multiple Urls, the path is unique and + * the same for all Urls, so it is assumed all the Urls have the + * same media layout. + * + */ + zypp::Pathname path() const; + /** + * set the product path. \see path() + * \param path the path to the product + */ + void setPath( const zypp::Pathname &path ); + + /** + * Url of a file which contains a list of repository urls + */ + zypp::Url mirrorListUrl() const; + /** + * The raw mirrorListUrl (no variables replaced). + */ + zypp::Url rawMirrorListUrl() const; + /** + * Set mirror list url. \see mirrorListUrl + * \param url The base url for the list + */ + void setMirrorListUrl( const zypp::Url &url ); + /** Like \ref setMirrorListUrl but take an \a url_set */ + void setMirrorListUrls( url_set urls ); + + /** Like \ref setMirrorListUrl but expect metalink format. */ + void setMetalinkUrl( const zypp::Url &url ); + /** Like \ref setMirrorListUrls but expect metalink format. */ + void setMetalinkUrls( url_set urls ); + + /** + * Type of repository, + * + */ + zypp::repo::RepoType type() const; + /** + * This allows to adjust the \ref RepoType lazy, from \c NONE to + * some probed value, even for const objects. + * + * This is a NOOP if the current type is not \c NONE. + */ + void setProbedType( const zypp::repo::RepoType &t ) const; + /** + * set the repository type \see type + * \param t + */ + void setType( const zypp::repo::RepoType &t ); + + /** + * \short Path where this repo metadata was read from + * + * \note could be an empty pathname for repo + * infos created in memory. + */ + zypp::Pathname metadataPath() const; + /** + * \short Set the path where the local metadata is stored + * + * The path to the repositories metadata is usually provided by + * the RepoManager. If you want to use a temporary repository + * (not under RepoManagers control), and you set a metadataPath + * with basename \c %AUTO%, all data directories (raw metadata, + * solv file and package cache) will be created by replacing \c %AUTO% + * with \c %RAW%, \c %SLV% or \c %PKG% . This will change the value + * of \ref packagesPath accordingly, unless you assigned a custom + * value using \ref setPackagesPath. + * + * \code + * RepoInfo repo; + * repo.setAlias( "Temp" ); + * repo.setBaseUrl( Url("http://someserver/somepath/") ); + * repo.setMetadataPath( "/tmp/temprepodata/%AUTO%" ); + * + * // will use + * // /tmp/temprepodata/%RAW% - raw metadata + * // /%SLV% - solv file + * // /%PKG% - packages + *\endcode + * + * \param path directory path + */ + void setMetadataPath( const zypp::Pathname &path ); + + /** Whether \ref metadataPath uses \c %AUTO% setup. */ + bool usesAutoMetadataPaths() const; + + /** + * \short Path where this repo packages are cached + */ + zypp::Pathname packagesPath() const; + /** + * \short set the path where the local packages are stored + * + * \param path directory path + */ + void setPackagesPath( const zypp::Pathname &path ); + + /** + * \short Path where this repo's solv cache is located + */ + zypp::Pathname solvCachePath() const; + /** + * \short set the path this repo's solv cache is located + * + * \param path directory path + */ + void setSolvCachePath( const zypp::Pathname &path ); + + + /** \name Repository gpgchecks + * How signature checking should be performed for this repo. + * + * The values are computed based in the settings of \c gpgcheck, \c repo_gpgcheck + * end \c pkg_gpgcheck in \c zypp.conf. Explicitly setting these values in the + * repositories \a .repo file will overwrite the defaults from \c zypp.conf for this + * repo. + * + * If \c gpgcheck is \c on (the default) we will check the signature of repo metadata + * (packages are secured via checksum inside the metadata). Using unsigned repos + * needs to be confirmed. + * Packages from signed repos are accepted if their checksum matches the checksum + * stated in the repo metadata. + * Packages from unsigned repos need a valid gpg signature, using unsigned packages + * needs to be confirmed. + * + * The above default behavior can be tuned by explicitly setting \c repo_gpgcheck + * and/or \c pkg_gpgcheck: + * + * \c repo_gpgcheck = \c on same as the default. + * + * \c repo_gpgcheck = \c off will silently accept unsigned repos. It will NOT turn of + * signature checking on the whole. Nevertheless, it's not a secure setting. + * + * \c pkg_gpgcheck = \c on will enforce the package signature checking and the need + * to confirm unsigned packages for all repos (signed and unsigned). + * + * \c pkg_gpgcheck = \c off will silently accept unsigned packages. It will NOT turn of + * signature checking on the whole. Nevertheless, it's not a secure setting. + * + * If \c gpgCheck is \c off (not recommneded), no checks are performed. You can still + * enable them individually by setting \c repo_gpgcheck and/or \c pkg_gpgcheck to \c on. + * + * \code + * R: check repo signature is mandatory, confirm unsigned repos + * r: check repo signature, unsigned repos are ok but enforce p + * : do not check repo signatures + * + * P: check package signature always, confirm unsigned packages + * p: like P for unsigned repos, accepted by checksum for signed repos + * b: like p but accept unsigned packages + * : do not check package signatures + * pkg_ + * gpgcheck 1| * 0 1 + * ------------------------------------ + * repo_ *1| R/p R/b R/P + * 0| r/p r/b r/P + * + * pkg_ + * gpgcheck 0| * 0 1 + * ------------------------------------ + * repo_ *0| P + * 1| R R R/P + * \endcode + */ + //@{ + /** Whether default signature checking should be performed. */ + bool gpgCheck() const; + /** Set the value for \ref gpgCheck (or \c indeterminate to use the default). */ + void setGpgCheck( zypp::TriBool value_r ); + + /** Whether the signature of repo metadata should be checked for this repo. */ + bool repoGpgCheck() const; + /** Mandatory check (\ref repoGpgCheck is \c on) must ask to confirm using unsigned repos. */ + bool repoGpgCheckIsMandatory() const; + /** Set the value for \ref repoGpgCheck (or \c indeterminate to use the default). */ + void setRepoGpgCheck( zypp::TriBool value_r ); + + /** Whether the signature of rpm packages should be checked for this repo. */ + bool pkgGpgCheck() const; + /** Mandatory check (\ref pkgGpgCheck is not \c off) must ask to confirm using unsigned packages. */ + bool pkgGpgCheckIsMandatory() const; + /** Set the value for \ref pkgGpgCheck (or \c indeterminate to use the default). */ + void setPkgGpgCheck( zypp::TriBool value_r ); + + /** Whether the repo metadata are signed and successfully validated or \c indeterminate if unsigned. + * The value is usually set by \ref repo::Downloader when retrieving the metadata. + */ + zypp::TriBool validRepoSignature() const; + /** Set the value for \ref validRepoSignature (or \c indeterminate if unsigned). */ + void setValidRepoSignature( zypp::TriBool value_r ); + + using GpgCheck = zypp::repo::GpgCheck; + + /** Adjust *GpgCheck settings according to \a mode_r. + * \c GpgCheck::indeterminate will leave the settings as they are. + * \return whether setting were changed + */ + bool setGpgCheck( GpgCheck mode_r ); + //@} + + + /** Whether gpgkey URLs are defined */ + bool gpgKeyUrlsEmpty() const; + /** Number of gpgkey URLs defined */ + urls_size_type gpgKeyUrlsSize() const; + + /** The list of gpgkey URLs defined for this repo */ + url_set gpgKeyUrls() const; + /** The list of raw gpgkey URLs defined for this repo (no variables replaced) */ + url_set rawGpgKeyUrls() const; + /** Set a list of gpgkey URLs defined for this repo */ + void setGpgKeyUrls( url_set urls ); + + /** (leagcy API) The 1st gpgkey URL defined for this repo */ + zypp::Url gpgKeyUrl() const; + /** (leagcy API) The 1st raw gpgkey URL defined for this repo (no variables replaced) */ + zypp::Url rawGpgKeyUrl() const; + /** (leagcy API) Set the gpgkey URL defined for this repo */ + void setGpgKeyUrl( const zypp::Url &gpgkey ); + + /** + * \short Whether packages downloaded from this repository will be kept in local cache + */ + bool keepPackages() const; + /** + * \short Set if packaqes downloaded from this repository will be kept in local cache + * + * If the setting is true, all downloaded packages from this repository will be + * copied to the local raw cache. + * + * \param keep true (keep the downloaded packages) or false (delete them after installation) + * + */ + void setKeepPackages( bool keep ); + + /** + * Gets name of the service to which this repository belongs or empty string + * if it has been added manually. + */ + std::string service() const; + /** + * sets service which added this repository + */ + void setService( const std::string& name ); + + /** + * Distribution for which is this repository meant. + */ + std::string targetDistribution() const; + /** + * Sets the distribution for which is this repository meant. This is + * an in-memory value only, does norepoInfot get written to the .repo file upon + * saving. + */ + void setTargetDistribution(const std::string & targetDistribution); + + + /** Content keywords defined. */ + const std::set & contentKeywords() const; + + /** Add content keywords */ + void addContent( const std::string & keyword_r ); + /** \overload add keywords from container */ + template + void addContentFrom( TIterator begin_r, TIterator end_r ) + { for_( it, begin_r, end_r ) addContent( *it ); } + /** \overload */ + template + void addContentFrom( const TContainer & container_r ) + { addContentFrom( container_r.begin(), container_r.end() ); } + + /** Check for content keywords. + * They may be missing due to missing metadata in disabled repos. + */ + bool hasContent() const; + /** \overload check for a keywords being present */ + bool hasContent( const std::string & keyword_r ) const; + /** \overload check for \b all keywords being present */ + template + bool hasContentAll( TIterator begin_r, TIterator end_r ) const + { for_( it, begin_r, end_r ) if ( ! hasContent( *it ) ) return false; return true; } + /** \overload */ + template + bool hasContentAll( const TContainer & container_r ) const + { return hasContentAll( container_r.begin(), container_r.end() ); } + /** \overload check for \b any keyword being present */ + template + bool hasContentAny( TIterator begin_r, TIterator end_r ) const + { for_( it, begin_r, end_r ) if ( hasContent( *it ) ) return true; return false; } + /** \overload */ + template + bool hasContentAny( const TContainer & container_r ) const + { return hasContentAny( container_r.begin(), container_r.end() ); } + + public: + /** \name Repository/Product license + * In case a repository provides multiple license tarballs in repomd.xml + * \code + * ... + * ... + * ... + * \endcode + * you can address the individual licenses by passing their name + * (e.g. \c "sles" to access the \c type="license-sles"). + * No on an empty name will refer to \c type="license". + */ + //@{ + /** Whether there is a license associated with the repo. */ + bool hasLicense() const; + /** \overload taking a (product)name */ + bool hasLicense( const std::string & name_r ) const; + + /** Whether the repo license has to be accepted, e.g. there is no + * no acceptance needed for openSUSE. + */ + bool needToAcceptLicense() const; + /** \overload taking a (product)name */ + bool needToAcceptLicense( const std::string & name_r ) const; + + /** Return the best license for the current (or a specified) locale. */ + std::string getLicense( const zypp::Locale & lang_r = zypp::Locale() ) const; + /** \overload taking a (product)name */ + std::string getLicense( const std::string & name_r, const zypp::Locale & lang_r = zypp::Locale() ) const; + + /** Return the locales the license is available for. + * \ref Locale::noCode is included in case of \c license.txt which does + * not specify a specific locale. + */ + zypp::LocaleSet getLicenseLocales() const; + + /** \overload taking a (product)name */ + zypp::LocaleSet getLicenseLocales( const std::string & name_r ) const; + //@} + + /** + * Returns true if this repository requires the media.1/media file to be included + * in the metadata status and repo status calculations. + */ + bool requireStatusWithMediaFile () const; + + public: + /** + * Write a human-readable representation of this RepoInfo object + * into the \a str stream. Useful for logging. + */ + std::ostream & dumpOn( std::ostream & str ) const override; + + /** + * Write this RepoInfo object into \a str in a .repo file format. + * Raw values, no variable replacement. + */ + std::ostream & dumpAsIniOn( std::ostream & str ) const override; + + /** + * Write an XML representation of this RepoInfo object. + * Repo variables replaced. + * + * \param str + * \param content this argument is ignored (used in other classed derived + * from RepoInfoBase. + */ + std::ostream & dumpAsXmlOn( std::ostream & str, const std::string & content = "" ) const override; + + /** Raw values for RepoManager + * \internal + */ + void getRawGpgChecks( zypp::TriBool & g_r, zypp::TriBool & r_r, zypp::TriBool & p_r ) const; + + struct Impl; + private: + template friend class zyppng::RepoManager; + + // for RepoManager to be able to set the context + void setContext( zyppng::ContextBaseRef context ); + + RepoInfoSharedData *pimpl(); + const RepoInfoSharedData *pimpl() const; + }; + + /** \relates RepoInfo */ + using RepoInfoList = std::list; + + /** \relates RepoInfoBase */ + inline bool operator==( const RepoInfo & lhs, const RepoInfo & rhs ) + { return lhs.alias() == rhs.alias(); } + + /** \relates RepoInfoBase */ + inline bool operator!=( const RepoInfo & lhs, const RepoInfo & rhs ) + { return lhs.alias() != rhs.alias(); } + + inline bool operator<( const RepoInfo & lhs, const RepoInfo & rhs ) + { return lhs.alias() < rhs.alias(); } + + /** \relates RepoInfo Stream output */ + std::ostream & operator<<( std::ostream & str, const RepoInfo & obj ) ZYPP_API; + + ///////////////////////////////////////////////////////////////// +} // namespace zypp +/////////////////////////////////////////////////////////////////// +#endif // ZYPP_NG_REPOINFO_INCLUDED diff --git a/zypp/ng/repoinfoshareddata.h b/zypp/ng/repoinfoshareddata.h new file mode 100644 index 0000000000..d728e871b7 --- /dev/null +++ b/zypp/ng/repoinfoshareddata.h @@ -0,0 +1,147 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ + +#ifndef ZYPP_NG_REPOINFOSHAREDDATA_INCLUDED +#define ZYPP_NG_REPOINFOSHAREDDATA_INCLUDED + +#include +#include +#include +#include +#include + + +namespace zyppng { + + /** RepoInfo implementation. */ + struct RepoInfoSharedData : public repo::RepoInfoBaseSharedData + { + RepoInfoSharedData( zyppng::ContextBaseRef &&context ); + RepoInfoSharedData(RepoInfoSharedData &&) = delete; + RepoInfoSharedData &operator=(const RepoInfoSharedData &) = delete; + RepoInfoSharedData &operator=(RepoInfoSharedData &&) = delete; + ~RepoInfoSharedData() override {} + + public: + static const unsigned defaultPriority = 99; + static const unsigned noPriority = unsigned(-1); + + void setType(const zypp::repo::RepoType &t); + + void setProbedType(const zypp::repo::RepoType &t) const; + + zypp::repo::RepoType type() const; + + public: + zypp::Pathname licenseTgz(const std::string &name_r) const; + + const RepoVariablesReplacedUrlList &baseUrls() const; + + RepoVariablesReplacedUrlList &baseUrls(); + + bool baseurl2dump() const; + + const RepoVariablesReplacedUrlList &gpgKeyUrls() const; + + RepoVariablesReplacedUrlList &gpgKeyUrls(); + + const std::set &contentKeywords() const; + + void addContent(const std::string &keyword_r); + + bool hasContent() const; + + bool hasContent(const std::string &keyword_r) const; + + /** Signature check result needs to be stored/retrieved from _metadataPath. + * Don't call them from outside validRepoSignature/setValidRepoSignature + */ + zypp::TriBool internalValidRepoSignature() const; + + void internalSetValidRepoSignature( zypp::TriBool value_r); + + /** We definitely have a symlink pointing to "zypp::indeterminate" (for repoGpgCheckIsMandatory)? + * I.e. user accepted the unsigned repo in Downloader. A test whether `internalValidRepoSignature` + * is zypp::indeterminate would include not yet checked repos, which is unwanted here. + */ + bool internalUnsignedConfirmed() const; + + bool triBoolFromPath(const zypp::Pathname &path_r, zypp::TriBool &ret_r) const; + + zypp::TriBool triBoolFromPath(const zypp::Pathname &path_r) const; + + zypp::TriBool rawGpgCheck() const { return _rawGpgCheck; } + zypp::TriBool rawRepoGpgCheck() const { return _rawRepoGpgCheck; } + zypp::TriBool rawPkgGpgCheck() const { return _rawPkgGpgCheck; } + + void rawGpgCheck( zypp::TriBool val_r ) { _rawGpgCheck = val_r; } + void rawRepoGpgCheck( zypp::TriBool val_r ) { _rawRepoGpgCheck = val_r; } + void rawPkgGpgCheck( zypp::TriBool val_r ) { _rawPkgGpgCheck = val_r; } + + bool cfgGpgCheck() const; + + zypp::TriBool cfgRepoGpgCheck() const; + + zypp::TriBool cfgPkgGpgCheck() const; + + void solvPath(zypp::Pathname new_r); + + void metadataPath(zypp::Pathname new_r); + + void packagesPath(zypp::Pathname new_r); + + bool usesAutoMetadataPaths() const; + + zypp::Pathname solvPath() const; + + zypp::Pathname metadataPath() const; + + zypp::Pathname packagesPath() const; + + zypp::DefaultIntegral priority; + + protected: + void bindVariables() override; + + private: + zypp::TriBool _rawGpgCheck; ///< default gpgcheck behavior: Y/N/ZConf + zypp::TriBool _rawRepoGpgCheck; ///< need to check repo sign.: Y/N/(ZConf(Y/N/gpgCheck)) + zypp::TriBool _rawPkgGpgCheck; ///< need to check pkg sign.: Y/N/(ZConf(Y/N/gpgCheck)) + zypp::TriBool _validRepoSignature; ///< have signed and valid repo metadata + zypp::repo::RepoType _type; + + public: + zypp::TriBool keeppackages; + RepoVariablesReplacedUrl _mirrorListUrl; + bool _mirrorListForceMetalink; + zypp::Pathname path; + std::string service; + std::string targetDistro; + mutable bool emptybaseurls; + + private: + zypp::Pathname _slvPath; + zypp::Pathname _metadataPath; + zypp::Pathname _packagesPath; + + mutable RepoVariablesReplacedUrlList _baseUrls; + mutable std::pair > _keywords; + + RepoVariablesReplacedUrlList _gpgKeyUrls; + + // support copying only for clone + RepoInfoSharedData(const RepoInfoSharedData &) = default; + + friend RepoInfoSharedData * zypp::rwcowClone( const RepoInfoSharedData * rhs ); + /** clone for RWCOW_pointer */ + RepoInfoSharedData *clone() const override; + }; +} + +#endif diff --git a/zypp/ng/repomanager.cc b/zypp/ng/repomanager.cc index 20056db366..6b4dba6124 100644 --- a/zypp/ng/repomanager.cc +++ b/zypp/ng/repomanager.cc @@ -23,12 +23,12 @@ #include #include #include -#include -#include +#include +#include #include #include #include -#include +#include #include #include @@ -166,12 +166,12 @@ namespace zyppng return true; } - expected> repositories_in_file(const zypp::Pathname &file) + expected> repositories_in_file( ContextBaseRef ctx, const zypp::Pathname &file) { try { MIL << "repo file: " << file << std::endl; RepoCollector collector; - zypp::parser::RepoFileReader parser( file, std::bind( &RepoCollector::collect, &collector, std::placeholders::_1 ) ); + zyppng::parser::RepoFileReader parser( ctx, file, std::bind( &RepoCollector::collect, &collector, std::placeholders::_1 ) ); return expected>::success( std::move(collector.repos) ); } catch ( ... ) { return expected>::error( ZYPP_FWD_CURRENT_EXCPT() ); @@ -217,7 +217,7 @@ namespace zyppng } else { - const std::list tmp( repositories_in_file( *it ).unwrap() ); + const std::list tmp( repositories_in_file( zyppContext, *it ).unwrap() ); repos.insert( repos.end(), tmp.begin(), tmp.end() ); } } @@ -265,14 +265,14 @@ namespace zyppng cmd.push_back( "PROGRAM" ); // [2] - fix index below if changing! for ( const auto & rinfo : repos() ) { - if ( ! rinfo.enabled() ) + if ( ! rinfo.second.enabled() ) continue; cmd.push_back( "-R" ); - cmd.push_back( rinfo.alias() ); + cmd.push_back( rinfo.second.alias() ); cmd.push_back( "-t" ); - cmd.push_back( rinfo.type().asString() ); + cmd.push_back( rinfo.second.type().asString() ); cmd.push_back( "-p" ); - cmd.push_back( (rinfo.metadataPath()/rinfo.path()).asString() ); // bsc#1197684: path to the repodata/ directory inside the cache + cmd.push_back( (rinfo.second.metadataPath()/rinfo.second.path()).asString() ); // bsc#1197684: path to the repodata/ directory inside the cache } for_( it, entries.begin(), entries.end() ) @@ -478,7 +478,7 @@ namespace zyppng // if it does not belong known repo, make it disappear bool found = false; for_( r, repoBegin(), repoEnd() ) - if ( subdir.basename() == r->escaped_alias() ) + if ( subdir.basename() == r->second.escaped_alias() ) { found = true; break; } if ( ! found && ( zypp::Date::now()-zypp::PathInfo(subdir).mtime() > zypp::Date::day ) ) @@ -600,10 +600,10 @@ namespace zyppng tosave.setFilepath(repofile); tosave.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ).unwrap() ); tosave.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ).unwrap() ); - reposManip().insert(tosave); + reposManip().insert( std::make_pair( tosave.alias(), tosave) ); // check for credentials in Urls - zypp::UrlCredentialExtractor( _options.rootDir ).collect( tosave.baseUrls() ); + zypp::UrlCredentialExtractor( _zyppContext ).collect( tosave.baseUrls() ); zypp::HistoryLog(_options.rootDir).addRepository(tosave); @@ -631,14 +631,14 @@ namespace zyppng // they can be the same only if the provided is empty, that means // the provided repo has no alias // then skip - if ( (!info.alias().empty()) && ( info.alias() != repo.alias() ) ) + if ( (!info.alias().empty()) && ( info.alias() != repo.first ) ) continue; // TODO match by url // we have a matching repository, now we need to know // where it does come from. - RepoInfo todelete = repo; + RepoInfo todelete = repo.second; if (todelete.filepath().empty()) { ZYPP_THROW(zypp::repo::RepoException( todelete, _("Can't figure out where the repo is stored.") )); @@ -646,7 +646,7 @@ namespace zyppng else { // figure how many repos are there in the file: - std::list filerepos = repositories_in_file(todelete.filepath()).unwrap(); + std::list filerepos = repositories_in_file( _zyppContext, todelete.filepath()).unwrap(); std::for_each( filerepos.begin (), filerepos.end(), [this]( RepoInfo &info ){ prepareRepoInfo(info).unwrap(); }); if ( filerepos.size() == 0 // bsc#984494: file may have already been deleted @@ -692,7 +692,7 @@ namespace zyppng // now delete metadata (#301037) cleanMetadata( todelete, ProgressObserver::makeSubTask( myProgress, 0.4 )).unwrap(); cleanPackages( todelete, ProgressObserver::makeSubTask( myProgress, 0.4 ), true/*isAutoClean*/ ).unwrap(); - reposManip().erase(todelete); + reposManip().erase(todelete.alias()); MIL << todelete.alias() << " successfully deleted." << std::endl; zypp::HistoryLog(_options.rootDir).removeRepository(todelete); @@ -735,7 +735,7 @@ namespace zyppng { ProgressObserver::increase( myProgress ); // figure how many repos are there in the file: - std::list filerepos = repositories_in_file(toedit.filepath()).unwrap(); + std::list filerepos = repositories_in_file( _zyppContext, toedit.filepath()).unwrap(); std::for_each( filerepos.begin (), filerepos.end(), [this]( RepoInfo &info ){ prepareRepoInfo(info).unwrap(); }); // there are more repos in the same file @@ -780,13 +780,13 @@ namespace zyppng ProgressObserver::increase( myProgress ); - reposManip().erase(toedit); - reposManip().insert(newinfo); + reposManip().erase(toedit.alias()); + reposManip().insert(std::make_pair(newinfo.alias(), newinfo)); ProgressObserver::increase( myProgress ); // check for credentials in Urls - zypp::UrlCredentialExtractor( _options.rootDir ).collect( newinfo.baseUrls() ); + zypp::UrlCredentialExtractor( _zyppContext ).collect( newinfo.baseUrls() ); zypp::HistoryLog(_options.rootDir).modifyRepository(toedit, newinfo); MIL << "repo " << alias << " modified" << std::endl; @@ -808,7 +808,7 @@ namespace zyppng try { RepoConstIterator it( findAlias( alias, repos() ) ); if ( it != repos().end() ) - return make_expected_success(*it); + return make_expected_success(it->second); RepoInfo info( _zyppContext ); info.setAlias( alias ); ZYPP_THROW( zypp::repo::RepoNotFoundException(info) ); @@ -825,10 +825,10 @@ namespace zyppng for_( it, repoBegin(), repoEnd() ) { - for_( urlit, (*it).baseUrlsBegin(), (*it).baseUrlsEnd() ) + for_( urlit, it->second.baseUrlsBegin(), it->second.baseUrlsEnd() ) { if ( (*urlit).asString(urlview) == url.asString(urlview) ) - return make_expected_success(*it); + return make_expected_success(it->second); } } RepoInfo info( _zyppContext ); @@ -864,10 +864,10 @@ namespace zyppng // do NOT capture by reference here, since this is possibly executed async const auto &updateProbedType = [this, info = info]( zypp::repo::RepoType repokind ) { // update probed type only for repos in system - for( const auto &repo : repos() ) { - if ( info.alias() == repo.alias() ) + for( const auto &repoIter : repos() ) { + if ( info.alias() == repoIter.first ) { - RepoInfo modifiedrepo = repo; + RepoInfo modifiedrepo = repoIter.second; modifiedrepo.setType( repokind ); // don't modify .repo in refresh. // modifyRepository( info.alias(), modifiedrepo ); m @@ -921,10 +921,10 @@ namespace zyppng // do NOT capture by reference here, since this is possibly executed async const auto &updateProbedType = [this, info = info]( zypp::repo::RepoType repokind ) { // update probed type only for repos in system - for( const auto &repo : repos() ) { - if ( info.alias() == repo.alias() ) + for( const auto &repoIter : repos() ) { + if ( info.alias() == repoIter.first ) { - RepoInfo modifiedrepo = repo; + RepoInfo modifiedrepo = repoIter.second; modifiedrepo.setType( repokind ); // don't modify .repo in refresh. // modifyRepository( info.alias(), modifiedrepo ); @@ -1049,10 +1049,10 @@ namespace zyppng // of the .service file. Finaly insert into the service list. ServiceInfo toSave( service ); saveService( toSave ).unwrap(); - _services.insert( toSave ); + _services.insert( std::make_pair( toSave.alias(), toSave ) ); // check for credentials in Url - zypp::UrlCredentialExtractor( _options.rootDir ).collect( toSave.url() ); + zypp::UrlCredentialExtractor( _zyppContext ).collect( toSave.url() ); MIL << "added service " << toSave.alias() << std::endl; @@ -1066,7 +1066,12 @@ namespace zyppng template expected RepoManager::refreshService( const std::string &alias, const RefreshServiceOptions &options_r ) { - return joinPipeline ( _zyppContext, RepoServicesWorkflow::refreshService( shared_this>(), getService( alias ), options_r ) ); + const auto &serviceOpt = getService(alias); + if( !serviceOpt ) + { + ZYPP_THROW(zypp::repo::ServiceException( _("Can't find service alias.") )); + } + return joinPipeline ( _zyppContext, RepoServicesWorkflow::refreshService( shared_this>(), *serviceOpt, options_r ) ); } /*! @@ -1076,13 +1081,12 @@ namespace zyppng expected RepoManager::refreshServices(const RefreshServiceOptions &options_r) { using namespace zyppng::operators; + // copy the set of services since refreshService // can eventually invalidate the iterator - ServiceSet servicesCopy( serviceBegin(), serviceEnd() ); - - // convert the set into a vector, transform needs a container with push_back support + // save it into a vector, transform needs a container with push_back support std::vector servicesVec; - std::copy( std::make_move_iterator(servicesCopy.begin()), std::make_move_iterator(servicesCopy.end()), std::back_inserter(servicesVec)); + std::transform( serviceBegin(), serviceEnd(), std::back_inserter(servicesVec), []( const auto &pair ){ return pair.second;} ); return joinPipeline( _zyppContext, std::move(servicesVec) @@ -1100,7 +1104,13 @@ namespace zyppng try { MIL << "Going to delete service " << alias << std::endl; - const ServiceInfo & service = getService( alias ); + const auto &serviceOpt = getService(alias); + if( !serviceOpt ) + { + ZYPP_THROW(zypp::repo::ServiceException( _("Can't find service alias.") )); + } + + const ServiceInfo & service = *serviceOpt; zypp::Pathname location = service.filepath(); if( location.empty() ) @@ -1108,11 +1118,11 @@ namespace zyppng ZYPP_THROW(zypp::repo::ServiceException( service, _("Can't figure out where the service is stored.") )); } - ServiceSet tmpSet; - zypp::parser::ServiceFileReader( location, ServiceCollector(tmpSet) ); + ServiceMap tmpMap; + parser::ServiceFileReader( _zyppContext, location, ServiceCollector(tmpMap) ); // only one service definition in the file - if ( tmpSet.size() == 1 ) + if ( tmpMap.size() == 1 ) { if ( zypp::filesystem::unlink(location) != 0 ) { @@ -1132,10 +1142,10 @@ namespace zyppng ZYPP_THROW( zypp::Exception(zypp::str::form( _("Can't open file '%s' for writing."), location.c_str() ))); } - for_(it, tmpSet.begin(), tmpSet.end()) + for_(it, tmpMap.begin(), tmpMap.end()) { - if( it->alias() != alias ) - it->dumpAsIniOn(file); + if( it->first != alias ) + it->second.dumpAsIniOn(file); } MIL << alias << " successfully deleted from file " << location << std::endl; @@ -1157,22 +1167,23 @@ namespace zyppng } template - expected RepoManager::modifyService( const std::string & oldAlias, const ServiceInfo & newService ) + expected RepoManager::modifyService( const std::string & oldAlias, ServiceInfo newService ) { try { MIL << "Going to modify service " << oldAlias << std::endl; + if ( newService.type() == zypp::repo::ServiceType::PLUGIN ) + { + ZYPP_THROW(zypp::repo::ServicePluginImmutableException( newService )); + } - // we need a writable copy to link it to the file where - // it is saved if we modify it - ServiceInfo service(newService); - - if ( service.type() == zypp::repo::ServiceType::PLUGIN ) + const auto &oldServiceOpt = getService(oldAlias); + if( !oldServiceOpt ) { - ZYPP_THROW(zypp::repo::ServicePluginImmutableException( service )); + ZYPP_THROW(zypp::repo::ServiceException( _("Can't find service alias.") )); } - const ServiceInfo & oldService = getService(oldAlias); + const ServiceInfo &oldService = *oldServiceOpt; zypp::Pathname location = oldService.filepath(); if( location.empty() ) @@ -1181,49 +1192,49 @@ namespace zyppng } // remember: there may multiple services being defined in one file: - ServiceSet tmpSet; - zypp::parser::ServiceFileReader( location, ServiceCollector(tmpSet) ); + ServiceMap tmpMap; + parser::ServiceFileReader( _zyppContext, location, ServiceCollector(tmpMap) ); zypp::filesystem::assert_dir(location.dirname()); std::ofstream file(location.c_str()); - for_(it, tmpSet.begin(), tmpSet.end()) + for_(it, tmpMap.begin(), tmpMap.end()) { - if( *it != oldAlias ) - it->dumpAsIniOn(file); + if( it->first != oldAlias ) + it->second.dumpAsIniOn(file); } - service.dumpAsIniOn(file); + newService.dumpAsIniOn(file); file.close(); - service.setFilepath(location); + newService.setFilepath(location); - _services.erase(oldAlias); - _services.insert(service); + _services.erase ( oldAlias ); + _services.insert ( std::make_pair( newService.alias(), newService) ); // check for credentials in Urls - zypp::UrlCredentialExtractor( _options.rootDir ).collect( service.url() ); + zypp::UrlCredentialExtractor( _zyppContext ).collect( newService.url() ); // changed properties affecting also repositories - if ( oldAlias != service.alias() // changed alias - || oldService.enabled() != service.enabled() ) // changed enabled status + if ( oldAlias != newService.alias() // changed alias + || oldService.enabled() != newService.enabled() ) // changed enabled status { std::vector toModify; getRepositoriesInService(oldAlias, std::back_inserter(toModify)); for_( it, toModify.begin(), toModify.end() ) { - if ( oldService.enabled() != service.enabled() ) + if ( oldService.enabled() != newService.enabled() ) { - if ( service.enabled() ) + if ( newService.enabled() ) { // reset to last refreshs state - const auto & last = service.repoStates().find( it->alias() ); - if ( last != service.repoStates().end() ) + const auto & last = newService.repoStates().find( it->alias() ); + if ( last != newService.repoStates().end() ) it->setEnabled( last->second.enabled ); } else it->setEnabled( false ); } - if ( oldAlias != service.alias() ) - it->setService(service.alias()); + if ( oldAlias != newService.alias() ) + it->setService(newService.alias()); modifyRepository(it->alias(), *it).unwrap(); } @@ -1367,11 +1378,11 @@ namespace zyppng //str::regex allowedServiceExt("^\\.service(_[0-9]+)?$"); for_(it, entries.begin(), entries.end() ) { - zypp::parser::ServiceFileReader(*it, ServiceCollector(_services)); + parser::ServiceFileReader( _zyppContext, *it, ServiceCollector(_services)); } } - zypp::repo::PluginServices(_options.pluginsPath/"services", ServiceCollector(_services)); + repo::PluginServices( _zyppContext, _options.pluginsPath/"services", ServiceCollector(_services) ); return expected::success(); @@ -1442,7 +1453,7 @@ namespace zyppng // initialize the paths' prepareRepoInfo(repoInfo).unwrap(); // remember it - _reposX.insert( repoInfo ); // direct access via _reposX in ctor! no reposManip. + _reposX.insert( std::make_pair( repoInfo.alias(), repoInfo ) ); // direct access via _reposX in ctor! no reposManip. // detect orphaned repos belonging to a deleted service const std::string & serviceAlias( repoInfo.service() ); diff --git a/zypp/ng/repomanager.h b/zypp/ng/repomanager.h index 5bd8ed9a89..29399a91a3 100644 --- a/zypp/ng/repomanager.h +++ b/zypp/ng/repomanager.h @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include @@ -34,11 +36,7 @@ #include namespace zyppng { - - using RepoInfo = zypp::RepoInfo; using RepoStatus = zypp::RepoStatus; - using RepoInfoList = zypp::RepoInfoList; - using ServiceInfo = zypp::ServiceInfo; using RepoManagerOptions = zypp::RepoManagerOptions; ZYPP_FWD_DECL_TYPE_WITH_REFS( ProgressObserver ); @@ -79,15 +77,41 @@ namespace zyppng { return expected::success(); } + namespace detail { + template + struct AliasCompare { + AliasCompare( const std::string &alias, const Info &iterValue ) : _res( alias == iterValue.alias() ) {} + operator bool() { + return _res; + } + private: + bool _res; + }; + + template + struct AliasCompare> { + AliasCompare( const std::string &alias, const std::pair &iterValue ) : _res(alias == iterValue.first) { + } + operator bool() { + return _res; + } + private: + bool _res; + }; + } + /** Check if alias_r is present in repo/service container. */ template inline bool foundAliasIn( const std::string & alias_r, Iterator begin_r, Iterator end_r ) { - for_( it, begin_r, end_r ) - if ( it->alias() == alias_r ) - return true; + for_( it, begin_r, end_r ) { + if ( detail::AliasCompare( alias_r, *it ) ) { + return true; + } + } return false; } + /** \overload */ template inline bool foundAliasIn( const std::string & alias_r, const Container & cont_r ) @@ -97,9 +121,11 @@ namespace zyppng { template inline Iterator findAlias( const std::string & alias_r, Iterator begin_r, Iterator end_r ) { - for_( it, begin_r, end_r ) - if ( it->alias() == alias_r ) - return it; + for_( it, begin_r, end_r ) { + if ( detail::AliasCompare( alias_r, *it ) ) { + return it; + } + } return end_r; } /** \overload */ @@ -155,7 +181,7 @@ namespace zyppng { * * \param file pathname of the file to read. */ - expected> repositories_in_file( const zypp::Pathname & file ); + expected> repositories_in_file( ContextBaseRef ctx, const zypp::Pathname & file ); //////////////////////////////////////////////////////////////////////////// @@ -219,20 +245,20 @@ namespace zyppng { class ServiceCollector { public: - using ServiceSet = std::set; + using ServiceMap = std::map; - ServiceCollector( ServiceSet & services_r ) + ServiceCollector( ServiceMap & services_r ) : _services( services_r ) {} bool operator()( const ServiceInfo & service_r ) const { - _services.insert( service_r ); + _services.insert( std::make_pair(service_r.alias(), service_r) ); return true; } private: - ServiceSet & _services; + ServiceMap & _services; }; //////////////////////////////////////////////////////////////////////////// @@ -278,32 +304,18 @@ namespace zyppng { } public: - - /** - * Functor thats filter RepoInfo by service which it belongs to. - */ - struct MatchServiceAlias - { - public: - MatchServiceAlias( std::string alias_ ) : alias(std::move(alias_)) {} - bool operator()( const RepoInfo & info ) const - { return info.service() == alias; } - private: - std::string alias; - }; - /** ServiceInfo typedefs */ - using ServiceSet = std::set; - using ServiceConstIterator = ServiceSet::const_iterator; - using ServiceSizeType = ServiceSet::size_type; + using ServiceMap = std::map; + using ServiceConstIterator = ServiceMap::const_iterator; + using ServiceSizeType = ServiceMap::size_type; /** RepoInfo typedefs */ - using RepoSet = std::set; - using RepoConstIterator = RepoSet::const_iterator; - using RepoSizeType = RepoSet::size_type; + using RepoMap = std::map; + using RepoConstIterator = RepoMap::const_iterator; + using RepoSizeType = RepoMap::size_type; - virtual ~RepoManager(); + ~RepoManager() override; public: @@ -365,10 +377,10 @@ namespace zyppng { bool hasRepo( const std::string & alias ) const { return foundAliasIn( alias, repos() ); } - RepoInfo getRepo( const std::string & alias ) const + std::optional getRepo( const std::string & alias ) const { RepoConstIterator it( findAlias( alias, repos() ) ); - return it == repos().end() ? RepoInfo::noRepo : *it; + return it == repos().end() ? std::optional() : it->second; } public: @@ -464,10 +476,10 @@ namespace zyppng { bool hasService( const std::string & alias ) const { return foundAliasIn( alias, _services ); } - ServiceInfo getService( const std::string & alias ) const + std::optional getService( const std::string & alias ) const { ServiceConstIterator it( findAlias( alias, _services ) ); - return it == _services.end() ? ServiceInfo::noService : *it; + return it == _services.end() ? std::optional() : it->second; } public: @@ -476,7 +488,7 @@ namespace zyppng { expected addService( const ServiceInfo & service ); expected addService( const std::string & alias, const zypp::Url & url ) - { return addService( ServiceInfo( alias, url ) ); } + { return addService( ServiceInfo( _zyppContext, alias, url ) ); } expected removeService( const std::string & alias ); expected removeService( const ServiceInfo & service ) @@ -488,7 +500,7 @@ namespace zyppng { expected refreshServices( const RefreshServiceOptions & options_r ); - expected modifyService( const std::string & oldAlias, const ServiceInfo & newService ); + expected modifyService( const std::string & oldAlias, ServiceInfo newService ); static expected touchIndexFile( const RepoInfo & info, const RepoManagerOptions &options ); @@ -516,10 +528,14 @@ namespace zyppng { template void getRepositoriesInService( const std::string & alias, OutputIterator out ) const { - MatchServiceAlias filter( alias ); - std::copy( boost::make_filter_iterator( filter, repos().begin(), repos().end() ), - boost::make_filter_iterator( filter, repos().end(), repos().end() ), - out); + const auto &filter = [&]( const std::pair &elem ){ + return elem.second.service() == alias; + }; + + std::transform( boost::make_filter_iterator( filter, repos().begin(), repos().end() ) + , boost::make_filter_iterator( filter, repos().end(), repos().end() ) + , out + , []( const std::pair &elem ){ return elem.second; } ); } zypp::Pathname generateNonExistingName( const zypp::Pathname & dir, const std::string & basefilename ) const; @@ -540,14 +556,17 @@ namespace zyppng { expected init_knownRepositories(); public: - const RepoSet & repos() const { return _reposX; } - RepoSet & reposManip() { if ( ! _reposDirty ) _reposDirty = true; return _reposX; } + const RepoMap & repos() const { return _reposX; } + RepoMap & reposManip() { if ( ! _reposDirty ) _reposDirty = true; return _reposX; } + + const ServiceMap & services() const { return _services; } + ServiceMap & servicesManip() { return _services; } protected: ContextRefType _zyppContext; RepoManagerOptions _options; - RepoSet _reposX; - ServiceSet _services; + RepoMap _reposX; + ServiceMap _services; zypp_private::repo::PluginRepoverification _pluginRepoverification; zypp::DefaultIntegral _reposDirty; }; diff --git a/zypp/ng/reporthelper.cc b/zypp/ng/reporthelper.cc index 147892eed5..8b32218c27 100644 --- a/zypp/ng/reporthelper.cc +++ b/zypp/ng/reporthelper.cc @@ -12,6 +12,7 @@ #include #include #include +#include namespace zyppng { @@ -72,7 +73,7 @@ namespace zyppng { label = zypp::str::Format( // TranslatorExplanation: speaking of a file _("File '%s' from repository '%s' is unsigned, continue?")) - % file % keycontext.repoInfo().asUserString(); + % file % keycontext.ngRepoInfo()->asUserString(); auto req = BooleanChoiceRequest::create ( label, false, AcceptUnsignedFileRequest::makeData ( file, keycontext ) ); @@ -126,9 +127,12 @@ namespace zyppng { void KeyRingReportHelper::reportAutoImportKey(const std::list &keyDataList_r, const zypp::PublicKeyData &keySigning_r, const zypp::KeyContext &keyContext_r) { if constexpr ( async() ) { + + const auto &repoInfoOpt = keyContext_r.ngRepoInfo(); + const std::string &lbl = zypp::str::Format( PL_( "Received %1% new package signing key from repository \"%2%\":", "Received %1% new package signing keys from repository \"%2%\":", - keyDataList_r.size() )) % keyDataList_r.size() % keyContext_r.repoInfo().asUserString(); + keyDataList_r.size() )) % keyDataList_r.size() % ( repoInfoOpt ? repoInfoOpt->asUserString() : std::string("norepo") ); this->_ctx->sendUserRequest( ShowMessageRequest::create( lbl, ShowMessageRequest::MType::Info, KeyAutoImportInfoEvent::makeData( keyDataList_r, keySigning_r, keyContext_r) ) ); } else { return _report->reportAutoImportKey( keyDataList_r, keySigning_r, keyContext_r ); @@ -145,7 +149,7 @@ namespace zyppng { label = zypp::str::Format(_("Signature verification failed for file '%1%'.") ) % file; else // translator: %1% is a file name, %2% a repositories na me - label = zypp::str::Format(_("Signature verification failed for file '%1%' from repository '%2%'.") ) % file % keycontext.repoInfo().asUserString(); + label = zypp::str::Format(_("Signature verification failed for file '%1%' from repository '%2%'.") ) % file % keycontext.ngRepoInfo()->asUserString(); // @TODO use a centralized Continue string! label += std::string(" ") + _("Continue?"); @@ -171,7 +175,7 @@ namespace zyppng { label = zypp::str::Format( // translators: the last %s is gpg key ID _("File '%s' from repository '%s' is signed with an unknown key '%s'. Continue?")) - % file % keycontext.repoInfo().asUserString() % id; + % file % keycontext.ngRepoInfo()->asUserString() % id; auto req = BooleanChoiceRequest::create ( label, false, AcceptUnknownKeyRequest::makeData ( file, id, keycontext ) ); this->_ctx->sendUserRequest ( req ); diff --git a/zypp/ng/serviceinfo.cc b/zypp/ng/serviceinfo.cc new file mode 100644 index 0000000000..9fdecbbe81 --- /dev/null +++ b/zypp/ng/serviceinfo.cc @@ -0,0 +1,221 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/ServiceInfo.cc + * + */ +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +using std::endl; +using zypp::xml::escape; + +namespace zyppng +{ + + ServiceInfoSharedData::ServiceInfoSharedData( ContextBaseRef &&context ) : repo::RepoInfoBaseSharedData( std::move(context) ) + { ServiceInfoSharedData::bindVariables(); } + + ServiceInfoSharedData::ServiceInfoSharedData( ContextBaseRef &&context, const std::string &alias ) + : repo::RepoInfoBaseSharedData( std::move(context), alias ) + { ServiceInfoSharedData::bindVariables(); } + + ServiceInfoSharedData::ServiceInfoSharedData( ContextBaseRef &&context, const std::string &alias, const zypp::Url &url_r ) + : repo::RepoInfoBaseSharedData( std::move(context), alias ) + , _url(url_r) + { ServiceInfoSharedData::bindVariables(); } + + void ServiceInfoSharedData::bindVariables() + { + repo::RepoInfoBaseSharedData::bindVariables(); + if ( _ctx ) { + _url.setTransformator( repo::RepoVariablesUrlReplacer( zypp::repo::RepoVarRetriever( *_ctx.get() ) ) ); + } else { + _url.setTransformator( repo::RepoVariablesUrlReplacer( nullptr ) ); + } + } + + ServiceInfoSharedData *ServiceInfoSharedData::clone() const + { + auto *n = new ServiceInfoSharedData(*this); + n->bindVariables (); + return n; + } + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : ServiceInfo::Impl + // + ////////////////////////////////////////////////////////////////// + + ServiceInfo::ServiceInfo( zyppng::ContextBaseRef ctx ) : repo::RepoInfoBase( ( *new ServiceInfoSharedData( std::move(ctx) )) ) {} + + ServiceInfo::ServiceInfo( zyppng::ContextBaseRef ctx, const std::string & alias ) + : repo::RepoInfoBase( ( *new ServiceInfoSharedData( std::move(ctx), alias )) ) + {} + + ServiceInfo::ServiceInfo( zyppng::ContextBaseRef ctx, const std::string & alias, const zypp::Url & url ) + : repo::RepoInfoBase( ( *new ServiceInfoSharedData( std::move(ctx), alias, url )) ) + {} + + ServiceInfo::~ServiceInfo() + {} + + zypp::Url ServiceInfo::url() const // Variables replaced + { return pimpl()->_url.transformed(); } + + zypp::Url ServiceInfo::rawUrl() const // Raw + { return pimpl()->_url.raw(); } + + void ServiceInfo::setUrl( const zypp::Url& url ) // Raw + { pimpl()->_url.raw() = url; } + + zypp::repo::ServiceType ServiceInfo::type() const { return pimpl()->_type; } + void ServiceInfo::setType( const zypp::repo::ServiceType & type ) { pimpl()->_type = type; } + void ServiceInfo::setProbedType( const zypp::repo::ServiceType &t ) const { pimpl()->setProbedType( t ); } + + zypp::Date::Duration ServiceInfo::ttl() const { return pimpl()->_ttl; } + void ServiceInfo::setTtl( zypp::Date::Duration ttl_r ) { pimpl()->_ttl = ttl_r; } + void ServiceInfo::setProbedTtl( zypp::Date::Duration ttl_r ) const { const_cast(this)->setTtl( ttl_r ); } + + zypp::Date ServiceInfo::lrf() const { return pimpl()->_lrf; } + void ServiceInfo::setLrf( zypp::Date lrf_r ) { pimpl()->_lrf = lrf_r; } + + bool ServiceInfo::reposToEnableEmpty() const { return pimpl()->_reposToEnable.empty(); } + ServiceInfo::ReposToEnable::size_type ServiceInfo::reposToEnableSize() const { return pimpl()->_reposToEnable.size(); } + ServiceInfo::ReposToEnable::const_iterator ServiceInfo::reposToEnableBegin() const { return pimpl()->_reposToEnable.begin(); } + ServiceInfo::ReposToEnable::const_iterator ServiceInfo::reposToEnableEnd() const { return pimpl()->_reposToEnable.end(); } + + bool ServiceInfo::repoToEnableFind( const std::string & alias_r ) const + { return( pimpl()->_reposToEnable.find( alias_r ) != pimpl()->_reposToEnable.end() ); } + + void ServiceInfo::addRepoToEnable( const std::string & alias_r ) + { + pimpl()->_reposToEnable.insert( alias_r ); + pimpl()->_reposToDisable.erase( alias_r ); + } + + void ServiceInfo::delRepoToEnable( const std::string & alias_r ) + { pimpl()->_reposToEnable.erase( alias_r ); } + + void ServiceInfo::clearReposToEnable() + { pimpl()->_reposToEnable.clear(); } + + + bool ServiceInfo::reposToDisableEmpty() const { return pimpl()->_reposToDisable.empty(); } + ServiceInfo::ReposToDisable::size_type ServiceInfo::reposToDisableSize() const { return pimpl()->_reposToDisable.size(); } + ServiceInfo::ReposToDisable::const_iterator ServiceInfo::reposToDisableBegin() const { return pimpl()->_reposToDisable.begin(); } + ServiceInfo::ReposToDisable::const_iterator ServiceInfo::reposToDisableEnd() const { return pimpl()->_reposToDisable.end(); } + + bool ServiceInfo::repoToDisableFind( const std::string & alias_r ) const + { return( pimpl()->_reposToDisable.find( alias_r ) != pimpl()->_reposToDisable.end() ); } + + void ServiceInfo::addRepoToDisable( const std::string & alias_r ) + { + pimpl()->_reposToDisable.insert( alias_r ); + pimpl()->_reposToEnable.erase( alias_r ); + } + + void ServiceInfo::delRepoToDisable( const std::string & alias_r ) + { pimpl()->_reposToDisable.erase( alias_r ); } + + void ServiceInfo::clearReposToDisable() + { pimpl()->_reposToDisable.clear(); } + + + const ServiceInfo::RepoStates & ServiceInfo::repoStates() const { return pimpl()->_repoStates; } + void ServiceInfo::setRepoStates( RepoStates newStates_r ) { swap( pimpl()->_repoStates, newStates_r ); } + + std::ostream & ServiceInfo::dumpAsIniOn( std::ostream & str ) const + { + RepoInfoBase::dumpAsIniOn(str) + << "url = " << zypp::hotfix1050625::asString( rawUrl() ) << endl + << "type = " << type() << endl; + + if ( ttl() ) + str << "ttl_sec = " << ttl() << endl; + + if ( lrf() ) + str << "lrf_dat = " << lrf().asSeconds() << endl; + + if ( ! repoStates().empty() ) + { + unsigned cnt = 0U; + for ( const auto & el : repoStates() ) + { + std::string tag( "repo_" ); + tag += zypp::str::numstring( ++cnt ); + const RepoState & state( el.second ); + + str << tag << "=" << el.first << endl + << tag << "_enabled=" << state.enabled << endl + << tag << "_autorefresh=" << state.autorefresh << endl; + if ( state.priority != RepoInfo::defaultPriority() ) + str + << tag << "_priority=" << state.priority << endl; + } + } + + if ( ! reposToEnableEmpty() ) + str << "repostoenable = " << zypp::str::joinEscaped( reposToEnableBegin(), reposToEnableEnd() ) << endl; + if ( ! reposToDisableEmpty() ) + str << "repostodisable = " << zypp::str::joinEscaped( reposToDisableBegin(), reposToDisableEnd() ) << endl; + return str; + } + + std::ostream & ServiceInfo::dumpAsXmlOn( std::ostream & str, const std::string & content ) const + { + str + << "" << endl; + else + str << ">" << endl << content << "" << endl; + + return str; + } + + ServiceInfoSharedData *ServiceInfo::pimpl() + { + return static_cast(_pimpl.get()); + } + + const ServiceInfoSharedData *ServiceInfo::pimpl() const + { + return static_cast(_pimpl.get()); + } + + + std::ostream & operator<<( std::ostream& str, const ServiceInfo &obj ) + { + return obj.dumpAsIniOn(str); + } + + +/////////////////////////////////////////////////////////////////////////////// + +} // namespace zyppng +/////////////////////////////////////////////////////////////////////////////// diff --git a/zypp/ng/serviceinfo.h b/zypp/ng/serviceinfo.h new file mode 100644 index 0000000000..cf739dbb74 --- /dev/null +++ b/zypp/ng/serviceinfo.h @@ -0,0 +1,230 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/ng/ServiceInfo.h + * + */ +#ifndef ZYPP_NG_SERVICE_INFO_H_INCLUDED +#define ZYPP_NG_SERVICE_INFO_H_INCLUDED + +#include +#include + +#include + +#include +#include +#include + + +#include +#include + +/////////////////////////////////////////////////////////////////// +namespace zyppng +{ ///////////////////////////////////////////////////////////////// + + struct ServiceInfoSharedData; + + /////////////////////////////////////////////////////////////////// + /// \class ServiceInfo + /// \brief Service data + /// + /// \note Name and Url are subject to repo variable replacement + /// (\see \ref RepoVariablesStringReplacer). + /// + class ServiceInfo : public repo::RepoInfoBase + { + public: + /** + * Default ctor creates \ref noService. + * \internal + */ + ServiceInfo( zyppng::ContextBaseRef contextRef ); + + /** + * Creates ServiceInfo with specified alias. + * + * \param alias unique short name of service + * \internal + */ + ServiceInfo( zyppng::ContextBaseRef contextRef, const std::string & alias ); + + /** + * ServiceInfo with alias and its URL + * + * \param alias unique shortname of service + * \param url url to service + * \internal + */ + ServiceInfo( zyppng::ContextBaseRef contextRef, const std::string & alias, const zypp::Url& url ); + + ServiceInfo(const ServiceInfo &) = default; + ServiceInfo(ServiceInfo &&) = default; + ServiceInfo &operator=(const ServiceInfo &) = default; + ServiceInfo &operator=(ServiceInfo &&) = default; + + ~ServiceInfo() override; + + /** The service url */ + zypp::Url url() const; + + /** The service raw url (no variables replaced) */ + zypp::Url rawUrl() const; + + /** Set the service url (raw value) */ + void setUrl( const zypp::Url& url ); + + + /** Service type */ + zypp::repo::ServiceType type() const; + + /** Set service type */ + void setType( const zypp::repo::ServiceType & type ); + + /** Lazy init service type */ + void setProbedType( const zypp::repo::ServiceType & t ) const; + + /** \name Housekeeping data + * You don't want to use the setters unless you are a \ref RepoManager. + */ + //@{ + /** Sugested TTL between two metadata auto-refreshs. + * The value (in seconds) may be provided in repoindex.xml:xpath:/repoindex@ttl. + * Default is \a 0 - perform each auto-refresh request. + */ + zypp::Date::Duration ttl() const; + + /** Set sugested TTL. */ + void setTtl( zypp::Date::Duration ttl_r ); + + /** Lazy init sugested TTL. */ + void setProbedTtl( zypp::Date::Duration ttl_r ) const; + + /** Date of last refresh (if known). */ + zypp::Date lrf() const; + + /** Set date of last refresh. */ + void setLrf( zypp::Date lrf_r ); + //@} + // + /** \name Set of repos (repository aliases) to enable on next refresh. + * + * Per default new repositories are created in disabled state. But repositories + * mentioned here will be created in enabled state on the next refresh. + * Afterwards they get removed from the list. + */ + //@{ + /** Container of repos. */ + using ReposToEnable = std::set; + bool reposToEnableEmpty() const; + ReposToEnable::size_type reposToEnableSize() const; + ReposToEnable::const_iterator reposToEnableBegin() const; + ReposToEnable::const_iterator reposToEnableEnd() const; + zypp::Iterable reposToEnable() const + { return zypp::makeIterable( reposToEnableBegin(), reposToEnableEnd() ); } + + /** Whether \c alias_r is mentioned in ReposToEnable. */ + bool repoToEnableFind( const std::string & alias_r ) const; + + /** Add \c alias_r to the set of ReposToEnable. */ + void addRepoToEnable( const std::string & alias_r ); + /** Remove \c alias_r from the set of ReposToEnable. */ + void delRepoToEnable( const std::string & alias_r ); + /** Clear the set of ReposToEnable. */ + void clearReposToEnable(); + //@} + + /** \name Set of repos (repository aliases) to disable on next refresh. + * + * Repositories mentioned here will be disabled on the next refresh, in case they + * still exist. Afterwards they get removed from the list. + */ + //@{ + /** Container of repos. */ + using ReposToDisable = std::set; + bool reposToDisableEmpty() const; + ReposToDisable::size_type reposToDisableSize() const; + ReposToDisable::const_iterator reposToDisableBegin() const; + ReposToDisable::const_iterator reposToDisableEnd() const; + zypp::Iterable reposToDisable() const + { return zypp::makeIterable( reposToDisableBegin(), reposToDisableEnd() ); } + + /** Whether \c alias_r is mentioned in ReposToDisable. */ + bool repoToDisableFind( const std::string & alias_r ) const; + + /** Add \c alias_r to the set of ReposToDisable. */ + void addRepoToDisable( const std::string & alias_r ); + /** Remove \c alias_r from the set of ReposToDisable. */ + void delRepoToDisable( const std::string & alias_r ); + /** Clear the set of ReposToDisable. */ + void clearReposToDisable(); + //@} + + /** \name The original repo state as defined by the repoindex.xml upon last refresh. + * + * This state is remembered to detect any user modifications applied to the repos. + * It may not be available for all repos or in plugin services. In this case all + * changes requested by a service refresh are applied unconditionally. + */ + //@{ + using RepoState = zypp::ServiceRepoState; + using RepoStates = std::map; + + /** Access the remembered repository states. */ + const RepoStates & repoStates() const; + + /** Remember a new set of repository states. */ + void setRepoStates( RepoStates newStates_r ); + //@} + + public: + /** + * Writes ServiceInfo to stream in ".service" format + * + * \param str stream where serialized version service is written + */ + std::ostream & dumpAsIniOn( std::ostream & str ) const override; + + /** + * Write an XML representation of this ServiceInfo object. + * + * \param str + * \param content if not empty, produces content + * otherwise + */ + std::ostream & dumpAsXmlOn( std::ostream & str, const std::string & content = "" ) const override; + + private: + ServiceInfoSharedData *pimpl(); + const ServiceInfoSharedData *pimpl() const; + }; + /////////////////////////////////////////////////////////////////// + /// + /** \relates ServiceInfo */ + using ServiceInfoList = std::list; + + /** \relates RepoInfoBase */ + inline bool operator==( const ServiceInfo & lhs, const ServiceInfo & rhs ) + { return lhs.alias() == rhs.alias(); } + + /** \relates RepoInfoBase */ + inline bool operator!=( const ServiceInfo & lhs, const ServiceInfo & rhs ) + { return lhs.alias() != rhs.alias(); } + + inline bool operator<( const ServiceInfo & lhs, const ServiceInfo & rhs ) + { return lhs.alias() < rhs.alias(); } + + /** \relates ServiceInfo Stream output */ + std::ostream & operator<<( std::ostream & str, const ServiceInfo & obj ); + + + ///////////////////////////////////////////////////////////////// +} // namespace zypp +/////////////////////////////////////////////////////////////////// +#endif // ZYPP_NG_SERVICE_INFO_H_INCLUDED diff --git a/zypp/ng/serviceinfoshareddata.h b/zypp/ng/serviceinfoshareddata.h new file mode 100644 index 0000000000..105e048a38 --- /dev/null +++ b/zypp/ng/serviceinfoshareddata.h @@ -0,0 +1,72 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/ng/ServiceInfo.h + * + */ +#ifndef ZYPP_NG_SERVICE_INFO_SHARED_DATA_H_INCLUDED +#define ZYPP_NG_SERVICE_INFO_SHARED_DATA_H_INCLUDED + +#include +#include +#include + +namespace zyppng +{ + + struct ServiceInfoSharedData : public repo::RepoInfoBaseSharedData + { + using ReposToEnable = ServiceInfo::ReposToEnable; + using ReposToDisable = ServiceInfo::ReposToDisable; + + public: + RepoVariablesReplacedUrl _url; + zypp::repo::ServiceType _type; + ReposToEnable _reposToEnable; + ReposToDisable _reposToDisable; + ServiceInfo::RepoStates _repoStates; + zypp::DefaultIntegral _ttl; + zypp::Date _lrf; + + public: + ServiceInfoSharedData( ContextBaseRef &&context ); + ServiceInfoSharedData( ContextBaseRef &&context, const std::string &alias ); + ServiceInfoSharedData( ContextBaseRef &&context, const std::string &alias, const zypp::Url &url_r ); + + ServiceInfoSharedData( ServiceInfoSharedData && ) = delete; + ServiceInfoSharedData &operator=( const ServiceInfoSharedData & ) = delete; + ServiceInfoSharedData &operator=( ServiceInfoSharedData && ) = delete; + + ~ServiceInfoSharedData() override + {} + + void setProbedType( const zypp::repo::ServiceType & type_r ) const + { + if ( _type == zypp::repo::ServiceType::NONE + && type_r != zypp::repo::ServiceType::NONE ) + { + // lazy init! + const_cast(this)->_type = type_r; + } + } + + protected: + void bindVariables () override; + + private: + friend ServiceInfoSharedData * zypp::rwcowClone( const ServiceInfoSharedData * rhs ); + + /** clone for RWCOW_pointer */ + ServiceInfoSharedData( const ServiceInfoSharedData &) = default; + ServiceInfoSharedData *clone() const override; + }; + +} + + +#endif // ZYPP_NG_SERVICE_INFO_SHARED_DATA_H_INCLUDED diff --git a/zypp/ng/userdata.cc b/zypp/ng/userdata.cc new file mode 100644 index 0000000000..2a2b6c68eb --- /dev/null +++ b/zypp/ng/userdata.cc @@ -0,0 +1,48 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +#include "userdata.h" + +#include + + +#undef ZYPP_BASE_LOGGER_LOGGROUP +#define ZYPP_BASE_LOGGER_LOGGROUP "zyppng::UserData" + +namespace zyppng { + bool UserData::hasData() + { + return !instance()._value.empty(); + } + + const std::string &UserData::data() + { + return instance()._value; + } + + bool UserData::setData( const std::string &str ) + { + for( auto ch = str.begin(); ch != str.end(); ch++ ) + { + if ( *ch < ' ' && *ch != '\t' ) + { + ERR << "New user data string rejectded: char " << (int)*ch << " at position " << (ch - str.begin()) << std::endl; + return false; + } + } + MIL << "Set user data string to '" << str << "'" << std::endl; + instance()._value = str; + return true; + } + + UserData &UserData::instance() + { + static UserData _inst; + return _inst; + } +} diff --git a/zypp/ng/userdata.h b/zypp/ng/userdata.h new file mode 100644 index 0000000000..6d64a925a5 --- /dev/null +++ b/zypp/ng/userdata.h @@ -0,0 +1,37 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +#ifndef ZYPP_NG_USERDATA_H_INCLUDED +#define ZYPP_NG_USERDATA_H_INCLUDED + +#include + +namespace zyppng { + + + /** + * Interface for usercode to define a string value to be passed to log, history, plugins... + */ + class UserData { + + public: + ~UserData() = default; + static bool hasData(); + static const std::string &data(); + static bool setData( const std::string &str ); + + private: + UserData() = default; + static UserData &instance(); + + std::string _value; + }; + +} + +#endif diff --git a/zypp/ng/workflows/keyringwf.cc b/zypp/ng/workflows/keyringwf.cc index f064d79e7e..e9340ddd1d 100644 --- a/zypp/ng/workflows/keyringwf.cc +++ b/zypp/ng/workflows/keyringwf.cc @@ -19,10 +19,12 @@ #include #include #include + #include #include #include #include +#include namespace zyppng::KeyRingWorkflow { @@ -38,7 +40,7 @@ namespace zyppng::KeyRingWorkflow { ZYPP_ENABLE_LOGIC_BASE(Executor, OpType); public: - ImportKeyFromRepoLogic( ZyppContextRefType context, std::string &&keyId, zypp::RepoInfo &&info ) + ImportKeyFromRepoLogic( ZyppContextRefType context, std::string &&keyId, RepoInfo &&info ) : _context( std::move(context) ), _keyId(std::move(keyId)), _repo( std::move(info) ) { } @@ -95,15 +97,15 @@ namespace zyppng::KeyRingWorkflow { ZyppContextRefType _context; std::string _keyId; - zypp::RepoInfo _repo; + RepoInfo _repo; }; - bool provideAndImportKeyFromRepository( SyncContextRef ctx, std::string id_r, zypp::RepoInfo info_r ) + bool provideAndImportKeyFromRepository( SyncContextRef ctx, std::string id_r, RepoInfo info_r ) { return SimpleExecutor>::run( ctx, std::move(id_r), std::move(info_r) ); } - AsyncOpRef provideAndImportKeyFromRepository( AsyncContextRef ctx, std::string id_r, zypp::RepoInfo info_r) + AsyncOpRef provideAndImportKeyFromRepository( AsyncContextRef ctx, std::string id_r, RepoInfo info_r) { return SimpleExecutor>::run( ctx, std::move(id_r), std::move(info_r) ); } @@ -209,7 +211,7 @@ namespace zyppng::KeyRingWorkflow { else if ( ! _verifyContext.keyContext().empty() ) { // try to find the key in the repository info - return provideAndImportKeyFromRepository ( _zyppContext, id, _verifyContext.keyContext().repoInfo() ) + return provideAndImportKeyFromRepository ( _zyppContext, id, *_verifyContext.keyContext().ngRepoInfo() ) | [this, id]( bool success ) { if ( !success ) { return FoundKeyData{ zypp::PublicKeyData(), zypp::Pathname() }; diff --git a/zypp/ng/workflows/keyringwf.h b/zypp/ng/workflows/keyringwf.h index 881dc2223f..90e8eb75d8 100644 --- a/zypp/ng/workflows/keyringwf.h +++ b/zypp/ng/workflows/keyringwf.h @@ -14,7 +14,6 @@ #include namespace zypp { - class RepoInfo; DEFINE_PTR_TYPE(KeyRing); namespace keyring { @@ -25,6 +24,8 @@ namespace zypp { namespace zyppng { + class RepoInfo; + /*! * \namespace KeyRingWorkflow * Contains all KeyRing related workflows. @@ -37,8 +38,8 @@ namespace zyppng { * Try to find the \a id in key cache or repository specified in \a info. Ask the user to trust * the key if it was found */ - bool provideAndImportKeyFromRepository(SyncContextRef ctx, std::string id_r, zypp::RepoInfo info_r ); - AsyncOpRef provideAndImportKeyFromRepository(AsyncContextRef ctx, std::string id_r, zypp::RepoInfo info_r ); + bool provideAndImportKeyFromRepository(SyncContextRef ctx, std::string id_r, RepoInfo info_r ); + AsyncOpRef provideAndImportKeyFromRepository(AsyncContextRef ctx, std::string id_r, RepoInfo info_r ); /** * Follows a signature verification interacting with the user. diff --git a/zypp/ng/workflows/repoinfowf.cc b/zypp/ng/workflows/repoinfowf.cc index f3abeb0b4c..efd8d5ebba 100644 --- a/zypp/ng/workflows/repoinfowf.cc +++ b/zypp/ng/workflows/repoinfowf.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -47,7 +48,7 @@ namespace zyppng { using MediaHandle = typename ProvideType::MediaHandle; using ProvideRes = typename ProvideType::Res; - RepoInfoProvideKeyLogic( ZyppContextRefType &&zyppContext, zypp::RepoInfo &&info, std::string &&keyID_r, zypp::Pathname &&targetDirectory_r ) + RepoInfoProvideKeyLogic( ZyppContextRefType &&zyppContext, RepoInfo &&info, std::string &&keyID_r, zypp::Pathname &&targetDirectory_r ) : _reports( std::move(zyppContext )) , _info( std::move(info) ) , _keyID_r(std::move( keyID_r )) @@ -188,7 +189,7 @@ namespace zyppng { } JobReportHelper _reports; - const zypp::RepoInfo _info; + const RepoInfo _info{nullptr}; const std::string _keyID_r; const zypp::Pathname _targetDirectory_r; const std::string _keyIDStr; @@ -209,12 +210,12 @@ namespace zyppng { }; } - zypp::filesystem::Pathname RepoInfoWorkflow::provideKey( SyncContextRef ctx, zypp::RepoInfo info, std::string keyID_r, zypp::filesystem::Pathname targetDirectory_r ) + zypp::filesystem::Pathname RepoInfoWorkflow::provideKey( SyncContextRef ctx, RepoInfo info, std::string keyID_r, zypp::filesystem::Pathname targetDirectory_r ) { return SimpleExecutor>::run( std::move(ctx), std::move(info), std::move(keyID_r), std::move(targetDirectory_r) ); } - AsyncOpRef RepoInfoWorkflow::provideKey(AsyncContextRef ctx, zypp::RepoInfo info, std::string keyID_r, zypp::filesystem::Pathname targetDirectory_r ) + AsyncOpRef RepoInfoWorkflow::provideKey(AsyncContextRef ctx, RepoInfo info, std::string keyID_r, zypp::filesystem::Pathname targetDirectory_r ) { return SimpleExecutor>::run( std::move(ctx), std::move(info), std::move(keyID_r), std::move(targetDirectory_r) ); } diff --git a/zypp/ng/workflows/repoinfowf.h b/zypp/ng/workflows/repoinfowf.h index cc329c2b55..6c444cc2e1 100644 --- a/zypp/ng/workflows/repoinfowf.h +++ b/zypp/ng/workflows/repoinfowf.h @@ -17,8 +17,8 @@ namespace zyppng { namespace RepoInfoWorkflow { - zypp::Pathname provideKey ( SyncContextRef ctx, zypp::RepoInfo info, std::string keyID_r, zypp::Pathname targetDirectory_r ); - AsyncOpRef provideKey ( AsyncContextRef ctx, zypp::RepoInfo info, std::string keyID_r, zypp::Pathname targetDirectory_r ); + zypp::Pathname provideKey ( SyncContextRef ctx, RepoInfo info, std::string keyID_r, zypp::Pathname targetDirectory_r ); + AsyncOpRef provideKey ( AsyncContextRef ctx, RepoInfo info, std::string keyID_r, zypp::Pathname targetDirectory_r ); } } diff --git a/zypp/parser/RepoindexFileReader.cc b/zypp/parser/RepoindexFileReader.cc deleted file mode 100644 index c8a339aea6..0000000000 --- a/zypp/parser/RepoindexFileReader.cc +++ /dev/null @@ -1,282 +0,0 @@ -/*---------------------------------------------------------------------\ -| ____ _ __ __ ___ | -| |__ / \ / / . \ . \ | -| / / \ V /| _/ _/ | -| / /__ | | | | | | | -| /_____||_| |_| |_| | -| | -\---------------------------------------------------------------------*/ -/** \file zypp/parser/RepoindexFileReader.cc - * Implementation of repoindex.xml file reader. - */ -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#include - - -#undef ZYPP_BASE_LOGGER_LOGGROUP -#define ZYPP_BASE_LOGGER_LOGGROUP "parser" - -using std::endl; - -namespace zypp -{ - namespace parser - { - using xml::Reader; - using xml::XmlString; - - /////////////////////////////////////////////////////////////////// - namespace - { - class VarReplacer : private base::NonCopyable - { - public: - /** */ - void setVar( const std::string & key_r, const std::string & val_r ) - { - //MIL << "*** Inject " << key_r << " = " << val_r; - _vars[key_r] = replace( val_r ); - //MIL << " (" << _vars[key_r] << ")" << endl; - } - - std::string replace( const std::string & val_r ) const - { - std::string::size_type vbeg = val_r.find( "%{", 0 ); - if ( vbeg == std::string::npos ) - return val_r; - - str::Str ret; - std::string::size_type cbeg = 0; - for( ; vbeg != std::string::npos; vbeg = val_r.find( "%{", vbeg ) ) - { - std::string::size_type nbeg = vbeg+2; - std::string::size_type nend = val_r.find( '}', nbeg ); - if ( nend == std::string::npos ) - { - WAR << "Incomplete variable in '" << val_r << "'" << endl; - break; - } - const auto & iter = _vars.find( val_r.substr( nbeg, nend-nbeg ) ); - if ( iter != _vars.end() ) - { - if ( cbeg < vbeg ) - ret << val_r.substr( cbeg, vbeg-cbeg ); - ret << iter->second; - cbeg = nend+1; - } - else - WAR << "Undefined variable %{" << val_r.substr( nbeg, nend-nbeg ) << "} in '" << val_r << "'" << endl; - vbeg = nend+1; - } - if ( cbeg < val_r.size() ) - ret << val_r.substr( cbeg ); - - return ret; - } - private: - std::unordered_map _vars; - }; - } // namespace - /////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////// - // - // CLASS NAME : RepoindexFileReader::Impl - // - class RepoindexFileReader::Impl : private base::NonCopyable - { - public: - /** - * CTOR - * - * \see RepoindexFileReader::RepoindexFileReader(Pathname,ProcessResource) - */ - Impl(const InputStream &is, ProcessResource &&callback); - - /** - * Callback provided to the XML parser. - */ - bool consumeNode( Reader & reader_r ); - - DefaultIntegral _ttl; - - private: - bool getAttrValue( const std::string & key_r, Reader & reader_r, std::string & value_r ) - { - const XmlString & s( reader_r->getAttribute( key_r ) ); - if ( s.get() ) - { - value_r = _replacer.replace( s.asString() ); - return !value_r.empty(); - } - value_r.clear(); - return false; - } - - private: - /** Function for processing collected data. Passed-in through constructor. */ - ProcessResource _callback; - VarReplacer _replacer; - }; - /////////////////////////////////////////////////////////////////////// - - RepoindexFileReader::Impl::Impl(const InputStream &is, - ProcessResource &&callback) - : _callback(std::move(callback)) - { - Reader reader( is ); - MIL << "Reading " << is.path() << endl; - reader.foreachNode( bind( &RepoindexFileReader::Impl::consumeNode, this, _1 ) ); - } - - // -------------------------------------------------------------------------- - - /* - * xpath and multiplicity of processed nodes are included in the code - * for convenience: - * - * // xpath: (?|*|+) - * - * if multiplicity is ommited, then the node has multiplicity 'one'. - */ - - // -------------------------------------------------------------------------- - - bool RepoindexFileReader::Impl::consumeNode( Reader & reader_r ) - { - if ( reader_r->nodeType() == XML_READER_TYPE_ELEMENT ) - { - // xpath: /repoindex - if ( reader_r->name() == "repoindex" ) - { - while ( reader_r.nextNodeAttribute() ) - { - const std::string & name( reader_r->localName().asString() ); - const std::string & value( reader_r->value().asString() ); - _replacer.setVar( name, value ); - // xpath: /repoindex@ttl - if ( name == "ttl" ) - _ttl = str::strtonum(value); - } - return true; - } - - // xpath: /repoindex/data (+) - if ( reader_r->name() == "repo" ) - { - RepoInfo info; - // Set some defaults that are not contained in the repo information - info.setAutorefresh( true ); - info.setEnabled(false); - - std::string attrValue; - - // required alias - // mandatory, so we can allow it in var replacement without reset - if ( getAttrValue( "alias", reader_r, attrValue ) ) - { - info.setAlias( attrValue ); - _replacer.setVar( "alias", attrValue ); - } - else - throw ParseException(str::form(_("Required attribute '%s' is missing."), "alias")); - - // required url - // SLES HACK: or path, but beware of the hardcoded '/repo' prefix! - { - std::string urlstr; - std::string pathstr; - getAttrValue( "url", reader_r, urlstr ); - getAttrValue( "path", reader_r, pathstr ); - if ( urlstr.empty() ) - { - if ( pathstr.empty() ) - throw ParseException(str::form(_("One or both of '%s' or '%s' attributes is required."), "url", "path")); - else - info.setPath( Pathname("/repo") / pathstr ); - } - else - { - if ( pathstr.empty() ) - info.setBaseUrl( Url(urlstr) ); - else - { - Url url( urlstr ); - url.setPathName( Pathname(url.getPathName()) / "repo" / pathstr ); - info.setBaseUrl( url ); - } - } - } - - // optional name - if ( getAttrValue( "name", reader_r, attrValue ) ) - info.setName( attrValue ); - - // optional targetDistro - if ( getAttrValue( "distro_target", reader_r, attrValue ) ) - info.setTargetDistribution( attrValue ); - - // optional priority - if ( getAttrValue( "priority", reader_r, attrValue ) ) - info.setPriority( str::strtonum( attrValue ) ); - - - // optional enabled - if ( getAttrValue( "enabled", reader_r, attrValue ) ) - info.setEnabled( str::strToBool( attrValue, info.enabled() ) ); - - // optional autorefresh - if ( getAttrValue( "autorefresh", reader_r, attrValue ) ) - info.setAutorefresh( str::strToBool( attrValue, info.autorefresh() ) ); - - DBG << info << endl; - - // ignore the rest - _callback(info); - return true; - } - } - - return true; - } - - - /////////////////////////////////////////////////////////////////// - // - // CLASS NAME : RepoindexFileReader - // - /////////////////////////////////////////////////////////////////// - - RepoindexFileReader::RepoindexFileReader( Pathname repoindex_file, ProcessResource callback ) - : _pimpl(new Impl( InputStream(std::move(repoindex_file)), std::move(callback) )) - {} - - RepoindexFileReader::RepoindexFileReader(const InputStream &is, ProcessResource callback ) - : _pimpl(new Impl( is, std::move(callback) )) - {} - - RepoindexFileReader::~RepoindexFileReader() - {} - - Date::Duration RepoindexFileReader::ttl() const { return _pimpl->_ttl; } - - } // ns parser -} // ns zypp - -// vim: set ts=2 sts=2 sw=2 et ai: diff --git a/zypp/repo/GpgCheck.cc b/zypp/repo/GpgCheck.cc new file mode 100644 index 0000000000..06888422d2 --- /dev/null +++ b/zypp/repo/GpgCheck.cc @@ -0,0 +1,31 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ + +#include "GpgCheck.h" + +namespace zypp { + std::ostream & operator<<( std::ostream & str, const repo::GpgCheck & obj ) + { + switch ( obj ) + { +#define OUTS( V ) case repo::V: return str << #V; break + OUTS( GpgCheck::On ); + OUTS( GpgCheck::Strict ); + OUTS( GpgCheck::AllowUnsigned ); + OUTS( GpgCheck::AllowUnsignedRepo ); + OUTS( GpgCheck::AllowUnsignedPackage ); + OUTS( GpgCheck::Default ); + OUTS( GpgCheck::Off ); + OUTS( GpgCheck::indeterminate ); +#undef OUTS + } + return str << "GpgCheck::UNKNOWN"; + } + +} diff --git a/zypp/repo/GpgCheck.h b/zypp/repo/GpgCheck.h new file mode 100644 index 0000000000..dedb11a5d6 --- /dev/null +++ b/zypp/repo/GpgCheck.h @@ -0,0 +1,40 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/source/GpgCheck.h + * +*/ +#ifndef ZYPP_REPO_GPGCHECK_H_INCLUDED +#define ZYPP_REPO_GPGCHECK_H_INCLUDED + +#include +#include + +namespace zypp { + namespace repo { + /** Some predefined settings */ + enum class ZYPP_API GpgCheck { + indeterminate, //< not specified + On, //< 1** --gpgcheck + Strict, //< 111 --gpgcheck-strict + AllowUnsigned, //< 100 --gpgcheck-allow-unsigned + AllowUnsignedRepo, //< 10* --gpgcheck-allow-unsigned-repo + AllowUnsignedPackage, //< 1*0 --gpgcheck-allow-unsigned-package + Default, //< *** --default-gpgcheck + Off, //< 0** --no-gpgcheck + }; + } + + /** \relates RepoInfo::GpgCheck Stream output */ + std::ostream & operator<<( std::ostream & str, const repo::GpgCheck & obj ) ZYPP_API; +} + + + + +#endif //ZYPP_REPO_GPGCHECK_H_INCLUDED diff --git a/zypp/repo/PackageProvider.cc b/zypp/repo/PackageProvider.cc index 37c9742c45..bdd0bf7acc 100644 --- a/zypp/repo/PackageProvider.cc +++ b/zypp/repo/PackageProvider.cc @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -35,8 +34,10 @@ #include #include +#include #include #include +#include #include @@ -144,8 +145,11 @@ namespace zypp /** Provide the package if it is cached. */ ManagedFile providePackageFromCache() const override { + const auto &ri = _package->ngRepoInfo(); + if ( !ri ) + return ManagedFile(); ManagedFile ret( doProvidePackageFromCache() ); - if ( ! ( ret->empty() || _package->repoInfo().keepPackages() ) ) + if ( ! ( ret->empty() || ri->keepPackages() ) ) ret.setDispose( filesystem::unlink ); return ret; } @@ -187,10 +191,14 @@ namespace zypp ManagedFile ret; OnMediaLocation loc = _package->location(); + const auto &ri = _package->ngRepoInfo(); + if ( !ri ) + ZYPP_THROW(Exception("No RepoInfo in repository, can not provide a package.")); + ProvideFilePolicy policy; policy.progressCB( bind( &Base::progressPackageDownload, this, _1 ) ); policy.fileChecker( bind( &Base::rpmSigFileChecker, this, _1 ) ); - return _access.provideFile( _package->repoInfo(), loc, policy ); + return _access.provideFile( *ri, loc, policy ); } protected: @@ -219,8 +227,8 @@ namespace zypp //@{ void rpmSigFileChecker( const Pathname & file_r ) const { - RepoInfo info = _package->repoInfo(); - if ( info.pkgGpgCheck() ) + const auto &info = _package->ngRepoInfo(); + if ( info.value_or( zyppng::RepoInfo(nullptr) ).pkgGpgCheck() ) { UserData userData( "pkgGpgCheck" ); ResObject::constPtr roptr( _package ); // gcc6 needs it more explcit. Has problem deducing @@ -230,7 +238,7 @@ namespace zypp RpmDb::CheckPackageResult res = RpmDb::CHK_NOKEY; while ( res == RpmDb::CHK_NOKEY ) { - res = packageSigCheck( file_r, info.pkgGpgCheckIsMandatory(), userData ); + res = packageSigCheck( file_r, info->pkgGpgCheckIsMandatory(), userData ); // publish the checkresult, even if it is OK. Apps may want to report something... report()->pkgGpgCheck( userData ); @@ -250,7 +258,7 @@ namespace zypp std::string keyID = hr->signatureKeyID(); if ( keyID.length() > 0 ) { - if ( !zyppng::KeyRingWorkflow::provideAndImportKeyFromRepository ( zypp::zypp_detail::GlobalStateHelper::context(), keyID, info ) ) + if ( !zyppng::KeyRingWorkflow::provideAndImportKeyFromRepository ( zypp::zypp_detail::GlobalStateHelper::context(), keyID, *info ) ) break; } else { @@ -391,25 +399,27 @@ namespace zypp } // HERE: cache misss, check toplevel cache or do download: - RepoInfo info = _package->repoInfo(); + const auto &info = _package->ngRepoInfo(); + if ( !info ) + ZYPP_THROW(Exception("No RepoInfo in repository, can not provide a package.")); // Check toplevel cache { - RepoManagerOptions topCache; - if ( info.packagesPath().dirname() != topCache.repoPackagesCachePath ) // not using toplevel cache + RepoManagerOptions topCache( info->context() ); + if ( info->packagesPath().dirname() != topCache.repoPackagesCachePath ) // not using toplevel cache { const OnMediaLocation & loc( _package->location() ); if ( ! loc.checksum().empty() ) // no cache hit without checksum { - PathInfo pi( topCache.repoPackagesCachePath / info.packagesPath().basename() / info.path() / loc.filename() ); + PathInfo pi( topCache.repoPackagesCachePath / info->packagesPath().basename() / info->path() / loc.filename() ); if ( pi.isExist() && loc.checksum() == CheckSum( loc.checksum().type(), std::ifstream( pi.c_str() ) ) ) { report()->start( _package, pi.path().asFileUrl() ); - const Pathname & dest( info.packagesPath() / info.path() / loc.filename() ); + const Pathname & dest( info->packagesPath() / info->path() / loc.filename() ); if ( filesystem::assert_dir( dest.dirname() ) == 0 && filesystem::hardlinkCopy( pi.path(), dest ) == 0 ) { ret = ManagedFile( dest ); - if ( ! info.keepPackages() ) + if ( ! info->keepPackages() ) ret.setDispose( filesystem::unlink ); MIL << "provided Package from toplevel cache " << _package << " at " << ret << endl; @@ -422,11 +432,11 @@ namespace zypp } // FIXME we only support the first url for now. - if ( info.baseUrlsEmpty() ) + if ( info->baseUrlsEmpty() ) ZYPP_THROW(Exception("No url in repository.")); MIL << "provide Package " << _package << endl; - Url url = * info.baseUrlsBegin(); + Url url = * info->baseUrlsBegin(); try { do { _retry = false; @@ -570,10 +580,14 @@ namespace zypp ManagedFile RpmPackageProvider::doProvidePackage() const { + const auto &ri = _package->ngRepoInfo(); + // check whether to process patch/delta rpms // FIXME we only check the first url for now. - if ( ZConfig::instance().download_use_deltarpm() - && ( _package->repoInfo().url().schemeIsDownloading() || ZConfig::instance().download_use_deltarpm_always() ) ) + if ( ri + && ri->context() + && ri->context()->config().download_use_deltarpm() + && ( _package->ngRepoInfo()->url().schemeIsDownloading() || ri->context()->config().download_use_deltarpm_always() ) ) { std::list deltaRpms; _deltas.deltaRpms( _package ).swap( deltaRpms ); @@ -610,7 +624,11 @@ namespace zypp { ProvideFilePolicy policy; policy.progressCB( bind( &RpmPackageProvider::progressDeltaDownload, this, _1 ) ); - delta = _access.provideFile( delta_r.repository().info(), delta_r.location(), policy ); + const auto &optRepo = delta_r.repository().ngInfo(); + if ( !optRepo ) { + return ManagedFile(); + } + delta = _access.provideFile( *optRepo, delta_r.location(), policy ); } catch ( const Exception & excpt ) { @@ -627,7 +645,7 @@ namespace zypp } // Build the package - Pathname cachedest( _package->repoInfo().packagesPath() / _package->repoInfo().path() / _package->location().filename() ); + Pathname cachedest( _package->ngRepoInfo()->packagesPath() / _package->ngRepoInfo()->path() / _package->location().filename() ); Pathname builddest( cachedest.extend( ".drpm" ) ); if ( ! applydeltarpm::provide( delta, builddest, diff --git a/zypp/repo/PluginRepoverification.cc b/zypp/repo/PluginRepoverification.cc index c6249e9ac7..967bf8e630 100644 --- a/zypp/repo/PluginRepoverification.cc +++ b/zypp/repo/PluginRepoverification.cc @@ -20,6 +20,9 @@ #include #include #include + +#include + using std::endl; /////////////////////////////////////////////////////////////////// @@ -108,7 +111,7 @@ namespace zypp_private { public: Impl( RW_pointer parent_r, - Pathname &&sigpathLocal_r, Pathname &&keypathLocal_r, RepoInfo &&repo_r ) + Pathname &&sigpathLocal_r, Pathname &&keypathLocal_r, zyppng::RepoInfo &&repo_r ) : _parent { std::move( parent_r ) } , _sigpathLocal { std::move(sigpathLocal_r) } , _keypathLocal { std::move(keypathLocal_r) } @@ -118,7 +121,7 @@ namespace zypp_private RW_pointer _parent; Pathname _sigpathLocal; Pathname _keypathLocal; - RepoInfo _repoinfo; + zyppng::RepoInfo _repoinfo; }; /////////////////////////////////////////////////////////////////// @@ -281,7 +284,7 @@ namespace zypp_private bool PluginRepoverification::checkIfNeeded() { return _pimpl->checkIfNeeded(); } - PluginRepoverification::Checker PluginRepoverification::getChecker( Pathname sigpathLocal_r, Pathname keypathLocal_r, RepoInfo repo_r ) const + PluginRepoverification::Checker PluginRepoverification::getChecker( Pathname sigpathLocal_r, Pathname keypathLocal_r, zyppng::RepoInfo repo_r ) const { return Checker( new Checker::Impl( _pimpl, std::move(sigpathLocal_r), std::move(keypathLocal_r), std::move(repo_r) ) ); } diff --git a/zypp/repo/PluginRepoverification.h b/zypp/repo/PluginRepoverification.h index c6e7620719..d40adbaa1e 100644 --- a/zypp/repo/PluginRepoverification.h +++ b/zypp/repo/PluginRepoverification.h @@ -14,10 +14,13 @@ #include #include -#include #include #include +namespace zyppng { + class RepoInfo; +} + /////////////////////////////////////////////////////////////////// namespace zypp_private { @@ -100,7 +103,7 @@ namespace zypp_private /////////////////////////////////////////////////////////////////// /** \ref FileChecker factory remembering the location of the master index files GPG signature and key. */ - Checker getChecker( Pathname sigpathLocal_r, Pathname keypathLocal_r, RepoInfo repo_r ) const; + Checker getChecker( Pathname sigpathLocal_r, Pathname keypathLocal_r, zyppng::RepoInfo repo_r ) const; public: class Impl; ///< Implementation class. diff --git a/zypp/repo/RepoException.cc b/zypp/repo/RepoException.cc index 56aa3eef5b..c0ea444bbc 100644 --- a/zypp/repo/RepoException.cc +++ b/zypp/repo/RepoException.cc @@ -16,6 +16,8 @@ using std::endl; +ZYPP_BEGIN_LEGACY_API + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// @@ -45,6 +47,14 @@ namespace zypp : Exception( msg_r ), _info( info ) {} + RepoException::RepoException( const zyppng::RepoInfo & info ) + : RepoException( RepoInfo(info) ) + {} + + RepoException::RepoException( const zyppng::RepoInfo & info, const std::string& msg_r ) + : RepoException( RepoInfo(info), msg_r ) + {} + RepoException::~RepoException() throw() {} @@ -60,7 +70,9 @@ namespace zypp CLASS::CLASS() : RepoException( MSG ) {} \ CLASS::CLASS( const std::string & msg_r ) : RepoException( msg_r ) {} \ CLASS::CLASS( const RepoInfo & service_r ) : RepoException( service_r, MSG ) {} \ - CLASS::CLASS( const RepoInfo & service_r, const std::string & msg_r ) : RepoException( service_r, msg_r ) {} + CLASS::CLASS( const RepoInfo & service_r, const std::string & msg_r ) : RepoException( service_r, msg_r ) {}\ + CLASS::CLASS( const zyppng::RepoInfo & service_r ) : RepoException( service_r, MSG ) {} \ + CLASS::CLASS( const zyppng::RepoInfo & service_r, const std::string & msg_r ) : RepoException( service_r, msg_r ) {} DEF_CTORS( RepoNotCachedException, "Repository is not cached" ); DEF_CTORS( RepoNoUrlException, "Repository has no or invalid url defined." ); @@ -95,6 +107,14 @@ namespace zypp : Exception( msg_r ), _service( service_r ) {} + ServiceException::ServiceException( const zyppng::ServiceInfo & service_r ) + : ServiceException( ServiceInfo(service_r) ) + {} + + ServiceException::ServiceException( const zyppng::ServiceInfo & service_r, const std::string & msg_r ) + : ServiceException( ServiceInfo(service_r), msg_r ) + {} + ServiceException::~ServiceException() throw() {} @@ -110,7 +130,9 @@ namespace zypp CLASS::CLASS() : DEF_BASECLASS( MSG ) {} \ CLASS::CLASS( const std::string & msg_r ) : DEF_BASECLASS( msg_r ) {} \ CLASS::CLASS( const ServiceInfo & service_r ) : DEF_BASECLASS( service_r, MSG ) {} \ - CLASS::CLASS( const ServiceInfo & service_r, const std::string & msg_r ) : DEF_BASECLASS( service_r, msg_r ) {} + CLASS::CLASS( const ServiceInfo & service_r, const std::string & msg_r ) : DEF_BASECLASS( service_r, msg_r ) {} \ + CLASS::CLASS( const zyppng::ServiceInfo & service_r ) : DEF_BASECLASS( service_r, MSG ) {} \ + CLASS::CLASS( const zyppng::ServiceInfo & service_r, const std::string & msg_r ) : DEF_BASECLASS( service_r, msg_r ) {} #define DEF_BASECLASS ServiceException DEF_CTORS( ServiceNoAliasException, "Service has no alias defined." ); @@ -135,3 +157,5 @@ namespace zypp ///////////////////////////////////////////////////////////////// } // namespace zypp /////////////////////////////////////////////////////////////////// + +ZYPP_END_LEGACY_API diff --git a/zypp/repo/RepoException.h b/zypp/repo/RepoException.h index f2a9aaacae..de6677ceb8 100644 --- a/zypp/repo/RepoException.h +++ b/zypp/repo/RepoException.h @@ -20,6 +20,13 @@ #include #include +namespace zyppng { + class RepoInfo; + class ServiceInfo; +} + +ZYPP_BEGIN_LEGACY_API + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// @@ -41,6 +48,9 @@ namespace zypp RepoException( const std::string & msg_r ); RepoException( const RepoInfo & info ); RepoException( const RepoInfo & info, const std::string & msg_r ); + RepoException( const zyppng::RepoInfo & info ); + RepoException( const zyppng::RepoInfo & info, const std::string & msg_r ); + ~RepoException() throw() override; RepoInfo info() @@ -69,6 +79,8 @@ namespace zypp RepoNotCachedException( const std::string & msg_r ); RepoNotCachedException( const RepoInfo & info ); RepoNotCachedException( const RepoInfo & info, const std::string & msg_r ); + RepoNotCachedException( const zyppng::RepoInfo & info ); + RepoNotCachedException( const zyppng::RepoInfo & info, const std::string & msg_r ); }; /** @@ -82,6 +94,8 @@ namespace zypp RepoNoUrlException( const std::string & msg_r ); RepoNoUrlException( const RepoInfo & info ); RepoNoUrlException( const RepoInfo & info, const std::string & msg_r ); + RepoNoUrlException( const zyppng::RepoInfo & info ); + RepoNoUrlException( const zyppng::RepoInfo & info, const std::string & msg_r ); }; /** @@ -95,6 +109,8 @@ namespace zypp RepoNoAliasException( const std::string & msg_r ); RepoNoAliasException( const RepoInfo & info ); RepoNoAliasException( const RepoInfo & info, const std::string & msg_r ); + RepoNoAliasException( const zyppng::RepoInfo & info ); + RepoNoAliasException( const zyppng::RepoInfo & info, const std::string & msg_r ); }; /** @@ -107,6 +123,8 @@ namespace zypp RepoInvalidAliasException( const std::string & msg_r ); RepoInvalidAliasException( const RepoInfo & info ); RepoInvalidAliasException( const RepoInfo & info, const std::string & msg_r ); + RepoInvalidAliasException( const zyppng::RepoInfo & info ); + RepoInvalidAliasException( const zyppng::RepoInfo & info, const std::string & msg_r ); }; /** @@ -120,6 +138,8 @@ namespace zypp RepoNotFoundException( const std::string & msg_r ); RepoNotFoundException( const RepoInfo & info ); RepoNotFoundException( const RepoInfo & info, const std::string & msg_r ); + RepoNotFoundException( const zyppng::RepoInfo & info ); + RepoNotFoundException( const zyppng::RepoInfo & info, const std::string & msg_r ); }; /** @@ -133,6 +153,8 @@ namespace zypp RepoAlreadyExistsException( const std::string & msg_r ); RepoAlreadyExistsException( const RepoInfo & info ); RepoAlreadyExistsException( const RepoInfo & info, const std::string & msg_r ); + RepoAlreadyExistsException( const zyppng::RepoInfo & info ); + RepoAlreadyExistsException( const zyppng::RepoInfo & info, const std::string & msg_r ); }; /** @@ -146,6 +168,8 @@ namespace zypp RepoUnknownTypeException( const std::string & msg_r ); RepoUnknownTypeException( const RepoInfo & info ); RepoUnknownTypeException( const RepoInfo & info, const std::string & msg_r ); + RepoUnknownTypeException( const zyppng::RepoInfo & info ); + RepoUnknownTypeException( const zyppng::RepoInfo & info, const std::string & msg_r ); }; /** @@ -159,6 +183,8 @@ namespace zypp RepoMetadataException( const std::string & msg_r ); RepoMetadataException( const RepoInfo & info ); RepoMetadataException( const RepoInfo & info, const std::string & msg_r ); + RepoMetadataException( const zyppng::RepoInfo & info ); + RepoMetadataException( const zyppng::RepoInfo & info, const std::string & msg_r ); }; //@} @@ -179,6 +205,8 @@ namespace zypp ServiceException( const std::string & msg_r ); ServiceException( const ServiceInfo & service_r ); ServiceException( const ServiceInfo & service_r, const std::string & msg_r ); + ServiceException( const zyppng::ServiceInfo & service_r ); + ServiceException( const zyppng::ServiceInfo & service_r, const std::string & msg_r ); ~ServiceException() throw() override; ServiceInfo service() @@ -204,6 +232,8 @@ namespace zypp ServiceNoAliasException( const std::string & msg_r ); ServiceNoAliasException( const ServiceInfo & service_r ); ServiceNoAliasException( const ServiceInfo & service_r, const std::string & msg_r ); + ServiceNoAliasException( const zyppng::ServiceInfo & service_r ); + ServiceNoAliasException( const zyppng::ServiceInfo & service_r, const std::string & msg_r ); }; /** @@ -216,6 +246,8 @@ namespace zypp ServiceInvalidAliasException( const std::string & msg_r ); ServiceInvalidAliasException( const ServiceInfo & info ); ServiceInvalidAliasException( const ServiceInfo & info, const std::string & msg_r ); + ServiceInvalidAliasException( const zyppng::ServiceInfo & service_r ); + ServiceInvalidAliasException( const zyppng::ServiceInfo & service_r, const std::string & msg_r ); }; /** Service already exists and some unique attribute can't be duplicated. @@ -227,6 +259,8 @@ namespace zypp ServiceAlreadyExistsException( const std::string & msg_r ); ServiceAlreadyExistsException( const ServiceInfo & service_r ); ServiceAlreadyExistsException( const ServiceInfo & service_r, const std::string & msg_r ); + ServiceAlreadyExistsException( const zyppng::ServiceInfo & service_r ); + ServiceAlreadyExistsException( const zyppng::ServiceInfo & service_r, const std::string & msg_r ); }; /** Service has no or invalid url defined. @@ -238,6 +272,8 @@ namespace zypp ServiceNoUrlException( const std::string & msg_r ); ServiceNoUrlException( const ServiceInfo & service_r ); ServiceNoUrlException( const ServiceInfo & service_r, const std::string & msg_r ); + ServiceNoUrlException( const zyppng::ServiceInfo & service_r ); + ServiceNoUrlException( const zyppng::ServiceInfo & service_r, const std::string & msg_r ); }; //@} @@ -255,6 +291,8 @@ namespace zypp ServicePluginException( const std::string & msg_r ); ServicePluginException( const ServiceInfo & service_r ); ServicePluginException( const ServiceInfo & service_r, const std::string & msg_r ); + ServicePluginException( const zyppng::ServiceInfo & service_r ); + ServicePluginException( const zyppng::ServiceInfo & service_r, const std::string & msg_r ); }; /** Service plugin has trouble providing the metadata but this should not be treated as error. @@ -266,6 +304,8 @@ namespace zypp ServicePluginInformalException( const std::string & msg_r ); ServicePluginInformalException( const ServiceInfo & service_r ); ServicePluginInformalException( const ServiceInfo & service_r, const std::string & msg_r ); + ServicePluginInformalException( const zyppng::ServiceInfo & service_r ); + ServicePluginInformalException( const zyppng::ServiceInfo & service_r, const std::string & msg_r ); }; /** Service plugin is immutable. @@ -277,6 +317,8 @@ namespace zypp ServicePluginImmutableException( const std::string & msg_r ); ServicePluginImmutableException( const ServiceInfo & service_r ); ServicePluginImmutableException( const ServiceInfo & service_r, const std::string & msg_r ); + ServicePluginImmutableException( const zyppng::ServiceInfo & service_r ); + ServicePluginImmutableException( const zyppng::ServiceInfo & service_r, const std::string & msg_r ); }; //@} @@ -286,4 +328,6 @@ namespace zypp ///////////////////////////////////////////////////////////////// } // namespace zypp /////////////////////////////////////////////////////////////////// + +ZYPP_END_LEGACY_API #endif // ZYPP_PARSER_TAGFILE_PARSEEXCEPTION_H diff --git a/zypp/repo/RepoInfoBase.cc b/zypp/repo/RepoInfoBase.cc index 9fc09aa8d9..e25b921388 100644 --- a/zypp/repo/RepoInfoBase.cc +++ b/zypp/repo/RepoInfoBase.cc @@ -6,172 +6,74 @@ | /_____||_| |_| |_| | | | \---------------------------------------------------------------------*/ -/** \file zypp/repo/RepoInfoBase.cc +/** \file zypp/repo/RepoInfoBase.cc * - */ -#include +*/ +#include "RepoInfoBase.h" +#include -#include -#include -#include -#include +ZYPP_BEGIN_LEGACY_API -#include -#include -#include +namespace zypp::repo { -#include - -using std::endl; - -/////////////////////////////////////////////////////////////////// -namespace zypp -{ - /////////////////////////////////////////////////////////////////// - namespace repo - { - - RepoInfoBase::Impl::Impl( zyppng::ContextBaseRef &&context ) - : _ctx( std::move(context) ) - , _enabled( indeterminate ) - , _autorefresh( indeterminate ) + RepoInfoBase::RepoInfoBase( ) {} - RepoInfoBase::Impl::Impl( zyppng::ContextBaseRef &&context, const std::string & alias_r ) - : _ctx( std::move(context) ) - , _enabled( indeterminate ) - , _autorefresh( indeterminate ) - { setAlias( alias_r ); } - - - void RepoInfoBase::Impl::setAlias( const std::string & alias_r ) - { - _alias = _escaped_alias = alias_r; - // replace slashes with underscores - str::replaceAll( _escaped_alias, "/", "_" ); - } - - RepoInfoBase::Impl * RepoInfoBase::Impl::clone() const - { return new Impl( *this ); } - - /////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////// - // - // CLASS NAME : RepoInfoBase - // - /////////////////////////////////////////////////////////////////// - - RepoInfoBase::RepoInfoBase(Impl &pimpl ) : _pimpl( &pimpl ) - {} - - RepoInfoBase::RepoInfoBase( zyppng::ContextBaseRef context ) - : _pimpl( new Impl( std::move(context) ) ) - { } - - RepoInfoBase::RepoInfoBase( zyppng::ContextBaseRef context, const std::string &alias ) - : _pimpl( new Impl( std::move(context), alias ) ) - { } - - zyppng::ContextBaseRef RepoInfoBase::context() const - { return _pimpl->_ctx; } - - RepoInfoBase::RepoInfoBase() - : RepoInfoBase( zypp_detail::GlobalStateHelper::context() ) - { /* LEGACY, DO NOT ADD CODE HERE */ } - - RepoInfoBase::RepoInfoBase(const std::string & alias) - : RepoInfoBase( zypp_detail::GlobalStateHelper::context(), alias ) - { /* LEGACY, DO NOT ADD CODE HERE */ } - RepoInfoBase::~RepoInfoBase() {} void RepoInfoBase::setEnabled( bool enabled ) - { _pimpl->_enabled = enabled; } + { pimpl().setEnabled(enabled); } void RepoInfoBase::setAutorefresh( bool autorefresh ) - { _pimpl->_autorefresh = autorefresh; } + { pimpl().setAutorefresh(autorefresh); } void RepoInfoBase::setAlias( const std::string &alias ) - { _pimpl->setAlias(alias); } + { pimpl().setAlias(alias); } void RepoInfoBase::setName( const std::string &name ) - { _pimpl->_name.raw() = name; } + { pimpl().setName(name); } - void RepoInfoBase::setFilepath( const Pathname &filepath ) - { _pimpl->_filepath = filepath; } + void RepoInfoBase::setFilepath( const zypp::Pathname &filepath ) + { pimpl().setFilepath(filepath); } - // true by default (if not set by setEnabled()) bool RepoInfoBase::enabled() const - { return indeterminate(_pimpl->_enabled) ? true : (bool) _pimpl->_enabled; } + { return pimpl().enabled(); } - // false by default (if not set by setAutorefresh()) bool RepoInfoBase::autorefresh() const - { return indeterminate(_pimpl->_autorefresh) ? false : (bool) _pimpl->_autorefresh; } + { return pimpl().autorefresh(); } std::string RepoInfoBase::alias() const - { return _pimpl->_alias; } + { return pimpl().alias(); } std::string RepoInfoBase::escaped_alias() const - { return _pimpl->_escaped_alias; } + { return pimpl().escaped_alias(); } std::string RepoInfoBase::name() const - { - if ( rawName().empty() ) - return alias(); - return repo::RepoVariablesStringReplacer()( rawName() ); - } + { return pimpl().name(); } std::string RepoInfoBase::rawName() const - { return _pimpl->_name.raw(); } + { return pimpl().rawName(); } std::string RepoInfoBase::label() const - { - if ( _pimpl->_ctx && _pimpl->_ctx->config().repoLabelIsAlias() ) - return alias(); - return name(); - } - - Pathname RepoInfoBase::filepath() const - { return _pimpl->_filepath; } + { return pimpl().label(); } + zypp::Pathname RepoInfoBase::filepath() const + { return pimpl().filepath(); } std::ostream & RepoInfoBase::dumpOn( std::ostream & str ) const - { - str << "--------------------------------------" << std::endl; - str << "- alias : " << alias() << std::endl; - if ( ! rawName().empty() ) - str << "- name : " << rawName() << std::endl; - str << "- enabled : " << enabled() << std::endl; - str << "- autorefresh : " << autorefresh() << std::endl; - - return str; - } + { return pimpl().dumpOn(str); } std::ostream & RepoInfoBase::dumpAsIniOn( std::ostream & str ) const - { - // we save the original data without variable replacement - str << "[" << alias() << "]" << endl; - if ( ! rawName().empty() ) - str << "name=" << rawName() << endl; - str << "enabled=" << (enabled() ? "1" : "0") << endl; - str << "autorefresh=" << (autorefresh() ? "1" : "0") << endl; - - return str; - } + { return pimpl().dumpAsIniOn(str); } std::ostream & RepoInfoBase::dumpAsXmlOn( std::ostream & str, const std::string & content ) const - { - return str << "" << endl; - } + { return pimpl().dumpAsXmlOn (str, content); } std::ostream & operator<<( std::ostream & str, const RepoInfoBase & obj ) { return obj.dumpOn(str); } +} - } // namespace repo - /////////////////////////////////////////////////////////////////// -} // namespace zypp -/////////////////////////////////////////////////////////////////// +ZYPP_END_LEGACY_API diff --git a/zypp/repo/RepoInfoBase.h b/zypp/repo/RepoInfoBase.h index 879df35918..b366e5129b 100644 --- a/zypp/repo/RepoInfoBase.h +++ b/zypp/repo/RepoInfoBase.h @@ -18,9 +18,10 @@ #include #include -namespace zyppng { - class ContextBase; - using ContextBaseRef = std::shared_ptr; +ZYPP_BEGIN_LEGACY_API + +namespace zyppng::repo { + class RepoInfoBase; } /////////////////////////////////////////////////////////////////// @@ -41,36 +42,21 @@ namespace zypp * \note Name is subject to repo variable replacement * (\see \ref RepoVariablesStringReplacer). */ - class ZYPP_API RepoInfoBase + class ZYPP_API ZYPP_INTERNAL_DEPRECATE RepoInfoBase { friend std::ostream & operator<<( std::ostream & str, const RepoInfoBase & obj ); public: - virtual ~RepoInfoBase(); -#if LEGACY(1733) - public: -#else protected: -#endif - RepoInfoBase( zyppng::ContextBaseRef context ) ZYPP_LOCAL; - RepoInfoBase( zyppng::ContextBaseRef context, const std::string &alias ) ZYPP_LOCAL; - - ZYPP_INTERNAL_DEPRECATE RepoInfoBase(); - ZYPP_INTERNAL_DEPRECATE RepoInfoBase(const std::string &alias); + RepoInfoBase(); RepoInfoBase(const RepoInfoBase &) = default; RepoInfoBase(RepoInfoBase &&) noexcept = default; RepoInfoBase &operator=(const RepoInfoBase &) = default; RepoInfoBase &operator=(RepoInfoBase &&) noexcept = default; public: - - /** - * Returns the associated context of the RepoInfo - */ - zyppng::ContextBaseRef context() const; - /** * unique identifier for this source. If not specified * It should be generated from the base url. @@ -183,12 +169,9 @@ namespace zypp */ virtual std::ostream & dumpAsXmlOn( std::ostream & str, const std::string & content = "" ) const; - struct Impl; - protected: - RepoInfoBase( Impl &pimpl ); - /** Pointer to implementation */ - RWCOW_pointer _pimpl; + virtual zyppng::repo::RepoInfoBase &pimpl() = 0; + virtual const zyppng::repo::RepoInfoBase &pimpl() const = 0; }; /////////////////////////////////////////////////////////////////// @@ -219,4 +202,6 @@ namespace zypp } // namespace zypp /////////////////////////////////////////////////////////////////// +ZYPP_END_LEGACY_API + #endif /*REPOINFOBASE_H_*/ diff --git a/zypp/repo/RepoMirrorList.cc b/zypp/repo/RepoMirrorList.cc index 0d6649fc9a..84b5fbcede 100644 --- a/zypp/repo/RepoMirrorList.cc +++ b/zypp/repo/RepoMirrorList.cc @@ -46,12 +46,12 @@ namespace zypp RepoMirrorListTempProvider( Pathname localfile_r ) : _localfile(std::move( localfile_r )) {} - RepoMirrorListTempProvider( const Url & url_r ) + RepoMirrorListTempProvider( zyppng::ContextBaseRef ctx, const Url & url_r ) { Url abs_url( url_r ); abs_url.setPathName( "/" ); abs_url.setQueryParam( "mediahandler", "curl" ); - _access.reset( new MediaSetAccess( abs_url ) ); + _access.reset( new MediaSetAccess( ctx, abs_url ) ); _localfile = _access->provideFile( url_r.getPathName() ); } @@ -124,7 +124,7 @@ namespace zypp } // namespace /////////////////////////////////////////////////////////////////// - RepoMirrorList::RepoMirrorList( const Url & url_r, const Pathname & metadatapath_r, bool mirrorListForceMetalink_r ) + RepoMirrorList::RepoMirrorList( zyppng::ContextBaseRef ctx, const Url & url_r, const Pathname & metadatapath_r, bool mirrorListForceMetalink_r ) { if ( url_r.getScheme() == "file" ) { @@ -134,7 +134,7 @@ namespace zypp else if ( ! PathInfo( metadatapath_r).isDir() ) { // no cachedir - RepoMirrorListTempProvider provider( url_r ); // RAII: lifetime of any downloaded files + RepoMirrorListTempProvider provider( ctx, url_r ); // RAII: lifetime of any downloaded files _urls = RepoMirrorListParse( url_r, provider.localfile(), mirrorListForceMetalink_r ); } else @@ -147,10 +147,10 @@ namespace zypp cachefile /= "mirrorlist.txt"; zypp::filesystem::PathInfo cacheinfo( cachefile ); - if ( !cacheinfo.isFile() || cacheinfo.mtime() < time(NULL) - (long) ZConfig::instance().repo_refresh_delay() * 60 ) + if ( !cacheinfo.isFile() || cacheinfo.mtime() < time(NULL) - (long) ctx->config().repo_refresh_delay() * 60 ) { DBG << "Getting MirrorList from URL: " << url_r << endl; - RepoMirrorListTempProvider provider( url_r ); // RAII: lifetime of downloaded file + RepoMirrorListTempProvider provider( ctx, url_r ); // RAII: lifetime of downloaded file // Create directory, if not existing DBG << "Copy MirrorList file to " << cachefile << endl; diff --git a/zypp/repo/RepoMirrorList.h b/zypp/repo/RepoMirrorList.h index 89a556f73a..b5a04a48ed 100644 --- a/zypp/repo/RepoMirrorList.h +++ b/zypp/repo/RepoMirrorList.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace zypp { @@ -21,10 +22,10 @@ namespace zypp class RepoMirrorList { public: - RepoMirrorList( const Url & url_r, const Pathname & metadatapath_r, bool mirrorListForceMetalink_r ); + RepoMirrorList( zyppng::ContextBaseRef ctx, const Url & url_r, const Pathname & metadatapath_r, bool mirrorListForceMetalink_r ); - RepoMirrorList( const Url & url_r ) - : RepoMirrorList( url_r, Pathname(), false ) + RepoMirrorList( zyppng::ContextBaseRef ctx, const Url & url_r ) + : RepoMirrorList( ctx, url_r, Pathname(), false ) {} const std::vector & getUrls() const diff --git a/zypp/repo/RepoProvideFile.cc b/zypp/repo/RepoProvideFile.cc index 830b0a3ee2..de16fc984c 100644 --- a/zypp/repo/RepoProvideFile.cc +++ b/zypp/repo/RepoProvideFile.cc @@ -32,6 +32,8 @@ #include #include +#include + using std::endl; using std::set; @@ -117,14 +119,15 @@ namespace zypp } // namespace /////////////////////////////////////////////////////////////////// - ManagedFile provideFile( RepoInfo repo_r, + ManagedFile provideFile( zyppng::RepoInfo repo_r, const OnMediaLocation & loc_r, const ProvideFilePolicy & policy_r ) { RepoMediaAccess access; - return access.provideFile(std::move(repo_r), loc_r, policy_r ); + return access.provideFile(repo_r, loc_r, policy_r ); } + /////////////////////////////////////////////////////////////////// class RepoMediaAccess::Impl { @@ -139,13 +142,11 @@ namespace zypp ~Impl() { - std::map >::iterator it; - for ( it = _medias.begin(); - it != _medias.end(); - ++it ) - { - it->second->release(); - } + std::for_each( _medias.begin (), _medias.end(), []( auto &val ){ + std::for_each ( val.second.begin(), val.second.begin(), [](auto &entry) { + entry.second->release(); + }); + }); } /** Provide a MediaSetAccess for \c url with label and verifier adjusted. @@ -155,26 +156,33 @@ namespace zypp * * \todo This mixture of media and repos specific data is fragile. */ - shared_ptr mediaAccessForUrl( const Url &url, RepoInfo repo ) + shared_ptr mediaAccessForUrl( const Url &url, zyppng::RepoInfo repo ) { - std::map >::const_iterator it; - it = _medias.find(url); + if ( !repo.context() ) { + ZYPP_THROW( zypp::Exception( str::Str()<<"Repo: " << repo << ", can not provide files without a context." ) ); + } + // quick hack using the context ptr address as key for the nested map + const uintptr_t key = reinterpret_cast( repo.context().get() ); + auto it = _medias.find(url); shared_ptr media; if ( it != _medias.end() ) { - media = it->second; + auto it2 = it->second.find( key ); + if ( it2 != it->second.end() ) + media = it2->second; } - else + + if ( !media ) { - media.reset( new MediaSetAccess(url) ); - _medias[url] = media; + media.reset( new MediaSetAccess( repo.context(), url) ); + _medias[url][key] = media; } - setVerifierForRepo( std::move(repo), media ); + setVerifierForRepo( repo, media ); return media; } private: - void setVerifierForRepo( const RepoInfo& repo, const shared_ptr& media ) + void setVerifierForRepo( const zyppng::RepoInfo& repo, const shared_ptr& media ) { // Always set the MediaSetAccess label. media->setLabel( repo.name() ); @@ -186,7 +194,7 @@ namespace zypp { if ( PathInfo(mediafile).isExist() ) { - std::map, RepoInfo>::const_iterator it; + std::map, zyppng::RepoInfo>::const_iterator it; it = _verifier.find(media); if ( it != _verifier.end() ) { @@ -204,7 +212,7 @@ namespace zypp media::MediaVerifierRef verifier( new repo::SUSEMediaVerifier( lverifier, i ) ); media->setVerifier( i, verifier); } - _verifier[media] = repo; + _verifier.insert_or_assign( media, repo ); } else { WAR << "Invalid verifier for repo '" << repo.alias() << "' in '" << repo.metadataPath() << "': " << lverifier << endl; @@ -222,8 +230,8 @@ namespace zypp } private: - std::map, RepoInfo> _verifier; - std::map > _medias; + std::map, zyppng::RepoInfo> _verifier; + std::map> > _medias; public: ProvideFilePolicy _defaultPolicy; @@ -244,7 +252,7 @@ namespace zypp const ProvideFilePolicy & RepoMediaAccess::defaultPolicy() const { return _impl->_defaultPolicy; } - ManagedFile RepoMediaAccess::provideFile( const RepoInfo& repo_r, + ManagedFile RepoMediaAccess::provideFile( const zyppng::RepoInfo& repo_r, const OnMediaLocation & loc_rx, const ProvideFilePolicy & policy_r ) { @@ -295,7 +303,7 @@ namespace zypp // Suppress (interactive) media::MediaChangeReport if we in have multiple basurls (>1) media::ScopedDisableMediaChangeReport guard( repo_r.baseUrlsSize() > 1 ); - for ( RepoInfo::urls_const_iterator it = repo_r.baseUrlsBegin(); + for ( auto it = repo_r.baseUrlsBegin(); it != repo_r.baseUrlsEnd(); /* incremented in the loop */ ) { @@ -343,6 +351,34 @@ namespace zypp } ///////////////////////////////////////////////////////////////// + + ManagedFile RepoMediaAccess::provideFile( const zyppng::RepoInfo &repo_r, + const OnMediaLocation &loc_r) { + return provideFile( repo_r, loc_r, defaultPolicy()); + } + + ZYPP_BEGIN_LEGACY_API + ManagedFile provideFile( RepoInfo repo_r, + const OnMediaLocation & loc_r, + const ProvideFilePolicy & policy_r ) + { + return provideFile( repo_r.ngRepoInfo (), loc_r, policy_r ); + } + + ManagedFile RepoMediaAccess::provideFile(RepoInfo repo_r, + const OnMediaLocation &loc_r) { + return provideFile( repo_r.ngRepoInfo (), loc_r ); + } + + ManagedFile RepoMediaAccess::provideFile( const RepoInfo& repo_r, + const OnMediaLocation & loc_rx, + const ProvideFilePolicy & policy_r ) + { + return provideFile( repo_r.ngRepoInfo (), loc_rx, policy_r ); + } + ZYPP_END_LEGACY_API + + } // namespace repo /////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// diff --git a/zypp/repo/RepoProvideFile.h b/zypp/repo/RepoProvideFile.h index 9555479772..dbf44db0a3 100644 --- a/zypp/repo/RepoProvideFile.h +++ b/zypp/repo/RepoProvideFile.h @@ -14,6 +14,7 @@ #include +#include #include #include #include @@ -23,6 +24,10 @@ #include #include +namespace zyppng { + class RepoInfo; +} + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// @@ -45,6 +50,10 @@ namespace zypp * \throws Exception */ ManagedFile provideFile( RepoInfo repo_r, + const OnMediaLocation & loc_r, + const ProvideFilePolicy & policy_r = ProvideFilePolicy() ) ZYPP_INTERNAL_DEPRECATE; + + ManagedFile provideFile( zyppng::RepoInfo repo_r, const OnMediaLocation & loc_r, const ProvideFilePolicy & policy_r = ProvideFilePolicy() ); @@ -74,13 +83,18 @@ namespace zypp * \throws Exception * \todo Investigate why this needs a non-const Repository as arg. */ - ManagedFile provideFile( const RepoInfo& repo_r, - const OnMediaLocation & loc_r, - const ProvideFilePolicy & policy_r ); + ManagedFile provideFile ( const RepoInfo& repo_r, + const OnMediaLocation & loc_r, + const ProvideFilePolicy & policy_r ) ZYPP_INTERNAL_DEPRECATE; + + ManagedFile provideFile ( const zyppng::RepoInfo& repo_r, + const OnMediaLocation & loc_r, + const ProvideFilePolicy & policy_r ); /** \overload Using the current default \ref ProvideFilePolicy. */ - ManagedFile provideFile( RepoInfo repo_r, const OnMediaLocation & loc_r ) - { return provideFile( std::move(repo_r), loc_r, defaultPolicy() ); } + ManagedFile provideFile( RepoInfo repo_r, const OnMediaLocation &loc_r ) ZYPP_INTERNAL_DEPRECATE; + + ManagedFile provideFile( const zyppng::RepoInfo &repo_r, const OnMediaLocation &loc_r ); public: /** Set a new default \ref ProvideFilePolicy. */ diff --git a/zypp/repo/RepoVariables.cc b/zypp/repo/RepoVariables.cc index 2cb65d2e4d..cadf1a810e 100644 --- a/zypp/repo/RepoVariables.cc +++ b/zypp/repo/RepoVariables.cc @@ -20,30 +20,23 @@ #include #include +#include +#include +#include +#include + #define ZYPP_DBG_VAREXPAND 0 #if ( ZYPP_DBG_VAREXPAND ) #warning ZYPP_DBG_VAREXPAND is on using std::cout; #endif // ZYPP_DBG_VAREXPAND -/////////////////////////////////////////////////////////////////// namespace zypp { - namespace env - { - /** Use faked releasever (e.g. for 'zupper dup' to next distro version */ - inline std::string ZYPP_REPO_RELEASEVER() - { - const char * env = getenv("ZYPP_REPO_RELEASEVER"); - return( env ? env : "" ); - } - } - - /////////////////////////////////////////////////////////////////// namespace repo { /////////////////////////////////////////////////////////////////// - // RepoVarExpand + // RepoVariables*Replace /////////////////////////////////////////////////////////////////// namespace { @@ -278,13 +271,13 @@ namespace zypp */ inline bool _expand( std::string & result_r, const std::string & value_r, unsigned level_r, RepoVarExpand::VarRetriever & varRetriever_r ) { -#if ( ZYPP_DBG_VAREXPAND ) + #if ( ZYPP_DBG_VAREXPAND ) cout << std::string( 2*level_r, ' ' ) << "\033[7m>>" << value_r << "<<\033[27m" << endl; std::ostringstream dbg; const char * dbgsbeg = value_r.c_str(); // track vars we already added to dbg unsigned dbgi = 0; // color 1-5 var / 6 moved value_r dbg << std::string( 2*level_r, ' ' ) << ">>"; -#endif // ZYPP_DBG_VAREXPAND + #endif // ZYPP_DBG_VAREXPAND bool expanded = false; @@ -297,12 +290,12 @@ namespace zypp const std::string *const knownVar = ( varRetriever_r ? varRetriever_r( scan.varName() ) : nullptr ); const std::string & varValue( knownVar ? *knownVar : _emptyValue ); -#if ( ZYPP_DBG_VAREXPAND ) + #if ( ZYPP_DBG_VAREXPAND ) dbg << std::string(dbgsbeg,scan._vbeg) << "\033[3" << ((dbgi%5)+1) << "m" << scan.var() << "\033[0m"; cout << dbg.str() << "|<< " << scan.varName() << " " << (knownVar?"("+varValue+")":"-") << " {" << scan.varEmbedded() << "}" << endl; dbgsbeg = scan._vend; dbgi++; -#endif // ZYPP_DBG_VAREXPAND + #endif // ZYPP_DBG_VAREXPAND bool mustSubstitute = false; // keep original text per default std::string substitutionValue; @@ -352,9 +345,9 @@ namespace zypp } } -#if ( ZYPP_DBG_VAREXPAND ) + #if ( ZYPP_DBG_VAREXPAND ) dbg << std::string( dbgsbeg ) << (scan._sbeg == value_r.c_str() ? "<<\033[36m(moved)\033[0m" : ""); -#endif // ZYPP_DBG_VAREXPAND + #endif // ZYPP_DBG_VAREXPAND // handle unwritten data: if ( scan._sbeg != value_r.c_str() ) @@ -367,11 +360,11 @@ namespace zypp ; // no replacements at all } -#if ( ZYPP_DBG_VAREXPAND ) + #if ( ZYPP_DBG_VAREXPAND ) dbg << "<<"; cout << dbg.str() << endl; cout << std::string( 2*level_r, ' ' ) << "\033[36m->" << result_r << "<-\033[0m" << endl; -#endif // ZYPP_DBG_VAREXPAND + #endif // ZYPP_DBG_VAREXPAND return expanded; } } // namespace @@ -383,205 +376,67 @@ namespace zypp std::string RepoVarExpand::operator()( std::string && value_r, VarRetriever varRetriever_r ) const { return expand( std::move(value_r), 0, varRetriever_r ); } - /////////////////////////////////////////////////////////////////// - // RepoVariables*Replace - /////////////////////////////////////////////////////////////////// - namespace - { - class RepoVarsMap : public std::map - { - public: - static RepoVarsMap & instance() - { static RepoVarsMap _instance; return _instance; } - - static const std::string * lookup( const std::string & name_r ) - { return instance()._lookup( name_r ); } - private: - const std::string * _lookup( const std::string & name_r ) - { - // Safe guard in case the caller does not own a zypp instance. In this case - // getZYpp()->getTarget() in checkOverride would create a zypp instance which - // would clear the variables parsed so far. - auto guard { getZYpp() }; - - if ( empty() ) // at init / after reset - { - // load user definitions from vars.d - filesystem::dirForEach( ZConfig::instance().repoManagerRoot() / ZConfig::instance().varsPath(), - filesystem::matchNoDots(), bind( &RepoVarsMap::parse, this, _1, _2 ) ); - // releasever_major/_minor are per default derived from releasever. - // If releasever is userdefined, inject missing _major/_minor too. - deriveFromReleasever( "releasever", /*dont't overwrite user defined values*/false ); - - dumpOn( DBG ); - // add builtin vars except for releasever{,_major,_minor} (see checkOverride) - { - const Arch & arch( ZConfig::instance().systemArchitecture() ); - { - std::string & var( operator[]( "arch" ) ); - if ( var.empty() ) var = arch.asString(); - } - { - std::string & var( operator[]( "basearch" ) ); - if ( var.empty() ) var = arch.baseArch().asString(); - } - } - } - - const std::string * ret = checkOverride( name_r ); - if ( !ret ) - { - // get value from map - iterator it = find( name_r ); - if ( it != end() ) - ret = &(it->second); - } - - return ret; - } - - std::ostream & dumpOn( std::ostream & str ) const - { - for ( auto && kv : *this ) - { - str << '{' << kv.first << '=' << kv.second << '}' << endl; - } - return str; - } - - private: - /** Get first line from file */ - bool parse( const Pathname & dir_r, const std::string & str_r ) - { - std::ifstream file( (dir_r/str_r).c_str() ); - operator[]( str_r ) = str::getline( file, /*trim*/false ); - return true; - } - - /** Derive \c releasever_major/_minor from \c releasever, keeping or overwrititing existing values. */ - void deriveFromReleasever( const std::string & stem_r, bool overwrite_r ) - { - if ( count( stem_r ) ) // releasever is defined.. - { - const std::string & stem_major( stem_r+"_major" ); - const std::string & stem_minor( stem_r+"_minor" ); - if ( overwrite_r ) - splitReleaseverTo( operator[]( stem_r ), &operator[]( stem_major ), &operator[]( stem_minor ) ); - else - splitReleaseverTo( operator[]( stem_r ), - count( stem_major ) ? nullptr : &operator[]( stem_major ), - count( stem_minor ) ? nullptr : &operator[]( stem_minor ) ); - } - } - - /** Split \c releasever at \c '.' and store major/minor parts as requested. */ - void splitReleaseverTo( const std::string & releasever_r, std::string * major_r, std::string * minor_r ) const - { - if ( major_r || minor_r ) - { - std::string::size_type pos = releasever_r.find( '.' ); - if ( pos == std::string::npos ) - { - if ( major_r ) *major_r = releasever_r; - if ( minor_r ) minor_r->clear(); - } - else - { - if ( major_r ) *major_r = releasever_r.substr( 0, pos ); - if ( minor_r ) *minor_r = releasever_r.substr( pos+1 ) ; - } - } - } + std::string RepoVariablesStringReplacer::operator()(const std::string &value_r) const + { + return RepoVariablesStringReplacerNg( RepoVarRetriever( *zypp_detail::GlobalStateHelper::context () ) )( value_r ); + } - /** Check for conditions overwriting the (user) defined values. */ - const std::string * checkOverride( const std::string & name_r ) - { - /////////////////////////////////////////////////////////////////// - // Always check for changing releasever{,_major,_minor} (bnc#943563) - if ( str::startsWith( name_r, "releasever" ) - && ( name_r.size() == 10 - || strcmp( name_r.c_str()+10, "_minor" ) == 0 - || strcmp( name_r.c_str()+10, "_major" ) == 0 ) ) - { - std::string val( env::ZYPP_REPO_RELEASEVER() ); - if ( !val.empty() ) - { - // $ZYPP_REPO_RELEASEVER always overwrites any defined value - if ( val != operator[]( "$releasever" ) ) - { - operator[]( "$releasever" ) = std::move(val); - deriveFromReleasever( "$releasever", /*overwrite previous values*/true ); - } - return &operator[]( "$"+name_r ); - } - else if ( !count( name_r ) ) - { - // No user defined value, so we follow the target - Target_Ptr trg( getZYpp()->getTarget() ); - if ( trg ) - val = trg->distributionVersion(); - else - val = Target::distributionVersion( Pathname()/*guess*/ ); + std::string RepoVariablesStringReplacer::operator()( std::string &&value_r ) const + { + return RepoVariablesStringReplacerNg( RepoVarRetriever( *zypp_detail::GlobalStateHelper::context () ) )( std::move(value_r) ); + } - if ( val != operator[]( "$_releasever" ) ) - { - operator[]( "$_releasever" ) = std::move(val); - deriveFromReleasever( "$_releasever", /*overwrite previous values*/true ); - } - return &operator[]( "$_"+name_r ); - } - // else: - return nullptr; // get user value from map - } - /////////////////////////////////////////////////////////////////// + zypp::Url RepoVariablesUrlReplacer::operator()(const zypp::Url &value) const + { + return RepoVariablesUrlReplacerNg( RepoVarRetriever( *zypp_detail::GlobalStateHelper::context () ) )( value ); + } - return nullptr; // get user value from map - } - }; - } // namespace - /////////////////////////////////////////////////////////////////// + RepoVariablesStringReplacerNg::RepoVariablesStringReplacerNg(RepoVarRetrieverFunctor varRetriever) + : _varRetriever( std::move(varRetriever) ) + {} - std::string RepoVariablesStringReplacer::operator()( const std::string & value ) const + std::string RepoVariablesStringReplacerNg::operator()(const std::string &value_r) const { - return RepoVarExpand()( value, RepoVarsMap::lookup ); + if ( _varRetriever ) + return repo::RepoVarExpand()( value_r, _varRetriever ); + return value_r; } - std::string RepoVariablesStringReplacer::operator()( std::string && value ) const + + std::string RepoVariablesStringReplacerNg::operator()( std::string &&value_r ) const { - return RepoVarExpand()( std::move(value), RepoVarsMap::lookup ); + if ( _varRetriever ) + return repo::RepoVarExpand()( std::move(value_r), _varRetriever ); + return value_r; } - Url RepoVariablesUrlReplacer::operator()( const Url & value ) const + RepoVariablesUrlReplacerNg::RepoVariablesUrlReplacerNg(RepoVarRetrieverFunctor varRetriever) + : _varRetriever( std::move(varRetriever) ) + { } + + zypp::Url RepoVariablesUrlReplacerNg::operator()(const zypp::Url &value) const { - Url::ViewOptions toReplace = value.getViewOptions() - url::ViewOption::WITH_USERNAME - url::ViewOption::WITH_PASSWORD; - // Legacy: Not 100% correct because it substitutes inside the 'proxypass=' value, - // but this was done before as well. The final fix will have to keep the proxypasswd - // out side the url in a cedential file. - Url tmpurl { value }; - tmpurl.setViewOptions( toReplace ); - const std::string & replaced( RepoVarExpand()( hotfix1050625::asString( tmpurl ), RepoVarsMap::lookup ) ); - - Url newurl; - if ( !replaced.empty() ) - { - newurl = replaced; - newurl.setUsername( value.getUsername( url::E_ENCODED ), url::E_ENCODED ); - newurl.setPassword( value.getPassword( url::E_ENCODED ), url::E_ENCODED ); - newurl.setViewOptions( value.getViewOptions() ); + if ( _varRetriever ) { + zypp::Url::ViewOptions toReplace = value.getViewOptions() - zypp::url::ViewOption::WITH_USERNAME - zypp::url::ViewOption::WITH_PASSWORD; + // Legacy: Not 100% correct because it substitutes inside the 'proxypass=' value, + // but this was done before as well. The final fix will have to keep the proxypasswd + // out side the url in a cedential file. + zypp::Url tmpurl { value }; + tmpurl.setViewOptions( toReplace ); + const std::string & replaced( zypp::repo::RepoVarExpand()( zypp::hotfix1050625::asString( tmpurl ), _varRetriever ) ); + + zypp::Url newurl; + if ( !replaced.empty() ) + { + newurl = replaced; + newurl.setUsername( value.getUsername( zypp::url::E_ENCODED ), zypp::url::E_ENCODED ); + newurl.setPassword( value.getPassword( zypp::url::E_ENCODED ), zypp::url::E_ENCODED ); + newurl.setViewOptions( value.getViewOptions() ); + } + return newurl; } - return newurl; + return value; } } // namespace repo /////////////////////////////////////////////////////////////////// } // namespace zypp -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// -namespace zyppintern -{ - using namespace zypp; - // internal helper called when re-acquiring the lock - void repoVariablesReset() - { repo::RepoVarsMap::instance().clear(); } - -} // namespace zyppintern -/////////////////////////////////////////////////////////////////// diff --git a/zypp/repo/RepoVariables.h b/zypp/repo/RepoVariables.h index 6c22c99ed4..3613148818 100644 --- a/zypp/repo/RepoVariables.h +++ b/zypp/repo/RepoVariables.h @@ -22,6 +22,38 @@ namespace zypp /////////////////////////////////////////////////////////////////// namespace repo { + + /** Function taking a variable name and returning a pointer to the variable value or \c nullptr if unset. */ + using RepoVarRetrieverFunctor = std::function; + + /*! + * Helper functor class, requires a reference to a object + * implementing a function called \a resolveRepoVar with the RepoVarRetrieverFunctor signature. + * + * \code + * const std::string * SomeType::resolveRepoVar (const std::string &); + * \endcode + */ + template + struct RepoVarRetriever + { + RepoVarRetriever(T &varContainer) : _varContainer(varContainer) {} + + ~RepoVarRetriever() = default; + RepoVarRetriever(const RepoVarRetriever &) = default; + RepoVarRetriever(RepoVarRetriever &&) = default; + RepoVarRetriever &operator=(const RepoVarRetriever &) = default; + RepoVarRetriever &operator=(RepoVarRetriever &&) = default; + + const std::string * operator() (const std::string &val) { + return std::invoke ( memFn, _varContainer.get(), val ); + } + + private: + std::reference_wrapper _varContainer; + }; + + /////////////////////////////////////////////////////////////////// /// \class RepoVarExpand /// \brief Functor expanding repo variables in a string @@ -57,7 +89,7 @@ namespace zypp struct ZYPP_API RepoVarExpand { /** Function taking a variable name and returning a pointer to the variable value or \c nullptr if unset. */ - using VarRetriever = function; + using VarRetriever = RepoVarRetrieverFunctor; /** Return a copy of \a value_r with embedded variables expanded. */ std::string operator()( const std::string & value_r, VarRetriever varRetriever_r ) const; @@ -102,7 +134,7 @@ namespace zypp * * \see \ref RepoVarExpand for supported variable syntax. */ - struct ZYPP_API RepoVariablesStringReplacer + struct ZYPP_API ZYPP_INTERNAL_DEPRECATE RepoVariablesStringReplacer { std::string operator()( const std::string & value_r ) const; @@ -116,24 +148,60 @@ namespace zypp * Replaces repository variables in the URL (except for user/pass inside authority) * \see RepoVariablesStringReplacer */ - struct ZYPP_API RepoVariablesUrlReplacer + struct ZYPP_API ZYPP_INTERNAL_DEPRECATE RepoVariablesUrlReplacer { Url operator()( const Url & url_r ) const; }; + + /*! + * Like \ref RepoVariablesStringReplacer, but uses a explicit \ref RepoVarRetrieverFunctor + * instead of a global static to retrieve variables + */ + struct ZYPP_API RepoVariablesStringReplacerNg + { + RepoVariablesStringReplacerNg( RepoVarRetrieverFunctor varRetriever = nullptr ); + + std::string operator()( const std::string & value_r ) const; + + /** \overload moving */ + std::string operator()( std::string && value_r ) const; + + private: + RepoVarRetrieverFunctor _varRetriever; + }; + + /*! + * Like \ref RepoVariablesUrlReplacer, but uses a explicit \ref RepoVarRetrieverFunctor + * instead of a global static to retrieve variables + */ + struct ZYPP_API RepoVariablesUrlReplacerNg + { + RepoVariablesUrlReplacerNg( RepoVarRetrieverFunctor varRetriever = nullptr ); + + zypp::Url operator()( const zypp::Url & value ) const; + + private: + RepoVarRetrieverFunctor _varRetriever; + }; + } // namespace repo /////////////////////////////////////////////////////////////////// + ZYPP_BEGIN_LEGACY_API + /** \relates RepoVariablesStringReplacer Helper managing repo variables replaced strings */ - using RepoVariablesReplacedString = base::ValueTransform; + using RepoVariablesReplacedString ZYPP_INTERNAL_DEPRECATE = base::ValueTransform; /** \relates RepoVariablesStringReplacer Helper managing repo variables replaced string lists */ - using RepoVariablesReplacedStringList = base::ContainerTransform, repo::RepoVariablesStringReplacer>; + using RepoVariablesReplacedStringList ZYPP_INTERNAL_DEPRECATE = base::ContainerTransform, repo::RepoVariablesStringReplacer>; /** \relates RepoVariablesUrlReplacer Helper managing repo variables replaced urls */ - using RepoVariablesReplacedUrl = base::ValueTransform; + using RepoVariablesReplacedUrl ZYPP_INTERNAL_DEPRECATE = base::ValueTransform; /** \relates RepoVariablesUrlReplacer Helper managing repo variables replaced url lists */ - using RepoVariablesReplacedUrlList = base::ContainerTransform, repo::RepoVariablesUrlReplacer>; + using RepoVariablesReplacedUrlList ZYPP_INTERNAL_DEPRECATE = base::ContainerTransform, repo::RepoVariablesUrlReplacer>; + + ZYPP_END_LEGACY_API } // namespace zypp /////////////////////////////////////////////////////////////////// diff --git a/zypp/repo/ServiceRepoState.cc b/zypp/repo/ServiceRepoState.cc new file mode 100644 index 0000000000..5b35c98864 --- /dev/null +++ b/zypp/repo/ServiceRepoState.cc @@ -0,0 +1,27 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +#include "ServiceRepoState.h" + +#include + +namespace zypp { + + ServiceRepoState::ServiceRepoState( const zyppng::RepoInfo &repo_r ) + : enabled( repo_r.enabled() ), autorefresh( repo_r.autorefresh() ), priority( repo_r.priority() ) + {} + +ZYPP_BEGIN_LEGACY_API + ServiceRepoState::ServiceRepoState(const RepoInfo &repo_r) + : ServiceRepoState(repo_r.ngRepoInfo()) {} +ZYPP_END_LEGACY_API + + ServiceRepoState::ServiceRepoState() + : enabled(false), autorefresh(true), + priority(zyppng::RepoInfo::defaultPriority()) {} +} // namespace zypp diff --git a/zypp/repo/ServiceRepoState.h b/zypp/repo/ServiceRepoState.h new file mode 100644 index 0000000000..5cbbcd46f2 --- /dev/null +++ b/zypp/repo/ServiceRepoState.h @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/repo/ServiceInfo.h + * + */ +#ifndef ZYPP_REPO_SERVICE_REPO_STATE_H +#define ZYPP_REPO_SERVICE_REPO_STATE_H + +#include + +namespace zyppng { + class RepoInfo; +} + +namespace zypp +{ + + /** \name The original repo state as defined by the repoindex.xml upon last refresh. + * + * This state is remembered to detect any user modifications applied to the repos. + * It may not be available for all repos or in plugin services. In this case all + * changes requested by a service refresh are applied unconditionally. + */ + //@{ + struct ZYPP_API ServiceRepoState + { + bool enabled; + bool autorefresh; + unsigned priority; + + ServiceRepoState(); + + ServiceRepoState( const RepoInfo &repo_r ) ZYPP_INTERNAL_DEPRECATE; + + ServiceRepoState( const zyppng::RepoInfo &repo_r ); + + bool operator==( const ServiceRepoState & rhs ) const + { return( enabled==rhs.enabled && autorefresh==rhs.autorefresh && priority==rhs.priority ); } + bool operator!=( const ServiceRepoState & rhs ) const + { return ! operator==( rhs ); } + friend std::ostream & operator<<( std::ostream & str, const ServiceRepoState & obj ); + }; + +} + +#endif diff --git a/zypp/repo/SrcPackageProvider.cc b/zypp/repo/SrcPackageProvider.cc index a6a95a7195..51016ae006 100644 --- a/zypp/repo/SrcPackageProvider.cc +++ b/zypp/repo/SrcPackageProvider.cc @@ -12,10 +12,13 @@ #include #include +#include #include #include #include #include +#include +#include using std::endl; @@ -25,7 +28,6 @@ namespace zypp /////////////////////////////////////////////////////////////////// namespace repo { - SrcPackageProvider::SrcPackageProvider( repo::RepoMediaAccess & access_r ) : _access( access_r ) {} @@ -34,7 +36,16 @@ namespace zypp {} ManagedFile SrcPackageProvider::provideSrcPackage( const SrcPackage_constPtr & srcPackage_r ) const - { return _access.provideFile( srcPackage_r->repoInfo(), srcPackage_r->location() ); } + { + const auto &ri = srcPackage_r->ngRepoInfo(); + if ( !ri ) { + RepoException repo_excpt(str::form(_("Can't provide file '%s' without a RepoInfo"), + srcPackage_r->location().filename().c_str() ) ); + + ZYPP_THROW(repo_excpt); + } + return _access.provideFile( *ri, srcPackage_r->location() ); + } } // namespace repo /////////////////////////////////////////////////////////////////// diff --git a/zypp/repo/detail/RepoInfoBaseImpl.h b/zypp/repo/detail/RepoInfoBaseImpl.h deleted file mode 100644 index 1c0b4d0767..0000000000 --- a/zypp/repo/detail/RepoInfoBaseImpl.h +++ /dev/null @@ -1,55 +0,0 @@ -/*---------------------------------------------------------------------\ -| ____ _ __ __ ___ | -| |__ / \ / / . \ . \ | -| / / \ V /| _/ _/ | -| / /__ | | | | | | | -| /_____||_| |_| |_| | -| | -\---------------------------------------------------------------------*/ -/** \file zypp/repo/detail/RepoInfoBaseImpl.h - * -*/ - -#include -#include -#include - -namespace zypp::repo -{ - - /////////////////////////////////////////////////////////////////// - /// \class RepoInfoBase::Impl - /// \brief RepoInfoBase data - /////////////////////////////////////////////////////////////////// - struct RepoInfoBase::Impl - { - Impl(const Impl &) = default; - Impl(Impl &&) = delete; - Impl &operator=(const Impl &) = default; - Impl &operator=(Impl &&) = delete; - Impl(zyppng::ContextBaseRef &&context); - - Impl( zyppng::ContextBaseRef &&context, const std::string & alias_r ); - - virtual ~Impl() = default; - - public: - zyppng::ContextBaseRef _ctx; - TriBool _enabled; - TriBool _autorefresh; - std::string _alias; - std::string _escaped_alias; - RepoVariablesReplacedString _name; - Pathname _filepath; - - public: - - void setAlias( const std::string & alias_r ); - - private: - friend Impl * rwcowClone( const Impl * rhs ); - - /** clone for RWCOW_pointer */ - virtual Impl *clone() const; - }; -} diff --git a/zypp/repo/yum/RepomdFileCollector.cc b/zypp/repo/yum/RepomdFileCollector.cc index 8eb7692207..1d77625e99 100644 --- a/zypp/repo/yum/RepomdFileCollector.cc +++ b/zypp/repo/yum/RepomdFileCollector.cc @@ -10,7 +10,8 @@ #include "RepomdFileCollector.h" #include #include -#include +#include +#include #include namespace zypp::env @@ -89,11 +90,11 @@ namespace zypp::repo::yum * Localized type: * susedata.LOCALE */ - RepomdFileCollector::RepomdFileCollector( const Pathname &destDir_r ) + RepomdFileCollector::RepomdFileCollector( zyppng::ContextBaseRef ctx, const Pathname &destDir_r ) : _destDir { destDir_r } { - addWantedLocale( ZConfig::instance().textLocale() ); - for ( const Locale & it : ZConfig::instance().repoRefreshLocales() ) + addWantedLocale( ctx->config().textLocale() ); + for ( const Locale & it : ctx->config().repoRefreshLocales() ) addWantedLocale( it ); } diff --git a/zypp/repo/yum/RepomdFileCollector.h b/zypp/repo/yum/RepomdFileCollector.h index a5875c5588..101db720ca 100644 --- a/zypp/repo/yum/RepomdFileCollector.h +++ b/zypp/repo/yum/RepomdFileCollector.h @@ -10,6 +10,7 @@ #ifndef ZYPP_SOURCE_YUM_REPOMDFILECOLLECTOR #define ZYPP_SOURCE_YUM_REPOMDFILECOLLECTOR +#include #include #include #include @@ -18,6 +19,10 @@ #include #include +namespace zyppng { + class RepoInfo; +} + namespace zypp::repo::yum { @@ -28,7 +33,7 @@ namespace zypp::repo::yum using FinalizeCb = std::function; - RepomdFileCollector( const Pathname & destDir_r ); + RepomdFileCollector( zyppng::ContextBaseRef ctx, const Pathname & destDir_r ); virtual ~RepomdFileCollector(); bool collect( const OnMediaLocation & loc_r, const std::string & typestr_r ); @@ -36,7 +41,7 @@ namespace zypp::repo::yum void finalize( const FinalizeCb &cb ); protected: - virtual const RepoInfo &repoInfo() const = 0; + virtual const zyppng::RepoInfo &repoInfo() const = 0; virtual const Pathname &deltaDir() const = 0; private: diff --git a/zypp/sat/Pool.cc b/zypp/sat/Pool.cc index 3eeddbe4f9..ef6ba12c5d 100644 --- a/zypp/sat/Pool.cc +++ b/zypp/sat/Pool.cc @@ -34,6 +34,8 @@ extern "C" #include #include +#include + using std::endl; /////////////////////////////////////////////////////////////////// @@ -150,7 +152,7 @@ namespace zypp if ( ret.isSystemRepo() ) { // autoprovide (dummy) RepoInfo - RepoInfo info; + zyppng::RepoInfo info(nullptr); info.setAlias( alias_r ); info.setName( alias_r ); info.setAutorefresh( true ); @@ -197,7 +199,14 @@ namespace zypp Repository Pool::addRepoSolv( const Pathname & file_r ) { return addRepoSolv( file_r, file_r.basename() ); } + ZYPP_BEGIN_LEGACY_API Repository Pool::addRepoSolv( const Pathname & file_r, const RepoInfo & info_r ) + { + return addRepoSolv( file_r, info_r.ngRepoInfo() ); + } + ZYPP_END_LEGACY_API + + Repository Pool::addRepoSolv( const Pathname & file_r, const zyppng::RepoInfo & info_r ) { Repository ret( addRepoSolv( file_r, info_r.alias() ) ); ret.setInfo( info_r ); @@ -221,13 +230,20 @@ namespace zypp Repository Pool::addRepoHelix( const Pathname & file_r ) { return addRepoHelix( file_r, file_r.basename() ); } - Repository Pool::addRepoHelix( const Pathname & file_r, const RepoInfo & info_r ) + Repository Pool::addRepoHelix( const Pathname & file_r, const zyppng::RepoInfo & info_r ) { Repository ret( addRepoHelix( file_r, info_r.alias() ) ); ret.setInfo( info_r ); return ret; } + ZYPP_BEGIN_LEGACY_API + Repository Pool::addRepoHelix( const Pathname & file_r, const RepoInfo & info_r ) + { + return addRepoHelix( file_r, info_r.ngRepoInfo() ); + } + ZYPP_END_LEGACY_API + ///////////////////////////////////////////////////////////////// void Pool::setTextLocale( const Locale & locale_r ) diff --git a/zypp/sat/Pool.h b/zypp/sat/Pool.h index e57126c6bb..80a619412d 100644 --- a/zypp/sat/Pool.h +++ b/zypp/sat/Pool.h @@ -22,6 +22,10 @@ #include #include +namespace zyppng { + class RepoInfo; +} + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// @@ -141,7 +145,11 @@ namespace zypp /** \overload Using the \ref RepoInfo::alias \ref Repo name. * Additionally stores the \ref RepoInfo. \See \ref Prool::setInfo. */ - Repository addRepoSolv( const Pathname & file_r, const RepoInfo & info_r ); + ZYPP_BEGIN_LEGACY_API + Repository ZYPP_INTERNAL_DEPRECATE addRepoSolv( const Pathname & file_r, const RepoInfo & info_r ); + ZYPP_END_LEGACY_API + + Repository addRepoSolv( const Pathname & file_r, const zyppng::RepoInfo & info_r ); public: /** Load \ref Solvables from a helix-file into a \ref Repository named \c name_r. @@ -156,7 +164,11 @@ namespace zypp /** \overload Using the \ref RepoInfo::alias \ref Repo name. * Additionally stores the \ref RepoInfo. \See \ref Prool::setInfo. */ - Repository addRepoHelix( const Pathname & file_r, const RepoInfo & info_r ); + ZYPP_BEGIN_LEGACY_API + Repository ZYPP_INTERNAL_DEPRECATE addRepoHelix( const Pathname & file_r, const RepoInfo & info_r ); + ZYPP_END_LEGACY_API + + Repository addRepoHelix( const Pathname & file_r, const zyppng::RepoInfo & info_r ); public: /** Whether \ref Pool contains solvables. */ diff --git a/zypp/sat/Solvable.cc b/zypp/sat/Solvable.cc index d7c9518872..c5a2857c5e 100644 --- a/zypp/sat/Solvable.cc +++ b/zypp/sat/Solvable.cc @@ -29,6 +29,7 @@ #include #include +#include using std::endl; @@ -234,28 +235,32 @@ namespace zypp medianr = 1; OnMediaLocation ret; - Pathname path; - switch ( repository().info().type().toEnum() ) - { - case repo::RepoType::NONE_e: - { - path = lookupDatadirIn( repository() ); - if ( ! path.empty() ) - repository().info().setProbedType( repo::RepoType::YAST2_e ); - } - break; - case repo::RepoType::YAST2_e: + const auto &ri = repository().ngInfo(); + if ( ri ) { + switch ( ri->type().toEnum() ) { - path = lookupDatadirIn( repository() ); - if ( path.empty() ) - path = "suse"; - } - break; + case repo::RepoType::NONE_e: + { + path = lookupDatadirIn( repository() ); + if ( ! path.empty() ) { + ri->setProbedType( repo::RepoType::YAST2_e ); + } + } + break; - default: + case repo::RepoType::YAST2_e: + { + path = lookupDatadirIn( repository() ); + if ( path.empty() ) + path = "suse"; + } break; + + default: + break; + } } ret.setLocation ( path/file, medianr ); ret.setDownloadSize( ByteCount( lookupNumAttribute( SolvAttr::downloadsize ) ) ); @@ -367,9 +372,13 @@ namespace zypp return Repository( _solvable->repo ); } + ZYPP_BEGIN_LEGACY_API RepoInfo Solvable::repoInfo() const { return repository().info(); } + ZYPP_END_LEGACY_API + const std::optional &Solvable::ngRepoInfo() const + { return repository().ngInfo(); } bool Solvable::isSystem() const { @@ -747,28 +756,34 @@ namespace zypp std::string ret = lookupStrAttribute( SolvAttr::eula, lang_r ); if ( ret.empty() && isKind() ) { - const RepoInfo & ri( repoInfo() ); + const auto &ri( ngRepoInfo () ); + if ( !ri ) + return ret; + std::string riname( name() ); // "license-"+name with fallback "license" - if ( ! ri.hasLicense( riname ) ) + if ( ! ri->hasLicense( riname ) ) riname.clear(); - if ( ri.needToAcceptLicense( riname ) || ! ui::Selectable::get( *this )->hasInstalledObj() ) - ret = ri.getLicense( riname, lang_r ); // bnc#908976: suppress informal license upon update + if ( ri->needToAcceptLicense( riname ) || ! ui::Selectable::get( *this )->hasInstalledObj() ) + ret = ri->getLicense( riname, lang_r ); // bnc#908976: suppress informal license upon update } return ret; } bool Solvable::needToAcceptLicense() const { - NO_SOLVABLE_RETURN( false ); + NO_SOLVABLE_RETURN( true ); if ( isKind() ) { - const RepoInfo & ri( repoInfo() ); + const auto &ri( ngRepoInfo() ); + if ( !ri ) + return true; + std::string riname( name() ); // "license-"+name with fallback "license" - if ( ! ri.hasLicense( riname ) ) + if ( !ri->hasLicense( riname ) ) riname.clear(); - return ri.needToAcceptLicense( riname ); + return ri->needToAcceptLicense( riname ); } return true; } diff --git a/zypp/sat/Solvable.h b/zypp/sat/Solvable.h index f48be2c929..ae11eead4e 100644 --- a/zypp/sat/Solvable.h +++ b/zypp/sat/Solvable.h @@ -24,6 +24,11 @@ #include #include #include +#include + +namespace zyppng { + class RepoInfo; +} /////////////////////////////////////////////////////////////////// namespace zypp @@ -121,8 +126,15 @@ namespace zypp /** The \ref Repository this \ref Solvable belongs to. */ Repository repository() const; + + ZYPP_BEGIN_LEGACY_API /** The repositories \ref RepoInfo. */ - RepoInfo repoInfo() const; + RepoInfo repoInfo() const ZYPP_INTERNAL_DEPRECATE; + ZYPP_END_LEGACY_API + +#ifdef __cpp_lib_optional + const std::optional &ngRepoInfo() const; +#endif /** Return whether this \ref Solvable belongs to the system repo. * \note This includes the otherwise hidden systemSolvable. diff --git a/zypp/sat/SolvableType.h b/zypp/sat/SolvableType.h index 9dcc013d20..3ba7caece7 100644 --- a/zypp/sat/SolvableType.h +++ b/zypp/sat/SolvableType.h @@ -13,6 +13,7 @@ #include +#include #include #include #include @@ -21,6 +22,10 @@ #include #include +namespace zyppng { + class RepoInfo; +} + /////////////////////////////////////////////////////////////////// namespace zypp { @@ -73,7 +78,14 @@ namespace zypp IdString vendor() const { return satSolvable().vendor(); } Repository repository() const { return satSolvable().repository(); } - RepoInfo repoInfo() const { return satSolvable().repoInfo(); } + + ZYPP_BEGIN_LEGACY_API + RepoInfo repoInfo() const ZYPP_INTERNAL_DEPRECATE { return satSolvable().repoInfo(); } + ZYPP_END_LEGACY_API + +#ifdef __cpp_lib_optional + const std::optional &ngRepoInfo() const { return satSolvable().ngRepoInfo(); } +#endif bool isSystem() const { return satSolvable().isSystem(); } bool onSystemByUser() const { return satSolvable().onSystemByUser(); } diff --git a/zypp/sat/detail/PoolImpl.cc b/zypp/sat/detail/PoolImpl.cc index 6466cec3b8..807c2d482d 100644 --- a/zypp/sat/detail/PoolImpl.cc +++ b/zypp/sat/detail/PoolImpl.cc @@ -34,6 +34,8 @@ #include #include +#include + extern "C" { // Workaround libsolv project not providing a common include @@ -427,24 +429,29 @@ namespace zypp return ::repo_add_solvable_block( repo_r, count_r ); } - void PoolImpl::setRepoInfo( RepoIdType id_r, const RepoInfo & info_r ) + void PoolImpl::setRepoInfo(RepoIdType id_r, const std::optional &info_r ) { CRepo * repo( getRepo( id_r ) ); if ( repo ) { + if ( !info_r ) { + eraseRepoInfo ( id_r ); + return; + } + bool dirty = false; // libsolv priority is based on '<', while yum's repoinfo // uses 1(highest)->99(lowest). Thus we use -info_r.priority. - if ( repo->priority != int(-info_r.priority()) ) + if ( repo->priority != int(-info_r->priority()) ) { - repo->priority = -info_r.priority(); + repo->priority = -info_r->priority(); dirty = true; } // subpriority is used to e.g. prefer http over dvd iff // both have same priority. - int mediaPriority( media::MediaPriority( info_r.url() ) ); + int mediaPriority( media::MediaPriority( info_r->url() ) ); if ( repo->subpriority != mediaPriority ) { repo->subpriority = mediaPriority; @@ -452,11 +459,19 @@ namespace zypp } if ( dirty ) - setDirty(__FUNCTION__, info_r.alias().c_str() ); + setDirty(__FUNCTION__, info_r->alias().c_str() ); } - _repoinfos[id_r] = info_r; + _repoinfos.insert_or_assign( id_r, *info_r ); } + const std::optional &PoolImpl::repoInfo(RepoIdType id_r) + { + return _repoinfos[id_r]; + } + + void PoolImpl::eraseRepoInfo(RepoIdType id_r) + { _repoinfos.erase(id_r); } + /////////////////////////////////////////////////////////////////// void PoolImpl::setTextLocale( const Locale & locale_r ) diff --git a/zypp/sat/detail/PoolImpl.h b/zypp/sat/detail/PoolImpl.h index 0e697c5033..9b7edb23d0 100644 --- a/zypp/sat/detail/PoolImpl.h +++ b/zypp/sat/detail/PoolImpl.h @@ -21,6 +21,7 @@ extern "C" #include } #include +#include #include #include @@ -34,6 +35,10 @@ extern "C" #include #include +namespace zyppng { + class RepoInfo; +} + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// @@ -215,13 +220,13 @@ namespace zypp public: /** */ - const RepoInfo & repoInfo( RepoIdType id_r ) - { return _repoinfos[id_r]; } + const std::optional &repoInfo( RepoIdType id_r ); + /** Also adjust repo priority and subpriority accordingly. */ - void setRepoInfo( RepoIdType id_r, const RepoInfo & info_r ); + void setRepoInfo( RepoIdType id_r, const std::optional & info_r ); + /** */ - void eraseRepoInfo( RepoIdType id_r ) - { _repoinfos.erase( id_r ); } + void eraseRepoInfo(RepoIdType id_r); public: /** Returns the id stored at \c offset_r in the internal @@ -361,7 +366,7 @@ namespace zypp /** Watch serial number. */ SerialNumberWatcher _watcher; /** Additional \ref RepoInfo. */ - std::map _repoinfos; + std::map> _repoinfos; /** */ base::SetTracker _requestedLocalesTracker; diff --git a/zypp/solver/detail/Testcase.cc b/zypp/solver/detail/Testcase.cc index e4eab3676f..3202ec8a12 100644 --- a/zypp/solver/detail/Testcase.cc +++ b/zypp/solver/detail/Testcase.cc @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -163,21 +164,21 @@ namespace zypp } const auto &myRepo = pi.repository(); - const auto &myRepoInfo = myRepo.info(); - if ( repos.find( myRepo.id()) == repos.end() ) { + const auto &myRepoInfo = myRepo.ngInfo(); + if ( myRepoInfo && repos.find( myRepo.id()) == repos.end() ) { repos.insert( myRepo.id() ); yOut << YAML::Value << YAML::BeginMap; yOut << YAML::Key << "alias" << YAML::Value << myRepo.alias(); yOut << YAML::Key << "url" << YAML::BeginSeq; - for ( auto itUrl = myRepoInfo.baseUrlsBegin(); itUrl != myRepoInfo.baseUrlsEnd(); ++itUrl ) { + for ( auto itUrl = myRepoInfo->baseUrlsBegin(); itUrl != myRepoInfo->baseUrlsEnd(); ++itUrl ) { yOut << YAML::Value << itUrl->asString(); } yOut << YAML::EndSeq; - yOut << YAML::Key << "path" << YAML::Value << myRepoInfo.path().asString(); - yOut << YAML::Key << "type" << YAML::Value << myRepoInfo.type().asString(); + yOut << YAML::Key << "path" << YAML::Value << myRepoInfo->path().asString(); + yOut << YAML::Key << "type" << YAML::Value << myRepoInfo->type().asString(); yOut << YAML::Key << "generated" << YAML::Value << myRepo.generatedTimestamp().form( "%Y-%m-%d %H:%M:%S" ); yOut << YAML::Key << "outdated" << YAML::Value << myRepo.suggestedExpirationTimestamp().form( "%Y-%m-%d %H:%M:%S" ); - yOut << YAML::Key << "priority" << YAML::Value << myRepoInfo.priority(); + yOut << YAML::Key << "priority" << YAML::Value << myRepoInfo->priority(); yOut << YAML::Key << "file" << YAML::Value << str::Format("%1%.repo.gz") % repoFileNames[myRepo.id()->repoid]; yOut << YAML::EndMap; @@ -330,7 +331,7 @@ namespace zypp << YAML::Key << "name" << YAML::Value << pi.name() << YAML::Key << "status" << YAML::Value << status.str(); if ( !shortInfo ) { - yOut << YAML::Key << "channel" << YAML::Value << pi.repoInfo().alias() + yOut << YAML::Key << "channel" << YAML::Value << (pi.ngRepoInfo() ? pi.ngRepoInfo()->alias() : "") << YAML::Key << "arch" << YAML::Value << pi.arch().asString() << YAML::Key << "version" << YAML::Value << pi.edition().version() << YAML::Key << "release" << YAML::Value << pi.edition().release(); diff --git a/zypp/target/CommitPackageCacheReadAhead.cc b/zypp/target/CommitPackageCacheReadAhead.cc index 8c6433b9e3..30bc0c9e13 100644 --- a/zypp/target/CommitPackageCacheReadAhead.cc +++ b/zypp/target/CommitPackageCacheReadAhead.cc @@ -18,6 +18,8 @@ #include #include +#include + using std::endl; /////////////////////////////////////////////////////////////////// @@ -36,7 +38,7 @@ namespace zypp std::ostream & operator<<( std::ostream & str, const IMediaKey & obj ) { return str << "[S" << obj._repo.id() << ":" << obj._mediaNr << "]" - << " " << obj._repo.info().alias(); + << " " << (obj._repo.ngInfo() ? obj._repo.ngInfo()->alias() : "norepo" ); } /////////////////////////////////////////////////////////////////// @@ -63,9 +65,9 @@ namespace zypp { if ( pi->mediaNr() == 0 ) // no media access at all return false; - if ( pi->repoInfo().baseUrlsEmpty() ) - return false; // no Url - should actually not happen - std::string scheme( pi->repoInfo().baseUrlsBegin()->getScheme() ); + if ( ! pi->ngRepoInfo() || pi->ngRepoInfo()->baseUrlsEmpty() ) + return false; // no RepoInfo or no Url - should actually not happen + std::string scheme( pi->ngRepoInfo()->baseUrlsBegin()->getScheme() ); return ( scheme == "dvd" || scheme == "cd" ); } diff --git a/zypp/target/RpmPostTransCollector.cc b/zypp/target/RpmPostTransCollector.cc index b6b6b37b59..13279ca224 100644 --- a/zypp/target/RpmPostTransCollector.cc +++ b/zypp/target/RpmPostTransCollector.cc @@ -235,7 +235,7 @@ namespace zypp // Scripts first... if ( _scripts ) { - Pathname noRootScriptDir( ZConfig::instance().update_scriptsPath() / tmpDir().basename() ); + Pathname noRootScriptDir( ZConfig::update_scriptsPath() / tmpDir().basename() ); // like rpm would report it (intentionally not translated and NL-terminated): str::Format fmtScriptFailedMsg { "warning: %%posttrans(%1%) scriptlet failed, exit status %2%\n" }; str::Format fmtPosttrans { "%%posttrans(%1%)" }; @@ -336,7 +336,7 @@ namespace zypp /** Lazy create tmpdir on demand. */ Pathname tmpDir() { - if ( !_ptrTmpdir ) _ptrTmpdir.reset( new filesystem::TmpDir( _root / ZConfig::instance().update_scriptsPath(), "posttrans" ) ); + if ( !_ptrTmpdir ) _ptrTmpdir.reset( new filesystem::TmpDir( _root / ZConfig::update_scriptsPath(), "posttrans" ) ); DBG << _ptrTmpdir->path() << endl; return _ptrTmpdir->path(); } diff --git a/zypp/target/rpm/RpmDb.cc b/zypp/target/rpm/RpmDb.cc index 385f2b1dc4..f548cf8688 100644 --- a/zypp/target/rpm/RpmDb.cc +++ b/zypp/target/rpm/RpmDb.cc @@ -1707,7 +1707,7 @@ void RpmDb::doInstallPackage( const Pathname & filename, RpmInstFlags flags, Rpm opts.push_back("--noglob"); // ZConfig defines cross-arch installation - if ( ! ZConfig::instance().systemArchitecture().compatibleWith( ZConfig::instance().defaultSystemArchitecture() ) ) + if ( ! ZConfig::instance().systemArchitecture().compatibleWith( ZConfig::defaults().defaultSystemArchitecture() ) ) opts.push_back("--ignorearch"); if (flags & RPMINST_NODIGEST) diff --git a/zypp/zypp_detail/ZYppImpl.cc b/zypp/zypp_detail/ZYppImpl.cc index bb612a2f50..b48e63c6ea 100644 --- a/zypp/zypp_detail/ZYppImpl.cc +++ b/zypp/zypp_detail/ZYppImpl.cc @@ -123,6 +123,7 @@ namespace zypp static bool zyppLegacyShutdownStarted = false; // set to true if the GlobalStateHelper was destructed + // if this logic is changed, also update the one in MediaConfig zypp::Pathname autodetectZyppConfPath() { const char *env_confpath = getenv("ZYPP_CONF"); return env_confpath ? env_confpath diff --git a/zypp/zypp_detail/urlcredentialextractor_p.h b/zypp/zypp_detail/urlcredentialextractor_p.h index f7cf100bf2..bf98544df1 100644 --- a/zypp/zypp_detail/urlcredentialextractor_p.h +++ b/zypp/zypp_detail/urlcredentialextractor_p.h @@ -14,7 +14,9 @@ #define ZYPP_ZYPP_DETAIL_URLCREDENTIALEXTRACTOR_P_H #include -#include + +#include +#include namespace zypp { @@ -42,12 +44,8 @@ namespace zypp class UrlCredentialExtractor { public: - UrlCredentialExtractor( const Pathname & root_r ) - : _root( root_r ) - {} - - UrlCredentialExtractor( Pathname & root_r ) - : _root( root_r ) + UrlCredentialExtractor( zyppng::ContextBaseRef ctx ) + : _ctx( std::move(ctx) ) {} ~UrlCredentialExtractor() @@ -59,7 +57,7 @@ namespace zypp bool ret = url_r.hasCredentialsInAuthority(); if ( ret ) { - if ( !_cmPtr ) _cmPtr.reset( new media::CredentialManager( _root ) ); + if ( !_cmPtr ) _cmPtr = zyppng::media::CredentialManager::create( media::CredManagerSettings(_ctx) ); _cmPtr->addUserCred( url_r ); } return ret; @@ -83,8 +81,8 @@ namespace zypp { bool ret = false; for ( Url & url : urls_r ) { if ( extract( url ) && !ret ) ret = true; } return ret; } private: - const Pathname & _root; - scoped_ptr _cmPtr; + zyppng::ContextBaseRef _ctx; + zyppng::media::CredentialManagerRef _cmPtr; }; }