From 89237084b93beda74ca7a2902bb5900cecf94891 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Fri, 27 Nov 2020 15:47:48 +0900 Subject: [PATCH] Imported Upstream version 17.23.0 --- CMakeLists.txt | 9 +- VERSION.cmake | 6 +- libzypp.spec.cmake | 9 ++ package/libzypp.changes | 10 ++ po/es.po | 10 +- po/fr.po | 16 +-- po/it.po | 10 +- po/zh_CN.po | 12 +- po/zh_TW.po | 12 +- tests/CMakeLists.txt | 3 +- tests/parser/HistoryLogReader_test.dat | 2 +- tests/repo/CMakeLists.txt | 7 +- tests/zypp/CMakeLists.txt | 11 +- tests/zyppng/EventLoop_test.cc | 3 +- tests/zyppng/media/CMakeLists.txt | 10 +- zypp/HistoryLog.cc | 6 +- zypp/HistoryLog.h | 3 +- zypp/HistoryLogData.cc | 4 +- zypp/PoolItem.cc | 12 -- zypp/PoolItem.h | 5 +- zypp/ResPool.cc | 7 +- zypp/ResPool.h | 50 ++++++- zypp/ResStatus.cc | 31 +++++ zypp/ResStatus.h | 9 ++ zypp/base/LogControl.h | 1 + zypp/pool/PoolImpl.cc | 6 + zypp/pool/PoolImpl.h | 67 ++++++++++ zypp/sat/Transaction.h | 5 + zypp/solver/detail/SATResolver.cc | 230 ++++++++++++++++++--------------- zypp/target/TargetImpl.cc | 31 +++++ 30 files changed, 424 insertions(+), 173 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 68009d1..e79e871 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ OPTION (ENABLE_BUILD_TRANS "Build translation files by default?" OFF) OPTION (ENABLE_BUILD_TESTS "Build and run test suite by default?" OFF) OPTION (ENABLE_USE_THREADS "Enable using threads (NOT being used by threads!)?" OFF) OPTION (ENABLE_ZCHUNK_COMPRESSION "Build with zchunk compression support?" OFF) +OPTION (DISABLE_MEDIABACKEND_TESTS "Disable Tests depending on Nginx and libfcgi?" OFF) OPTION (DISABLE_LIBPROXY "Build without libproxy support even if package is installed?" OFF) OPTION (DISABLE_AUTODOCS "Do not require doxygen being installed (required to build autodocs)?" OFF) @@ -100,7 +101,13 @@ MACRO(ADD_TESTS) FOREACH( loop_var ${ARGV} ) SET_SOURCE_FILES_PROPERTIES( ${loop_var}_test.cc COMPILE_FLAGS "-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN -DBOOST_AUTO_TEST_MAIN=\"\" " ) ADD_EXECUTABLE( ${loop_var}_test ${loop_var}_test.cc ) - TARGET_LINK_LIBRARIES( ${loop_var}_test zypp-allsym ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} zypp_test_utils) + + SET(TEST_REQ_LIBS zypp-allsym ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ) + IF(NOT DISABLE_MEDIABACKEND_TESTS) + LIST( APPEND TEST_REQ_LIBS zypp_test_utils) + ENDIF() + + TARGET_LINK_LIBRARIES( ${loop_var}_test ${TEST_REQ_LIBS} ) ADD_TEST( ${loop_var}_test ${CMAKE_CURRENT_BINARY_DIR}/${loop_var}_test --catch_system_errors=no) ENDFOREACH( loop_var ) ENDMACRO(ADD_TESTS) diff --git a/VERSION.cmake b/VERSION.cmake index 612d80c..9cefbe0 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -60,9 +60,9 @@ # SET(LIBZYPP_MAJOR "17") SET(LIBZYPP_COMPATMINOR "22") -SET(LIBZYPP_MINOR "22") -SET(LIBZYPP_PATCH "1") +SET(LIBZYPP_MINOR "23") +SET(LIBZYPP_PATCH "0") # -# LAST RELEASED: 17.22.1 (22) +# LAST RELEASED: 17.23.0 (22) # (The number in parenthesis is LIBZYPP_COMPATMINOR) #======= diff --git a/libzypp.spec.cmake b/libzypp.spec.cmake index 01024e8..6eb36fd 100644 --- a/libzypp.spec.cmake +++ b/libzypp.spec.cmake @@ -21,6 +21,8 @@ %bcond_with zchunk %endif +%bcond_without mediabackend_tests + Name: libzypp Version: @VERSION@ Release: 0 @@ -88,7 +90,9 @@ BuildRequires: glib2-devel BuildRequires: libsigc++2-devel # required for testsuite +%if %{with mediabackend_tests} BuildRequires: nginx +%endif Requires: rpm @@ -108,12 +112,16 @@ BuildRequires: librpm-devel > 4.4 %if 0%{?suse_version} BuildRequires: libgpgme-devel #testsuite +%if %{with mediabackend_tests} BuildRequires: FastCGI-devel +%endif %else BuildRequires: gpgme-devel #testsuite +%if %{with mediabackend_tests} BuildRequires: fcgi-devel %endif +%endif %define min_curl_version 7.19.4 %if 0%{?suse_version} @@ -235,6 +243,7 @@ cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_SKIP_RPATH=1 \ %{?with_zchunk:-DENABLE_ZCHUNK_COMPRESSION=1} \ + %{!?with_mediabackend_tests:-DDISABLE_MEDIABACKEND_TESTS=1} \ ${EXTRA_CMAKE_OPTIONS} \ .. make %{?_smp_mflags} VERBOSE=1 diff --git a/package/libzypp.changes b/package/libzypp.changes index e23b5a1..7cf0bee 100644 --- a/package/libzypp.changes +++ b/package/libzypp.changes @@ -1,4 +1,14 @@ ------------------------------------------------------------------- +Fri Feb 21 16:06:57 CET 2020 - ma@suse.de + +- Log patch status changes to history (jsc#SLE-5116) +- Allow to disable all WebServer dependent tests when building. OBS + wants to be able to get rid of the nginx/FastCGI-devel build + requirement. Use 'rpmbuild --without mediabackend_tests' or + 'cmake -DDISABLE_MEDIABACKEND_TESTS=1'. +- version 17.23.0 (22) + +------------------------------------------------------------------- Fri Feb 7 14:56:40 CET 2020 - ma@suse.de - update translations diff --git a/po/es.po b/po/es.po index 6a2a3ab..f619f95 100644 --- a/po/es.po +++ b/po/es.po @@ -17,7 +17,7 @@ msgstr "" "Project-Id-Version: zypp\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-12-05 14:22+0100\n" -"PO-Revision-Date: 2019-03-23 20:19+0000\n" +"PO-Revision-Date: 2020-02-19 23:54+0000\n" "Last-Translator: Juan Sarria \n" "Language-Team: Spanish \n" @@ -26,7 +26,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.3\n" +"X-Generator: Weblate 3.6.1\n" #. dubious: Throw on malformed known types, otherwise log a warning. #: zypp/CheckSum.cc:136 @@ -4640,19 +4640,19 @@ msgstr "instalar %s desde el repositorio excluido" #: zypp/solver/detail/SATResolver.cc:1386 #, boost-format msgid "install %1% although it has been retracted" -msgstr "" +msgstr "instalar %1% aunque se haya retraído" #. translator: %1% is a package name #: zypp/solver/detail/SATResolver.cc:1389 #, boost-format msgid "allow to install the PTF %1%" -msgstr "" +msgstr "permitir la instalación de PTF %1%" #. translator: %1% is a package name #: zypp/solver/detail/SATResolver.cc:1392 #, boost-format msgid "install %1% although it is blacklisted" -msgstr "" +msgstr "instalar %1% aunque esté en la lista negra" #: zypp/solver/detail/SATResolver.cc:1412 #, c-format, boost-format diff --git a/po/fr.po b/po/fr.po index 8c21cda..38c7169 100644 --- a/po/fr.po +++ b/po/fr.po @@ -20,16 +20,16 @@ msgstr "" "Project-Id-Version: zypp.fr\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-12-05 14:22+0100\n" -"PO-Revision-Date: 2019-03-23 20:19+0000\n" +"PO-Revision-Date: 2020-02-20 18:54+0000\n" "Last-Translator: Christine Gabriel \n" -"Language-Team: French \n" +"Language-Team: French " +"\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 3.3\n" +"X-Generator: Weblate 3.6.1\n" #. dubious: Throw on malformed known types, otherwise log a warning. #: zypp/CheckSum.cc:136 @@ -124,7 +124,7 @@ msgstr "Aruba" #. :ABW:533: #: zypp/CountryCode.cc:173 msgid "Aland Islands" -msgstr "Îles Aland" +msgstr "Îles Åland" #. :ALA:248: #: zypp/CountryCode.cc:174 @@ -4642,19 +4642,19 @@ msgstr "installer %s depuis le dépôt exclu" #: zypp/solver/detail/SATResolver.cc:1386 #, boost-format msgid "install %1% although it has been retracted" -msgstr "" +msgstr "installer %1% bien qu'il ait été retiré" #. translator: %1% is a package name #: zypp/solver/detail/SATResolver.cc:1389 #, boost-format msgid "allow to install the PTF %1%" -msgstr "" +msgstr "autoriser l'installation du PTF %1%" #. translator: %1% is a package name #: zypp/solver/detail/SATResolver.cc:1392 #, boost-format msgid "install %1% although it is blacklisted" -msgstr "" +msgstr "installer %1% bien qu'il ait été placé en liste noire" #: zypp/solver/detail/SATResolver.cc:1412 #, c-format, boost-format diff --git a/po/it.po b/po/it.po index a7844db..55ae262 100644 --- a/po/it.po +++ b/po/it.po @@ -15,7 +15,7 @@ msgstr "" "Project-Id-Version: zypp\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-12-05 14:22+0100\n" -"PO-Revision-Date: 2019-03-23 20:19+0000\n" +"PO-Revision-Date: 2020-02-19 17:54+0000\n" "Last-Translator: Davide Aiello \n" "Language-Team: Italian \n" @@ -24,7 +24,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.3\n" +"X-Generator: Weblate 3.6.1\n" "X-Poedit-Bookmarks: 370,-1,-1,-1,-1,-1,-1,-1,-1,-1\n" #. dubious: Throw on malformed known types, otherwise log a warning. @@ -4624,19 +4624,19 @@ msgstr "installa %s da repository escluso" #: zypp/solver/detail/SATResolver.cc:1386 #, boost-format msgid "install %1% although it has been retracted" -msgstr "" +msgstr "installare %1% anche se è stato ritirato" #. translator: %1% is a package name #: zypp/solver/detail/SATResolver.cc:1389 #, boost-format msgid "allow to install the PTF %1%" -msgstr "" +msgstr "consentire installazione di PTF %1%" #. translator: %1% is a package name #: zypp/solver/detail/SATResolver.cc:1392 #, boost-format msgid "install %1% although it is blacklisted" -msgstr "" +msgstr "Installare %1% anche se è nella black list" #: zypp/solver/detail/SATResolver.cc:1412 #, c-format, boost-format diff --git a/po/zh_CN.po b/po/zh_CN.po index 00d634b..d5489b9 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -12,8 +12,8 @@ msgstr "" "Project-Id-Version: YaST (@memory@)\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-12-05 14:22+0100\n" -"PO-Revision-Date: 2019-03-14 18:32+0000\n" -"Last-Translator: Marguerite Su \n" +"PO-Revision-Date: 2020-02-17 05:54+0000\n" +"Last-Translator: Grace Yu \n" "Language-Team: Chinese (China) \n" "Language: zh_CN\n" @@ -21,7 +21,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 3.3\n" +"X-Generator: Weblate 3.6.1\n" #. dubious: Throw on malformed known types, otherwise log a warning. #: zypp/CheckSum.cc:136 @@ -4601,19 +4601,19 @@ msgstr "从排除的软件源安装 %s" #: zypp/solver/detail/SATResolver.cc:1386 #, boost-format msgid "install %1% although it has been retracted" -msgstr "" +msgstr "尽管 %1% 已收回,仍予以安装" #. translator: %1% is a package name #: zypp/solver/detail/SATResolver.cc:1389 #, boost-format msgid "allow to install the PTF %1%" -msgstr "" +msgstr "允许安装 PTF %1%" #. translator: %1% is a package name #: zypp/solver/detail/SATResolver.cc:1392 #, boost-format msgid "install %1% although it is blacklisted" -msgstr "" +msgstr "尽管 %1% 已列入黑名单,仍予以安装" #: zypp/solver/detail/SATResolver.cc:1412 #, c-format, boost-format diff --git a/po/zh_TW.po b/po/zh_TW.po index 86718dc..171e5e3 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -11,8 +11,8 @@ msgstr "" "Project-Id-Version: zypp\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-12-05 14:22+0100\n" -"PO-Revision-Date: 2019-05-03 09:49+0000\n" -"Last-Translator: Ramax Lo \n" +"PO-Revision-Date: 2020-02-17 14:54+0000\n" +"Last-Translator: Grace Yu \n" "Language-Team: Chinese (Taiwan) \n" "Language: zh_TW\n" @@ -20,7 +20,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 3.3\n" +"X-Generator: Weblate 3.6.1\n" #. dubious: Throw on malformed known types, otherwise log a warning. #: zypp/CheckSum.cc:136 @@ -4592,19 +4592,19 @@ msgstr "自排除的套件庫中安裝 %s" #: zypp/solver/detail/SATResolver.cc:1386 #, boost-format msgid "install %1% although it has been retracted" -msgstr "" +msgstr "儘管 %1% 已收回,仍予以安裝" #. translator: %1% is a package name #: zypp/solver/detail/SATResolver.cc:1389 #, boost-format msgid "allow to install the PTF %1%" -msgstr "" +msgstr "允許安裝 PTF %1%" #. translator: %1% is a package name #: zypp/solver/detail/SATResolver.cc:1392 #, boost-format msgid "install %1% although it is blacklisted" -msgstr "" +msgstr "儘管 %1% 已列入黑名單,仍予以安裝" #: zypp/solver/detail/SATResolver.cc:1412 #, c-format, boost-format diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0501775..6cc4b9f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,8 +1,9 @@ ADD_DEFINITIONS( -DTESTS_SRC_DIR="${CMAKE_CURRENT_SOURCE_DIR}" -DTESTS_BUILD_DIR="${CMAKE_CURRENT_BINARY_DIR}" ) - +IF( NOT DISABLE_MEDIABACKEND_TESTS ) ADD_SUBDIRECTORY(lib) +ENDIF() ENABLE_TESTING() INCLUDE_DIRECTORIES( ${LIBZYPP_SOURCE_DIR}/tests/lib ) diff --git a/tests/parser/HistoryLogReader_test.dat b/tests/parser/HistoryLogReader_test.dat index 1732b8a..b8b2deb 100644 --- a/tests/parser/HistoryLogReader_test.dat +++ b/tests/parser/HistoryLogReader_test.dat @@ -11,4 +11,4 @@ discard\|one field discard|to fields but bad date 2015-08-11 18:42:49|command|root@fibonacci|'/Local/ma/zypp/BUILD/zypper/src/zypper' 'in' '-f' 'xteddy'| -2011-07-18 18:08:09|pstate|patch-name|2.6.37.6-0.5.1|noarch|repo-update|moderate|security|needed|satisfied +2011-07-18 18:08:09|patch|patch-name|2.6.37.6-0.5.1|noarch|repo-update|moderate|security|needed|applied| diff --git a/tests/repo/CMakeLists.txt b/tests/repo/CMakeLists.txt index 5110460..69f5011 100644 --- a/tests/repo/CMakeLists.txt +++ b/tests/repo/CMakeLists.txt @@ -7,9 +7,14 @@ INCLUDE_DIRECTORIES( ${LIBZYPP_SOURCE_DIR}/tests/zypp ) ADD_TESTS( DUdata ExtendedMetadata - MirrorList PluginServices RepoLicense RepoSigcheck RepoVariables ) + +IF( NOT DISABLE_MEDIABACKEND_TESTS ) +ADD_TESTS( + MirrorList +) +ENDIF() diff --git a/tests/zypp/CMakeLists.txt b/tests/zypp/CMakeLists.txt index b6a08ed..9bed39b 100644 --- a/tests/zypp/CMakeLists.txt +++ b/tests/zypp/CMakeLists.txt @@ -18,7 +18,6 @@ ADD_TESTS( Deltarpm Edition ExtendedPool - Fetcher FileChecker Flags GZStream @@ -26,7 +25,6 @@ ADD_TESTS( KeyRing Locale Locks - MediaSetAccess PathInfo Pathname PluginFrame @@ -37,7 +35,6 @@ ADD_TESTS( PublicKey PurgeKernels RWPtr - RepoInfo RepoManager RepoStatus ResKind @@ -61,3 +58,11 @@ IF (ENABLE_ZCHUNK_COMPRESSION) ) ENDIF(ENABLE_ZCHUNK_COMPRESSION) +IF( NOT DISABLE_MEDIABACKEND_TESTS ) + ADD_TESTS( + Fetcher + MediaSetAccess + RepoInfo + ) +ENDIF() + diff --git a/tests/zyppng/EventLoop_test.cc b/tests/zyppng/EventLoop_test.cc index fd19b60..ef944dc 100644 --- a/tests/zyppng/EventLoop_test.cc +++ b/tests/zyppng/EventLoop_test.cc @@ -48,7 +48,8 @@ BOOST_AUTO_TEST_CASE(eventloop) hitT4++; //timer deviation should not be too big, can only be tested on a singleShot timer - BOOST_REQUIRE_LE( t.now() - t.expires(), 3 ); + // ma: disabled as OBS builder have quite big deviation >15 + // BOOST_REQUIRE_LE( t.now() - t.expires(), 3 ); }); //convenience function to execute a function later diff --git a/tests/zyppng/media/CMakeLists.txt b/tests/zyppng/media/CMakeLists.txt index 3ce9228..379a57c 100644 --- a/tests/zyppng/media/CMakeLists.txt +++ b/tests/zyppng/media/CMakeLists.txt @@ -1,4 +1,6 @@ -ADD_TESTS( - NetworkRequestDispatcher - EvDownloader -) +IF( NOT DISABLE_MEDIABACKEND_TESTS) + ADD_TESTS( + NetworkRequestDispatcher + EvDownloader + ) +ENDIF() diff --git a/zypp/HistoryLog.cc b/zypp/HistoryLog.cc index 7911326..c4b20d7 100644 --- a/zypp/HistoryLog.cc +++ b/zypp/HistoryLog.cc @@ -332,7 +332,7 @@ namespace zypp } } - void HistoryLog::patchStateChange( const PoolItem & pi, const std::string &oldstate ) + void HistoryLog::patchStateChange( const PoolItem & pi, ResStatus::ValidateValue oldstate ) { if ( ! pi.isKind() ) return; const Patch::constPtr p = asKind(pi.resolvable()); @@ -346,8 +346,8 @@ namespace zypp << _sep << p->repoInfo().alias() // 6 repo alias << _sep << p->severity() // 7 severity << _sep << p->category() // 8 category - << _sep << oldstate // 9 old state - << _sep << pi.patchStatusAsString() // 10 new state + << _sep << ResStatus::validateValueAsString( oldstate ) // 9 old state + << _sep << pi.status().validateValueAsString() // 10 new state << _sep << str::escape(ZConfig::instance().userData(), _sep) // 11 userdata << endl; } diff --git a/zypp/HistoryLog.h b/zypp/HistoryLog.h index d956a39..91914c6 100644 --- a/zypp/HistoryLog.h +++ b/zypp/HistoryLog.h @@ -15,6 +15,7 @@ #include #include "zypp/Pathname.h" +#include "zypp/ResStatus.h" namespace zypp { @@ -128,7 +129,7 @@ namespace zypp * * \param oldstate info about the old state */ - void patchStateChange ( const PoolItem & pi, const std::string &oldstate ); + void patchStateChange( const PoolItem & pi, ResStatus::ValidateValue oldstate ); }; /////////////////////////////////////////////////////////////////// diff --git a/zypp/HistoryLogData.cc b/zypp/HistoryLogData.cc index bc9e396..0307a5d 100644 --- a/zypp/HistoryLogData.cc +++ b/zypp/HistoryLogData.cc @@ -60,7 +60,7 @@ namespace zypp _table["ralias"] = REPO_CHANGE_ALIAS_e; _table["rurl"] = REPO_CHANGE_URL_e; _table["command"] = STAMP_COMMAND_e; - _table["pstate"] = PATCH_STATE_CHANGE_e; + _table["patch"] = PATCH_STATE_CHANGE_e; _table["NONE"] = _table["none"] = NONE_e; } @@ -88,7 +88,7 @@ namespace zypp _table[REPO_CHANGE_ALIAS_e] = PairType( "ralias" , "ralias " ); _table[REPO_CHANGE_URL_e] = PairType( "rurl" , "rurl " ); _table[STAMP_COMMAND_e] = PairType( "command" , "command" ); - _table[PATCH_STATE_CHANGE_e]= PairType( "pstate" , "pstate " ); + _table[PATCH_STATE_CHANGE_e]= PairType( "patch" , "patch " ); _table[NONE_e] = PairType( "NONE" , "NONE " ); } diff --git a/zypp/PoolItem.cc b/zypp/PoolItem.cc index 5efda63..37f401a 100644 --- a/zypp/PoolItem.cc +++ b/zypp/PoolItem.cc @@ -100,17 +100,6 @@ namespace zypp return isBroken() && status().isLocked(); } - std::string patchStatusAsString() const - { - if ( isUndetermined() ) return "undetermined"; - if ( isRelevant() ) return "relevant"; - if ( isSatisfied() ) return "satisfied"; - if ( isBroken() ) return "broken"; - if ( isNeeded() ) return "needed"; - if ( isUnwanted() ) return "unwanted"; - return "none"; - } - private: mutable ResStatus _status; ResObject::constPtr _resolvable; @@ -222,7 +211,6 @@ namespace zypp bool PoolItem::isBroken() const { return _pimpl->isBroken(); } bool PoolItem::isNeeded() const { return _pimpl->isNeeded(); } bool PoolItem::isUnwanted() const { return _pimpl->isUnwanted(); } - std::string PoolItem::patchStatusAsString() const { return _pimpl->patchStatusAsString(); } void PoolItem::saveState() const { _pimpl->saveState(); } void PoolItem::restoreState() const { _pimpl->restoreState(); } diff --git a/zypp/PoolItem.h b/zypp/PoolItem.h index e137832..d3d94e7 100644 --- a/zypp/PoolItem.h +++ b/zypp/PoolItem.h @@ -77,6 +77,7 @@ namespace zypp /** Reset status. */ ResStatus & statusReset() const; + //@} /** \name Status validation. @@ -104,12 +105,8 @@ namespace zypp /** Broken (needed) but locked patches. */ bool isUnwanted() const; - - std::string patchStatusAsString () const; - //@} - //@} public: /** Return the \ref ResPool the item belongs to. */ ResPool pool() const; diff --git a/zypp/ResPool.cc b/zypp/ResPool.cc index fa708ee..25f730d 100644 --- a/zypp/ResPool.cc +++ b/zypp/ResPool.cc @@ -26,6 +26,10 @@ namespace zypp { ///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// + // class ResPool + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// // // METHOD NAME : ResPool::instance // METHOD TYPE : ResPool @@ -66,10 +70,11 @@ namespace zypp ResPool::size_type ResPool::size() const { return _pimpl->size(); } - PoolItem ResPool::find( const sat::Solvable & slv_r ) const { return _pimpl->find( slv_r ); } + ResPool::EstablishedStates ResPool::establishedStates() const + { return _pimpl->establishedStates(); } ResPool::size_type ResPool::knownRepositoriesSize() const { return _pimpl->knownRepositoriesSize(); } diff --git a/zypp/ResPool.h b/zypp/ResPool.h index b64b7ad..572151f 100644 --- a/zypp/ResPool.h +++ b/zypp/ResPool.h @@ -297,9 +297,57 @@ namespace zypp //@} public: - /** \name Special iterators. */ + /** \name Misc Data. */ //@{ + /////////////////////////////////////////////////////////////////// + /// A copy of the Pools initial ValidateValues of pseudo installed items. + /// + /// AKA Patch status. Whenever the Pools content changes, the status + /// of pseudo installed items (like Patches) is computed (roughly whether + /// their dependencies are broken or satisfied) and remembered. + /// + /// Comparing the items established state against it's current state + /// tells how the current transaction would influence the item (break + /// or repair a Patch). + /// + class EstablishedStates + { + public: + ~EstablishedStates(); + /** Map holding pseudo installed items where current and established status differ. */ + typedef std::map ChangedPseudoInstalled; + /** Return all pseudo installed items whose current state differs from the established one */ + ChangedPseudoInstalled changedPseudoInstalled() const; + private: + class Impl; + RW_pointer _pimpl; + private: + friend class pool::PoolImpl; + /** Factory: \ref ResPool::establishedStates */ + EstablishedStates( shared_ptr pimpl_r ) + : _pimpl { pimpl_r } + {} + }; + /////////////////////////////////////////////////////////////////// + + /** Factory for \ref EstablishedStates. + * A few internal algorithms benefit from keeping an instance across pool + * content changes. User code usually want's to call \ref changedPseudoInstalled + * directly. + */ + EstablishedStates establishedStates() const; + /** Map holding pseudo installed items where current and established status differ. */ + typedef EstablishedStates::ChangedPseudoInstalled ChangedPseudoInstalled; + + /** Return all pseudo installed items whose current state differs from their initial one. + * E.g. a Patch may become SATISFIED by updating the packages it refers to. + * For this to happen it does not matter whether you selected the Patch or + * whether you selected the individual Packages. + * A Patches status is computed and updated with every solver run. + */ + ChangedPseudoInstalled changedPseudoInstalled() const + { return establishedStates().changedPseudoInstalled(); } //@} public: /** \name Iterate over all Repositories that contribute ResObjects. diff --git a/zypp/ResStatus.cc b/zypp/ResStatus.cc index ee770f3..803ac7b 100644 --- a/zypp/ResStatus.cc +++ b/zypp/ResStatus.cc @@ -62,6 +62,37 @@ namespace zypp } } + namespace + { + // NOTE: Strings defined here are written to the history file + // and used by zypper. Do not change them! + static const char* strBROKEN = "needed"; + static const char* strSATISFIED = "applied"; + static const char* strNONRELEVANT = "not-needed"; + static const char* strUNDETERMINED = "undetermined"; + } + + std::string ResStatus::validateValueAsString( ValidateValue val_r ) + { + const char* ret = strUNDETERMINED; + switch ( val_r ) + { + case BROKEN: ret = strBROKEN; break; + case SATISFIED: ret = strSATISFIED; break; + case NONRELEVANT: ret = strNONRELEVANT; break; + case UNDETERMINED:break;// to avoid default: + } + return ret; + } + + ResStatus::ValidateValue ResStatus::stringToValidateValue( const std::string & str_r ) + { + ValidateValue ret = UNDETERMINED; + if ( str_r == strBROKEN ) ret = BROKEN; + else if ( str_r == strSATISFIED ) ret = SATISFIED; + else if ( str_r == strNONRELEVANT ) ret = NONRELEVANT; + return ret; + } /****************************************************************** ** diff --git a/zypp/ResStatus.h b/zypp/ResStatus.h index 89ebe40..652cc39 100644 --- a/zypp/ResStatus.h +++ b/zypp/ResStatus.h @@ -225,6 +225,15 @@ namespace zypp bool isNonRelevant() const { return fieldValueIs( NONRELEVANT ); } + std::string validateValueAsString() const + { return validateValueAsString( validate() ); } + + /** ValidateValue to string used in the history file. */ + static std::string validateValueAsString( ValidateValue val_r ); + + /** ValidateValue from string used in the history file. */ + static ValidateValue stringToValidateValue( const std::string & str_r ); + public: // These two are IMMUTABLE! diff --git a/zypp/base/LogControl.h b/zypp/base/LogControl.h index b31c453..75cc36a 100644 --- a/zypp/base/LogControl.h +++ b/zypp/base/LogControl.h @@ -13,6 +13,7 @@ #define ZYPP_BASE_LOGCONTROL_H #include +#include //for std::endl #include "zypp/base/Logger.h" #include "zypp/base/PtrTypes.h" diff --git a/zypp/pool/PoolImpl.cc b/zypp/pool/PoolImpl.cc index 23d803a..c10c8f0 100644 --- a/zypp/pool/PoolImpl.cc +++ b/zypp/pool/PoolImpl.cc @@ -20,6 +20,12 @@ using std::endl; namespace zypp { ///////////////////////////////////////////////////////////////// + ResPool::EstablishedStates::~EstablishedStates() + {} + + ResPool::EstablishedStates::ChangedPseudoInstalled ResPool::EstablishedStates::changedPseudoInstalled() const + { return _pimpl->changedPseudoInstalled(); } + /////////////////////////////////////////////////////////////////// namespace pool { ///////////////////////////////////////////////////////////////// diff --git a/zypp/pool/PoolImpl.h b/zypp/pool/PoolImpl.h index 807f4a7..60d5cf7 100644 --- a/zypp/pool/PoolImpl.h +++ b/zypp/pool/PoolImpl.h @@ -105,6 +105,57 @@ namespace zypp } /////////////////////////////////////////////////////////////////// + namespace solver { + namespace detail { + void establish( sat::Queue & pseudoItems_r, sat::Queue & pseudoFlags_r ); // in solver/detail/SATResolver.cc + } + } + /////////////////////////////////////////////////////////////////// + /// Store initial establish status of pseudo installed items. + /// + class ResPool::EstablishedStates::Impl + { + public: + Impl() + { solver::detail::establish( _pseudoItems, _pseudoFlags ); } + + /** Return all pseudo installed items whose current state differs from their initial one. */ + ResPool::EstablishedStates::ChangedPseudoInstalled changedPseudoInstalled() const + { + ChangedPseudoInstalled ret; + + if ( ! _pseudoItems.empty() ) + { + for ( sat::Queue::size_type i = 0; i < _pseudoItems.size(); ++i ) + { + PoolItem pi { sat::Solvable(_pseudoItems[i]) }; + ResStatus::ValidateValue vorig { validateValue( i ) }; + if ( pi.status().validate() != vorig ) + ret[pi] = vorig; + } + } + return ret; + } + + private: + ResStatus::ValidateValue validateValue( sat::Queue::size_type i ) const + { + ResStatus::ValidateValue ret { ResStatus::UNDETERMINED }; + switch ( _pseudoFlags[i] ) + { + case 0: ret = ResStatus::BROKEN /*2*/; break; + case 1: ret = ResStatus::SATISFIED /*4*/; break; + case -1: ret = ResStatus::NONRELEVANT /*6*/; break; + } + return ret; + } + + private: + sat::Queue _pseudoItems; + sat::Queue _pseudoFlags; + }; + + /////////////////////////////////////////////////////////////////// namespace pool { ///////////////////////////////////////////////////////////////// @@ -128,6 +179,8 @@ namespace zypp typedef sat::detail::SolvableIdType SolvableIdType; + typedef ResPool::EstablishedStates::Impl EstablishedStatesImpl; + public: /** Default ctor */ PoolImpl(); @@ -198,6 +251,14 @@ namespace zypp return *_poolProxy; } + /** True factory for \ref ResPool::EstablishedStates. + * Internally we maintain the ResPool::EstablishedStates::Impl + * reference shared_ptr. Updated whenever the pool content changes. + * On demand hand it out as ResPool::EstablishedStates Impl. + */ + ResPool::EstablishedStates establishedStates() const + { store(); return ResPool::EstablishedStates( _establishedStates ); } + public: /** Forward list of Repositories that contribute ResObjects from \ref sat::Pool */ size_type knownRepositoriesSize() const @@ -352,6 +413,10 @@ namespace zypp { reapplyHardLocks(); } + + // Compute the initial status of Patches etc. + if ( !_establishedStates ) + _establishedStates.reset( new EstablishedStatesImpl ); } return _store; } @@ -394,6 +459,7 @@ namespace zypp _id2itemDirty = true; _id2item.clear(); _poolProxy.reset(); + _establishedStates.reset(); } private: @@ -408,6 +474,7 @@ namespace zypp private: mutable shared_ptr _poolProxy; + mutable shared_ptr _establishedStates; private: /** Set of queries that define hardlocks. */ diff --git a/zypp/sat/Transaction.h b/zypp/sat/Transaction.h index 60406a4..5d1793e 100644 --- a/zypp/sat/Transaction.h +++ b/zypp/sat/Transaction.h @@ -165,6 +165,8 @@ namespace zypp /** Pointer behind the last action step in transaction. */ action_iterator actionEnd() const; + /** Iterate the [filtered] transaction steps. */ + Iterable action( StepStages filter_r = StepStages() ) const; //@} public: @@ -392,6 +394,9 @@ namespace zypp return cnt; } + inline Iterable Transaction::action( StepStages filter_r ) const + { return makeIterable( actionBegin( filter_r ), actionEnd() ); } + ///////////////////////////////////////////////////////////////// } // namespace sat /////////////////////////////////////////////////////////////////// diff --git a/zypp/solver/detail/SATResolver.cc b/zypp/solver/detail/SATResolver.cc index f529f62..ad30275 100644 --- a/zypp/solver/detail/SATResolver.cc +++ b/zypp/solver/detail/SATResolver.cc @@ -37,6 +37,7 @@ extern "C" #include "zypp/ZConfig.h" #include "zypp/Product.h" +#include "zypp/AutoDispose.h" #include "zypp/sat/WhatProvides.h" #include "zypp/sat/WhatObsoletes.h" #include "zypp/sat/detail/PoolImpl.h" @@ -90,6 +91,74 @@ namespace zypp } } + /** Helper collecting pseudo installed items from the pool. + * \todo: pseudoItems are cachable as long as pool content does not change + */ + inline sat::Queue collectPseudoInstalled( const ResPool & pool_r ) + { + sat::Queue ret; + for ( const PoolItem & pi : pool_r ) + if ( traits::isPseudoInstalled( pi.kind() ) ) ret.push( pi.id() ); + return ret; + } + + /** Copy back new \ref WeakValue to \ref PoolItem after solving. + * On the fly collect orphaned items (cached by the solver for the UI) + */ + inline void solverCopyBackWeak( sat::detail::CSolver & satSolver_r, PoolItemList & orphanedItems_r ) + { + // NOTE: assert all items weak stati are reset (resetWeak was called) + { + sat::Queue recommendations; + sat::Queue suggestions; + ::solver_get_recommendations( &satSolver_r, recommendations, suggestions, 0 ); + for ( sat::Queue::size_type i = 0; i < recommendations.size(); ++i ) + PoolItem(sat::Solvable(i)).status().setRecommended( true ); + for ( sat::Queue::size_type i = 0; i < suggestions.size(); ++i ) + PoolItem(sat::Solvable(i)).status().setSuggested( true ); + } + { + orphanedItems_r.clear(); // cached on the fly + sat::Queue orphaned; + ::solver_get_orphaned( &satSolver_r, orphaned ); + for ( sat::Queue::size_type i = 0; i < orphaned.size(); ++i ) + { + PoolItem pi { sat::Solvable(i) }; + pi.status().setOrphaned( true ); + orphanedItems_r.push_back( pi ); + } + } + { + sat::Queue unneeded; + ::solver_get_unneeded( &satSolver_r, unneeded, 1 ); + for ( sat::Queue::size_type i = 0; i < unneeded.size(); ++i ) + PoolItem(sat::Solvable(i)).status().setUnneeded( true ); + } + } + + /** Copy back new \ref ValidateValue to \ref PoolItem after solving. */ + inline void solverCopyBackValidate( sat::detail::CSolver & satSolver_r, const ResPool & pool_r ) + { + sat::Queue pseudoItems { collectPseudoInstalled( pool_r ) }; + if ( ! pseudoItems.empty() ) + { + sat::Queue pseudoFlags; + ::solver_trivial_installable( &satSolver_r, pseudoItems, pseudoFlags ); + + for ( sat::Queue::size_type i = 0; i < pseudoItems.size(); ++i ) + { + PoolItem pi { sat::Solvable(pseudoItems[i]) }; + switch ( pseudoFlags[i] ) + { + case 0: pi.status().setBroken(); break; + case 1: pi.status().setSatisfied(); break; + case -1: pi.status().setNonRelevant(); break; + default: pi.status().setUndetermined(); break; + } + } + } + } + } //namespace /////////////////////////////////////////////////////////////////////// @@ -110,6 +179,50 @@ int vendorCheck( sat::detail::CPool *pool, Solvable *solvable1, Solvable *solvab IdString(solvable2->vendor) ) ? 0 : 1; } +/** ResPool helper to compute the initial status of Patches etc. + * An empty solver run (no jobs) just to compute the initial status + * of pseudo installed items (patches). + */ +void establish( sat::Queue & pseudoItems_r, sat::Queue & pseudoFlags_r ) +{ + pseudoItems_r = collectPseudoInstalled( ResPool::instance() ); + if ( ! pseudoItems_r.empty() ) + { + MIL << "Establish..." << endl; + sat::detail::CPool * cPool { sat::Pool::instance().get() }; + ::pool_set_custom_vendorcheck( cPool, &vendorCheck ); + + sat::Queue jobQueue; + // Add rules for parallel installable resolvables with different versions + for ( const sat::Solvable & solv : sat::Pool::instance().multiversion() ) + { + jobQueue.push( SOLVER_NOOBSOLETES | SOLVER_SOLVABLE ); + jobQueue.push( solv.id() ); + } + + AutoDispose cSolver { ::solver_create( cPool ), ::solver_free }; + sat::Pool::instance().prepare(); + if ( ::solver_solve( cSolver, jobQueue ) != 0 ) + INT << "How can establish fail?" << endl; + + ::solver_trivial_installable( cSolver, pseudoItems_r, pseudoFlags_r ); + + for ( sat::Queue::size_type i = 0; i < pseudoItems_r.size(); ++i ) + { + PoolItem pi { sat::Solvable(pseudoItems_r[i]) }; + switch ( pseudoFlags_r[i] ) + { + case 0: pi.status().setBroken(); break; + case 1: pi.status().setSatisfied(); break; + case -1: pi.status().setNonRelevant(); break; + default: pi.status().setUndetermined(); break; + } + } + MIL << "Establish DONE" << endl; + } + else + MIL << "Establish not needed." << endl; +} inline std::string itemToString( const PoolItem & item ) { @@ -127,14 +240,6 @@ inline std::string itemToString( const PoolItem & item ) return ret; } -inline PoolItem getPoolItem( Id id_r ) -{ - PoolItem ret( (sat::Solvable( id_r )) ); - if ( !ret && id_r ) - INT << "id " << id_r << " not found in ZYPP pool." << endl; - return ret; -} - //--------------------------------------------------------------------------- std::ostream & @@ -358,24 +463,6 @@ class CheckIfUpdate : public resfilter::PoolItemFilterFunctor }; -class CollectPseudoInstalled : public resfilter::PoolItemFilterFunctor -{ - public: - Queue *solvableQueue; - - CollectPseudoInstalled( Queue *queue ) - :solvableQueue (queue) - {} - - // collecting PseudoInstalled items - bool operator()( PoolItem item ) - { - if ( traits::isPseudoInstalled( item.satSolvable().kind() ) ) - queue_push( solvableQueue, item.satSolvable().id() ); - return true; - } -}; - bool SATResolver::solving(const CapabilitySet & requires_caps, const CapabilitySet & conflict_caps) @@ -441,7 +528,7 @@ SATResolver::solving(const CapabilitySet & requires_caps, { if ( id < 0 ) continue; - sat::Solvable slv { id }; + sat::Solvable slv { (sat::detail::SolvableIdType)id }; // get product buddies (they carry the weakremover)... static const Capability productCap { "product()" }; if ( slv && slv.provides().matches( productCap ) ) @@ -484,7 +571,7 @@ SATResolver::solving(const CapabilitySet & requires_caps, if ( p < 0 ) continue; - sat::Solvable slv { p }; + sat::Solvable slv { (sat::detail::SolvableIdType)p }; if ( ! slv || slv.isSystem() ) continue; @@ -534,81 +621,10 @@ SATResolver::solving(const CapabilitySet & requires_caps, } } - Queue recommendations; - Queue suggestions; - Queue orphaned; - Queue unneeded; - queue_init(&recommendations); - queue_init(&suggestions); - queue_init(&orphaned); - queue_init(&unneeded); - solver_get_recommendations(_satSolver, &recommendations, &suggestions, 0); - solver_get_orphaned(_satSolver, &orphaned); - solver_get_unneeded(_satSolver, &unneeded, 1); - /* solvables which are recommended */ - for ( int i = 0; i < recommendations.count; ++i ) - { - PoolItem poolItem( getPoolItem( recommendations.elements[i] ) ); - poolItem.status().setRecommended( true ); - } - - /* solvables which are suggested */ - for ( int i = 0; i < suggestions.count; ++i ) - { - PoolItem poolItem( getPoolItem( suggestions.elements[i] ) ); - poolItem.status().setSuggested( true ); - } - - _problem_items.clear(); - /* solvables which are orphaned */ - for ( int i = 0; i < orphaned.count; ++i ) - { - PoolItem poolItem( getPoolItem( orphaned.elements[i] ) ); - poolItem.status().setOrphaned( true ); - _problem_items.push_back( poolItem ); - } - - /* solvables which are unneeded */ - for ( int i = 0; i < unneeded.count; ++i ) - { - PoolItem poolItem( getPoolItem( unneeded.elements[i] ) ); - poolItem.status().setUnneeded( true ); - } - - queue_free(&recommendations); - queue_free(&suggestions); - queue_free(&orphaned); - queue_free(&unneeded); - - /* Write validation state back to pool */ - Queue flags, solvableQueue; - - queue_init(&flags); - queue_init(&solvableQueue); - - CollectPseudoInstalled collectPseudoInstalled(&solvableQueue); - invokeOnEach( _pool.begin(), - _pool.end(), - functor::functorRef (collectPseudoInstalled) ); - solver_trivial_installable(_satSolver, &solvableQueue, &flags ); - for (int i = 0; i < solvableQueue.count; i++) { - PoolItem item = _pool.find (sat::Solvable(solvableQueue.elements[i])); - item.status().setUndetermined(); - - if (flags.elements[i] == -1) { - item.status().setNonRelevant(); - XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !"); - } else if (flags.elements[i] == 1) { - item.status().setSatisfied(); - XDEBUG("SATSolutionToPool(" << item << " ) satisfied !"); - } else if (flags.elements[i] == 0) { - item.status().setBroken(); - XDEBUG("SATSolutionToPool(" << item << " ) broken !"); - } - } - queue_free(&(solvableQueue)); - queue_free(&flags); - + // copy back computed status values to pool + // (on the fly cache orphaned items for the UI) + solverCopyBackWeak( *_satSolver, _problem_items ); + solverCopyBackValidate( *_satSolver, _pool ); // Solvables which were selected due requirements which have been made by the user will // be selected by APPL_LOW. We can't use any higher level, because this setting must @@ -895,7 +911,7 @@ void SATResolver::doUpdate() if ( p < 0 ) continue; - sat::Solvable solv { p }; + sat::Solvable solv { (sat::detail::SolvableIdType)p }; if ( ! solv || solv.isSystem() ) continue; @@ -927,6 +943,12 @@ void SATResolver::doUpdate() ERR << "id " << i << " not found in ZYPP pool." << endl; } } + + // copy back computed status values to pool + // (on the fly cache orphaned items for the UI) + solverCopyBackWeak( *_satSolver, _problem_items ); + solverCopyBackValidate( *_satSolver, _pool ); + MIL << "SATResolver::doUpdate() done" << endl; } diff --git a/zypp/target/TargetImpl.cc b/zypp/target/TargetImpl.cc index ab0dc34..a387060 100644 --- a/zypp/target/TargetImpl.cc +++ b/zypp/target/TargetImpl.cc @@ -698,6 +698,31 @@ namespace zypp sendNotification( root_r, result_r.updateMessages() ); } + /** jsc#SLE-5116: Log patch status changes to history. + * Adjust precomputed set if transaction is incomplete. + */ + void logPatchStatusChanges( const sat::Transaction & transaction_r, TargetImpl & target_r ) + { + ResPool::ChangedPseudoInstalled changedPseudoInstalled { ResPool::instance().changedPseudoInstalled() }; + if ( changedPseudoInstalled.empty() ) + return; + + if ( ! transaction_r.actionEmpty( ~sat::Transaction::STEP_DONE ) ) + { + // Need to recompute the patch list if commit is incomplete! + // We remember the initially established status, then reload the + // Target to get the current patch status. Then compare. + WAR << "Need to recompute the patch status changes as commit is incomplete!" << endl; + ResPool::EstablishedStates establishedStates{ ResPool::instance().establishedStates() }; + target_r.load(); + changedPseudoInstalled = establishedStates.changedPseudoInstalled(); + } + + HistoryLog historylog; + for ( const auto & el : changedPseudoInstalled ) + historylog.patchStateChange( el.first, el.second ); + } + ///////////////////////////////////////////////////////////////// } // namespace /////////////////////////////////////////////////////////////////// @@ -1711,8 +1736,14 @@ namespace zypp result_r ); } + // jsc#SLE-5116: Log patch status changes to history + // NOTE: Should be the last action as it may need to reload + // the Target in case of an incomplete transaction. + logPatchStatusChanges( result_r.transaction(), *this ); + if ( abort ) { + HistoryLog().comment( "Commit was aborted." ); ZYPP_THROW( TargetAbortedException( ) ); } } -- 2.7.4