diff --git a/CMakeLists.txt b/CMakeLists.txt index a95b9bdd5..418a6fa56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -440,10 +440,10 @@ ELSE ( ENABLE_BUILD_TRANS ) ADD_SUBDIRECTORY( po EXCLUDE_FROM_ALL ) ENDIF ( ENABLE_BUILD_TRANS ) -IF ( ENABLE_BUILD_TESTS ) - ADD_SUBDIRECTORY( tests ) -ELSE ( ENABLE_BUILD_TESTS ) +#IF ( ENABLE_BUILD_TESTS ) +# ADD_SUBDIRECTORY( tests ) +#ELSE ( ENABLE_BUILD_TESTS ) ADD_SUBDIRECTORY( tests EXCLUDE_FROM_ALL ) -ENDIF ( ENABLE_BUILD_TESTS ) +#ENDIF ( ENABLE_BUILD_TESTS ) INCLUDE(CTest) ENABLE_TESTING() diff --git a/libzypp.spec.cmake b/libzypp.spec.cmake index ec9895d51..4e438b507 100644 --- a/libzypp.spec.cmake +++ b/libzypp.spec.cmake @@ -115,6 +115,7 @@ BuildRequires: libxml2-devel BuildRequires: yaml-cpp-devel BuildRequires: gobject-introspection-devel +BuildRequires: gtk-doc # we are loading libproxy dynamically, however we have # a failsafe unit test that links against libproxy to make diff --git a/zypp-core/zyppng/base/eventdispatcher.h b/zypp-core/zyppng/base/eventdispatcher.h index 46d62076f..7dfc62e2d 100644 --- a/zypp-core/zyppng/base/eventdispatcher.h +++ b/zypp-core/zyppng/base/eventdispatcher.h @@ -64,12 +64,11 @@ class EventDispatcher : public Base * \brief Convenience function to schedule a callback to be called later. * \param callback a std::function that is called after all other events have been processed */ - template< typename T = IdleFunction > - static void invokeOnIdle ( T &&callback ) + static void invokeOnIdle ( IdleFunction &&callback ) { auto ev = instance(); if ( ev ) - ev->invokeOnIdleImpl( std::forward(callback) ); + ev->invokeOnIdleImpl( std::move(callback) ); } /*! diff --git a/zypp-core/zyppng/base/threaddata.cc b/zypp-core/zyppng/base/threaddata.cc index b771c36ae..5fbf986dd 100644 --- a/zypp-core/zyppng/base/threaddata.cc +++ b/zypp-core/zyppng/base/threaddata.cc @@ -35,6 +35,8 @@ namespace zyppng if (!sp) { MIL << "Creating the Event Dispatcher for thread: " << name() << "("<<_threadId<<")" << std::endl; _dispatcher = sp = EventDispatcherPrivate::create( ctx ); + } else { + if ( ctx && ctx != sp->glibContext() ) MIL << "Ignoring passed GMainContext, because a Zypp Event Dispatcher was created before. This might be a bug!" << std::endl; } return sp; } diff --git a/zypp-core/zyppng/pipelines/expected.h b/zypp-core/zyppng/pipelines/expected.h index 9f8c011bf..50653d506 100644 --- a/zypp-core/zyppng/pipelines/expected.h +++ b/zypp-core/zyppng/pipelines/expected.h @@ -623,7 +623,10 @@ namespace zyppng { namespace detail { template struct transform_collect_helper { + template + transform_collect_helper( F &&cb ) : _callback( std::forward(cb)) {} Fun _callback; + template auto operator() ( T &&in ) { return transform_collect( std::forward(in), _callback ); @@ -634,7 +637,7 @@ namespace zyppng { namespace operators { template auto transform_collect( Transformation &&f ) { - return detail::transform_collect_helper{ std::forward(f)}; + return detail::transform_collect_helper( std::forward(f) ); } } diff --git a/zypp-core/zyppng/pipelines/mtry.h b/zypp-core/zyppng/pipelines/mtry.h index 1712b5c2b..94de4e609 100644 --- a/zypp-core/zyppng/pipelines/mtry.h +++ b/zypp-core/zyppng/pipelines/mtry.h @@ -56,7 +56,7 @@ namespace zyppng { namespace operators { template auto mtry ( Fun && function ) { - return detail::mtry_helper { + return zyppng::detail::mtry_helper { std::forward(function) }; } diff --git a/zypp-core/zyppng/ui/progressobserver.cc b/zypp-core/zyppng/ui/progressobserver.cc index 5faf64bd9..9578d4911 100644 --- a/zypp-core/zyppng/ui/progressobserver.cc +++ b/zypp-core/zyppng/ui/progressobserver.cc @@ -129,6 +129,8 @@ namespace zyppng { return; } + child.d_func()->_parent.reset(); + const auto idx = std::distance ( _children.begin (), i ); _children.erase(i); _childInfo.erase( _childInfo.begin () + idx ); @@ -195,6 +197,11 @@ namespace zyppng { return d_func()->_counterValue; } + ProgressObserverRef ProgressObserver::parent() const + { + return d_func()->_parent.lock(); + } + const std::vector &ProgressObserver::children() { return d_func()->_children; @@ -240,6 +247,11 @@ namespace zyppng { return d_func()->_sigNewSubprogress; } + SignalProxy ProgressObserver::sigEvent() + { + return d_func()->_sigEvent; + } + void ProgressObserver::setBaseSteps(int steps) { Z_D(); @@ -260,6 +272,8 @@ namespace zyppng { void ProgressObserver::setCurrent(double curr) { Z_D(); + if ( !d->_started ) start(); + auto set = std::max(0, std::min( curr, d->_baseSteps ) ); if ( set == d->_baseValue ) return; @@ -282,12 +296,12 @@ namespace zyppng { // others we have to manually remove while ( d->_children.size() ) { auto back = d->_children.back(); - bool remove = !back->started (); back->setFinished( result ); + bool remove = !back->started (); if ( remove ) d->_children.pop_back(); } - if ( result != Error ) + if ( d->_started && result != Error ) setCurrent( d->_baseSteps ); if ( d->_started ) @@ -318,6 +332,7 @@ namespace zyppng { } , adjustedWeight }); + child->d_func ()->_parent = weak_this(); d->_sigNewSubprogress.emit( *this, child ); // if the child has been started already, we also need to start() @@ -363,6 +378,8 @@ namespace zyppng { d->_sigEvent.emit( *this, event ); if ( !event->accepted () ) { // our receivers did not handle the request, we need to bubble up! + auto p = d->_parent.lock(); + if ( p ) p->sendUserRequest( event ); } } diff --git a/zypp-core/zyppng/ui/progressobserver.h b/zypp-core/zyppng/ui/progressobserver.h index b4c36e15f..3872d9518 100644 --- a/zypp-core/zyppng/ui/progressobserver.h +++ b/zypp-core/zyppng/ui/progressobserver.h @@ -59,6 +59,7 @@ namespace zyppng { double progress() const; double current() const; + ProgressObserverRef parent() const; inline static ProgressObserverRef makeSubTask( ProgressObserverRef parentProgress, float weight = 1.0, const std::string &label = std::string(), int steps = 100 ) { if ( parentProgress ) return parentProgress->makeSubTask( weight, label, steps ); @@ -107,7 +108,6 @@ namespace zyppng { zypp::ProgressData::ReceiverFnc makeProgressDataReceiver (); - void sendUserRequest( const UserRequestRef& event ); SignalProxy sigStarted (); diff --git a/zypp-core/zyppng/ui/userrequest.cc b/zypp-core/zyppng/ui/userrequest.cc index 43f4da94a..b30af56e4 100644 --- a/zypp-core/zyppng/ui/userrequest.cc +++ b/zypp-core/zyppng/ui/userrequest.cc @@ -29,6 +29,21 @@ namespace zyppng return _userData; } + void UserRequest::accept() + { + _accepted = true; + } + + void UserRequest::ignore() + { + _accepted = false; + } + + bool UserRequest::accepted() const + { + return _accepted; + } + ZYPP_IMPL_PRIVATE_CONSTR_ARGS(ShowMessageRequest, std::string message, MType mType, UserData data ) : UserRequest( std::move(data) ) , _type( mType ) diff --git a/zypp-core/zyppng/ui/userrequest.h b/zypp-core/zyppng/ui/userrequest.h index f6040d957..771a5688a 100644 --- a/zypp-core/zyppng/ui/userrequest.h +++ b/zypp-core/zyppng/ui/userrequest.h @@ -18,18 +18,11 @@ namespace zyppng { using UserData = zypp::callback::UserData; using ContentType = zypp::ContentType; - ZYPP_FWD_DECL_TYPE_WITH_REFS( UserRequest ); ZYPP_FWD_DECL_TYPE_WITH_REFS( ShowMessageRequest ); ZYPP_FWD_DECL_TYPE_WITH_REFS( ListChoiceRequest ); ZYPP_FWD_DECL_TYPE_WITH_REFS( BooleanChoiceRequest ); - /* - constexpr std::string_view CTYPE_SHOW_MESSAGE_REQUEST ("userreq/show-message"); - constexpr std::string_view CTYPE_LIST_CHOICE_REQUEST ("userreq/list-choice"); - constexpr std::string_view CTYPE_BOOLEAN_COICE_REQUEST("userreq/boolean-choice"); - */ - // keep in sync with glib wrapper code enum class UserRequestType : uint { diff --git a/zypp-glib/CMakeLists.txt b/zypp-glib/CMakeLists.txt index ba6a410cb..2738560dd 100644 --- a/zypp-glib/CMakeLists.txt +++ b/zypp-glib/CMakeLists.txt @@ -20,6 +20,7 @@ INCLUDE_DIRECTORIES ( ${LIBZYPP_SOURCE_DIR} ${LIBZYPP_BINARY_DIR} ) ADD_DEFINITIONS( -DLOCALEDIR="${CMAKE_INSTALL_PREFIX}/share/locale" -DTEXTDOMAIN="zypp" -DZYPP_DLL ) SET( zypp_glib_HEADERS + application.h context.h error.h expected.h @@ -44,6 +45,7 @@ SET( zypp_glib_ui_HEADERS SET( zypp_glib_private_HEADERS private/context_p.h + private/error_p.h private/expected_p.h private/globals_p.h private/infobase_p.h @@ -66,6 +68,7 @@ SET( zypp_glib_private_HEADERS ) SET( zypp_glib_SRCS + application.cc context.cc error.cc expected.cc @@ -77,6 +80,7 @@ SET( zypp_glib_SRCS repomanager.cc repository.cc serviceinfo.cc + zypp-glib.cc ui/booleanchoicerequest.cc ui/listchoicerequest.cc ui/showmessagerequest.cc @@ -128,7 +132,7 @@ ADD_LIBRARY( zypp-glib SHARED ${zypp_glib_lib_SRCS} ${zypp_glib_lib_HEADERS} ) target_link_libraries( zypp-glib zypp_lib_compiler_flags ) TARGET_LINK_LIBRARIES( zypp-glib zypp-allsym ) target_link_libraries( zypp-glib ${LIBGOBJECT_LIBRARIES} ) -#target_link_libraries( zypp-glib ${LIBGIO_LIBRARIES} ) +target_link_libraries( zypp-glib ${LIBGIO_LIBRARIES} ) INSTALL(TARGETS zypp-glib LIBRARY DESTINATION ${LIB_INSTALL_DIR} ) @@ -142,12 +146,12 @@ GENERATE_EXPORT_HEADER( gobject_introspection( FILENAME Zypp-1.0.gir - PACKAGES glib-2.0 gobject-2.0 + PACKAGES glib-2.0 gobject-2.0 gio-2.0 NAMESPACE Zypp LIBRARY zypp-glib #QUIET SCANNER_ARGS --add-include-path=${CMAKE_CURRENT_SOURCE_DIR} - --include=GLib-2.0 --include=GObject-2.0 + --include=GLib-2.0 --include=GObject-2.0 --include=Gio-2.0 COMPILER_ARGS --includedir=${CMAKE_CURRENT_SOURCE_DIR} SYMBOL_PREFIXES zypp SOURCES ${zypp_glib_public_HEADERS} diff --git a/zypp-glib/application.cc b/zypp-glib/application.cc new file mode 100644 index 000000000..5dfe52e2a --- /dev/null +++ b/zypp-glib/application.cc @@ -0,0 +1,174 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ + +#include "application.h" +#include "private/globals_p.h" + +#include +#include +#include + +struct ZyppApplicationPrivate +{ + ZyppApplicationPrivate( ZyppApplication *pub ){} + + void initialize() { + if ( !_dispatcher ) { + _dispatcher = zyppng::ThreadData::current().ensureDispatcher(); + } + } + + void finalize() { /* Nothing to do atm */} + + + ZyppApplication *_gObject = nullptr; + zyppng::EventDispatcherRef _dispatcher; + std::string version = LIBZYPP_VERSION_STRING; +}; + +G_DEFINE_TYPE_WITH_PRIVATE( ZyppApplication, zypp_application, G_TYPE_OBJECT ) + +ZYPP_DECLARE_GOBJECT_BOILERPLATE( ZyppApplication, zypp_application ) +ZYPP_DEFINE_GOBJECT_BOILERPLATE ( ZyppApplication, zypp_application, ZYPP, APPLICATION ) + +#define ZYPP_APPLICATION_D() \ + auto d = zypp_application_get_private( self ) + +typedef enum +{ + PROP_EVENT_DISPATCHER = 1, + PROP_VERSION, + N_PROPERTIES +} ZyppApplicationProperty; + +static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; + +void zypp_application_class_init( ZyppApplicationClass *klass ) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + ZYPP_INIT_GOBJECT_BOILERPLATE_KLASS( zypp_application, object_class ); + + obj_properties[PROP_EVENT_DISPATCHER] = + g_param_spec_boxed ( "eventDispatcher", + "EventDispatcher", + "Libzypp Event Dispatcher.", + G_TYPE_MAIN_CONTEXT, + GParamFlags( G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE ) ); + + obj_properties[PROP_VERSION] = + g_param_spec_string ( "version", + "Version", + "Libzypp Library version.", + NULL /* default value */, + GParamFlags( G_PARAM_READABLE) ); + + g_object_class_install_properties (object_class, + N_PROPERTIES, + obj_properties); +} + +static void +zypp_application_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + g_return_if_fail( ZYPP_IS_APPLICATION(object) ); + ZyppApplication *self = ZYPP_APPLICATION (object); + + ZYPP_APPLICATION_D(); + + switch ((ZyppApplicationProperty)property_id ) + { + case PROP_EVENT_DISPATCHER: { + GMainContext *ctx = reinterpret_cast(g_value_get_boxed( value )); + + // this will take a reference of the context + if ( !d->_dispatcher ) d->_dispatcher = zyppng::ThreadData::current().ensureDispatcher( ctx ); + else MIL << "Ignoring GMainContext, dispatcher already initialized!" << std::endl; + + break; + } + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +zypp_application_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + g_return_if_fail( ZYPP_IS_APPLICATION(object) ); + ZyppApplication *self = ZYPP_APPLICATION (object); + + ZYPP_APPLICATION_D(); + + switch ((ZyppApplicationProperty)property_id ) + { + case PROP_EVENT_DISPATCHER: + g_value_set_boxed( value, d->_dispatcher->nativeDispatcherHandle() ); + break; + case PROP_VERSION: + g_value_set_string ( value, d->version.c_str() ); + break; + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +ZyppApplication *zypp_application_new( GMainContext *eventDispatcher ) +{ + if ( eventDispatcher ){ + GValue dispValue = G_VALUE_INIT; + g_value_init( &dispValue, G_TYPE_MAIN_CONTEXT ); + g_value_set_boxed ( &dispValue, eventDispatcher ); + return static_cast( g_object_new( ZYPP_TYPE_APPLICATION, "eventDispatcher", &dispValue, nullptr ) ); + } else { + return static_cast( g_object_new( ZYPP_TYPE_APPLICATION, nullptr ) ); + } +} + +GMainContext *zypp_application_get_dispatcher( ZyppApplication *self ) +{ + g_return_val_if_fail ( ZYPP_IS_APPLICATION(self), nullptr ); + ZYPP_APPLICATION_D(); + return d->_dispatcher->glibContext(); +} + +const gchar * zypp_application_get_version ( ZyppApplication *self ) +{ + g_return_val_if_fail( ZYPP_IS_APPLICATION(self), nullptr ); + ZYPP_APPLICATION_D(); + return d->version.c_str(); +} + +void zypp_application_set_user_data (ZyppApplication *self, const gchar *userData ) +{ + if ( !userData ) { + zyppng::UserData::setData( std::string() ); + return; + } + zyppng::UserData::setData ( zypp::str::asString (userData) ); +} + +gboolean zypp_application_has_user_data ( ZyppApplication *self ) +{ + return zyppng::UserData::hasData(); +} + +const gchar *zypp_application_get_user_data ( ZyppApplication *self ) +{ + return zyppng::UserData::data().c_str(); +} diff --git a/zypp-glib/application.h b/zypp-glib/application.h new file mode 100644 index 000000000..fc20999c2 --- /dev/null +++ b/zypp-glib/application.h @@ -0,0 +1,111 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +#ifndef ZYPP_GLIB_APPLICATION_H +#define ZYPP_GLIB_APPLICATION_H + +/* + * The zyppng API library aims to provide a new set of APIs for the libzypp API which + * makes it possible to use libzypp from different programming languages and offers a + * more high level and stable API than the original library. + * + * In order to support using multiple languages, zyppng will leverage GObject and GIR technologies, + * featuring a pure glib based C API as described here: https://gi.readthedocs.io/en/latest/index.html + * + * The ultimate goal of this project is to function as the only officially supported API for compiling against + * zypp. Tools like zypper will be rewritten to use this API set. + * + * \code {.python} + * #!/usr/bin/env python3 + * + * import gi.repository + * + * # Set the search path to use the newly generated introspection files, only required if they are not in the default directories + * gi.require_version('GIRepository', '2.0') + * from gi.repository import GIRepository + * GIRepository.Repository.prepend_search_path('/home/zbenjamin/build/libzypp/zyppng') + * + * gi.require_version('Zypp', '1.0') + * from gi.repository import Zypp + * + * zyppApplication = Zypp.Application() + * context = Zypp.Context() + * print(context.version()) + * \endcode + */ + +#include +#include + +G_BEGIN_DECLS + +#define ZYPP_TYPE_APPLICATION (zypp_application_get_type ()) + +#pragma GCC visibility push(default) +G_DECLARE_DERIVABLE_TYPE ( ZyppApplication, zypp_application, ZYPP, APPLICATION, GObject ) +#pragma GCC visibility pop + +struct LIBZYPP_GLIB_EXPORT _ZyppApplicationClass { + GObjectClass parent_class; + gpointer padding[12]; +}; + +/** + * zypp_application_new: (constructor): + * @eventDispatcher: (transfer none) (nullable): The event dispatcher to use when running async code. + * + * Creates a new ZyppApplication instance, if there is already a existing instance this one is returned instead. + * If there is no event dispatcher passed to the constructor, one is created automatically. + * + * Returns: (transfer full): Reference to the new Application object + */ +ZyppApplication *zypp_application_new( GMainContext *eventDispatcher ) LIBZYPP_GLIB_EXPORT; + +/** + * zypp_application_get_dispatcher: + * + * Returns the internally used event dispatcher, this is at least valid as long as the Application + * instance is valid. + * + * Returns: (nullable) (transfer none): The event dispatcher used by zypp + */ +GMainContext *zypp_application_get_dispatcher( ZyppApplication *self ) LIBZYPP_GLIB_EXPORT; + +/** + * zypp_application_get_version: + * Returns: The libzypp version string + */ +const gchar * zypp_application_get_version ( ZyppApplication *self ) LIBZYPP_GLIB_EXPORT; + +/** + * zypp_application_set_user_data: + * @userData: (transfer none) (nullable): The userdata string + * + * Set's a user defined string to be passed to log, history, plugins. + * Passing a nullptr string clears the userdata + */ +void zypp_application_set_user_data ( ZyppApplication *self, const gchar *userData ) LIBZYPP_GLIB_EXPORT; + +/** + * zypp_application_has_user_data: + * + * Returns: True if a userdata string has been set + */ +gboolean zypp_application_has_user_data ( ZyppApplication *self ) LIBZYPP_GLIB_EXPORT; + +/** + * zypp_application_get_user_data: + * + * Returns: (transfer none) (nullable): The currently used userdata string, or NULL if none was set + */ +const gchar *zypp_application_get_user_data ( ZyppApplication *self ) LIBZYPP_GLIB_EXPORT; + +G_END_DECLS + + +#endif diff --git a/zypp-glib/context.cc b/zypp-glib/context.cc index 7ed679d04..44d9fdc74 100644 --- a/zypp-glib/context.cc +++ b/zypp-glib/context.cc @@ -7,41 +7,33 @@ | | \---------------------------------------------------------------------*/ -#include "error.h" +#include "private/error_p.h" #include "private/context_p.h" -#include "private/repomanager_p.h" +#include "private/progressobserver_p.h" +#include #include #include #include #include - -#include -#include -#include -#include -#include - #include typedef enum { PROP_CPPOBJ = 1, - PROP_VERSION, N_PROPERTIES } ZyppContextProperty; -GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; - +static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; +#if 0 /* Signals */ typedef enum { - SIG_EVENT = 1, LAST_SIGNAL } ZyppContextSignals; static guint signals[LAST_SIGNAL] = { 0, }; - +#endif G_DEFINE_TYPE_WITH_PRIVATE(ZyppContext, zypp_context, G_TYPE_OBJECT) @@ -49,7 +41,7 @@ ZYPP_DECLARE_GOBJECT_BOILERPLATE( ZyppContext, zypp_context ) ZYPP_DEFINE_GOBJECT_BOILERPLATE ( ZyppContext, zypp_context, ZYPP, CONTEXT ) #define ZYPP_CONTEXT_D() \ - ZYPP_GLIB_WRAPPER_D( ZyppContext, zypp_context ) + auto d = zypp_context_get_private(self) void zypp_context_class_init( ZyppContextClass *klass ) { @@ -58,33 +50,9 @@ void zypp_context_class_init( ZyppContextClass *klass ) obj_properties[PROP_CPPOBJ] = ZYPP_GLIB_ADD_CPPOBJ_PROP(); - obj_properties[PROP_VERSION] = - g_param_spec_string ("versionprop", - "Version", - "Libzypp Library version.", - NULL /* default value */, - GParamFlags( G_PARAM_READABLE) ); - g_object_class_install_properties (object_class, N_PROPERTIES, obj_properties); - - { - std::vector signal_parms = { ZYPP_TYPE_USER_REQUEST }; - signals[SIG_EVENT] = - g_signal_newv ("event", - G_TYPE_FROM_CLASS (klass), - (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS), - NULL /* closure */, - NULL /* accumulator */, - NULL /* accumulator data */, - NULL /* C marshaller */, - G_TYPE_NONE /* return_type */, - signal_parms.size() /* n_params */, - signal_parms.data() ); - } - - } static void glogHandler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data); @@ -98,46 +66,25 @@ void ZyppContextPrivate::initializeCpp() if ( _constructProps && _constructProps->_cppObj ) { _context = std::move( _constructProps->_cppObj ); } else { - _context = zyppng::SyncContext::create(); + _context = zyppng::AsyncContext::create(); } _constructProps.reset(); _signalConns.insert ( _signalConns.end(), { - _context->connectFunc( &zyppng::ContextBase::sigEvent, [this]( zyppng::UserRequestRef req ) { - switch( req->type() ) { - case zyppng::UserRequestType::Invalid: { - ERR << "Ignoring user request with type Invalid, this is a bug!" << std::endl; - return; //ignore - } - case zyppng::UserRequestType::Message: { - auto actualReq = std::dynamic_pointer_cast(req); - auto gObjMsg = zypp::glib::zypp_wrap_cpp(actualReq); - g_signal_emit (_gObject, signals[SIG_EVENT], 0, gObjMsg.get(), nullptr ); - return; - } - case zyppng::UserRequestType::ListChoice: { - auto actualReq = std::dynamic_pointer_cast(req); - auto gObjMsg = zypp::glib::zypp_wrap_cpp(actualReq); - g_signal_emit (_gObject, signals[SIG_EVENT], 0, gObjMsg.get(), nullptr ); - return; - } - case zyppng::UserRequestType::BooleanChoice: { - auto actualReq = std::dynamic_pointer_cast(req); - auto gObjMsg = zypp::glib::zypp_wrap_cpp(actualReq); - g_signal_emit (_gObject, signals[SIG_EVENT], 0, gObjMsg.get(), nullptr ); - return; - } - case zyppng::UserRequestType::Custom: { - ERR << "Custom user requests can not be wrapped with glib!" << std::endl; - return; //ignore - } - } - }) + _context->connectFunc( &zyppng::ContextBase::sigProgressObserverChanged, [this]() { + if ( _context->progressObserver () ) + _masterProgress = zypp::glib::zypp_wrap_cpp( _context->progressObserver ()); + else + _masterProgress = nullptr; + }) }); + if ( _context->progressObserver () ) + _masterProgress = zypp::glib::zypp_wrap_cpp( _context->progressObserver ()); + } -zyppng::SyncContextRef &ZyppContextPrivate::cppType() +zyppng::AsyncContextRef &ZyppContextPrivate::cppType() { return _context; } @@ -148,8 +95,8 @@ zypp_context_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - ZyppContext *self = ZYPP_CONTEXT (object); g_return_if_fail( ZYPP_IS_CONTEXT(object) ); + ZyppContext *self = ZYPP_CONTEXT (object); ZYPP_CONTEXT_D(); @@ -157,7 +104,7 @@ zypp_context_set_property (GObject *object, { case PROP_CPPOBJ: g_return_if_fail( d->_constructProps ); // only if the constr props are still valid - ZYPP_GLIB_SET_CPPOBJ_PROP( zyppng::SyncContextRef, value, d->_constructProps->_cppObj ) + ZYPP_GLIB_SET_CPPOBJ_PROP( zyppng::AsyncContextRef, value, d->_constructProps->_cppObj ) default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -171,16 +118,10 @@ zypp_context_get_property (GObject *object, GValue *value, GParamSpec *pspec) { - ZyppContext *self = ZYPP_CONTEXT (object); g_return_if_fail( ZYPP_IS_CONTEXT(object) ); - ZYPP_CONTEXT_D(); - switch ((ZyppContextProperty)property_id ) { - case PROP_VERSION: - g_value_set_string ( value, d->version.c_str() ); - break; default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -188,14 +129,16 @@ zypp_context_get_property (GObject *object, } } -zyppng::SyncContextRef zypp_context_get_cpp( ZyppContext *self ) +zyppng::AsyncContextRef zypp_context_get_cpp( ZyppContext *self ) { + g_return_val_if_fail( ZYPP_CONTEXT(self), nullptr ); ZYPP_CONTEXT_D(); return d->_context; } gboolean zypp_context_load_system (ZyppContext *self, const gchar *sysRoot , GError **error) { + g_return_val_if_fail( ZYPP_CONTEXT(self), false ); ZYPP_CONTEXT_D(); zyppng::ContextSettings set; @@ -205,33 +148,42 @@ gboolean zypp_context_load_system (ZyppContext *self, const gchar *sysRoot , GEr try { d->_context->initialize( std::move(set) ).unwrap(); return true; - } catch ( const zypp::Exception &e ) { - if ( error ) { - g_error_new( ZYPP_EXCEPTION, ZYPP_ERROR, "%s", e.asString().c_str() ); - } - } catch ( const std::exception &e ) { - if ( error ) { - g_error_new( ZYPP_EXCEPTION, ZYPP_ERROR, "%s", e.what() ); - } } catch ( ... ) { - if ( error ) { - g_error_new( ZYPP_EXCEPTION, ZYPP_ERROR, "%s", "Unknown exception." ); - } + zypp_error_from_exception ( error, std::current_exception () ); } return false; } -const gchar * zypp_context_version ( ZyppContext *self ) +gchar * zypp_context_sysroot ( ZyppContext *self ) { + g_return_val_if_fail( ZYPP_CONTEXT(self), nullptr ); ZYPP_CONTEXT_D(); - return d->version.c_str(); + return g_strdup ( d->_context->contextRoot().c_str() ); } -gchar * zypp_context_sysroot ( ZyppContext *self ) +ZyppProgressObserver *zypp_context_get_progress_observer( ZyppContext *self ) { + g_return_val_if_fail( ZYPP_CONTEXT(self), nullptr ); ZYPP_CONTEXT_D(); - return g_strdup ( d->_context->contextRoot().c_str() ); + return d->_masterProgress.get(); +} + +void zypp_context_set_progress_observer( ZyppContext *self, ZyppProgressObserver *obs ) +{ + g_return_if_fail( ZYPP_CONTEXT(self) ); + ZYPP_CONTEXT_D(); + if ( obs ) + d->_context->setProgressObserver ( zypp_progress_observer_get_cpp (obs) ); + else + d->_context->resetProgressObserver (); +} + +void zypp_context_reset_progress_observer( ZyppContext *self ) +{ + g_return_if_fail( ZYPP_CONTEXT(self) ); + ZYPP_CONTEXT_D(); + d->_context->resetProgressObserver(); } static gpointer installLogHandler ( gpointer ) diff --git a/zypp-glib/context.h b/zypp-glib/context.h index 667f07d11..173310e00 100644 --- a/zypp-glib/context.h +++ b/zypp-glib/context.h @@ -9,37 +9,12 @@ #ifndef ZYPP_GLIB_CONTEXT_H #define ZYPP_GLIB_CONTEXT_H -/*! - * The zyppng API library aims to provide a new set of APIs for the libzypp API which - * makes it possible to use libzypp from different programming languages and offers a - * more high level and stable API than the original library. - * - * In order to support using multiple languages, zyppng will leverage GObject and GIR technologies, - * featuring a pure glib based C API as described here: https://gi.readthedocs.io/en/latest/index.html - * - * The ultimate goal of this project is to function as the only officially supported API for compiling against - * zypp. Tools like zypper will be rewritten to use this API set. - * - * \code {.python} - * #!/usr/bin/env python3 - * - * import gi.repository - * - * # Set the search path to use the newly generated introspection files, only required if they are not in the default directories - * gi.require_version('GIRepository', '2.0') - * from gi.repository import GIRepository - * GIRepository.Repository.prepend_search_path('/home/zbenjamin/build/libzypp/zyppng') - * - * gi.require_version('Zypp', '1.0') - * from gi.repository import Zypp - * - * context = Zypp.Context() - * print(context.version()) - * \endcode - * - * - */ +#include +#include + +G_BEGIN_DECLS +typedef struct _ZyppProgressObserver ZyppProgressObserver; /** * ZyppContext: @@ -54,10 +29,6 @@ */ -#include -#include -G_BEGIN_DECLS - /** * ZyppContext: glibContext: (transfer full) * @@ -84,8 +55,6 @@ G_DECLARE_FINAL_TYPE ( ZyppContext, zypp_context, ZYPP, CONTEXT, GObject ) */ gboolean zypp_context_load_system ( ZyppContext *self, const gchar *sysRoot, GError **error ) LIBZYPP_GLIB_EXPORT; -const gchar * zypp_context_version ( ZyppContext *self ) LIBZYPP_GLIB_EXPORT; - /** * zypp_context_sysroot: * @@ -93,6 +62,32 @@ const gchar * zypp_context_version ( ZyppContext *self ) LIBZYPP_GLIB_EXPORT; */ gchar *zypp_context_sysroot( ZyppContext *self ) LIBZYPP_GLIB_EXPORT; + +/** + * zypp_context_get_progress_observer: + * + * Returns: (transfer full) (nullable): The currently used progress observer, or NULL if there was none registered. + */ +ZyppProgressObserver *zypp_context_get_progress_observer( ZyppContext *self ) LIBZYPP_GLIB_EXPORT; + +/** + * zypp_context_set_progress_observer: + * + * Sets the progress observer, this is where libzypp will generate progress and callback messages. + * The context will hold a strong reference to the observer until it is resettet. + */ +void zypp_context_set_progress_observer( ZyppContext *self, ZyppProgressObserver *obs ) LIBZYPP_GLIB_EXPORT; + +/** + * zypp_context_reset_progress_observer: + * + * Clears the reference to the current progress observer, code will not be able to generate task information + * for new tasks anymore, already running code however might still hold a reference to it. + */ +void zypp_context_reset_progress_observer( ZyppContext *self ) LIBZYPP_GLIB_EXPORT; + + + G_END_DECLS #ifdef __cplusplus diff --git a/zypp-glib/error.cc b/zypp-glib/error.cc index 243af0632..5d85c94a2 100644 --- a/zypp-glib/error.cc +++ b/zypp-glib/error.cc @@ -7,5 +7,78 @@ | | \---------------------------------------------------------------------*/ #include "error.h" +#include +#include +#include -G_DEFINE_QUARK (zypp-exception-quark, zypp_exception ) +#include + +typedef struct +{ + zypp::Exception e; +} ZyppErrorPrivate; + +static void +zypp_error_private_init ( ZyppErrorPrivate *priv ) +{ + new (priv) ZyppErrorPrivate(); +} + +static void +zypp_error_private_copy (const ZyppErrorPrivate *src_priv, ZyppErrorPrivate *dest_priv) +{ + *dest_priv = *src_priv; +} + +static void +zypp_error_private_clear (ZyppErrorPrivate *priv) +{ + priv->~ZyppErrorPrivate(); +} + +// This defines the zypp_error_get_private and zypp_error_quark functions. +G_DEFINE_EXTENDED_ERROR (ZyppError, zypp_error) + +GList *zypp_error_get_history (GError *error) +{ + ZyppErrorPrivate *priv = zypp_error_get_private (error); + g_return_val_if_fail (priv != NULL, NULL); + // g_return_val_if_fail (error->code != MY_ERROR_BAD_REQUEST, NULL); + + zypp::glib::GCharContainer res; + for ( auto i = priv->e.historyBegin (); i != priv->e.historyEnd (); i++ ) { + res.push_back ( g_strdup( (*i).c_str ()) ); + } + return res.take(); +} + +void zypp_error_from_exception ( GError **err, std::exception_ptr exception ) +{ + try { + std::rethrow_exception (exception); + } catch ( const zypp::Exception &e ) { + ZyppErrorPrivate *priv; + g_set_error (err, ZYPP_ERROR, ZYPP_ERROR_GENERIC, "%s", e.msg ().c_str() ); + if (err != nullptr && *err != nullptr) { + priv = zypp_error_get_private (*err); + g_return_if_fail ( priv != nullptr ); + priv->e = e; + } + } catch ( std::exception &e ) { + ZyppErrorPrivate *priv; + g_set_error (err, ZYPP_ERROR, ZYPP_ERROR_GENERIC, "%s", e.what() ); + if (err != nullptr && *err != nullptr) { + priv = zypp_error_get_private (*err); + g_return_if_fail ( priv != nullptr ); + priv->e = zypp::Exception( e.what() ); + } + } catch ( ... ) { + ZyppErrorPrivate *priv; + g_set_error (err, ZYPP_ERROR, ZYPP_ERROR_GENERIC, "Unknown exception." ); + if (err != nullptr && *err != nullptr) { + priv = zypp_error_get_private (*err); + g_return_if_fail ( priv != nullptr ); + priv->e = zypp::Exception( "Unknown exception" ); + } + } +} diff --git a/zypp-glib/error.h b/zypp-glib/error.h index ec6230e4d..3dd09d99f 100644 --- a/zypp-glib/error.h +++ b/zypp-glib/error.h @@ -18,23 +18,29 @@ G_BEGIN_DECLS * ZYPP_ERROR: * * Error domain for the zypp exception handling. Errors in this domain will - * be from the #ZyppException enumeration. See #GError for information + * be from the #ZyppError enumeration. See #GError for information * on error domains. */ -#define ZYPP_EXCEPTION zypp_exception_quark () +#define ZYPP_ERROR zypp_error_quark () /** * ZyppError: - * @ZYPP_ERROR: Generic Error that happend in the zypp API, check error string for details + * @ZYPP_ERROR_GENERIC: Generic Error that happend in the zypp API, check error string for details */ typedef enum { - ZYPP_ERROR -} ZyppException; + ZYPP_ERROR_GENERIC +} ZyppError; -GQuark zypp_exception_quark () LIBZYPP_GLIB_EXPORT; +GQuark zypp_error_quark () LIBZYPP_GLIB_EXPORT; +/** + * zypp_error_get_history: + * + * Returns: (element-type gchar) (transfer full) (nullable): the history strings from the exception + */ +GList * zypp_error_get_history (GError *error) LIBZYPP_GLIB_EXPORT; G_END_DECLS diff --git a/zypp-glib/private/context_p.h b/zypp-glib/private/context_p.h index 6a1e4318c..dac44b18d 100644 --- a/zypp-glib/private/context_p.h +++ b/zypp-glib/private/context_p.h @@ -17,6 +17,7 @@ #include #include "globals_p.h" +#include "progressobserver_p.h" // the good ol zypp API #include @@ -27,16 +28,17 @@ struct ZyppContextPrivate ZyppContextPrivate( ZyppContext *pub ) : WrapperPrivateBase(pub) {}; void initializeCpp(); - zyppng::SyncContextRef &cppType(); + zyppng::AsyncContextRef &cppType(); struct ConstructionProps { zypp::Pathname _sysRoot = "/"; - zyppng::SyncContextRef _cppObj; + zyppng::AsyncContextRef _cppObj; }; std::optional _constructProps = ConstructionProps(); - std::string version = LIBZYPP_VERSION_STRING; - zyppng::SyncContextRef _context; + zypp::glib::GObjectPtr _masterProgress; //synced with the progress observer in zyppng::Context + + zyppng::AsyncContextRef _context; }; /* @@ -52,6 +54,6 @@ struct _ZyppContext /** * zypp_context_get_cpp: (skip) */ -zyppng::SyncContextRef zypp_context_get_cpp( ZyppContext *self ); +zyppng::AsyncContextRef zypp_context_get_cpp( ZyppContext *self ); #endif // CONTEXT_P_H diff --git a/zypp-glib/private/error_p.h b/zypp-glib/private/error_p.h new file mode 100644 index 000000000..625cc2a58 --- /dev/null +++ b/zypp-glib/private/error_p.h @@ -0,0 +1,18 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ + +#ifndef ERROR_P_H +#define ERROR_P_H + +#include +#include + +void zypp_error_from_exception (GError **err, std::exception_ptr exception ); + +#endif diff --git a/zypp-glib/private/progressobserver_p.h b/zypp-glib/private/progressobserver_p.h index a5c800c8b..6bbf711ef 100644 --- a/zypp-glib/private/progressobserver_p.h +++ b/zypp-glib/private/progressobserver_p.h @@ -44,4 +44,9 @@ struct _ZyppProgressObserver GObjectClass parent_class; }; +/** + * zypp_progress_observer_get_cpp: (skip) + */ +zyppng::ProgressObserverRef zypp_progress_observer_get_cpp( ZyppProgressObserver *self ); + #endif diff --git a/zypp-glib/private/repomanager_p.h b/zypp-glib/private/repomanager_p.h index 84b07d1ae..42c7e013e 100644 --- a/zypp-glib/private/repomanager_p.h +++ b/zypp-glib/private/repomanager_p.h @@ -22,17 +22,17 @@ struct ZyppRepoManagerPrivate ZyppRepoManagerPrivate( ZyppRepoManager *pub ) : WrapperPrivateBase(pub) {}; void initializeCpp(); - zyppng::SyncRepoManagerRef &cppType() { + zyppng::AsyncRepoManagerRef &cppType() { return _cppObj; } struct ConstructData { - zyppng::SyncRepoManagerRef _cppObj; + zyppng::AsyncRepoManagerRef _cppObj; zypp::glib::ZyppContextRef _ctx; }; std::optional _constrProps = ConstructData(); - zyppng::SyncRepoManagerRef _cppObj; + zyppng::AsyncRepoManagerRef _cppObj; }; struct _ZyppRepoManager diff --git a/zypp-glib/progressobserver.cc b/zypp-glib/progressobserver.cc index effefc6d9..19f622827 100644 --- a/zypp-glib/progressobserver.cc +++ b/zypp-glib/progressobserver.cc @@ -7,18 +7,24 @@ | | \---------------------------------------------------------------------*/ #include "private/progressobserver_p.h" -#include + +#include +#include +#include +#include +#include #include #include -#include G_DEFINE_FINAL_TYPE_WITH_PRIVATE( ZyppProgressObserver, zypp_progress_observer, G_TYPE_OBJECT ) /* Signals */ typedef enum { SIG_FINISHED = 1, + SIG_STARTED, SIG_NEW_CHILD, + SIG_EVENT, LAST_SIGNAL } ZyppProgressObserverSignals; @@ -54,6 +60,21 @@ static void zypp_progress_observer_class_init (ZyppProgressObserverClass *klass) object_class->get_property = zypp_progress_observer_get_property; object_class->set_property = zypp_progress_observer_set_property; + { + std::vector signal_parms = {}; + signals[SIG_STARTED] = + g_signal_newv ("start", + G_TYPE_FROM_CLASS (klass), + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS), + NULL /* closure */, + NULL /* accumulator */, + NULL /* accumulator data */, + NULL /* C marshaller */, + G_TYPE_NONE /* return_type */, + signal_parms.size() /* n_params */, + signal_parms.data() ); + } + { std::vector signal_parms = {}; signals[SIG_FINISHED] = @@ -84,6 +105,21 @@ static void zypp_progress_observer_class_init (ZyppProgressObserverClass *klass) signal_parms.data() ); } + { + std::vector signal_parms = { ZYPP_TYPE_USER_REQUEST }; + signals[SIG_EVENT] = + g_signal_newv ("event", + G_TYPE_FROM_CLASS (klass), + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS), + NULL /* closure */, + NULL /* accumulator */, + NULL /* accumulator data */, + NULL /* C marshaller */, + G_TYPE_NONE /* return_type */, + signal_parms.size() /* n_params */, + signal_parms.data() ); + } + obj_properties[PROP_CPPOBJ] = ZYPP_GLIB_ADD_CPPOBJ_PROP(); obj_properties[PROP_LABEL] = g_param_spec_string ( @@ -360,6 +396,9 @@ void ZyppProgressObserverPrivate::initializeCpp() { _cppObj->connectFunc( &zyppng::ProgressObserver::sigProgressChanged, [this]( auto &, double ){ g_object_notify_by_pspec ( G_OBJECT(_gObject), obj_properties[PROP_PROGRESS] ); }), + _cppObj->connectFunc( &zyppng::ProgressObserver::sigStarted, [this]( zyppng::ProgressObserver &sender ){ + g_signal_emit (_gObject, signals[SIG_STARTED], 0); + }), _cppObj->connectFunc( &zyppng::ProgressObserver::sigFinished, [this]( zyppng::ProgressObserver &sender, zyppng::ProgressObserver::FinishResult ){ g_signal_emit (_gObject, signals[SIG_FINISHED], 0); }), @@ -367,10 +406,47 @@ void ZyppProgressObserverPrivate::initializeCpp() { auto wrapped = zypp::glib::zypp_wrap_cpp( newRef ); zypp_progress_observer_reg_child ( _gObject, zypp::glib::ZyppProgressObserverRef(wrapped) ); g_signal_emit( _gObject, signals[SIG_NEW_CHILD], 0, wrapped.get() ); - }) + }), + _cppObj->connectFunc( &zyppng::ProgressObserver::sigEvent, [this]( zyppng::ProgressObserver &s, zyppng::UserRequestRef req ) { + switch( req->type() ) { + case zyppng::UserRequestType::Invalid: { + ERR << "Ignoring user request with type Invalid, this is a bug!" << std::endl; + return; //ignore + } + case zyppng::UserRequestType::Message: { + auto actualReq = std::dynamic_pointer_cast(req); + auto gObjMsg = zypp::glib::zypp_wrap_cpp(actualReq); + g_signal_emit (_gObject, signals[SIG_EVENT], 0, gObjMsg.get(), nullptr ); + return; + } + case zyppng::UserRequestType::ListChoice: { + auto actualReq = std::dynamic_pointer_cast(req); + auto gObjMsg = zypp::glib::zypp_wrap_cpp(actualReq); + g_signal_emit (_gObject, signals[SIG_EVENT], 0, gObjMsg.get(), nullptr ); + return; + } + case zyppng::UserRequestType::BooleanChoice: { + auto actualReq = std::dynamic_pointer_cast(req); + auto gObjMsg = zypp::glib::zypp_wrap_cpp(actualReq); + g_signal_emit (_gObject, signals[SIG_EVENT], 0, gObjMsg.get(), nullptr ); + return; + } + case zyppng::UserRequestType::Custom: { + ERR << "Custom user requests can not be wrapped with glib!" << std::endl; + return; //ignore + } + } + }) }); for ( const auto &chld : _cppObj->children () ) { zypp_progress_observer_reg_child( _gObject, zypp::glib::zypp_wrap_cpp(chld) ); } } + +zyppng::ProgressObserverRef zypp_progress_observer_get_cpp( ZyppProgressObserver *self ) +{ + g_return_val_if_fail( ZYPP_PROGRESS_OBSERVER(self), nullptr ); + ZYPP_PROGRESS_OBSERVER_D(); + return d->_cppObj; +} diff --git a/zypp-glib/repomanager.cc b/zypp-glib/repomanager.cc index 0343abbff..29fab25b1 100644 --- a/zypp-glib/repomanager.cc +++ b/zypp-glib/repomanager.cc @@ -9,7 +9,9 @@ #include "private/repomanager_p.h" #include "private/serviceinfo_p.h" #include "private/repoinfo_p.h" +#include "private/error_p.h" #include "expected.h" +#include "zypp-core/zyppng/ui/progressobserver.h" #include #include #include @@ -81,7 +83,7 @@ void ZyppRepoManagerPrivate::initializeCpp( ) } else { if ( !_constrProps->_ctx ) g_error("Context argument can not be NULL"); auto ctx = zypp_context_get_cpp( _constrProps->_ctx.get() ); - _cppObj = zyppng::SyncRepoManager::create ( ctx, zyppng::RepoManagerOptions(ctx) ); + _cppObj = zyppng::AsyncRepoManager::create ( ctx, zyppng::RepoManagerOptions(ctx) ); } _constrProps.reset(); } @@ -101,7 +103,7 @@ zypp_repo_manager_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( zyppng::SyncRepoManagerRef, value, d->_constrProps->_cppObj ) + ZYPP_GLIB_SET_CPPOBJ_PROP( zyppng::AsyncRepoManagerRef, value, d->_constrProps->_cppObj ) case CONTEXT_PROPERTY: { ZyppContext *obj = ZYPP_CONTEXT(g_value_get_object( value )); @@ -146,6 +148,16 @@ ZyppRepoManager *zypp_repo_manager_new( ZyppContext *ctx ) return static_cast( g_object_new( zypp_repo_manager_get_type(), "zyppcontext", ctx, nullptr ) ); } +ZyppRepoManager *zypp_repo_manager_new_initialized( ZyppContext *ctx, GError **error ) +{ + auto rM = zypp::glib::ZyppRepoManagerRef( zypp_repo_manager_new(ctx), zypp::glib::retain_object ); + if ( !zypp_repo_manager_initialize( rM.get(), error ) ) + return nullptr; + + return rM.detach (); +} + + gboolean zypp_repo_manager_initialize( ZyppRepoManager *self, GError **error ) { ZYPP_REPO_MANAGER_D(); @@ -154,18 +166,8 @@ gboolean zypp_repo_manager_initialize( ZyppRepoManager *self, GError **error ) try { d->cppType ()->initialize().unwrap(); return true; - } catch ( const zypp::Exception &e ) { - if ( error ) { - g_error_new( ZYPP_EXCEPTION, ZYPP_ERROR, "%s", e.asString().c_str() ); - } - } catch ( const std::exception &e ) { - if ( error ) { - g_error_new( ZYPP_EXCEPTION, ZYPP_ERROR, "%s", e.what() ); - } } catch ( ... ) { - if ( error ) { - g_error_new( ZYPP_EXCEPTION, ZYPP_ERROR, "%s", "Unknown exception." ); - } + zypp_error_from_exception ( error, std::current_exception() ); } return false; } @@ -218,26 +220,59 @@ GList *zypp_repo_manager_get_known_services(ZyppRepoManager *self) return ret; } -GList *zypp_repo_manager_refresh_repos( ZyppRepoManager *self, GList *repos, gboolean forceDownload, ZyppProgressObserver *statusTracker ) +void zypp_repo_manager_refresh_repos_async ( ZyppRepoManager *self, GList *repos, gboolean forceDownload, GCancellable *cancellable, GAsyncReadyCallback cb, gpointer user_data ) { ZYPP_REPO_MANAGER_D(); - d->_cppObj->zyppContext(); + auto ctx = d->_cppObj->zyppContext(); + auto progress = ctx->progressObserver(); zypp::glib::GListContainer results; zypp::glib::GListView repoInfos( repos ); + std::vector cppInfos; + std::transform( repoInfos.begin (), repoInfos.end(), std::back_inserter(cppInfos), []( ZyppRepoInfo *i) { return zypp_repo_info_get_cpp (i); } ); + + auto task = [ mgr = d->_cppObj, progress, repos = std::move(cppInfos), forceDownload ](){ + return mgr->refreshMetadata( repos, forceDownload ? zypp::RepoManagerFlags::RefreshForced : zypp::RepoManagerFlags::RefreshIfNeeded, progress ); + }; + +#if 0 + auto cppResults = d->_cppObj->refreshMetadata( std::move(cppInfos), forceDownload ? zypp::RepoManagerFlags::RefreshForced : zypp::RepoManagerFlags::RefreshIfNeeded, progress ); + + // need to give the results back to the calling code + for ( const auto &res : cppResults ) { + if ( res.second ) { + // need to sync back the result + for ( auto info : repoInfos ) { + zyppng::RepoInfo &repo = zypp_repo_info_get_cpp (info); + if ( repo.alias() == res.first.alias() ) { + repo = res.first; + } + } + + GValue val = G_VALUE_INIT; + g_value_init( &val, ZYPP_TYPE_REPO_REFRESH_RESULT); + g_value_set_enum ( &val, ZYPP_REPO_MANAGER_REFRESHED ); + results.push_back ( zypp_expected_new_value (&val) ); + + } else { + GError *err = nullptr; + zypp_error_from_exception ( &err, res.second.error() ); + results.push_back ( zypp_expected_new_error ( err ) ); + } + } //keep a reference to the tracker - zypp::glib::ZyppProgressObserverRef tracker( statusTracker, zypp::glib::retain_object ); - zypp_progress_observer_set_current ( statusTracker, 0 ); - zypp_progress_observer_set_base_steps ( statusTracker, repoInfos.size()); + zypp::glib::ZyppProgressObserverRef statusTracker = zypp::glib::zypp_wrap_cpp(progress); + zypp_progress_observer_set_current ( statusTracker.get(), 0 ); + zypp_progress_observer_set_base_steps ( statusTracker.get(), repoInfos.size()); std::vector subTasksTracker; for ( const auto &info : repoInfos ) { const auto &zInfo = zypp_repo_info_get_cpp(info); const std::string &name = zInfo.name (); zypp::glib::ZyppProgressObserverRef subTask = zypp::glib::g_object_create( "label", name.c_str (), "base-steps", 10 ); - zypp_progress_observer_add_subtask ( statusTracker, subTask.get(), 1.0 ); + zypp_progress_observer_add_subtask ( statusTracker.get(), subTask.get(), 1.0 ); subTasksTracker.push_back ( subTask ); } @@ -252,7 +287,7 @@ GList *zypp_repo_manager_refresh_repos( ZyppRepoManager *self, GList *repos, gbo zypp_progress_observer_set_finished ( t.get() ); } - zypp_progress_observer_set_current ( statusTracker, repoInfos.size() ); + zypp_progress_observer_set_current ( statusTracker.get(), repoInfos.size() ); GValue val = G_VALUE_INIT; g_value_init( &val, ZYPP_TYPE_REPO_REFRESH_RESULT); @@ -263,5 +298,6 @@ GList *zypp_repo_manager_refresh_repos( ZyppRepoManager *self, GList *repos, gbo results.push_back ( zypp_expected_new_value (&val) ); results.push_back ( zypp_expected_new_error ( g_error_new( ZYPP_REPO_MANAGER_ERROR, ZYPP_REPO_MANAGER_ERROR_REF_FAILED, "Refresh failed horribly") ) ); return results.take(); +#endif } diff --git a/zypp-glib/repomanager.h b/zypp-glib/repomanager.h index 8651cafb7..49cbc528d 100644 --- a/zypp-glib/repomanager.h +++ b/zypp-glib/repomanager.h @@ -11,6 +11,7 @@ #include +#include #include G_BEGIN_DECLS @@ -18,7 +19,6 @@ G_BEGIN_DECLS typedef struct _ZyppContext ZyppContext; typedef struct _ZyppRepoInfo ZyppRepoInfo; typedef struct _ZyppExpected ZyppExpected; -typedef struct _ZyppProgressObserver ZyppProgressObserver; typedef enum { ZYPP_REPO_MANAGER_UP_TO_DATE, @@ -42,10 +42,19 @@ typedef enum { /** * zypp_repo_manager_new: (constructor) * @ctx: The #ZyppContext the RepoManager should operate on + * * Returns: (transfer full): newly created #ZyppRepoManager */ ZyppRepoManager *zypp_repo_manager_new( ZyppContext *ctx ) LIBZYPP_GLIB_EXPORT; +/** + * zypp_repo_manager_new_initialized: (constructor) + * @ctx: The #ZyppContext the RepoManager should operate on + * + * Returns: (transfer full): newly created #ZyppRepoManager + */ +ZyppRepoManager *zypp_repo_manager_new_initialized( ZyppContext *ctx, GError **error ) LIBZYPP_GLIB_EXPORT; + /** * zypp_repo_manager_initialize: @@ -73,17 +82,41 @@ GList *zypp_repo_manager_get_known_repos ( ZyppRepoManager *self ) LIBZYPP_GLIB_ */ GList *zypp_repo_manager_get_known_services ( ZyppRepoManager *self ) LIBZYPP_GLIB_EXPORT; - +#if 0 /** * zypp_repo_manager_refresh_repos: * @self: a #ZyppRepoManager * @repos: (element-type ZyppRepoInfo) (transfer none): the repositories to refresh * @forceDownload: Force downloading the repository even if its up 2 date - * @statusTracker: (transfer full) (nullable): Progress tracker * * Returns: (element-type ZyppExpected) (transfer full): list of results for the refreshed repos */ -GList *zypp_repo_manager_refresh_repos ( ZyppRepoManager *self, GList *repos, gboolean forceDownload, ZyppProgressObserver *statusTracker ) LIBZYPP_GLIB_EXPORT; +GList *zypp_repo_manager_refresh_repos ( ZyppRepoManager *self, GList *repos, gboolean forceDownload ) LIBZYPP_GLIB_EXPORT; +#endif + +/** + * zypp_repo_manager_refresh_repos_async: + * @self: a #ZyppRepoManager + * @repos: (element-type ZyppRepoInfo) (transfer none): the repositories to refresh + * @forceDownload: Force downloading the repository even if its up 2 date + * @cancellable: (nullable) + * @cb: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Returns: (element-type ZyppExpected) (transfer full): list of results for the refreshed repos + */ +void zypp_repo_manager_refresh_repos_async ( ZyppRepoManager *self, GList *repos, gboolean forceDownload, GCancellable *cancellable, GAsyncReadyCallback cb, gpointer user_data ) LIBZYPP_GLIB_EXPORT; + +/** + * zypp_repo_manager_refresh_repos_finish: + * @self: (in): a #ZyppRepoManager + * @result: where to place the result + * @error: return location for a GError, or NULL + * + * Returns: (transfer full): Path where the file was downloaded to + */ +gchar * zypp_repo_manager_refresh_repos_finish ( ZyppRepoManager *self, GAsyncResult *result, GError **error ); + G_END_DECLS diff --git a/zypp-glib/serviceinfo.cc b/zypp-glib/serviceinfo.cc index f662537cc..029607845 100644 --- a/zypp-glib/serviceinfo.cc +++ b/zypp-glib/serviceinfo.cc @@ -1,3 +1,11 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ #include "private/serviceinfo_p.h" #include "private/infobase_p.h" #include "zypp-glib/private/context_p.h" diff --git a/zypp-glib/test.py b/zypp-glib/test.py index bf47d7d10..28c7eddd6 100755 --- a/zypp-glib/test.py +++ b/zypp-glib/test.py @@ -1,97 +1,163 @@ #!/usr/bin/env python3 import sys +import re +import inquirer import gi.repository # Set the search path to use the newly generated introspection files gi.require_version('GIRepository', '2.0') gi.require_version('GLib', '2.0') gi.require_version('Gio', '2.0') +from tqdm import tqdm + from gi.repository import GIRepository from gi.repository import GLib from gi.repository import Gio -GIRepository.Repository.prepend_search_path('/home/zbenjamin/build/libzypp/zyppng') - -mainloop = GLib.MainLoop() +GIRepository.Repository.prepend_search_path('/home/zbenjamin/build/zypp-stack/Desktop-Debug/libzypp/zypp-glib') gi.require_version('Zypp', '1.0') from gi.repository import Zypp -context = Zypp.Context( glibContext=mainloop.get_context()) -if not context.load_system("/"): - print ("Failed to load system") - exit(1) +context = Zypp.Context() +class Tracker: + def __init__(self, tracker = None, nesting = 0 ): + if tracker is None: + self.zyppTracker = Zypp.ProgressObserver() + else: + self.zyppTracker = tracker -repomgr = context.get_repo_manager() -known_repos = repomgr.get_known_repos() -for i in known_repos: - print ( i.name() ) + self.childBars = [] #where we store our children + self.progressBar = None + self.nesting = 0 -print("\n\n") + self.zyppTracker.connect("notify::label", self.on_label_change ) + self.zyppTracker.connect("notify::progress", self.on_progress ) + self.zyppTracker.connect("start", self.on_start ) + self.zyppTracker.connect("finished", self.on_finished ) + self.zyppTracker.connect("new-subtask", self.on_new_subtask ) + self.zyppTracker.connect("event", self.on_user_request ) -def on_progress( tracker, param ): - print("New progress %r" % tracker.get_property(param.name)) + self.progressBar = tqdm( total=100, position=self.nesting, desc=self.zyppTracker.get_label() ) -def on_change( tracker, param ): - print("New value for param: %r %r" % (param.name, tracker.get_property(param.name)) ) + def on_start( self, sender ): + self.progressBar.update() + self.lastProgress = 0 -def on_finished( tracker ): - print("Tracker finished: %s " % tracker.get_label()) + def on_finished( self, sender ): + self.progressBar.close() + del self.progressBar + self.progressBar = None -def on_new_subtask( tracker, subtask_param ): - print("Got new subtask: %s" % subtask_param.get_label()) - subtask_param.connect("finished", on_finished) + def on_progress( self, sender, param ): + newProgress = sender.get_property(param.name) + self.progressBar.update( n=(newProgress - self.lastProgress) ) + self.lastProgress = newProgress -tracker = Zypp.TaskStatus( label="Refreshing" ) -tracker.connect("notify::value", on_change) -tracker.connect("notify::steps", on_change) -tracker.connect("notify::progress", on_progress) -tracker.connect("finished", on_finished) -tracker.connect("new-subtask", on_new_subtask) -refresh_results = repomgr.refresh_repos( known_repos, True, tracker ) -tracker.set_finished() -for res in refresh_results: - try: - result1 = res.get_value() - except GLib.GError as e: - print("Error: " + e.message) - else: - print("No error with res: ") - print(result1) + def on_label_change( self, sender, param ): + self.progressBar.set_description( desc=sender.get_property(param.name), refresh=True ) -cancellable = Gio.Cancellable() -downloader = context.get_downloader() + def on_child_finished( self, child ): + try: + for child in self.childBars: + if child.zyppTracker == child: + self.childBars.remove(child) + return + except ValueError: + pass -list = GLib.List() + def on_new_subtask( self, sender, subtask_param ): + self.childBars.append( Tracker(subtask_param, self.nesting+1) ) + subtask_param.connect("finished", self.on_child_finished ) -l = [i for i in range(10)] -l.append( (sys.maxsize*2)+1 ) -print("Maxsize is: "+str( (sys.maxsize*2)+1 )+"\n" ) -repomgr.test_list(l) + def on_user_request( self, sender, event ): + match event: + case Zypp.BooleanChoiceRequest() as boolReq: -for i in l: - print("Elem is: "+str(i)+"\n") + # we are going to handle the event + boolReq.set_accepted() + questions = [ + inquirer.List('choice', + message=boolReq.get_label(), + choices=[('yes', True), ('no', False)], + default=['no'] + ), + ] + answer = inquirer.prompt(questions)["choice"] + print("User selected: %s" % str(answer)) + boolReq.set_choice(answer) -resi = None + case Zypp.ListChoiceRequest() as listReq: -def on_ready_callback( source_object, result, user_data ): - print("Yay it's ready") - try: - p = source_object.get_file_finish( result ) - except GLib.GError as e: - print("Error: " + e.message) - else: - resi = Zypp.ManagedFile( p.get_path(), True ) - p.set_dispose_enabled(False) - print("File was downloaded to " + p.get_path() ) - mainloop.quit() + # we are going to handle the event + listReq.set_accepted() + + # build a list of tuples for our choices, + # where each tuple is the label for the option, and the value returned if the corresponding option is chosen. + # Here it's simply the index of the option in the options list + choices = [] + for idx, opt in enumerate(listReq.get_options()): + choices.append( ("%s(%s)" % (opt.get_label(), opt.get_detail()), idx) ); + + print ("Default for upcoming question is: %s" % choices[listReq.get_default()][0]) + + questions = [ + inquirer.List('choice', + message=listReq.get_label(), + choices=choices, + default=choices[listReq.get_default()][0] + ), + ] + answer = inquirer.prompt(questions)["choice"] + print("User selected: %s" % str(answer)) + listReq.set_choice(answer) + + case Zypp.ShowMsgRequest() as msgReq: + # we are going to handle the event + msgReq.set_accepted() -#downloader.get_file_async( "https://download.opensuse.org/repositories/server:/mail/15.4/server:mail.repo", "/tmp", cancellable, on_ready_callback, None) -#mainloop.run() + print(msgReq.get_message()) -#if resi: - #print("File was downloaded to " + resi.get_path() ) + +progBar = Tracker() +context.set_progress_observer(progBar.zyppTracker) + + +print ("Load system") + +if not context.load_system("/tmp/fake"): + print ("Failed to load system") + exit(1) + +print ("Loaded system") + +repomgr = None +try: + repomgr = Zypp.RepoManager.new_initialized( context ) +except GLib.GError as e: + print("Error: " + e.message) + print("History: " + str(Zypp.Error.get_history(e))) + exit(1) + +known_repos = repomgr.get_known_repos() +print ("Knows repos: " + str(len(known_repos) )) +for i in known_repos: + print ( "Repo: "+i.name() ) + +print ("Refreshing") + +#refreshing the repos might change properties in the RepoInfos in our list +refresh_results = repomgr.refresh_repos( known_repos, True) +for res in refresh_results: + try: + result1 = res.get_value() + except GLib.GError as e: + print("Error: " + e.message) + print("History: " + str(Zypp.Error.get_history(e))) + else: + print("No error with res: ") + print(str(result1)) diff --git a/zypp-glib/ui/booleanchoicerequest.cc b/zypp-glib/ui/booleanchoicerequest.cc index c1b4b66c7..2b8f9adda 100644 --- a/zypp-glib/ui/booleanchoicerequest.cc +++ b/zypp-glib/ui/booleanchoicerequest.cc @@ -44,6 +44,10 @@ static void zypp_boolean_choice_request_class_init (ZyppBooleanChoiceRequestClas GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ZYPP_INIT_GOBJECT_BOILERPLATE_KLASS ( zypp_boolean_choice_request, gobject_class ); obj_properties[PROP_CPPOBJ] = ZYPP_GLIB_ADD_CPPOBJ_PROP(); + + g_object_class_install_properties (gobject_class, + N_PROPERTIES, + obj_properties); } static void diff --git a/zypp-glib/ui/listchoicerequest.cc b/zypp-glib/ui/listchoicerequest.cc index b62e4325f..e9aa2ee20 100644 --- a/zypp-glib/ui/listchoicerequest.cc +++ b/zypp-glib/ui/listchoicerequest.cc @@ -77,6 +77,10 @@ static void zypp_list_choice_request_class_init (ZyppListChoiceRequestClass *kla GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ZYPP_INIT_GOBJECT_BOILERPLATE_KLASS ( zypp_list_choice_request, gobject_class ); obj_properties[PROP_CPPOBJ] = ZYPP_GLIB_ADD_CPPOBJ_PROP(); + + g_object_class_install_properties (gobject_class, + N_PROPERTIES, + obj_properties); } static void diff --git a/zypp-glib/ui/private/userrequest_p.h b/zypp-glib/ui/private/userrequest_p.h index 3df7e80cc..b1e3b7d2e 100644 --- a/zypp-glib/ui/private/userrequest_p.h +++ b/zypp-glib/ui/private/userrequest_p.h @@ -105,6 +105,9 @@ struct ZyppUserRequestImpl iface->get_data = get_data; iface->get_keys = get_keys; iface->get_content_type = get_content_type; + iface->set_accepted = set_accepted; + iface->set_ignored = set_ignored; + iface->get_accepted = get_accepted; } }; diff --git a/zypp-glib/ui/showmessagerequest.cc b/zypp-glib/ui/showmessagerequest.cc index 21cb60e9e..451a9ba69 100644 --- a/zypp-glib/ui/showmessagerequest.cc +++ b/zypp-glib/ui/showmessagerequest.cc @@ -63,6 +63,10 @@ static void zypp_show_msg_request_class_init (ZyppShowMsgRequestClass *klass) zypp_show_msg_request_type_get_type(), ZYPP_SHOW_MSG_TYPE_INFO, GParamFlags( G_PARAM_CONSTRUCT | G_PARAM_READWRITE ) ); + + g_object_class_install_properties (gobject_class, + N_PROPERTIES, + obj_properties); } static void diff --git a/zypp-glib/utils/RetainPtr b/zypp-glib/utils/RetainPtr index 38538f60f..957d0ed61 100644 --- a/zypp-glib/utils/RetainPtr +++ b/zypp-glib/utils/RetainPtr @@ -200,7 +200,7 @@ struct retain_ptr { return *this; } - retain_ptr& operator = (nullptr_t) noexcept { this->reset(); return *this; } + retain_ptr& operator = (nullptr_t) noexcept { this->reset( nullptr ); return *this; } void swap (retain_ptr& that) noexcept { using std::swap; diff --git a/zypp-glib/zypp-glib.cc b/zypp-glib/zypp-glib.cc new file mode 100644 index 000000000..7757042d9 --- /dev/null +++ b/zypp-glib/zypp-glib.cc @@ -0,0 +1,9 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +#include "zypp-glib.h" diff --git a/zypp/FileChecker.cc b/zypp/FileChecker.cc index c5c68b4c9..9e2dbed21 100644 --- a/zypp/FileChecker.cc +++ b/zypp/FileChecker.cc @@ -37,7 +37,7 @@ namespace zypp void ChecksumFileChecker::operator()( const Pathname &file ) const { - const auto &res = zyppng::CheckSumWorkflow::verifyChecksum ( zypp_detail::GlobalStateHelper::context(), _checksum, file ); + const auto &res = zyppng::CheckSumWorkflow::verifyChecksum ( zypp_detail::GlobalStateHelper::context(), zypp_detail::GlobalStateHelper::context()->progressObserver(), _checksum, file ); if ( !res ) { std::rethrow_exception( res.error ( ) ); } @@ -88,7 +88,7 @@ namespace zypp SignatureFileChecker & self { const_cast(*this) }; self._verifyContext.file( file_r ); - auto res = zyppng::SignatureFileCheckWorkflow::verifySignature ( zypp_detail::GlobalStateHelper::context(), keyring::VerifyFileContext(_verifyContext) ); + auto res = zyppng::SignatureFileCheckWorkflow::verifySignature ( zypp_detail::GlobalStateHelper::context(), zypp_detail::GlobalStateHelper::context()->progressObserver(), keyring::VerifyFileContext(_verifyContext) ); if ( !res ) { std::rethrow_exception( res.error ( ) ); } diff --git a/zypp/PurgeKernels.cc b/zypp/PurgeKernels.cc index 0aa372831..6d85900a3 100644 --- a/zypp/PurgeKernels.cc +++ b/zypp/PurgeKernels.cc @@ -637,7 +637,6 @@ namespace zypp { MIL << "Package not explicitly handled" << std::endl; } } - } MIL << "Grouped packages: " << std::endl; diff --git a/zypp/RepoManager.cc b/zypp/RepoManager.cc index d2ae4a6ad..7c4d4f3f6 100644 --- a/zypp/RepoManager.cc +++ b/zypp/RepoManager.cc @@ -183,8 +183,9 @@ namespace zypp RepoManager::RefreshCheckStatus RepoManager::checkIfToRefreshMetadata( const RepoInfo &info, const Url &url, RawMetadataRefreshPolicy policy ) { auto res = _pimpl->ngMgr().checkIfToRefreshMetadata( const_cast(info).ngRepoInfo() , url, policy ).unwrap(); + const_cast(info).ngRepoInfo() = res.first; _pimpl->syncRepos(); - return res; + return res.second; } Pathname RepoManager::metadataPath( const RepoInfo &info ) const @@ -197,7 +198,7 @@ namespace zypp { // Suppress (interactive) media::MediaChangeReport if we in have multiple basurls (>1) zypp::media::ScopedDisableMediaChangeReport guard( info.baseUrlsSize() > 1 ); - _pimpl->ngMgr().refreshMetadata( const_cast(info).ngRepoInfo(), policy, nullptr ).unwrap(); + const_cast(info).ngRepoInfo() = _pimpl->ngMgr().refreshMetadata( info.ngRepoInfo(), policy, nullptr ).unwrap(); _pimpl->syncRepos(); } @@ -214,7 +215,7 @@ namespace zypp { callback::SendReport report; auto adapt = zyppng::ProgressObserverAdaptor( progressrcv, report ); - _pimpl->ngMgr().buildCache( const_cast(info).ngRepoInfo(), policy, adapt.observer() ).unwrap(); + const_cast(info).ngRepoInfo() = _pimpl->ngMgr().buildCache( const_cast(info).ngRepoInfo(), policy, adapt.observer() ).unwrap(); _pimpl->syncRepos(); } @@ -240,7 +241,7 @@ namespace zypp { callback::SendReport report; auto adapt = zyppng::ProgressObserverAdaptor( progressrcv, report ); - _pimpl->ngMgr().addRepository( const_cast(info).ngRepoInfo(), adapt.observer() ).unwrap(); + const_cast(info).ngRepoInfo() = _pimpl->ngMgr().addRepository( info.ngRepoInfo (), adapt.observer() ).unwrap(); _pimpl->syncRepos(); } @@ -262,8 +263,7 @@ 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.ngRepoInfo(), nullptr ).unwrap(); + const_cast(newinfo).ngRepoInfo() = _pimpl->ngMgr().modifyRepository( alias, newinfo.ngRepoInfo(), nullptr ).unwrap(); _pimpl->syncRepos(); } @@ -349,7 +349,9 @@ namespace zypp } void RepoManager::refreshGeoIp (const RepoInfo::url_set &urls) - { (void) _pimpl->ngMgr().refreshGeoIp( urls ); } + { + (void) zyppng::RepoManagerWorkflow::refreshGeoIPData( _pimpl->ngMgr().zyppContext(), urls); + } //////////////////////////////////////////////////////////////////////////// diff --git a/zypp/ng/contextbase.cc b/zypp/ng/contextbase.cc index e17d91765..70e4ec369 100644 --- a/zypp/ng/contextbase.cc +++ b/zypp/ng/contextbase.cc @@ -8,12 +8,32 @@ namespace zyppng { - ContextBase::ContextBase() : _tmpDir( zypp::filesystem::TmpPath::defaultLocation(), "zypp." ) , _repoVarCache( *this ) { } + void ContextBase::setProgressObserver(ProgressObserverRef observer) + { + if ( _masterProgress != observer ) { + _masterProgress = observer; + _sigProgressObserverChanged.emit(); + } + } + + ProgressObserverRef ContextBase::progressObserver() const + { + return _masterProgress; + } + + void ContextBase::resetProgressObserver() + { + if ( _masterProgress ) { + _masterProgress.reset(); + _sigProgressObserverChanged.emit(); + } + } + ContextBase::~ContextBase() { } diff --git a/zypp/ng/contextbase.h b/zypp/ng/contextbase.h index 12faf0047..29bd37136 100644 --- a/zypp/ng/contextbase.h +++ b/zypp/ng/contextbase.h @@ -27,6 +27,7 @@ namespace zypp { namespace zyppng { ZYPP_FWD_DECL_TYPE_WITH_REFS (ContextBase); + ZYPP_FWD_DECL_TYPE_WITH_REFS (ProgressObserver); using KeyRing = zypp::KeyRing; using KeyRingRef = zypp::KeyRing_Ptr; @@ -49,6 +50,28 @@ namespace zyppng { ContextBase &operator=(const ContextBase &) = delete; ContextBase &operator=(ContextBase &&) = delete; + + /*! + * Sets the master progress observer for this context, this is the place where all + * events and progress are received from, can be shared with another context. + */ + void setProgressObserver( ProgressObserverRef observer ); + + + /*! + * Returns the current \ref ProgressObserver, or a empty reference if + * no observer was registered + */ + ProgressObserverRef progressObserver( ) const; + + /*! + * Resets the currently used \ref ProgressObserver. + * Currently running pipelines might still have a reference to the + * observer though. + */ + void resetProgressObserver(); + + /*! * Returns the root path of the context */ @@ -114,6 +137,14 @@ namespace zyppng { return _sigClose; } + /*! + * This signal is always emitted when the progress observer is changed, + * primarily used to signal the C wrapper to update its reference + */ + SignalProxy sigProgressObserverChanged() { + return _sigProgressObserverChanged; + } + protected: ContextBase(); @@ -150,6 +181,7 @@ namespace zyppng { Signal _sigClose; Signal _sigTargetChanged; // legacy support signal in case the context changes its target + Signal _sigProgressObserverChanged; expected aquireLock(); expected loadConfig( zypp::Pathname confPath ); @@ -166,6 +198,8 @@ namespace zyppng { zypp::ZyppContextLockRef _myLock; repo::RepoVarsMap _repoVarCache; + ProgressObserverRef _masterProgress; + protected: std::map _resourceLocks; }; diff --git a/zypp/ng/repo/refresh.cc b/zypp/ng/repo/refresh.cc index eb97dcea5..4d291bab6 100644 --- a/zypp/ng/repo/refresh.cc +++ b/zypp/ng/repo/refresh.cc @@ -9,6 +9,7 @@ #include "refresh.h" #include #include +#include #include #include @@ -16,16 +17,15 @@ namespace zyppng::repo { template - 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) ) + RefreshContext::RefreshContext( private_constr_t, RepoManagerRef &&repoManager, RepoInfo &&info, zypp::Pathname &&rawCachePath, zypp::filesystem::TmpDir &&tempDir ) + : _repoManager( std::move(repoManager) ) , _repoInfo( std::move(info) ) , _rawCachePath( std::move(rawCachePath) ) , _tmpDir( std::move(tempDir) ) {} template - expected> RefreshContext::create( Ref zyppContext, RepoInfo info, RepoManagerRef repoManager ) + expected> RefreshContext::create( RepoManagerRef repoManager, RepoInfo info ) { using namespace operators; using CtxType = RefreshContext; @@ -45,11 +45,10 @@ namespace zyppng::repo { MIL << "Creating RefreshContext " << std::endl; return expected::success( std::make_shared( private_constr_t{} - , std::move(zyppContext) + , std::move(repoManager) , std::move(info) , std::move(rawCachePath) - , std::move(tmpdir) - , std::move(repoManager))); + , std::move(tmpdir))); } ); } @@ -78,9 +77,9 @@ namespace zyppng::repo { } template - const Ref &RefreshContext::zyppContext() const + Ref RefreshContext::zyppContext() const { - return _zyppContext; + return _repoManager->zyppContext(); } template diff --git a/zypp/ng/repo/refresh.h b/zypp/ng/repo/refresh.h index 632be8731..410595d36 100644 --- a/zypp/ng/repo/refresh.h +++ b/zypp/ng/repo/refresh.h @@ -14,14 +14,17 @@ #include #include -#include +#include #include #include -#include #include #include #include +namespace zyppng { + ZYPP_FWD_DECL_TEMPL_TYPE_WITH_REFS_ARG1 (RepoManager, ZyppContextType); +} + namespace zyppng::repo { ZYPP_FWD_DECL_TEMPL_TYPE_WITH_REFS_ARG1 (RefreshContext, ZyppContextType); @@ -46,8 +49,8 @@ namespace zyppng::repo { using MediaHandle = typename ProvideType::MediaHandle; using PluginRepoverification = zypp_private::repo::PluginRepoverification; - 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 ); + static expected> create( RepoManagerRef repoManager, RepoInfo info ); + ZYPP_DECL_PRIVATE_CONSTR_ARGS(RefreshContext, RepoManagerRef &&repoManager, RepoInfo &&info, zypp::Pathname &&rawCachePath, zypp::filesystem::TmpDir &&tempDir ); ~RefreshContext() override; @@ -74,7 +77,7 @@ namespace zyppng::repo { * Current zypp context we are working on, either \ref zyppng::Context * or \ref zyppng::SyncContext. */ - const Ref &zyppContext () const; + Ref zyppContext() const; /*! * Current \ref zypp::RepoInfo this refresh context is operating with, @@ -119,7 +122,6 @@ namespace zyppng::repo { SignalProxy sigProbedTypeChanged(); private: - Ref _zyppContext; RepoManagerRef _repoManager; RepoInfo _repoInfo; zypp::Pathname _rawCachePath; diff --git a/zypp/ng/repo/workflows/plaindir.cc b/zypp/ng/repo/workflows/plaindir.cc index 171543c97..2829d4f39 100644 --- a/zypp/ng/repo/workflows/plaindir.cc +++ b/zypp/ng/repo/workflows/plaindir.cc @@ -24,7 +24,7 @@ namespace zyppng::PlaindirWorkflows { namespace { template - auto statusLogic( DlContextRefType &&ctx, MediaHandle mediaHandle ) { + auto statusLogic( DlContextRefType &&ctx, ProgressObserverRef taskObserver, MediaHandle mediaHandle ) { constexpr bool isAsync = std::is_same_v; // this can only happen if this function is called with a non mounting medium, but those do not support plaindir anyway @@ -39,14 +39,14 @@ namespace zyppng::PlaindirWorkflows { } } - AsyncOpRef > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle) + AsyncOpRef > repoStatus(repo::AsyncDownloadContextRef dl, ProgressObserverRef taskObserver, ProvideMediaHandle mediaHandle) { - return statusLogic( std::move(dl), std::move(mediaHandle) ); + return statusLogic( std::move(dl), std::move(taskObserver), std::move(mediaHandle) ); } - expected repoStatus(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle) + expected repoStatus(repo::SyncDownloadContextRef dl, ProgressObserverRef taskObserver, SyncMediaHandle mediaHandle) { - return statusLogic( std::move(dl), std::move(mediaHandle) ); + return statusLogic( std::move(dl), std::move(taskObserver), std::move(mediaHandle) ); } @@ -85,12 +85,12 @@ namespace zyppng::PlaindirWorkflows { } } - AsyncOpRef > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver) + AsyncOpRef > download(repo::AsyncDownloadContextRef dl, ProgressObserverRef progressObserver, ProvideMediaHandle mediaHandle ) { return dlLogic( std::move(dl), std::move(mediaHandle), std::move(progressObserver) ); } - expected download(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, ProgressObserverRef progressObserver) + expected download(repo::SyncDownloadContextRef dl, ProgressObserverRef progressObserver, SyncMediaHandle mediaHandle) { return dlLogic( std::move(dl), std::move(mediaHandle), std::move(progressObserver) ); } diff --git a/zypp/ng/repo/workflows/plaindir.h b/zypp/ng/repo/workflows/plaindir.h index 2ea7f78f3..5e227cb2f 100644 --- a/zypp/ng/repo/workflows/plaindir.h +++ b/zypp/ng/repo/workflows/plaindir.h @@ -24,11 +24,11 @@ namespace zyppng { ZYPP_FWD_DECL_TYPE_WITH_REFS( ProgressObserver ); namespace PlaindirWorkflows { - AsyncOpRef> repoStatus( repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle ); - expected repoStatus( repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle ); + AsyncOpRef> repoStatus(repo::AsyncDownloadContextRef dl, ProgressObserverRef taskObserver, ProvideMediaHandle mediaHandle ); + expected repoStatus( repo::SyncDownloadContextRef dl, ProgressObserverRef taskObserver, SyncMediaHandle mediaHandle ); - AsyncOpRef> download ( repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver = nullptr ); - expected download ( repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, ProgressObserverRef progressObserver = nullptr ); + AsyncOpRef> download (repo::AsyncDownloadContextRef dl, ProgressObserverRef progressObserver, ProvideMediaHandle mediaHandle ); + expected download ( repo::SyncDownloadContextRef dl, ProgressObserverRef progressObserver, SyncMediaHandle mediaHandle ); } } diff --git a/zypp/ng/repo/workflows/repodownloaderwf.cc b/zypp/ng/repo/workflows/repodownloaderwf.cc index 7ca3d7551..e514018ec 100644 --- a/zypp/ng/repo/workflows/repodownloaderwf.cc +++ b/zypp/ng/repo/workflows/repodownloaderwf.cc @@ -48,10 +48,11 @@ namespace zyppng { using MediaHandle = typename ProvideType::MediaHandle; using ProvideRes = typename ProvideType::Res; - DownloadMasterIndexLogic( DlContextRefType &&ctxRef, MediaHandle &&mediaHandle, zypp::filesystem::Pathname &&masterIndex_r ) + DownloadMasterIndexLogic( DlContextRefType &&ctxRef, MediaHandle &&mediaHandle, zypp::filesystem::Pathname &&masterIndex_r, ProgressObserverRef progressObserver ) : _dlContext( std::move(ctxRef) ) , _media(std::move( mediaHandle )) , _masterIndex(std::move( masterIndex_r )) + , _progressObserver(std::move(progressObserver)) { } public: @@ -151,7 +152,7 @@ namespace zyppng { vCtx.addBuddyKey( keyData.id() ); } - return SignatureFileCheckWorkflow::verifySignature( _dlContext->zyppContext(), std::move(vCtx)) + return SignatureFileCheckWorkflow::verifySignature( _dlContext->zyppContext(), _progressObserver, std::move(vCtx)) | and_then([ this, res = std::move(res) ]( zypp::keyring::VerifyFileContext verRes ){ // remember the validation status _repoSigValidated = verRes.fileValidated(); @@ -278,6 +279,7 @@ namespace zyppng { DlContextRefType _dlContext; MediaHandle _media; zypp::Pathname _masterIndex; + ProgressObserverRef _progressObserver; zypp::Pathname _destdir; zypp::Pathname _sigpath; @@ -289,38 +291,38 @@ namespace zyppng { } - AsyncOpRef > RepoDownloaderWorkflow::downloadMasterIndex(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, zypp::Pathname masterIndex_r) + AsyncOpRef > RepoDownloaderWorkflow::downloadMasterIndex(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, zypp::Pathname masterIndex_r, ProgressObserverRef progressObserver ) { - return SimpleExecutor>>::run( std::move(dl), std::move(mediaHandle), std::move(masterIndex_r) ); + return SimpleExecutor>>::run( std::move(dl), std::move(mediaHandle), std::move(masterIndex_r), std::move(progressObserver) ); } - expected RepoDownloaderWorkflow::downloadMasterIndex(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, zypp::Pathname masterIndex_r) + expected RepoDownloaderWorkflow::downloadMasterIndex(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, zypp::Pathname masterIndex_r, ProgressObserverRef progressObserver ) { - return SimpleExecutor>>::run( std::move(dl), std::move(mediaHandle), std::move(masterIndex_r) ); + return SimpleExecutor>>::run( std::move(dl), std::move(mediaHandle), std::move(masterIndex_r), std::move(progressObserver) ); } - AsyncOpRef> RepoDownloaderWorkflow::downloadMasterIndex ( repo::AsyncDownloadContextRef dl, AsyncLazyMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r ) + AsyncOpRef> RepoDownloaderWorkflow::downloadMasterIndex ( repo::AsyncDownloadContextRef dl, AsyncLazyMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r, ProgressObserverRef progressObserver ) { using namespace zyppng::operators; return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle ) - | and_then([ dl, mi = std::move(masterIndex_r) ]( ProvideMediaHandle handle ) mutable { - return downloadMasterIndex( std::move(dl), std::move(handle), std::move(mi) ); + | and_then([ dl, mi = std::move(masterIndex_r), po = std::move(progressObserver) ]( ProvideMediaHandle handle ) mutable { + return downloadMasterIndex( std::move(dl), std::move(handle), std::move(mi), std::move(po) ); }); } - expected RepoDownloaderWorkflow::downloadMasterIndex ( repo::SyncDownloadContextRef dl, SyncLazyMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r ) + expected RepoDownloaderWorkflow::downloadMasterIndex ( repo::SyncDownloadContextRef dl, SyncLazyMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r, ProgressObserverRef progressObserver ) { using namespace zyppng::operators; return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle ) - | and_then([ dl, mi = std::move(masterIndex_r) ]( SyncMediaHandle handle ) mutable { - return downloadMasterIndex( std::move(dl), std::move(handle), std::move(mi) ); + | and_then([ dl, mi = std::move(masterIndex_r), po = std::move(progressObserver) ]( SyncMediaHandle handle ) mutable { + return downloadMasterIndex( std::move(dl), std::move(handle), std::move(mi), std::move(po) ); }); } namespace { template - auto statusImpl ( DlContextRefType dlCtx, MediaHandleType &&mediaHandle ) { + auto statusImpl ( DlContextRefType dlCtx, MediaHandleType &&mediaHandle, ProgressObserverRef progressObserver ) { constexpr bool isAsync = std::is_same_v; @@ -330,11 +332,11 @@ namespace zyppng { switch( dlCtx->repoInfo().type().toEnum()) { case zypp::repo::RepoType::RPMMD_e: - return RpmmdWorkflows::repoStatus( dlCtx, std::forward(mediaHandle) ) | and_then( std::move(finalizeStatus) ); + return RpmmdWorkflows::repoStatus( dlCtx, std::move(progressObserver), std::forward(mediaHandle) ) | and_then( std::move(finalizeStatus) ); case zypp::repo::RepoType::YAST2_e: - return SuseTagsWorkflows::repoStatus( dlCtx, std::forward(mediaHandle) ) | and_then( std::move(finalizeStatus) ); + return SuseTagsWorkflows::repoStatus( dlCtx, std::move(progressObserver), std::forward(mediaHandle) ) | and_then( std::move(finalizeStatus) ); case zypp::repo::RepoType::RPMPLAINDIR_e: - return PlaindirWorkflows::repoStatus ( dlCtx, std::forward(mediaHandle) ) | and_then( std::move(finalizeStatus) ); + return PlaindirWorkflows::repoStatus ( dlCtx, std::move(progressObserver), std::forward(mediaHandle) ) | and_then( std::move(finalizeStatus) ); case zypp::repo::RepoType::NONE_e: break; } @@ -343,27 +345,27 @@ namespace zyppng { } } - AsyncOpRef > RepoDownloaderWorkflow::repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle) { - return statusImpl( dl, std::move(mediaHandle) ); + AsyncOpRef > RepoDownloaderWorkflow::repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver ) { + return statusImpl( dl, std::move(mediaHandle), std::move(progressObserver) ); } - expected RepoDownloaderWorkflow::repoStatus(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle) { - return statusImpl( dl, std::move(mediaHandle) ); + expected RepoDownloaderWorkflow::repoStatus(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, ProgressObserverRef progressObserver ) { + return statusImpl( dl, std::move(mediaHandle), std::move(progressObserver) ); } - AsyncOpRef > RepoDownloaderWorkflow::repoStatus( repo::AsyncDownloadContextRef dl, AsyncLazyMediaHandle mediaHandle ) { + AsyncOpRef > RepoDownloaderWorkflow::repoStatus( repo::AsyncDownloadContextRef dl, AsyncLazyMediaHandle mediaHandle, ProgressObserverRef progressObserver ) { using namespace zyppng::operators; return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle ) - | and_then([ dl ]( ProvideMediaHandle handle ) { - return repoStatus( dl, std::move(handle) ); + | and_then([ dl, obs = std::move(progressObserver) ]( ProvideMediaHandle handle ) mutable { + return repoStatus( dl, std::move(handle), std::move(obs) ); }); } - expected RepoDownloaderWorkflow::repoStatus( repo::SyncDownloadContextRef dl, SyncLazyMediaHandle mediaHandle ) { + expected RepoDownloaderWorkflow::repoStatus( repo::SyncDownloadContextRef dl, SyncLazyMediaHandle mediaHandle, ProgressObserverRef progressObserver ) { using namespace zyppng::operators; return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle ) - | and_then([ dl ]( SyncMediaHandle handle ) { - return repoStatus( dl, std::move(handle) ); + | and_then([ dl, obs = std::move(progressObserver) ]( SyncMediaHandle handle ) { + return repoStatus( dl, std::move(handle), std::move(obs) ); }); } @@ -376,11 +378,11 @@ namespace zyppng { switch( dlCtx->repoInfo().type().toEnum()) { case zypp::repo::RepoType::RPMMD_e: - return RpmmdWorkflows::download( std::move(dlCtx), std::forward(mediaHandle), std::move(progressObserver) ); + return RpmmdWorkflows::download( std::move(dlCtx), std::move(progressObserver), std::forward(mediaHandle) ); case zypp::repo::RepoType::YAST2_e: - return SuseTagsWorkflows::download( std::move(dlCtx), std::forward(mediaHandle), std::move(progressObserver) ); + return SuseTagsWorkflows::download( std::move(dlCtx), std::move(progressObserver), std::forward(mediaHandle) ); case zypp::repo::RepoType::RPMPLAINDIR_e: - return PlaindirWorkflows::download ( std::move(dlCtx), std::forward(mediaHandle) ); + return PlaindirWorkflows::download ( std::move(dlCtx), std::move(progressObserver), std::forward(mediaHandle) ); case zypp::repo::RepoType::NONE_e: break; } diff --git a/zypp/ng/repo/workflows/repodownloaderwf.h b/zypp/ng/repo/workflows/repodownloaderwf.h index 91a34936b..5de0df04c 100644 --- a/zypp/ng/repo/workflows/repodownloaderwf.h +++ b/zypp/ng/repo/workflows/repodownloaderwf.h @@ -34,20 +34,20 @@ namespace zyppng { using SyncLazyMediaHandle = LazyMediaHandle; namespace RepoDownloaderWorkflow { - AsyncOpRef> downloadMasterIndex ( repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r ); - AsyncOpRef> downloadMasterIndex ( repo::AsyncDownloadContextRef dl, AsyncLazyMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r ); - expected downloadMasterIndex ( repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r ); - expected downloadMasterIndex ( repo::SyncDownloadContextRef dl, SyncLazyMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r ); + AsyncOpRef> downloadMasterIndex ( repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r, ProgressObserverRef progressObserver = nullptr ); + AsyncOpRef> downloadMasterIndex ( repo::AsyncDownloadContextRef dl, AsyncLazyMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r, ProgressObserverRef progressObserver = nullptr ); + expected downloadMasterIndex ( repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r, ProgressObserverRef progressObserver = nullptr ); + expected downloadMasterIndex ( repo::SyncDownloadContextRef dl, SyncLazyMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r, ProgressObserverRef progressObserver = nullptr ); - AsyncOpRef> repoStatus( repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle ); - AsyncOpRef > repoStatus( repo::AsyncDownloadContextRef dl, AsyncLazyMediaHandle mediaHandle ); - expected repoStatus( repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle ); - expected repoStatus( repo::SyncDownloadContextRef dl, SyncLazyMediaHandle mediaHandle ); + AsyncOpRef> repoStatus( repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver = nullptr ); + AsyncOpRef > repoStatus( repo::AsyncDownloadContextRef dl, AsyncLazyMediaHandle mediaHandle, ProgressObserverRef progressObserver = nullptr ); + expected repoStatus( repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, ProgressObserverRef progressObserver = nullptr ); + expected repoStatus( repo::SyncDownloadContextRef dl, SyncLazyMediaHandle mediaHandle, ProgressObserverRef progressObserver = nullptr ); AsyncOpRef> download ( repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver = nullptr ); AsyncOpRef > download(repo::AsyncDownloadContextRef dl, AsyncLazyMediaHandle mediaHandle, ProgressObserverRef progressObserver); expected download ( repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, ProgressObserverRef progressObserver = nullptr ); - expected download(repo::SyncDownloadContextRef dl, SyncLazyMediaHandle mediaHandle, ProgressObserverRef progressObserver); + expected download( repo::SyncDownloadContextRef dl, SyncLazyMediaHandle mediaHandle, ProgressObserverRef progressObserver); template auto downloadMediaInfo ( MediaHandle &&mediaHandle, const zypp::filesystem::Pathname &destdir ) { diff --git a/zypp/ng/repo/workflows/repomanagerwf.cc b/zypp/ng/repo/workflows/repomanagerwf.cc index d7e91d0f6..99557fd90 100644 --- a/zypp/ng/repo/workflows/repomanagerwf.cc +++ b/zypp/ng/repo/workflows/repomanagerwf.cc @@ -652,6 +652,7 @@ namespace zyppng::RepoManagerWorkflow { MaybeAsyncRef> execute() { ProgressObserver::setup ( _progressObserver, zypp::str::form(_("Building repository '%s' cache"), _refCtx->repoInfo().label().c_str()), 100 ); + ProgressObserver::start ( _progressObserver ); return assert_alias(_refCtx->repoInfo() ) | and_then( mtry( [this] { @@ -728,8 +729,6 @@ namespace zyppng::RepoManagerWorkflow { needs_cleaning = true; } - ProgressObserver::start( _progressObserver ); - if (needs_cleaning) { auto r = _refCtx->repoManager()->cleanCache(info); diff --git a/zypp/ng/repo/workflows/rpmmd.cc b/zypp/ng/repo/workflows/rpmmd.cc index 5316a288b..130a0949b 100644 --- a/zypp/ng/repo/workflows/rpmmd.cc +++ b/zypp/ng/repo/workflows/rpmmd.cc @@ -40,9 +40,10 @@ namespace zyppng::RpmmdWorkflows { using MediaHandle = typename ProvideType::MediaHandle; using ProvideRes = typename ProvideType::Res; - StatusLogic( DlContextRefType ctx, MediaHandle &&media ) + StatusLogic( DlContextRefType ctx, MediaHandle &&media, ProgressObserverRef &&progressObserver ) : _ctx(std::move(ctx)) , _handle(std::move(media)) + , _progressObserver( std::move(progressObserver) ) {} MaybeAsyncRef> execute() { @@ -69,17 +70,18 @@ namespace zyppng::RpmmdWorkflows { DlContextRefType _ctx; MediaHandle _handle; + ProgressObserverRef _progressObserver; }; } - AsyncOpRef > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle) + AsyncOpRef > repoStatus(repo::AsyncDownloadContextRef dl, ProgressObserverRef progressObserver, ProvideMediaHandle mediaHandle ) { - return SimpleExecutor< StatusLogic, AsyncOp> >::run( std::move(dl), std::move(mediaHandle) ); + return SimpleExecutor< StatusLogic, AsyncOp> >::run( std::move(dl), std::move(mediaHandle), std::move(progressObserver) ); } - expected repoStatus(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle) + expected repoStatus(repo::SyncDownloadContextRef dl, ProgressObserverRef progressObserver, SyncMediaHandle mediaHandle) { - return SimpleExecutor< StatusLogic, SyncOp> >::run( std::move(dl), std::move(mediaHandle) ); + return SimpleExecutor< StatusLogic, SyncOp> >::run( std::move(dl), std::move(mediaHandle), std::move(progressObserver) ); } @@ -116,8 +118,7 @@ namespace zyppng::RpmmdWorkflows { if ( _progressObserver ) _progressObserver->inc(); - return RepoDownloaderWorkflow::downloadMasterIndex( _ctx, _mediaHandle, _ctx->repoInfo().path() / "/repodata/repomd.xml" ) - | inspect( incProgress( _progressObserver ) ) + return RepoDownloaderWorkflow::downloadMasterIndex( _ctx, _mediaHandle, _ctx->repoInfo().path() / "/repodata/repomd.xml", _progressObserver ) | inspect( incProgress( _progressObserver ) ) | and_then( [this] ( DlContextRefType && ) { zypp::Pathname repomdPath = _ctx->files().front(); @@ -140,7 +141,7 @@ namespace zyppng::RpmmdWorkflows { return transform_collect ( std::move(requiredFiles), [this]( zypp::OnMediaLocation file ) { - return DownloadWorkflow::provideToCacheDir( _ctx, _mediaHandle, file.filename(), ProvideFileSpec(file) ) + return DownloadWorkflow::provideToCacheDir( _ctx, _progressObserver, _mediaHandle, file.filename(), ProvideFileSpec(file) ) | inspect ( incProgress( _progressObserver ) ); }) | and_then ( [this]( std::vector &&dlFiles ) { @@ -169,12 +170,12 @@ namespace zyppng::RpmmdWorkflows { }; } - AsyncOpRef > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver) + AsyncOpRef > download(repo::AsyncDownloadContextRef dl, ProgressObserverRef progressObserver, ProvideMediaHandle mediaHandle) { return SimpleExecutor< DlLogic, AsyncOp> >::run( std::move(dl), std::move(mediaHandle), std::move(progressObserver) ); } - expected download(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, ProgressObserverRef progressObserver) + expected download(repo::SyncDownloadContextRef dl, ProgressObserverRef progressObserver, SyncMediaHandle mediaHandle) { return SimpleExecutor< DlLogic, SyncOp> >::run( std::move(dl), std::move(mediaHandle), std::move(progressObserver) ); } diff --git a/zypp/ng/repo/workflows/rpmmd.h b/zypp/ng/repo/workflows/rpmmd.h index 1dc6829ba..f3cd0c434 100644 --- a/zypp/ng/repo/workflows/rpmmd.h +++ b/zypp/ng/repo/workflows/rpmmd.h @@ -30,11 +30,11 @@ namespace zyppng { * to be downloaded to the local disk. */ namespace RpmmdWorkflows { - AsyncOpRef> repoStatus( repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle ); - expected repoStatus(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle ); + AsyncOpRef> repoStatus(repo::AsyncDownloadContextRef dl, ProgressObserverRef progressObserver , ProvideMediaHandle mediaHandle); + expected repoStatus(repo::SyncDownloadContextRef dl, ProgressObserverRef progressObserver, SyncMediaHandle mediaHandle ); - AsyncOpRef> download ( repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver = nullptr ); - expected download ( repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, ProgressObserverRef progressObserver = nullptr ); + AsyncOpRef> download ( repo::AsyncDownloadContextRef dl, ProgressObserverRef progressObserver, ProvideMediaHandle mediaHandle ); + expected download ( repo::SyncDownloadContextRef dl, ProgressObserverRef progressObserver, SyncMediaHandle mediaHandle ); } } diff --git a/zypp/ng/repo/workflows/serviceswf.cc b/zypp/ng/repo/workflows/serviceswf.cc index 846e7f330..d22f26a25 100644 --- a/zypp/ng/repo/workflows/serviceswf.cc +++ b/zypp/ng/repo/workflows/serviceswf.cc @@ -333,6 +333,7 @@ namespace zyppng::RepoServicesWorkflow { : _repoMgr( std::move(repoMgr) ) , _service( std::move(info) ) , _options(options) + , _urlCredentialExtractor( _repoMgr->zyppContext() ) { } MaybeAsyncRef> probeServiceIfNeeded() { @@ -404,7 +405,7 @@ namespace zyppng::RepoServicesWorkflow { _informalError = e; } catch ( ... ) { // all other errors cancel the operation - return Ret::error( ZYPP_FWD_CURRENT_EXCPT() ); + return makeReadyResult(Ret::error( ZYPP_FWD_CURRENT_EXCPT() )); } } @@ -482,12 +483,11 @@ namespace zyppng::RepoServicesWorkflow { //////////////////////////////////////////////////////////////////////////// // Now compare collected repos with the ones in the system... // - RepoInfoList oldRepos; - _repoMgr->getRepositoriesInService( _service.alias(), std::back_inserter( oldRepos ) ); + _repoMgr->getRepositoriesInService( _service.alias(), std::back_inserter( _oldRepos ) ); //////////////////////////////////////////////////////////////////////////// // find old repositories to remove... - for_( oldRepo, oldRepos.begin(), oldRepos.end() ) + for_( oldRepo, _oldRepos.begin(), _oldRepos.end() ) { if ( ! foundAliasIn( oldRepo->alias(), collector.repos ) ) { @@ -508,224 +508,232 @@ namespace zyppng::RepoServicesWorkflow { DBG << "Service removes disabled repo " << oldRepo->alias() << std::endl; auto remRes = _repoMgr->removeRepository( *oldRepo ); - if ( !remRes ) return Ret::error( remRes.error() ); + if ( !remRes ) return makeReadyResult(Ret::error( remRes.error() )); } } - //////////////////////////////////////////////////////////////////////////// // create missing repositories and modify existing ones if needed... - 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? - // User explicitly requested the repo being disabled? - // And hopefully not both ;) If so, enable wins. - - zypp::TriBool toBeEnabled( zypp::indeterminate ); // indeterminate - follow the service request - DBG << "Service request to " << (it->enabled()?"enable":"disable") << " service repo " << it->alias() << std::endl; - - if ( _options.testFlag( zypp::RepoManagerFlags::RefreshService_restoreStatus ) ) - { - DBG << "Opt RefreshService_restoreStatus " << it->alias() << std::endl; - // this overrides any pending request! - // Remove from enable request list. - // NOTE: repoToDisable is handled differently. - // It gets cleared on each refresh. - _service.delRepoToEnable( it->alias() ); - // toBeEnabled stays indeterminate! - } - else - { - if ( _service.repoToEnableFind( it->alias() ) ) + return std::move( collector.repos ) + | operators::transform_collect( [this]( RepoInfo info ){ return updateOrAddRepo(info); } ) + | and_then([this, newRepoStates = std::move(newRepoStates)]( auto ) mutable -> expected { + // Unlike reposToEnable, reposToDisable is always cleared after refresh. + if ( ! _service.reposToDisableEmpty() ) { - DBG << "User request to enable service repo " << it->alias() << std::endl; - toBeEnabled = true; - // Remove from enable request list. - // NOTE: repoToDisable is handled differently. - // It gets cleared on each refresh. - _service.delRepoToEnable( it->alias() ); + _service.clearReposToDisable(); _serviceModified = true; } - else if ( _service.repoToDisableFind( it->alias() ) ) + + // Remember original service request for next refresh + if ( _service.repoStates() != newRepoStates ) { - DBG << "User request to disable service repo " << it->alias() << std::endl; - toBeEnabled = false; + _service.setRepoStates( std::move(newRepoStates) ); + _serviceModified = true; } - } - - RepoInfoList::iterator oldRepo( findAlias( it->alias(), oldRepos ) ); - if ( oldRepo == oldRepos.end() ) - { - // Not found in oldRepos ==> a new repo to add - - // Make sure the service repo is created with the appropriate enablement - if ( ! indeterminate(toBeEnabled) ) - it->setEnabled( ( bool ) toBeEnabled ); - - DBG << "Service adds repo " << it->alias() << " " << (it->enabled()?"enabled":"disabled") << std::endl; - const auto &addRes = _repoMgr->addRepository( *it ); - if (!addRes) return Ret::error( addRes.error() ); - } - else - { - // ==> an exising repo to check - bool oldRepoModified = false; - if ( indeterminate(toBeEnabled) ) + //////////////////////////////////////////////////////////////////////////// + // save service if modified: (unless a plugin service) + if ( _service.type() != zypp::repo::ServiceType::PLUGIN ) { - // No user request: check for an old user modificaton otherwise follow service request. - // NOTE: Assert toBeEnabled is boolean afterwards! - if ( oldRepo->enabled() == it->enabled() ) - toBeEnabled = it->enabled(); // service requests no change to the system - else if ( _options.testFlag( zypp::RepoManagerFlags::RefreshService_restoreStatus ) ) + if ( _service.ttl() ) { - toBeEnabled = it->enabled(); // RefreshService_restoreStatus forced - DBG << "Opt RefreshService_restoreStatus " << it->alias() << " forces " << (toBeEnabled?"enabled":"disabled") << std::endl; + _service.setLrf( zypp::Date::now() ); // remember last refresh + _serviceModified = true; // or use a cookie file } - else + + if ( _serviceModified ) { - const auto & last = _service.repoStates().find( oldRepo->alias() ); - if ( last == _service.repoStates().end() || last->second.enabled != it->enabled() ) - toBeEnabled = it->enabled(); // service request has changed since last refresh -> follow - else - { - toBeEnabled = oldRepo->enabled(); // service request unchaned since last refresh -> keep user modification - DBG << "User modified service repo " << it->alias() << " may stay " << (toBeEnabled?"enabled":"disabled") << std::endl; - } + // write out modified service file. + auto modRes = _repoMgr->modifyService( _service.alias(), _service ); + if ( !modRes ) return Ret::error( modRes.error() ); } } - // changed enable? - if ( toBeEnabled == oldRepo->enabled() ) - { - DBG << "Service repo " << it->alias() << " stays " << (oldRepo->enabled()?"enabled":"disabled") << std::endl; - } - else if ( toBeEnabled ) - { - DBG << "Service repo " << it->alias() << " gets enabled" << std::endl; - oldRepo->setEnabled( true ); - oldRepoModified = true; - } - else - { - DBG << "Service repo " << it->alias() << " gets disabled" << std::endl; - oldRepo->setEnabled( false ); - oldRepoModified = true; + if ( _informalError ) { + return Ret::error( std::make_exception_ptr (_informalError.value()) ); } - // all other attributes follow the service request: + return Ret::success( ); + }); + }; + } - // changed name (raw!) - if ( oldRepo->rawName() != it->rawName() ) - { - DBG << "Service repo " << it->alias() << " gets new NAME " << it->rawName() << std::endl; - oldRepo->setName( it->rawName() ); - oldRepoModified = true; - } + MaybeAsyncRef> updateOrAddRepo( RepoInfo info ) + { + // User explicitly requested the repo being enabled? + // User explicitly requested the repo being disabled? + // And hopefully not both ;) If so, enable wins. + zypp::TriBool toBeEnabled( zypp::indeterminate ); // indeterminate - follow the service request + DBG << "Service request to " << (info.enabled()?"enable":"disable") << " service repo " << info.alias() << std::endl; - // changed autorefresh - if ( oldRepo->autorefresh() != it->autorefresh() ) - { - DBG << "Service repo " << it->alias() << " gets new AUTOREFRESH " << it->autorefresh() << std::endl; - oldRepo->setAutorefresh( it->autorefresh() ); - oldRepoModified = true; - } + if ( _options.testFlag( zypp::RepoManagerFlags::RefreshService_restoreStatus ) ) + { + DBG << "Opt RefreshService_restoreStatus " << info.alias() << std::endl; + // this overrides any pending request! + // Remove from enable request list. + // NOTE: repoToDisable is handled differently. + // It gets cleared on each refresh. + _service.delRepoToEnable( info.alias() ); + // toBeEnabled stays indeterminate! + } + else + { + if ( _service.repoToEnableFind( info.alias() ) ) + { + DBG << "User request to enable service repo " << info.alias() << std::endl; + toBeEnabled = true; + // Remove from enable request list. + // NOTE: repoToDisable is handled differently. + // It gets cleared on each refresh. + _service.delRepoToEnable( info.alias() ); + _serviceModified = true; + } + else if ( _service.repoToDisableFind( info.alias() ) ) + { + DBG << "User request to disable service repo " << info.alias() << std::endl; + toBeEnabled = false; + } + } - // changed priority? - if ( oldRepo->priority() != it->priority() ) - { - DBG << "Service repo " << it->alias() << " gets new PRIORITY " << it->priority() << std::endl; - oldRepo->setPriority( it->priority() ); - oldRepoModified = true; - } + RepoInfoList::iterator oldRepo( findAlias( info.alias(), _oldRepos ) ); + if ( oldRepo == _oldRepos.end() ) + { + // Not found in oldRepos ==> a new repo to add - // changed url? - { - RepoInfo::url_set newUrls( it->rawBaseUrls() ); - urlCredentialExtractor.extract( newUrls ); // Extract! to prevent passwds from disturbing the comparison below - if ( oldRepo->rawBaseUrls() != newUrls ) - { - DBG << "Service repo " << it->alias() << " gets new URLs " << newUrls << std::endl; - oldRepo->setBaseUrls( std::move(newUrls) ); - oldRepoModified = true; - } - } + // Make sure the service repo is created with the appropriate enablement + if ( ! indeterminate(toBeEnabled) ) + info.setEnabled( ( bool ) toBeEnabled ); - // changed gpg check settings? - // ATM only plugin services can set GPG values. - if ( _service.type() == zypp::repo::ServiceType::PLUGIN ) - { - zypp::TriBool ogpg[3]; // Gpg RepoGpg PkgGpg - zypp::TriBool ngpg[3]; - oldRepo->getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] ); - it-> getRawGpgChecks( ngpg[0], ngpg[1], ngpg[2] ); - #define Z_CHKGPG(I,N) \ - if ( ! sameTriboolState( ogpg[I], ngpg[I] ) ) \ - { \ - DBG << "Service repo " << it->alias() << " gets new "#N"Check " << ngpg[I] << std::endl; \ - oldRepo->set##N##Check( ngpg[I] ); \ - oldRepoModified = true; \ - } - Z_CHKGPG( 0, Gpg ); - Z_CHKGPG( 1, RepoGpg ); - Z_CHKGPG( 2, PkgGpg ); - #undef Z_CHKGPG - } + DBG << "Service adds repo " << info.alias() << " " << (info.enabled()?"enabled":"disabled") << std::endl; + return _repoMgr->addRepository( info ); + } + else + { + // ==> an exising repo to check + bool oldRepoModified = false; - // save if modified: - if ( oldRepoModified ) + if ( indeterminate(toBeEnabled) ) + { + // No user request: check for an old user modificaton otherwise follow service request. + // NOTE: Assert toBeEnabled is boolean afterwards! + if ( oldRepo->enabled() == info.enabled() ) + toBeEnabled = info.enabled(); // service requests no change to the system + else if ( _options.testFlag( zypp::RepoManagerFlags::RefreshService_restoreStatus ) ) + { + toBeEnabled = info.enabled(); // RefreshService_restoreStatus forced + DBG << "Opt RefreshService_restoreStatus " << info.alias() << " forces " << (toBeEnabled?"enabled":"disabled") << std::endl; + } + else + { + const auto & last = _service.repoStates().find( oldRepo->alias() ); + if ( last == _service.repoStates().end() || last->second.enabled != info.enabled() ) + toBeEnabled = info.enabled(); // service request has changed since last refresh -> follow + else { - auto modRes = _repoMgr->modifyRepository( oldRepo->alias(), *oldRepo ); - if ( !modRes ) return Ret::error( modRes.error() ); + toBeEnabled = oldRepo->enabled(); // service request unchaned since last refresh -> keep user modification + DBG << "User modified service repo " << info.alias() << " may stay " << (toBeEnabled?"enabled":"disabled") << std::endl; } } } - // Unlike reposToEnable, reposToDisable is always cleared after refresh. - if ( ! _service.reposToDisableEmpty() ) + // changed enable? + if ( toBeEnabled == oldRepo->enabled() ) { - _service.clearReposToDisable(); - _serviceModified = true; + DBG << "Service repo " << info.alias() << " stays " << (oldRepo->enabled()?"enabled":"disabled") << std::endl; + } + else if ( toBeEnabled ) + { + DBG << "Service repo " << info.alias() << " gets enabled" << std::endl; + oldRepo->setEnabled( true ); + oldRepoModified = true; } + else + { + DBG << "Service repo " << info.alias() << " gets disabled" << std::endl; + oldRepo->setEnabled( false ); + oldRepoModified = true; + } + + // all other attributes follow the service request: - // Remember original service request for next refresh - if ( _service.repoStates() != newRepoStates ) + // changed name (raw!) + if ( oldRepo->rawName() != info.rawName() ) { - _service.setRepoStates( std::move(newRepoStates) ); - _serviceModified = true; + DBG << "Service repo " << info.alias() << " gets new NAME " << info.rawName() << std::endl; + oldRepo->setName( info.rawName() ); + oldRepoModified = true; } - //////////////////////////////////////////////////////////////////////////// - // save service if modified: (unless a plugin service) - if ( _service.type() != zypp::repo::ServiceType::PLUGIN ) + // changed autorefresh + if ( oldRepo->autorefresh() != info.autorefresh() ) { - if ( _service.ttl() ) - { - _service.setLrf( zypp::Date::now() ); // remember last refresh - _serviceModified = true; // or use a cookie file - } + DBG << "Service repo " << info.alias() << " gets new AUTOREFRESH " << info.autorefresh() << std::endl; + oldRepo->setAutorefresh( info.autorefresh() ); + oldRepoModified = true; + } + + // changed priority? + if ( oldRepo->priority() != info.priority() ) + { + DBG << "Service repo " << info.alias() << " gets new PRIORITY " << info.priority() << std::endl; + oldRepo->setPriority( info.priority() ); + oldRepoModified = true; + } - if ( _serviceModified ) + // changed url? + { + RepoInfo::url_set newUrls( info.rawBaseUrls() ); + _urlCredentialExtractor.extract( newUrls ); // Extract! to prevent passwds from disturbing the comparison below + if ( oldRepo->rawBaseUrls() != newUrls ) { - // write out modified service file. - auto modRes = _repoMgr->modifyService( _service.alias(), _service ); - if ( !modRes ) return Ret::error( modRes.error() ); + DBG << "Service repo " << info.alias() << " gets new URLs " << newUrls << std::endl; + oldRepo->setBaseUrls( std::move(newUrls) ); + oldRepoModified = true; } } - if ( _informalError ) { - return Ret::error( std::make_exception_ptr (_informalError.value()) ); + // changed gpg check settings? + // ATM only plugin services can set GPG values. + if ( _service.type() == zypp::repo::ServiceType::PLUGIN ) + { + zypp::TriBool ogpg[3]; // Gpg RepoGpg PkgGpg + zypp::TriBool ngpg[3]; + oldRepo->getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] ); + info. getRawGpgChecks( ngpg[0], ngpg[1], ngpg[2] ); + +#define Z_CHKGPG(I,N) \ + if ( ! sameTriboolState( ogpg[I], ngpg[I] ) ) \ + { \ + DBG << "Service repo " << info.alias() << " gets new "#N"Check " << ngpg[I] << std::endl; \ + oldRepo->set##N##Check( ngpg[I] ); \ + oldRepoModified = true; \ + } + + Z_CHKGPG( 0, Gpg ); + Z_CHKGPG( 1, RepoGpg ); + Z_CHKGPG( 2, PkgGpg ); +#undef Z_CHKGPG } - return Ret::success( ); - }; + // save if modified: + if ( oldRepoModified ) { + return makeReadyResult( _repoMgr->modifyRepository( oldRepo->alias(), *oldRepo ) ); + } else { + // nothing to do + return makeReadyResult( make_expected_success(*oldRepo) ); + } + } } + RepoMgrRefType _repoMgr; ServiceInfo _service; zypp::RepoManagerFlags::RefreshServiceOptions _options; + zypp::UrlCredentialExtractor _urlCredentialExtractor; // To collect any credentials stored in repo URLs + + // working variable so we do not have to store the oldRepos multiple times + RepoInfoList _oldRepos; // NOTE: It might be necessary to modify and rewrite the service info. // Either when probing the type, or when adjusting the repositories diff --git a/zypp/ng/repo/workflows/susetags.cc b/zypp/ng/repo/workflows/susetags.cc index 61aaaa1d1..f46cf86ea 100644 --- a/zypp/ng/repo/workflows/susetags.cc +++ b/zypp/ng/repo/workflows/susetags.cc @@ -48,8 +48,9 @@ namespace zyppng::SuseTagsWorkflows { using MediaHandle = typename ProvideType::MediaHandle; using ProvideRes = typename ProvideType::Res; - StatusLogic( DlContextRefType ctx, MediaHandle &&media ) + StatusLogic( DlContextRefType ctx, ProgressObserverRef &&taskObserver, MediaHandle &&media ) : _ctx(std::move(ctx)) + , _taskObserver( std::move(taskObserver) ) , _handle(std::move(media)) {} @@ -77,18 +78,19 @@ namespace zyppng::SuseTagsWorkflows { } DlContextRefType _ctx; + ProgressObserverRef _taskObserver; MediaHandle _handle; }; } - AsyncOpRef > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle) + AsyncOpRef > repoStatus(repo::AsyncDownloadContextRef dl, ProgressObserverRef taskObserver, ProvideMediaHandle mediaHandle) { - return SimpleExecutor< StatusLogic, AsyncOp> >::run( std::move(dl), std::move(mediaHandle) ); + return SimpleExecutor< StatusLogic, AsyncOp> >::run( std::move(dl), std::move(taskObserver), std::move(mediaHandle) ); } - expected repoStatus(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle) + expected repoStatus(repo::SyncDownloadContextRef dl, ProgressObserverRef taskObserver, SyncMediaHandle mediaHandle) { - return SimpleExecutor< StatusLogic, SyncOp> >::run( std::move(dl), std::move(mediaHandle) ); + return SimpleExecutor< StatusLogic, SyncOp> >::run( std::move(dl), std::move(taskObserver), std::move(mediaHandle) ); } @@ -293,7 +295,7 @@ namespace zyppng::SuseTagsWorkflows { return transform_collect ( std::move(requiredFiles), [this]( zypp::OnMediaLocation file ) { - return DownloadWorkflow::provideToCacheDir( _ctx, _mediaHandle, file.filename(), ProvideFileSpec(file) ) + return DownloadWorkflow::provideToCacheDir( _ctx, _progressObserver, _mediaHandle, file.filename(), ProvideFileSpec(file) ) | inspect ( incProgress( _progressObserver ) ); }) | and_then ( [this]( std::vector &&dlFiles ) { @@ -327,12 +329,12 @@ namespace zyppng::SuseTagsWorkflows { }; } - AsyncOpRef > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver) + AsyncOpRef > download(repo::AsyncDownloadContextRef dl, ProgressObserverRef progressObserver, ProvideMediaHandle mediaHandle) { return SimpleExecutor< DlLogic, AsyncOp> >::run( std::move(dl), std::move(mediaHandle), std::move(progressObserver) ); } - expected download(repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, ProgressObserverRef progressObserver) + expected download(repo::SyncDownloadContextRef dl, ProgressObserverRef progressObserver, SyncMediaHandle mediaHandle) { return SimpleExecutor< DlLogic, SyncOp> >::run( std::move(dl), std::move(mediaHandle), std::move(progressObserver) ); } diff --git a/zypp/ng/repo/workflows/susetags.h b/zypp/ng/repo/workflows/susetags.h index eb400a6c0..b7e7cbf74 100644 --- a/zypp/ng/repo/workflows/susetags.h +++ b/zypp/ng/repo/workflows/susetags.h @@ -33,14 +33,14 @@ namespace zyppng { /*! * Calculate status of the remote SUSETags repository */ - AsyncOpRef> repoStatus( repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle ); - expected repoStatus( repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle ); + AsyncOpRef> repoStatus(repo::AsyncDownloadContextRef dl, ProgressObserverRef taskObserver, ProvideMediaHandle mediaHandle ); + expected repoStatus(repo::SyncDownloadContextRef dl, ProgressObserverRef taskObserver, SyncMediaHandle mediaHandle ); /*! * Download metadata to a local directory */ - AsyncOpRef> download ( repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver = nullptr ); - expected download ( repo::SyncDownloadContextRef dl, SyncMediaHandle mediaHandle, ProgressObserverRef progressObserver = nullptr ); + AsyncOpRef> download ( repo::AsyncDownloadContextRef dl, ProgressObserverRef progressObserver, ProvideMediaHandle mediaHandle ); + expected download ( repo::SyncDownloadContextRef dl, ProgressObserverRef progressObserver, SyncMediaHandle mediaHandle ); } } diff --git a/zypp/ng/repoinfo.h b/zypp/ng/repoinfo.h index 50825870e..454e41c54 100644 --- a/zypp/ng/repoinfo.h +++ b/zypp/ng/repoinfo.h @@ -6,7 +6,7 @@ | /_____||_| |_| |_| | | | \---------------------------------------------------------------------*/ -/** \file zypp/RepoInfo.h +/** \file zypp/ng/repoinfo.h * */ #ifndef ZYPP_NG_REPOINFO_INCLUDED diff --git a/zypp/ng/repomanager.cc b/zypp/ng/repomanager.cc index 5d389b772..d63b85dba 100644 --- a/zypp/ng/repomanager.cc +++ b/zypp/ng/repomanager.cc @@ -188,14 +188,14 @@ namespace zyppng * \param dir pathname of the directory to read. */ template - std::list repositories_in_dir( ZContextRef zyppContext, const zypp::Pathname &dir ) + std::list repositories_in_dir( ZContextRef zyppContext, ProgressObserverRef taskObserver, const zypp::Pathname &dir ) { MIL << "directory " << dir << std::endl; std::list repos; bool nonroot( geteuid() != 0 ); if ( nonroot && ! zypp::PathInfo(dir).userMayRX() ) { - JobReportHelper(zyppContext).warning( zypp::str::Format(_("Cannot read repo directory '%1%': Permission denied")) % dir ); + JobReportHelper(zyppContext, taskObserver).warning( zypp::str::Format(_("Cannot read repo directory '%1%': Permission denied")) % dir ); } else { @@ -213,7 +213,7 @@ namespace zyppng { if ( nonroot && ! zypp::PathInfo(*it).userMayR() ) { - JobReportHelper(zyppContext).warning( zypp::str::Format(_("Cannot read repo file '%1%': Permission denied")) % *it ); + JobReportHelper(zyppContext, taskObserver).warning( zypp::str::Format(_("Cannot read repo file '%1%': Permission denied")) % *it ); } else { @@ -519,12 +519,12 @@ namespace zyppng } template - expected RepoManager::loadFromCache( FusionPoolRef fPool, const RepoInfo & info, ProgressObserverRef myProgress ) + typename RepoManager::template MaybeAsyncRef> RepoManager::loadFromCache( FusionPoolRef fPool, RepoInfo info, ProgressObserverRef myProgress ) { using namespace zyppng::operators; if ( !info.context() || info.context() != zyppContext() ) { - return expected::error( ZYPP_EXCPT_PTR( zypp::Exception("None or different context in RepoInfo is not supported.")) ); + return makeReadyResult(expected::error( ZYPP_EXCPT_PTR( zypp::Exception("None or different context in RepoInfo is not supported.")) )); } return zyppng::mtry( [this, fPool, info, myProgress](){ @@ -560,7 +560,7 @@ namespace zyppng | and_then([this, info = info, myProgress] () mutable { return buildCache ( info, zypp::RepoManagerFlags::BuildIfNeeded, ProgressObserver::makeSubTask( myProgress ) ); }) - | and_then( mtry([this, fPool, info = info]{ + | and_then( mtry([this, fPool]( RepoInfo info ){ fPool->satPool().addRepoSolv( solv_path_for_repoinfo(_options, info).unwrap() / "solv", info ); })); }) @@ -581,6 +581,9 @@ namespace zyppng try { auto tosave = info; + if ( repos().find(tosave.alias()) != repos().end() ) + return expected::error( ZYPP_EXCPT_PTR(zypp::repo::RepoAlreadyExistsException(tosave)) ); + // assert the directory exists zypp::filesystem::assert_dir(_options.knownReposPath); @@ -709,7 +712,7 @@ namespace zyppng } template - expected RepoManager::modifyRepository(const std::string & alias, RepoInfo &newinfo_r, ProgressObserverRef myProgress ) + expected RepoManager::modifyRepository(const std::string & alias, RepoInfo newinfo_r, ProgressObserverRef myProgress ) { try { @@ -792,13 +795,12 @@ namespace zyppng ProgressObserver::finish ( myProgress ); - newinfo_r = newinfo; - return expected::success(); + return expected::success(newinfo); } } catch ( ... ) { ProgressObserver::finish ( myProgress, ProgressObserver::Error ); - return expected::error( ZYPP_FWD_CURRENT_EXCPT() ); + return expected::error( ZYPP_FWD_CURRENT_EXCPT() ); } } @@ -841,23 +843,21 @@ namespace zyppng } template - expected::RefreshCheckStatus> RepoManager::checkIfToRefreshMetadata( RepoInfo &info, const zypp::Url &url, RawMetadataRefreshPolicy policy) + typename RepoManager::template MaybeAsyncRef::RefreshCheckStatus>>> RepoManager::checkIfToRefreshMetadata( RepoInfo info, const zypp::Url &url, RawMetadataRefreshPolicy policy) { using namespace zyppng::operators; - return joinPipeline( _zyppContext, - prepareRepoInfo ( info ) - | and_then( [ this, info, url ]() { return RepoManagerWorkflow::refreshGeoIPData( _zyppContext, {url} ); } ) - | [this, info](auto) { return zyppng::repo::RefreshContext::create( _zyppContext, info, shared_this>() ); } + return RepoManagerWorkflow::refreshGeoIPData( _zyppContext, {url} ) + | [this, info](auto) { return prepareRefreshContext(info); } | and_then( [this, url, policy]( zyppng::repo::RefreshContextRef &&refCtx ) { refCtx->setPolicy ( static_cast( policy ) ); return _zyppContext->provider()->prepareMedia( url, zyppng::ProvideMediaSpec(_zyppContext) ) - | and_then( [ r = std::move(refCtx) ]( auto mediaHandle ) mutable { return zyppng::RepoManagerWorkflow::checkIfToRefreshMetadata ( std::move(r), std::move(mediaHandle), nullptr ); } ); - }) - ); + | and_then( [ refCtx ]( auto mediaHandle ) mutable { return zyppng::RepoManagerWorkflow::checkIfToRefreshMetadata ( std::move(refCtx), std::move(mediaHandle), nullptr ); } ) + | and_then( [ refCtx ]( auto checkStatus ){ return make_expected_success (std::make_pair( refCtx->repoInfo(), checkStatus ) ); }); + }); } template - expected RepoManager::refreshMetadata( RepoInfo &info, RawMetadataRefreshPolicy policy, ProgressObserverRef myProgress ) + typename RepoManager::template MaybeAsyncRef> RepoManager::refreshMetadata( RepoInfo info, RawMetadataRefreshPolicy policy, ProgressObserverRef myProgress ) { using namespace zyppng::operators; // helper callback in case the repo type changes on the remote @@ -876,11 +876,9 @@ namespace zyppng } }; - expected res = joinPipeline( _zyppContext, // make sure geoIP data is up 2 date, but ignore errors - RepoManagerWorkflow::refreshGeoIPData( _zyppContext, info.baseUrls() ) - | [this, info = info](auto) { return cloneAndPrepare(info); } - | and_then( [this]( RepoInfo info ) { return zyppng::repo::RefreshContext::create( _zyppContext, info, shared_this>()); } ) + return RepoManagerWorkflow::refreshGeoIPData( _zyppContext, info.baseUrls() ) + | [this, info = info](auto) { return prepareRefreshContext(info); } | and_then( [policy, myProgress, cb = updateProbedType]( repo::RefreshContextRef refCtx ) { refCtx->setPolicy( static_cast( policy ) ); // in case probe detects a different repokind, update our internal repos @@ -894,28 +892,21 @@ namespace zyppng rMgr->reposManip(); // remember to trigger appdata refresh return expected::success ( ctx->repoInfo() ); - })); - - if ( res ) { - // sync - info = res.get(); - return expected::success (); - } - - return expected::error( res.error() ); + }); } template - std::vector>> RepoManager::refreshMetadata( std::vector infos, RawMetadataRefreshPolicy policy, ProgressObserverRef myProgress ) + typename RepoManager::template MaybeAsyncRef > > > RepoManager::refreshMetadata( std::vector infos, RawMetadataRefreshPolicy policy, ProgressObserverRef myProgress ) { using namespace zyppng::operators; ProgressObserver::setup( myProgress, "Refreshing repositories" , 1 ); - auto r = std::move(infos) + return std::move(infos) | transform( [this, policy, myProgress]( const RepoInfo &info ) { auto subProgress = ProgressObserver::makeSubTask( myProgress, 1.0, zypp::str::Str() << _("Refreshing Repository: ") << info.alias(), 3 ); + ProgressObserver::start( subProgress ); // helper callback in case the repo type changes on the remote // do NOT capture by reference here, since this is possibly executed async @@ -938,7 +929,7 @@ namespace zyppng return // make sure geoIP data is up 2 date, but ignore errors RepoManagerWorkflow::refreshGeoIPData( _zyppContext, info.baseUrls() ) - | [sharedThis, info = info](auto) { return zyppng::repo::RefreshContext::create( sharedThis->_zyppContext, info, sharedThis); } + | [sharedThis, info = info](auto) { return sharedThis->prepareRefreshContext(info); } | inspect( incProgress( subProgress ) ) | and_then( [policy, subProgress, cb = updateProbedType]( repo::RefreshContextRef refCtx ) { refCtx->setPolicy( static_cast( policy ) ); @@ -959,6 +950,8 @@ namespace zyppng | [ info = info, subProgress ]( expected> result ) { if ( result ) { ProgressObserver::finish( subProgress, ProgressObserver::Success ); + RepoInfo info = result.get()->repoInfo(); + info.setName( info.name() + " refreshed" ); return std::make_pair(info, expected::success() ); } else { ProgressObserver::finish( subProgress, ProgressObserver::Error ); @@ -971,8 +964,6 @@ namespace zyppng return res; } ); - - return joinPipeline( _zyppContext, r ); } /** Probe the metadata type of a repository located at \c url. @@ -982,56 +973,51 @@ namespace zyppng * a cache path must not be rewritten (bnc#946129) */ template - expected RepoManager::probe(const zypp::Url &url, const zypp::Pathname &path) const + typename RepoManager::template MaybeAsyncRef> RepoManager::probe(const zypp::Url &url, const zypp::Pathname &path) const { using namespace zyppng::operators; - return joinPipeline( _zyppContext, - RepoManagerWorkflow::refreshGeoIPData( _zyppContext, {url} ) + return RepoManagerWorkflow::refreshGeoIPData( _zyppContext, {url} ) | [this, url=url](auto) { return _zyppContext->provider()->prepareMedia( url, zyppng::ProvideMediaSpec(_zyppContext) ); } | and_then( [this, path = path]( auto mediaHandle ) { return RepoManagerWorkflow::probeRepoType( _zyppContext, std::forward(mediaHandle), path ); - })); + }); } template - expected RepoManager::buildCache( RepoInfo &info, CacheBuildPolicy policy, ProgressObserverRef myProgress ) + typename RepoManager::template MaybeAsyncRef> RepoManager::buildCache( RepoInfo info, CacheBuildPolicy policy, ProgressObserverRef myProgress ) { using namespace zyppng::operators; - return joinPipeline( _zyppContext, - prepareRepoInfo ( info ) - | and_then( [this, info ]() { return zyppng::repo::RefreshContext::create( _zyppContext, info, shared_this>() ); } ) + return cloneAndPrepare ( info ) + | and_then( [this ]( auto info ) { return zyppng::repo::RefreshContext::create( shared_this>(), info ); } ) | and_then( [policy, myProgress]( repo::RefreshContextRef refCtx ) { return zyppng::RepoManagerWorkflow::buildCache ( std::move(refCtx), policy, myProgress ); }) - | and_then([]( auto ){ return expected::success(); }) - ); + | and_then([]( zyppng::repo::RefreshContextRef ctx ){ return make_expected_success(ctx->repoInfo());}) + ; } template - expected RepoManager::addRepository( RepoInfo &info, ProgressObserverRef myProgress ) + typename RepoManager::template MaybeAsyncRef> RepoManager::addRepository( RepoInfo info, ProgressObserverRef myProgress ) { - expected_return_on_error( void, prepareRepoInfo (info) ); - auto res = joinPipeline( _zyppContext, RepoManagerWorkflow::addRepository( shared_this>(), info, std::move(myProgress) ) ); - - if ( res ) { - info = *res; - return expected::success (); - } - return expected::error( res.error() ); + using namespace zyppng::operators; + return cloneAndPrepare (info) + | and_then( [this, myProgress]( RepoInfo info ){ + return RepoManagerWorkflow::addRepository( shared_this>(), info, std::move(myProgress) ); + }); } template - expected RepoManager::addRepositories( const zypp::Url &url, ProgressObserverRef myProgress ) + typename RepoManager::template MaybeAsyncRef> RepoManager::addRepositories( const zypp::Url &url, ProgressObserverRef myProgress ) { using namespace zyppng::operators; - return joinPipeline( _zyppContext, RepoManagerWorkflow::addRepositories( shared_this>(), url, std::move(myProgress))); + return RepoManagerWorkflow::addRepositories( shared_this>(), url, std::move(myProgress)); } template - expected RepoManager::probeService( const zypp::Url & url ) const + typename RepoManager::template MaybeAsyncRef> RepoManager::probeService( const zypp::Url & url ) const { - return joinPipeline( _zyppContext, RepoServicesWorkflow::probeServiceType ( _zyppContext, url ) ); + return RepoServicesWorkflow::probeServiceType ( _zyppContext, url ); } template @@ -1064,21 +1050,21 @@ namespace zyppng } template - expected RepoManager::refreshService( const std::string &alias, const RefreshServiceOptions &options_r ) + typename RepoManager::template MaybeAsyncRef> RepoManager::refreshService( const std::string &alias, const RefreshServiceOptions &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 ) ); + return RepoServicesWorkflow::refreshService( shared_this>(), *serviceOpt, options_r ); } /*! * \todo ignore ServicePluginInformalException in calling code */ template - expected RepoManager::refreshServices(const RefreshServiceOptions &options_r) + typename RepoManager::template MaybeAsyncRef> RepoManager::refreshServices(const RefreshServiceOptions &options_r) { using namespace zyppng::operators; @@ -1088,12 +1074,10 @@ namespace zyppng std::vector servicesVec; std::transform( serviceBegin(), serviceEnd(), std::back_inserter(servicesVec), []( const auto &pair ){ return pair.second;} ); - return joinPipeline( _zyppContext, - std::move(servicesVec) + return std::move(servicesVec) | transform( [options_r, this]( ServiceInfo i ){ return RepoServicesWorkflow::refreshService( shared_this>(), i, options_r ); } ) | join() - | collect() - ); + | collect(); } //////////////////////////////////////////////////////////////////////////// @@ -1349,12 +1333,6 @@ namespace zyppng return expected::success(); } - template - expected RepoManager::refreshGeoIp( const RepoInfo::url_set &urls ) - { - return joinPipeline( _zyppContext, RepoManagerWorkflow::refreshGeoIPData( _zyppContext, urls) ); - } - template expected RepoManager::touchIndexFile( const RepoInfo & info ) { @@ -1446,7 +1424,7 @@ namespace zyppng { std::list repoEscAliases; std::list orphanedRepos; - for ( const RepoInfo & rI : repositories_in_dir( _zyppContext, _options.knownReposPath ) ) + for ( const RepoInfo & rI : repositories_in_dir( _zyppContext, _zyppContext->progressObserver(), _options.knownReposPath ) ) { RepoInfo repoInfo = rI; @@ -1476,7 +1454,7 @@ namespace zyppng // translators: Cleanup a repository previously owned by a meanwhile unknown (deleted) service. // %1% = service name // %2% = repository name - JobReportHelper(_zyppContext).warning( zypp::str::Format(_("Unknown service '%1%': Removing orphaned service repository '%2%'")) + JobReportHelper(_zyppContext, _zyppContext->progressObserver()).warning( zypp::str::Format(_("Unknown service '%1%': Removing orphaned service repository '%2%'")) % repoInfo.service() % repoInfo.alias() ); try { @@ -1485,7 +1463,7 @@ namespace zyppng } catch ( const zypp::Exception & caugth ) { - JobReportHelper(_zyppContext).error( caugth.asUserHistory() ); + JobReportHelper(_zyppContext, _zyppContext->progressObserver()).error( caugth.asUserHistory() ); } } } diff --git a/zypp/ng/repomanager.h b/zypp/ng/repomanager.h index 29399a91a..3a0a33ff2 100644 --- a/zypp/ng/repomanager.h +++ b/zypp/ng/repomanager.h @@ -12,6 +12,7 @@ #ifndef ZYPP_NG_REPOMANAGER_INCLUDED #define ZYPP_NG_REPOMANAGER_INCLUDED + #include #include @@ -23,6 +24,7 @@ #include #include #include +#include #include @@ -363,6 +365,20 @@ namespace zyppng { return prepareRepoInfo (info) | and_then( [&info](){ return expected::success(info); } ); } + /*! + * Prepare a refresh context that can be used to have more control over running a refresh operation + * manually. + */ + expected> prepareRefreshContext( RepoInfo info ) { + using namespace zyppng::operators; + return cloneAndPrepare (info ) | + and_then( [this]( RepoInfo info ) { + return repo::RefreshContext::create( shared_this>(), info ); + } + ); + } + + ContextRefType zyppContext() const { return _zyppContext; } @@ -422,18 +438,20 @@ namespace zyppng { }); } - expected loadFromCache( FusionPoolRef fPool, const RepoInfo & info, ProgressObserverRef myProgress = nullptr ); + MaybeAsyncRef> loadFromCache( FusionPoolRef fPool, RepoInfo info, ProgressObserverRef myProgress = nullptr ); expected addProbedRepository( RepoInfo info, zypp::repo::RepoType probedType ); expected removeRepository(RepoInfo &info, ProgressObserverRef myProgress = nullptr ); - expected modifyRepository( const std::string & alias, RepoInfo & newinfo_r, ProgressObserverRef myProgress = nullptr ); + expected modifyRepository(const std::string & alias, RepoInfo newinfo_r, ProgressObserverRef myProgress = nullptr ); expected getRepositoryInfo( const std::string & alias ); expected getRepositoryInfo( const zypp::Url & url, const zypp::url::ViewOption &urlview ); - expected checkIfToRefreshMetadata( RepoInfo & info, const zypp::Url & url, RawMetadataRefreshPolicy policy ); + MaybeAsyncRef>> checkIfToRefreshMetadata( RepoInfo info, const zypp::Url & url, RawMetadataRefreshPolicy policy ); + + /** * \short Refresh local raw cache @@ -452,20 +470,20 @@ namespace zyppng { * \todo Currently no progress is generated, especially for the async code * We might need to change this */ - expected refreshMetadata( RepoInfo & info, RawMetadataRefreshPolicy policy, ProgressObserverRef myProgress = nullptr ); + MaybeAsyncRef> refreshMetadata( RepoInfo info, RawMetadataRefreshPolicy policy, ProgressObserverRef myProgress = nullptr ); - std::vector > > refreshMetadata( std::vector infos, RawMetadataRefreshPolicy policy, ProgressObserverRef myProgress = nullptr ); + MaybeAsyncRef>>> refreshMetadata( std::vector infos, RawMetadataRefreshPolicy policy, ProgressObserverRef myProgress = nullptr ); - expected probe( const zypp::Url & url, const zypp::Pathname & path = zypp::Pathname() ) const; + MaybeAsyncRef> probe( const zypp::Url & url, const zypp::Pathname & path = zypp::Pathname() ) const; - expected buildCache( RepoInfo & info, CacheBuildPolicy policy, ProgressObserverRef myProgress = nullptr ); + MaybeAsyncRef> buildCache( RepoInfo info, CacheBuildPolicy policy, ProgressObserverRef myProgress = nullptr ); /*! * Adds the repository in \a info and returns the updated \ref RepoInfo object. */ - expected addRepository(RepoInfo &info, ProgressObserverRef myProgress = nullptr ); + MaybeAsyncRef> addRepository( RepoInfo info, ProgressObserverRef myProgress = nullptr ); - expected addRepositories( const zypp::Url & url, ProgressObserverRef myProgress = nullptr ); + MaybeAsyncRef> addRepositories( const zypp::Url & url, ProgressObserverRef myProgress = nullptr ); public: bool serviceEmpty() const { return _services.empty(); } @@ -484,7 +502,7 @@ namespace zyppng { public: - expected probeService( const zypp::Url & url ) const; + MaybeAsyncRef> probeService( const zypp::Url & url ) const; expected addService( const ServiceInfo & service ); expected addService( const std::string & alias, const zypp::Url & url ) @@ -494,11 +512,11 @@ namespace zyppng { expected removeService( const ServiceInfo & service ) { return removeService( service.alias() ); } - expected refreshService( const std::string & alias, const RefreshServiceOptions & options_r ); - expected refreshService( const ServiceInfo & service, const RefreshServiceOptions & options_r ) + MaybeAsyncRef> refreshService( const std::string & alias, const RefreshServiceOptions & options_r ); + MaybeAsyncRef> refreshService( const ServiceInfo & service, const RefreshServiceOptions & options_r ) { return refreshService( service.alias(), options_r ); } - expected refreshServices( const RefreshServiceOptions & options_r ); + MaybeAsyncRef> refreshServices( const RefreshServiceOptions & options_r ); expected modifyService( const std::string & oldAlias, ServiceInfo newService ); @@ -519,12 +537,6 @@ namespace zyppng { }); } - /*! - * Checks for any of the given \a urls if there is no geoip data available, caches the results - * in the metadata cache for 24hrs. The given urls need to be configured as valid geoIP targets ( usually download.opensuse.org ) - */ - expected refreshGeoIp ( const RepoInfo::url_set &urls ); - template void getRepositoriesInService( const std::string & alias, OutputIterator out ) const { diff --git a/zypp/ng/reporthelper.h b/zypp/ng/reporthelper.h index 0baf817ef..8bbd115a5 100644 --- a/zypp/ng/reporthelper.h +++ b/zypp/ng/reporthelper.h @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -47,7 +48,7 @@ namespace zyppng { }; template - using default_report_tag_t = typename DefaultReportTag::Type; + using default_report_tag_t = NewStyleReportTag; // typename DefaultReportTag::Type; template class ReportHolder; @@ -61,6 +62,7 @@ namespace zyppng { { public: ReportHolder() : _d( std::make_shared>() ){} + virtual ~ReportHolder(){}; ReportHolder(const ReportHolder &) = default; ReportHolder(ReportHolder &&) = default; @@ -78,6 +80,7 @@ namespace zyppng { template class BasicReportHelper { public: + virtual ~BasicReportHelper() = default; BasicReportHelper(const BasicReportHelper &) = default; BasicReportHelper(BasicReportHelper &&) = default; BasicReportHelper &operator=(const BasicReportHelper &) = default; @@ -92,10 +95,12 @@ namespace zyppng { } protected: - BasicReportHelper( ZyppContextRef &&ctx ) : _ctx(std::move(ctx)) { - - } + BasicReportHelper( ZyppContextRef &&ctx, ProgressObserverRef &&taskObserver ) + : _ctx(std::move(ctx)) + , _taskObserver( std::move(taskObserver) ) + { } ZyppContextRef _ctx; + ProgressObserverRef _taskObserver; }; template> @@ -103,8 +108,10 @@ namespace zyppng { public: using BasicReportHelper::useNewStyleReports; - DigestReportHelper(ZyppContextRef r) - : BasicReportHelper(std::move(r)) {} + DigestReportHelper(ZyppContextRef r, ProgressObserverRef taskObserver) + : BasicReportHelper(std::move(r), std::move(taskObserver)) {} + + virtual ~DigestReportHelper() = default; DigestReportHelper(const DigestReportHelper &) = default; DigestReportHelper(DigestReportHelper &&) = default; @@ -116,7 +123,7 @@ namespace zyppng { if constexpr ( useNewStyleReports() ) { std::string label = (zypp::str::Format(_("No digest for file %s.")) % file ).str(); auto req = BooleanChoiceRequest::create( label, false, AcceptNoDigestRequest::makeData(file) ); - this->_ctx->sendUserRequest( req ); + this->_taskObserver->sendUserRequest( req ); return req->choice (); } else { return _report->askUserToAcceptNoDigest(file); @@ -127,7 +134,7 @@ namespace zyppng { if constexpr ( useNewStyleReports() ) { std::string label = (zypp::str::Format(_("Unknown digest %s for file %s.")) %name % file).str(); auto req = BooleanChoiceRequest::create( label, false, AcceptUnknownDigestRequest::makeData(file, name) ); - this->_ctx->sendUserRequest( req ); + this->_taskObserver->sendUserRequest( req ); return req->choice (); } else { return _report->askUserToAccepUnknownDigest( file, name ); @@ -138,7 +145,7 @@ namespace zyppng { if constexpr ( useNewStyleReports() ) { std::string label = (zypp::str::Format(_("Digest verification failed for file '%s'")) % file).str(); auto req = BooleanChoiceRequest::create( label, false, AcceptWrongDigestRequest::makeData(file, requested, found) ); - this->_ctx->sendUserRequest( req ); + this->_taskObserver->sendUserRequest( req ); return req->choice (); } else { return _report->askUserToAcceptWrongDigest( file, requested, found ); @@ -154,8 +161,9 @@ namespace zyppng { public: using BasicReportHelper::useNewStyleReports; - KeyRingReportHelper(ZyppContextRef r) - : BasicReportHelper(std::move(r)) {} + KeyRingReportHelper(ZyppContextRef r, ProgressObserverRef taskObserver) + : BasicReportHelper(std::move(r), std::move(taskObserver)) {} + virtual ~KeyRingReportHelper() = default; KeyRingReportHelper(const KeyRingReportHelper &) = default; KeyRingReportHelper(KeyRingReportHelper &&) = default; @@ -180,7 +188,7 @@ namespace zyppng { auto req = BooleanChoiceRequest::create ( label, false, AcceptUnsignedFileRequest::makeData ( file, keycontext ) ); - this->_ctx->sendUserRequest ( req ); + this->_taskObserver->sendUserRequest ( req ); return req->choice (); } else { return _report->askUserToAcceptUnsignedFile( file, keycontext ); @@ -202,7 +210,7 @@ namespace zyppng { 0, // default is option 0, do not trust AcceptKeyRequest::makeData ( key, keycontext ) ); - this->_ctx->sendUserRequest ( req ); + this->_taskObserver->sendUserRequest ( req ); switch (req->choice()) { default: case 0: @@ -233,7 +241,7 @@ namespace zyppng { if constexpr ( useNewStyleReports() ) { std::string label = zypp::str::Format( _("Key Name: %1%")) % keyData_r.name(); auto req = ShowMessageRequest::create( label, ShowMessageRequest::MType::Info, VerifyInfoEvent::makeData ( file_r, keyData_r, keycontext) ); - this->_ctx->sendUserRequest ( req ); + this->_taskObserver->sendUserRequest ( req ); } else { return _report->infoVerify( file_r, keyData_r, keycontext ); } @@ -248,7 +256,7 @@ namespace zyppng { 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() % ( repoInfoOpt ? repoInfoOpt->asUserString() : std::string("norepo") ); - this->_ctx->sendUserRequest( ShowMessageRequest::create( lbl, ShowMessageRequest::MType::Info, KeyAutoImportInfoEvent::makeData( keyDataList_r, keySigning_r, keyContext_r) ) ); + this->_taskObserver->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 ); } @@ -268,7 +276,7 @@ namespace zyppng { // @TODO use a centralized Continue string! label += std::string(" ") + _("Continue?"); auto req = BooleanChoiceRequest::create ( label, false, AcceptFailedVerificationRequest::makeData ( file, key, keycontext ) ); - this->_ctx->sendUserRequest ( req ); + this->_taskObserver->sendUserRequest ( req ); return req->choice (); } else { return _report->askUserToAcceptVerificationFailed( file, key, keycontext ); @@ -291,7 +299,7 @@ namespace zyppng { % file % keycontext.ngRepoInfo()->asUserString() % id; auto req = BooleanChoiceRequest::create ( label, false, AcceptUnknownKeyRequest::makeData ( file, id, keycontext ) ); - this->_ctx->sendUserRequest ( req ); + this->_taskObserver->sendUserRequest ( req ); return req->choice (); } else { return _report->askUserToAcceptUnknownKey( file, id, keycontext ); @@ -308,8 +316,9 @@ namespace zyppng { public: using BasicReportHelper::useNewStyleReports; - JobReportHelper(ZyppContextRef r) - : BasicReportHelper(std::move(r)) {} + JobReportHelper(ZyppContextRef r, ProgressObserverRef taskObserver) + : BasicReportHelper(std::move(r), std::move(taskObserver)) {} + virtual ~JobReportHelper() = default; JobReportHelper(const JobReportHelper &) = default; JobReportHelper(JobReportHelper &&) = default; @@ -320,7 +329,7 @@ namespace zyppng { bool debug( std::string msg_r, UserData userData_r = UserData() ) { if constexpr ( useNewStyleReports() ) { - this->_ctx->sendUserRequest( ShowMessageRequest::create( std::move(msg_r), ShowMessageRequest::MType::Debug, std::move(userData_r) ) ); + this->_taskObserver->sendUserRequest( ShowMessageRequest::create( std::move(msg_r), ShowMessageRequest::MType::Debug, std::move(userData_r) ) ); return true; } else { return zypp::JobReport::debug ( msg_r, userData_r ); @@ -331,7 +340,7 @@ namespace zyppng { bool info( std::string msg_r, UserData userData_r = UserData() ) { if constexpr ( useNewStyleReports() ) { - this->_ctx->sendUserRequest( ShowMessageRequest::create( std::move(msg_r), ShowMessageRequest::MType::Info, std::move(userData_r) ) ); + this->_taskObserver->sendUserRequest( ShowMessageRequest::create( std::move(msg_r), ShowMessageRequest::MType::Info, std::move(userData_r) ) ); return true; } else { return zypp::JobReport::info ( msg_r, userData_r ); @@ -342,7 +351,7 @@ namespace zyppng { bool warning( std::string msg_r, UserData userData_r = UserData() ) { if constexpr ( useNewStyleReports() ) { - this->_ctx->sendUserRequest( ShowMessageRequest::create( std::move(msg_r), ShowMessageRequest::MType::Warning, std::move(userData_r) ) ); + this->_taskObserver->sendUserRequest( ShowMessageRequest::create( std::move(msg_r), ShowMessageRequest::MType::Warning, std::move(userData_r) ) ); return true; } else { return zypp::JobReport::warning ( msg_r, userData_r ); @@ -353,7 +362,7 @@ namespace zyppng { bool error( std::string msg_r, UserData userData_r = UserData() ) { if constexpr ( useNewStyleReports() ) { - this->_ctx->sendUserRequest( ShowMessageRequest::create( std::move(msg_r), ShowMessageRequest::MType::Error, std::move(userData_r) ) ); + this->_taskObserver->sendUserRequest( ShowMessageRequest::create( std::move(msg_r), ShowMessageRequest::MType::Error, std::move(userData_r) ) ); return true; } else { return zypp::JobReport::error ( msg_r, userData_r ); @@ -364,7 +373,7 @@ namespace zyppng { bool important( std::string msg_r, UserData userData_r = UserData() ) { if constexpr ( useNewStyleReports() ) { - this->_ctx->sendUserRequest( ShowMessageRequest::create( std::move(msg_r), ShowMessageRequest::MType::Important, std::move(userData_r) ) ); + this->_taskObserver->sendUserRequest( ShowMessageRequest::create( std::move(msg_r), ShowMessageRequest::MType::Important, std::move(userData_r) ) ); return true; } else { return zypp::JobReport::important ( msg_r, userData_r ); @@ -375,7 +384,7 @@ namespace zyppng { bool data( std::string msg_r, UserData userData_r = UserData() ) { if constexpr ( useNewStyleReports() ) { - this->_ctx->sendUserRequest( ShowMessageRequest::create( std::move(msg_r), ShowMessageRequest::MType::Data, std::move(userData_r) ) ); + this->_taskObserver->sendUserRequest( ShowMessageRequest::create( std::move(msg_r), ShowMessageRequest::MType::Data, std::move(userData_r) ) ); return true; } else { return zypp::JobReport::data ( msg_r, userData_r ); diff --git a/zypp/ng/workflows/checksumwf.cc b/zypp/ng/workflows/checksumwf.cc index 5e1b37ec9..fde5aa319 100644 --- a/zypp/ng/workflows/checksumwf.cc +++ b/zypp/ng/workflows/checksumwf.cc @@ -41,9 +41,10 @@ namespace zyppng::CheckSumWorkflow { using MediaHandle = typename ProvideType::MediaHandle; using ProvideRes = typename ProvideType::Res; - CheckSumWorkflowLogic( ZyppContextRefType zyppContext, zypp::CheckSum &&checksum, zypp::Pathname file ) + CheckSumWorkflowLogic( ZyppContextRefType zyppContext, ProgressObserverRef &&taskObserver, zypp::CheckSum &&checksum, zypp::Pathname file ) : _context( std::move(zyppContext) ) - , _report( _context ) + , _taskObserver( std::move(taskObserver) ) + , _report( _context, _taskObserver ) , _checksum(std::move( checksum )) , _file(std::move( file )) {} @@ -106,27 +107,28 @@ namespace zyppng::CheckSumWorkflow { protected: ZyppContextRefType _context; + ProgressObserverRef _taskObserver; DigestReportHelper _report; zypp::CheckSum _checksum; zypp::Pathname _file; }; - expected verifyChecksum( SyncContextRef zyppCtx, zypp::CheckSum checksum, zypp::Pathname file ) + expected verifyChecksum( SyncContextRef zyppCtx, ProgressObserverRef taskObserver, zypp::CheckSum checksum, zypp::Pathname file ) { - return SimpleExecutor>>::run( std::move(zyppCtx), std::move(checksum), std::move(file) ); + return SimpleExecutor>>::run( std::move(zyppCtx), std::move(taskObserver), std::move(checksum), std::move(file) ); } - AsyncOpRef > verifyChecksum( AsyncContextRef zyppCtx, zypp::CheckSum checksum, zypp::filesystem::Pathname file ) + AsyncOpRef > verifyChecksum(AsyncContextRef zyppCtx, ProgressObserverRef taskObserver, zypp::CheckSum checksum, zypp::filesystem::Pathname file ) { - return SimpleExecutor>>::run( std::move(zyppCtx), std::move(checksum), std::move(file) ); + return SimpleExecutor>>::run( std::move(zyppCtx), std::move(taskObserver), std::move(checksum), std::move(file) ); } - std::function > (ProvideRes &&)> checksumFileChecker( AsyncContextRef zyppCtx, zypp::CheckSum checksum ) + std::function > (ProvideRes &&)> checksumFileChecker( AsyncContextRef zyppCtx, ProgressObserverRef taskObserver, zypp::CheckSum checksum ) { using zyppng::operators::operator|; - return [ zyppCtx, checksum=std::move(checksum) ]( ProvideRes res ) mutable -> AsyncOpRef> { - return verifyChecksum( zyppCtx, std::move(checksum), res.file() ) + return [ zyppCtx = std::move(zyppCtx), tO = std::move(taskObserver), checksum=std::move(checksum) ]( ProvideRes res ) mutable -> AsyncOpRef> { + return verifyChecksum( zyppCtx, std::move(tO), std::move(checksum), res.file() ) | [ res ] ( expected result ) mutable { if ( result ) return expected::success( std::move(res) ); @@ -136,11 +138,11 @@ namespace zyppng::CheckSumWorkflow { }; } - std::function (SyncProvideRes &&)> checksumFileChecker(SyncContextRef zyppCtx, zypp::CheckSum checksum) + std::function (SyncProvideRes &&)> checksumFileChecker(SyncContextRef zyppCtx, ProgressObserverRef taskObserver, zypp::CheckSum checksum) { using zyppng::operators::operator|; - return [ zyppCtx = std::move(zyppCtx), checksum=std::move(checksum) ]( SyncProvideRes res ) mutable -> expected { - return verifyChecksum( zyppCtx, std::move(checksum), res.file() ) + return [ zyppCtx = std::move(zyppCtx), tO = std::move(taskObserver), checksum=std::move(checksum) ]( SyncProvideRes res ) mutable -> expected { + return verifyChecksum( zyppCtx, std::move(tO), std::move(checksum), res.file() ) | [ res ] ( expected result ) mutable { if ( result ) return expected::success( std::move(res) ); diff --git a/zypp/ng/workflows/checksumwf.h b/zypp/ng/workflows/checksumwf.h index 94be8976c..7ba9aaf43 100644 --- a/zypp/ng/workflows/checksumwf.h +++ b/zypp/ng/workflows/checksumwf.h @@ -29,16 +29,18 @@ namespace zyppng { class ProvideRes; + ZYPP_FWD_DECL_TYPE_WITH_REFS (ProgressObserver); + namespace CheckSumWorkflow { - expected verifyChecksum ( SyncContextRef zyppCtx, zypp::CheckSum checksum, zypp::Pathname file ); - AsyncOpRef> verifyChecksum ( AsyncContextRef zyppCtx, zypp::CheckSum checksum, zypp::Pathname file ); + expected verifyChecksum (SyncContextRef zyppCtx, zyppng::ProgressObserverRef taskObserver, zypp::CheckSum checksum, zypp::Pathname file ); + AsyncOpRef> verifyChecksum ( AsyncContextRef zyppCtx, ProgressObserverRef taskObserver, zypp::CheckSum checksum, zypp::Pathname file ); /*! * Returns a callable that executes the verify checksum as part of a pipeline, * forwarding the \ref ProvideRes if the workflow was successful. */ - std::function< AsyncOpRef>( ProvideRes && ) > checksumFileChecker( AsyncContextRef zyppCtx, zypp::CheckSum checksum ); - std::function< expected( SyncProvideRes && ) > checksumFileChecker( SyncContextRef zyppCtx, zypp::CheckSum checksum ); + std::function< AsyncOpRef>( ProvideRes && ) > checksumFileChecker(AsyncContextRef zyppCtx, zyppng::ProgressObserverRef taskObserver, zypp::CheckSum checksum ); + std::function< expected( SyncProvideRes && ) > checksumFileChecker( SyncContextRef zyppCtx, ProgressObserverRef taskObserver, zypp::CheckSum checksum ); } } diff --git a/zypp/ng/workflows/downloadwf.cc b/zypp/ng/workflows/downloadwf.cc index a6729d856..8ca17b19c 100644 --- a/zypp/ng/workflows/downloadwf.cc +++ b/zypp/ng/workflows/downloadwf.cc @@ -88,8 +88,9 @@ namespace zyppng { using ProvideRes = typename ProvideType::Res; public: - ProvideFromCacheOrMediumLogic( CacheProviderContextRefType cacheContext, MediaHandle &&medium, zypp::Pathname &&file, ProvideFileSpec &&filespec ) + ProvideFromCacheOrMediumLogic( CacheProviderContextRefType cacheContext, ProgressObserverRef &&taskObserver, MediaHandle &&medium, zypp::Pathname &&file, ProvideFileSpec &&filespec ) : _ctx( std::move(cacheContext) ) + , _taskObserver( std::move(taskObserver) ) , _medium( std::move(medium) ) , _file(std::move( file )) , _filespec( std::move(filespec) ) {} @@ -190,7 +191,7 @@ namespace zyppng { return zypp::Pathname( dlFilePath ) | [this]( zypp::Pathname &&dlFilePath ) { if ( !_filespec.checksum().empty () ) { - return CheckSumWorkflow::verifyChecksum( _ctx->zyppContext(), _filespec.checksum (), std::move(dlFilePath) ); + return CheckSumWorkflow::verifyChecksum( _ctx->zyppContext(), _taskObserver, _filespec.checksum (), std::move(dlFilePath) ); } return makeReadyResult(expected::success()); }; @@ -198,6 +199,7 @@ namespace zyppng { } CacheProviderContextRefType _ctx; + ProgressObserverRef _taskObserver; MediaHandle _medium; zypp::Pathname _file; ProvideFileSpec _filespec; @@ -206,14 +208,14 @@ namespace zyppng { namespace DownloadWorkflow { - AsyncOpRef > provideToCacheDir( AsyncCacheProviderContextRef cacheContext, ProvideMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec ) + AsyncOpRef > provideToCacheDir( AsyncCacheProviderContextRef cacheContext,ProgressObserverRef taskObserver, ProvideMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec ) { - return SimpleExecutor>>::run( std::move(cacheContext), std::move(medium), std::move(file), std::move(filespec) ); + return SimpleExecutor>>::run( std::move(cacheContext), std::move(taskObserver), std::move(medium), std::move(file), std::move(filespec) ); } - expected provideToCacheDir(SyncCacheProviderContextRef cacheContext, SyncMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec ) + expected provideToCacheDir(SyncCacheProviderContextRef cacheContext, ProgressObserverRef taskObserver, SyncMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec ) { - return SimpleExecutor>>::run( std::move(cacheContext), std::move(medium), std::move(file), std::move(filespec) ); + return SimpleExecutor>>::run( std::move(cacheContext), std::move(taskObserver), std::move(medium), std::move(file), std::move(filespec) ); } } diff --git a/zypp/ng/workflows/downloadwf.h b/zypp/ng/workflows/downloadwf.h index 1358ef0ea..4e21ac0c2 100644 --- a/zypp/ng/workflows/downloadwf.h +++ b/zypp/ng/workflows/downloadwf.h @@ -53,8 +53,8 @@ namespace zyppng { ZYPP_FWD_DECL_REFS(SyncCacheProviderContext); namespace DownloadWorkflow { - AsyncOpRef> provideToCacheDir( AsyncCacheProviderContextRef cacheContext, ProvideMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec ); - expected provideToCacheDir( SyncCacheProviderContextRef cacheContext, SyncMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec ); + AsyncOpRef> provideToCacheDir(AsyncCacheProviderContextRef cacheContext, ProgressObserverRef taskObserver, ProvideMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec ); + expected provideToCacheDir( SyncCacheProviderContextRef cacheContext, ProgressObserverRef taskObserver, SyncMediaHandle medium, zypp::Pathname file, ProvideFileSpec filespec ); } } diff --git a/zypp/ng/workflows/keyringwf.cc b/zypp/ng/workflows/keyringwf.cc index e9340ddd1..6c481c605 100644 --- a/zypp/ng/workflows/keyringwf.cc +++ b/zypp/ng/workflows/keyringwf.cc @@ -40,8 +40,8 @@ namespace zyppng::KeyRingWorkflow { ZYPP_ENABLE_LOGIC_BASE(Executor, OpType); public: - ImportKeyFromRepoLogic( ZyppContextRefType context, std::string &&keyId, RepoInfo &&info ) - : _context( std::move(context) ), _keyId(std::move(keyId)), _repo( std::move(info) ) + ImportKeyFromRepoLogic( ZyppContextRefType context, ProgressObserverRef &&taskObserver, std::string &&keyId, RepoInfo &&info ) + : _context( std::move(context) ), _taskObserver(std::move(taskObserver)), _keyId(std::move(keyId)), _repo( std::move(info) ) { } MaybeAsyncRef execute () { @@ -56,7 +56,7 @@ namespace zyppng::KeyRingWorkflow { const zypp::ZConfig &conf = _context->config(); zypp::Pathname cacheDir = conf.repoManagerRoot() / conf.pubkeyCachePath(); - return RepoInfoWorkflow::provideKey( _context, _repo, _keyId, cacheDir ) + return RepoInfoWorkflow::provideKey( _context, _taskObserver, _repo, _keyId, cacheDir ) | [this, cacheDir]( zypp::Pathname myKey ) { if ( myKey.empty() ) // if we did not find any keys, there is no point in checking again, break @@ -79,7 +79,7 @@ namespace zyppng::KeyRingWorkflow { zypp::KeyContext context; context.setRepoInfo( _repo ); - if ( !KeyRingReportHelper(_context).askUserToAcceptPackageKey( key, context ) ) { + if ( !KeyRingReportHelper(_context, _taskObserver).askUserToAcceptPackageKey( key, context ) ) { return false; } @@ -96,18 +96,19 @@ namespace zyppng::KeyRingWorkflow { } ZyppContextRefType _context; + ProgressObserverRef _taskObserver; std::string _keyId; RepoInfo _repo; }; - bool provideAndImportKeyFromRepository( SyncContextRef ctx, std::string id_r, RepoInfo info_r ) + bool provideAndImportKeyFromRepository( SyncContextRef ctx, ProgressObserverRef taskObserver, std::string id_r, RepoInfo info_r ) { - return SimpleExecutor>::run( ctx, std::move(id_r), std::move(info_r) ); + return SimpleExecutor>::run( ctx, std::move(taskObserver), std::move(id_r), std::move(info_r) ); } - AsyncOpRef provideAndImportKeyFromRepository( AsyncContextRef ctx, std::string id_r, RepoInfo info_r) + AsyncOpRef provideAndImportKeyFromRepository(AsyncContextRef ctx, ProgressObserverRef taskObserver, std::string id_r, RepoInfo info_r) { - return SimpleExecutor>::run( ctx, std::move(id_r), std::move(info_r) ); + return SimpleExecutor>::run( ctx, std::move(taskObserver), std::move(id_r), std::move(info_r) ); } namespace { @@ -124,9 +125,10 @@ namespace zyppng::KeyRingWorkflow { using ZyppContextRefType = MaybeAsyncContextRef; using KeyTrust = zypp::KeyRingReport::KeyTrust; - VerifyFileSignatureLogic( ZyppContextRefType zyppContext, KeyRingRef &&keyRing, zypp::keyring::VerifyFileContext &&ctx ) + VerifyFileSignatureLogic( ZyppContextRefType zyppContext, ProgressObserverRef &&taskObserver, KeyRingRef &&keyRing, zypp::keyring::VerifyFileContext &&ctx ) : _zyppContext( std::move(zyppContext) ) - , _keyringReport( _zyppContext ) + , _taskObserver( std::move(taskObserver) ) + , _keyringReport( _zyppContext, _taskObserver ) , _keyRing( std::move(keyRing) ) , _verifyContext( std::move(ctx) ) { } @@ -211,12 +213,12 @@ namespace zyppng::KeyRingWorkflow { else if ( ! _verifyContext.keyContext().empty() ) { // try to find the key in the repository info - return provideAndImportKeyFromRepository ( _zyppContext, id, *_verifyContext.keyContext().ngRepoInfo() ) + return provideAndImportKeyFromRepository ( _zyppContext, _taskObserver, id, *_verifyContext.keyContext().ngRepoInfo() ) | [this, id]( bool success ) { if ( !success ) { return FoundKeyData{ zypp::PublicKeyData(), zypp::Pathname() }; } - return FoundKeyData{ _keyRing->pimpl().publicKeyExists( id, _keyRing->pimpl().trustedKeyRing() ), _keyRing->pimpl().trustedKeyRing(), true }; + return FoundKeyData{ _keyRing->pimpl().publicKeyExists( id, _keyRing->pimpl().trustedKeyRing() ), _keyRing->pimpl().trustedKeyRing(), true }; }; } } @@ -319,6 +321,7 @@ namespace zyppng::KeyRingWorkflow { protected: ZyppContextRefType _zyppContext; + ProgressObserverRef _taskObserver; KeyRingReportHelper _keyringReport; KeyRingRef _keyRing; zypp::keyring::VerifyFileContext _verifyContext; @@ -331,26 +334,26 @@ namespace zyppng::KeyRingWorkflow { }; } - std::pair verifyFileSignature( SyncContextRef zyppContext, zypp::keyring::VerifyFileContext &&context_r ) + std::pair verifyFileSignature(SyncContextRef zyppContext, ProgressObserverRef taskObserver, zypp::keyring::VerifyFileContext &&context_r ) { auto kr = zyppContext->keyRing(); - return SimpleExecutor >>::run( std::move(zyppContext), std::move(kr), std::move(context_r) ); + return SimpleExecutor >>::run( std::move(zyppContext), std::move(taskObserver), std::move(kr), std::move(context_r) ); } - AsyncOpRef> verifyFileSignature( AsyncContextRef zyppContext, zypp::keyring::VerifyFileContext &&context_r ) + AsyncOpRef> verifyFileSignature( AsyncContextRef zyppContext, ProgressObserverRef taskObserver, zypp::keyring::VerifyFileContext &&context_r ) { auto kr = zyppContext->keyRing(); - return SimpleExecutor >>::run( std::move(zyppContext), std::move(kr), std::move(context_r) ); + return SimpleExecutor >>::run( std::move(zyppContext), std::move(taskObserver), std::move(kr), std::move(context_r) ); } - std::pair verifyFileSignature( SyncContextRef zyppContext, zypp::KeyRing_Ptr keyRing, zypp::keyring::VerifyFileContext &&context_r ) + std::pair verifyFileSignature(SyncContextRef zyppContext, ProgressObserverRef taskObserver, zypp::KeyRing_Ptr keyRing, zypp::keyring::VerifyFileContext &&context_r ) { - return SimpleExecutor >>::run( std::move(zyppContext), std::move(keyRing), std::move(context_r) ); + return SimpleExecutor >>::run( std::move(zyppContext), std::move(taskObserver), std::move(keyRing), std::move(context_r) ); } - AsyncOpRef> verifyFileSignature(AsyncContextRef zyppContext, zypp::KeyRing_Ptr keyRing, zypp::keyring::VerifyFileContext &&context_r ) + AsyncOpRef> verifyFileSignature(AsyncContextRef zyppContext, ProgressObserverRef taskObserver, zypp::KeyRing_Ptr keyRing, zypp::keyring::VerifyFileContext &&context_r ) { - return SimpleExecutor >>::run( std::move(zyppContext), std::move(keyRing), std::move(context_r) ); + return SimpleExecutor >>::run( std::move(zyppContext), std::move(taskObserver), std::move(keyRing), std::move(context_r) ); } } diff --git a/zypp/ng/workflows/keyringwf.h b/zypp/ng/workflows/keyringwf.h index 90e8eb75d..71667652d 100644 --- a/zypp/ng/workflows/keyringwf.h +++ b/zypp/ng/workflows/keyringwf.h @@ -25,6 +25,7 @@ namespace zypp { namespace zyppng { class RepoInfo; + ZYPP_FWD_DECL_TYPE_WITH_REFS (ProgressObserver); /*! * \namespace KeyRingWorkflow @@ -38,8 +39,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, RepoInfo info_r ); - AsyncOpRef provideAndImportKeyFromRepository(AsyncContextRef ctx, std::string id_r, RepoInfo info_r ); + bool provideAndImportKeyFromRepository(SyncContextRef ctx, zyppng::ProgressObserverRef taskObserver, std::string id_r, RepoInfo info_r ); + AsyncOpRef provideAndImportKeyFromRepository(AsyncContextRef ctx, ProgressObserverRef taskObserver, std::string id_r, RepoInfo info_r ); /** * Follows a signature verification interacting with the user. @@ -72,11 +73,11 @@ namespace zyppng { * * \see \ref zypp::KeyRingReport */ - std::pair verifyFileSignature( SyncContextRef zyppContext, zypp::keyring::VerifyFileContext && context_r ); - AsyncOpRef> verifyFileSignature( AsyncContextRef zyppContext, zypp::keyring::VerifyFileContext && context_r ); + std::pair verifyFileSignature( SyncContextRef zyppContext, ProgressObserverRef taskObserver, zypp::keyring::VerifyFileContext && context_r ); + AsyncOpRef> verifyFileSignature(AsyncContextRef zyppContext, zyppng::ProgressObserverRef taskObserver, zypp::keyring::VerifyFileContext && context_r ); - std::pair verifyFileSignature( SyncContextRef zyppContext, zypp::KeyRing_Ptr keyRing, zypp::keyring::VerifyFileContext &&context_r ); - AsyncOpRef> verifyFileSignature( AsyncContextRef zyppContext, zypp::KeyRing_Ptr keyRing, zypp::keyring::VerifyFileContext &&context_r ); + std::pair verifyFileSignature( SyncContextRef zyppContext, ProgressObserverRef taskObserver, zypp::KeyRing_Ptr keyRing, zypp::keyring::VerifyFileContext &&context_r ); + AsyncOpRef> verifyFileSignature(AsyncContextRef zyppContext, zyppng::ProgressObserverRef taskObserver, zypp::KeyRing_Ptr keyRing, zypp::keyring::VerifyFileContext &&context_r ); } } diff --git a/zypp/ng/workflows/repoinfowf.cc b/zypp/ng/workflows/repoinfowf.cc index 2a242541b..5ce516a0c 100644 --- a/zypp/ng/workflows/repoinfowf.cc +++ b/zypp/ng/workflows/repoinfowf.cc @@ -48,8 +48,9 @@ namespace zyppng { using MediaHandle = typename ProvideType::MediaHandle; using ProvideRes = typename ProvideType::Res; - RepoInfoProvideKeyLogic( ZyppContextRefType &&zyppContext, RepoInfo &&info, std::string &&keyID_r, zypp::Pathname &&targetDirectory_r ) - : _reports( std::move(zyppContext )) + RepoInfoProvideKeyLogic( ZyppContextRefType &&zyppContext, ProgressObserverRef &&taskObserver, RepoInfo &&info, std::string &&keyID_r, zypp::Pathname &&targetDirectory_r ) + : _taskObserver( std::move(taskObserver) ) + , _reports( std::move(zyppContext), _taskObserver ) , _info( std::move(info) ) , _keyID_r(std::move( keyID_r )) , _targetDirectory_r(std::move( targetDirectory_r )) @@ -188,6 +189,7 @@ namespace zyppng { return _targetDirectory_r/(zypp::str::Format("%1%.key") % keyData.rpmName()).asString(); } + ProgressObserverRef _taskObserver; JobReportHelper _reports; const RepoInfo _info{nullptr}; const std::string _keyID_r; @@ -198,7 +200,7 @@ namespace zyppng { zypp::KeyRing _tempKeyRing; }; - +#if 0 struct AsyncRepoInfoProvideKey : public RepoInfoProvideKeyLogic> { using RepoInfoProvideKeyLogic::RepoInfoProvideKeyLogic; @@ -208,16 +210,17 @@ namespace zyppng { { using RepoInfoProvideKeyLogic::RepoInfoProvideKeyLogic; }; +#endif } - zypp::filesystem::Pathname RepoInfoWorkflow::provideKey( SyncContextRef ctx, RepoInfo info, std::string keyID_r, zypp::filesystem::Pathname targetDirectory_r ) + zypp::filesystem::Pathname RepoInfoWorkflow::provideKey( SyncContextRef ctx, ProgressObserverRef taskObserver, 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) ); + return SimpleExecutor>::run( std::move(ctx), std::move(taskObserver), std::move(info), std::move(keyID_r), std::move(targetDirectory_r) ); } - AsyncOpRef RepoInfoWorkflow::provideKey(AsyncContextRef ctx, RepoInfo info, std::string keyID_r, zypp::filesystem::Pathname targetDirectory_r ) + AsyncOpRef RepoInfoWorkflow::provideKey(AsyncContextRef ctx, ProgressObserverRef taskObserver, 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) ); + return SimpleExecutor>::run( std::move(ctx), std::move(taskObserver), 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 6c444cc2e..58379cf9d 100644 --- a/zypp/ng/workflows/repoinfowf.h +++ b/zypp/ng/workflows/repoinfowf.h @@ -16,9 +16,11 @@ namespace zyppng { + ZYPP_FWD_DECL_TYPE_WITH_REFS (ProgressObserver); + namespace RepoInfoWorkflow { - 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 ); + zypp::Pathname provideKey ( SyncContextRef ctx, ProgressObserverRef taskObserver, RepoInfo info, std::string keyID_r, zypp::Pathname targetDirectory_r ); + AsyncOpRef provideKey ( AsyncContextRef ctx, ProgressObserverRef taskObserver, RepoInfo info, std::string keyID_r, zypp::Pathname targetDirectory_r ); } } diff --git a/zypp/ng/workflows/signaturecheckwf.cc b/zypp/ng/workflows/signaturecheckwf.cc index f68157245..cfdb8dbe6 100644 --- a/zypp/ng/workflows/signaturecheckwf.cc +++ b/zypp/ng/workflows/signaturecheckwf.cc @@ -28,8 +28,9 @@ namespace zyppng { ZYPP_ENABLE_LOGIC_BASE(Executor,OpType); using ZyppContextRefType = MaybeAsyncContextRef; - VerifySignatureLogic( ZyppContextRefType &&zyppCtx, zypp::keyring::VerifyFileContext &&ctx ) + VerifySignatureLogic( ZyppContextRefType &&zyppCtx, ProgressObserverRef &&taskObserver, zypp::keyring::VerifyFileContext &&ctx ) : _zyppCtx( std::move(zyppCtx) ) + , _taskObserver( std::move(taskObserver) ) , _verifyCtx( std::move(ctx) ) { } MaybeAsyncRef> execute () { @@ -41,7 +42,7 @@ namespace zyppng { MIL << "Checking " << _verifyCtx.file ()<< " file validity using digital signature.." << std::endl; - return KeyRingWorkflow::verifyFileSignature( _zyppCtx, zypp::keyring::VerifyFileContext( _verifyCtx ) ) + return KeyRingWorkflow::verifyFileSignature( _zyppCtx, _taskObserver, zypp::keyring::VerifyFileContext( _verifyCtx ) ) | []( auto &&res ) { if ( not res.first ) return expected::error( ZYPP_EXCPT_PTR( zypp::SignatureCheckException( "Signature verification failed for " + res.second.file().basename() ) ) ); @@ -50,20 +51,21 @@ namespace zyppng { } protected: - ZyppContextRefType _zyppCtx; + ZyppContextRefType _zyppCtx; + ProgressObserverRef _taskObserver; zypp::keyring::VerifyFileContext _verifyCtx; }; } namespace SignatureFileCheckWorkflow { - expected verifySignature(SyncContextRef ctx, zypp::keyring::VerifyFileContext context ) + expected verifySignature(SyncContextRef ctx, ProgressObserverRef taskObserver, zypp::keyring::VerifyFileContext context ) { - return SimpleExecutor>>::run( std::move(ctx), std::move(context) ); + return SimpleExecutor>>::run( std::move(ctx), std::move(taskObserver), std::move(context) ); } - AsyncOpRef > verifySignature(AsyncContextRef ctx, zypp::keyring::VerifyFileContext context ) + AsyncOpRef > verifySignature(AsyncContextRef ctx, ProgressObserverRef taskObserver, zypp::keyring::VerifyFileContext context ) { - return SimpleExecutor>>::run( std::move(ctx), std::move(context) ); + return SimpleExecutor>>::run( std::move(ctx), std::move(taskObserver), std::move(context) ); } } } diff --git a/zypp/ng/workflows/signaturecheckwf.h b/zypp/ng/workflows/signaturecheckwf.h index 2abef474b..66a27d1dc 100644 --- a/zypp/ng/workflows/signaturecheckwf.h +++ b/zypp/ng/workflows/signaturecheckwf.h @@ -22,9 +22,11 @@ namespace zyppng { + ZYPP_FWD_DECL_TYPE_WITH_REFS (ProgressObserver); + namespace SignatureFileCheckWorkflow { - expected verifySignature( SyncContextRef ctx, zypp::keyring::VerifyFileContext context ); - AsyncOpRef> verifySignature( AsyncContextRef ctx, zypp::keyring::VerifyFileContext context ); + expected verifySignature(SyncContextRef ctx, zyppng::ProgressObserverRef taskObserver, zypp::keyring::VerifyFileContext context ); + AsyncOpRef> verifySignature( AsyncContextRef ctx, ProgressObserverRef taskObserver, zypp::keyring::VerifyFileContext context ); } } diff --git a/zypp/repo/PackageProvider.cc b/zypp/repo/PackageProvider.cc index bdd0bf7ac..6f9e93fea 100644 --- a/zypp/repo/PackageProvider.cc +++ b/zypp/repo/PackageProvider.cc @@ -258,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(), zypp_detail::GlobalStateHelper::context()->progressObserver(), keyID, *info ) ) break; } else { diff --git a/zypp/zypp_detail/ZYppImpl.cc b/zypp/zypp_detail/ZYppImpl.cc index b48e63c6e..729c794fc 100644 --- a/zypp/zypp_detail/ZYppImpl.cc +++ b/zypp/zypp_detail/ZYppImpl.cc @@ -164,12 +164,12 @@ namespace zypp if ( zyppLegacyShutdownStarted ) ZYPP_THROW("Global State requested after it was freed"); - auto &inst = instance(); - if (!inst._config) { - inst._config.reset( new ZConfig( autodetectZyppConfPath () ) ); - } + auto &inst = instance(); + if (!inst._config) { + inst._config.reset( new ZConfig( autodetectZyppConfPath () ) ); + } - return *inst._config; + return *inst._config; } void GlobalStateHelper::lock()