From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Date: Wed, 30 Jun 2021 16:09:40 +0300 (MSK) From: Ivan Zakharyaschev To: Oleg Solovyov Message-ID: User-Agent: Alpine 2.20 (LFD 67 2015-01-07) MIME-Version: 1.0 Content-Type: multipart/mixed; BOUNDARY="1807885841-568500546-1625058580=:22813" Cc: devel@lists.altlinux.org Subject: [devel] PATCH for apt: custom callbacks X-BeenThere: devel@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: ALT Linux Team development discussions List-Id: ALT Linux Team development discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Jun 2021 13:09:41 -0000 Archived-At: List-Archive: List-Post: This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. --1807885841-568500546-1625058580=:22813 Content-Type: text/plain; charset=KOI8-R Content-Transfer-Encoding: 8BIT Hello! ðÒÅÄÌÁÇÁÅÔÓÑ ÐÁÔÞ ÎÁ apt (API), ÄÏÂÁ×ÌÑÀÝÉÊ custom callbacks. ðÏÓÌÅ ÞÔÅÎÉÑ × ÏÂÝÉÈ ÞÅÒÔÁÈ Õ ÍÅÎÑ ÎÅ ÐÏÑ×ÉÌÏÓØ ÚÁÍÅÞÁÎÉÊ ÐÏ ÁÒÈÉÔÅËÔÕÒÅ (Á ÔÁËÖÅ ÏÆÏÒÍÌÅÎÉÀ, ÓÔÉÌÀ: git show --check; ÏÔÄÅÌØÎÙÅ ÍÅÓÔÁ, ÇÄÅ ×ÏÚÍÏÖÎÙ ÒÁÚÎÙÅ ÓÔÉÌÉÓÔÉÞÅÓËÉÅ ÒÅÛÅÎÉÑ ×ÐÏÌÎÅ ÓÏÏÔ×ÅÔÓÔ×ÕÀÔ ÏËÒÕÖÁÀÝÅÍÕ ËÏÄÕ, Á enforced style guide Õ ÎÁÓ ÏÔÓÕÔÓÔ×ÕÅÔ). apt ÉÍÅÅÔ Ó×ÏÊ ÔÉÐ ÄÌÑ callback-Ï×, ÏÓÏÂÅÎÎÏÓÔÉ rpm ÓËÒÙÔÙ, ÞÔÏ ÓÏÏÔ×ÅÔÓÔ×ÕÅÔ ÏÂÝÅÍÕ ÐÏÄÈÏÄÕ × apt. "ðÅÒÅ×ÏÄÏÍ" ÄÌÑ rpm ÚÁÎÉÍÁÅÔÓÑ ÆÕÎËÃÉÑ pkgRPMLibPM::customCallback ÉÚ apt-pkg/rpm/rpmpm.{h,cc}: static void * customCallback(const void * h, const rpmCallbackType what, const uint64_t amount, const uint64_t total, const void * pkgKey, void * data); ðÏÔÏÍ ÞÅÒÅÚ ÎÅ£ rpm ÒÁÂÏÔÁÅÔ Ó apt-Ï×ÙÍÉ callback-ÁÍÉ × apt-pkg/rpm/rpmpm.cc: struct CallbackData data; if (callback != nullptr ) { data.callback = callback; data.callbackData = callbackData; rc = rpmtsSetNotifyCallback(TS, customCallback, &data); } else { rc = rpmtsSetNotifyCallback(TS, rpmShowProgress, (void *) (unsigned long) notifyFlags); } ñ ÅÝ£ ÓÅÊÞÁÓ ÐÏÞÉÔÁÀ ×ÎÉÍÁÔÅÌØÎÅÅ, × ÐÅÒ×ÕÀ ÏÞÅÒÅÄØ, ÞÔÏÂÙ ÉÚÍÅÎÅÎÉÑ ÎÅ ÐÒÉ×ÏÄÉÌÉ Ë ÉÚÍÅÎÅÎÉÀ ÓÔÁÒÏÇÏ ÐÏ×ÅÄÅÎÉÑ. ÷ÏÔ ÐÁÔÞ -- ×ÄÒÕÇ Õ ËÏÇÏ-ÔÏ ÂÕÄÕÔ ÃÅÎÎÙÅ ÚÁÍÅÞÁÎÉÑ: $ git --no-pager show --reverse gears/sisyphus..276207.200/master commit 07dfdf44e9df71646815dcdf83f8e405bf6c988b Author: Oleg Solovyov Date: Wed Dec 11 12:15:00 2019 +0300 Implemented generic callback system for package manager transactions We're introducing custom callback for higher layers (like packagekit), letting them pass their own callbacks to APT instead of using rpmShowProgress when it's necessary. It's useful in particular case of offline updating when packagekit can send messages to plymouth letting user know about transaction progress but because APT does not send anything since it's using rpmShowProgress, packagekit reports nothing because it's just nothing to report. diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index c2e2f08be..50bb304ea 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -661,11 +661,11 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() // --------------------------------------------------------------------- /* This uses the filenames in FileNames and the information in the DepCache to perform the installation of packages.*/ -pkgPackageManager::OrderResult pkgPackageManager::DoInstall() +pkgPackageManager::OrderResult pkgPackageManager::DoInstall(PackageManagerCallback_t callback, void *callbackData) { OrderResult Res = OrderInstall(); if (Res != Failed) - if (Go() == false) + if (Go(callback, callbackData) == false) return Failed; return Res; } diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index 9c5f04825..dce84811f 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -45,6 +45,32 @@ class pkgDepCache; class pkgSourceList; class pkgOrderList; class pkgRecords; + +typedef enum aptCallbackType_e { + APTCALLBACK_UNKNOWN = 0, + APTCALLBACK_INST_PROGRESS, + APTCALLBACK_INST_START, + APTCALLBACK_INST_STOP, + APTCALLBACK_TRANS_PROGRESS, + APTCALLBACK_TRANS_START, + APTCALLBACK_TRANS_STOP, + APTCALLBACK_UNINST_PROGRESS, + APTCALLBACK_UNINST_START, + APTCALLBACK_UNINST_STOP, + APTCALLBACK_UNPACK_ERROR, + APTCALLBACK_CPIO_ERROR, + APTCALLBACK_SCRIPT_ERROR, + APTCALLBACK_SCRIPT_START, + APTCALLBACK_SCRIPT_STOP, + APTCALLBACK_ELEM_PROGRESS, +} aptCallbackType; + +typedef void (*PackageManagerCallback_t)(const char *nevra, + const aptCallbackType what, + const uint64_t amount, + const uint64_t total, + void *callbackData); + class pkgPackageManager : protected pkgCache::Namespace { public: @@ -76,7 +102,7 @@ class pkgPackageManager : protected pkgCache::Namespace virtual bool Install(PkgIterator /*Pkg*/,const string &/*File*/) {return false;} virtual bool Configure(PkgIterator /*Pkg*/) {return false;} virtual bool Remove(PkgIterator /*Pkg*/,bool /*Purge*/=false) {return false;} - virtual bool Go() {return true;} + virtual bool Go(PackageManagerCallback_t /*callback*/ = nullptr, void * /*callbackData*/ = nullptr) {return true;} virtual void Reset() {} public: @@ -84,7 +110,7 @@ class pkgPackageManager : protected pkgCache::Namespace // Main action members bool GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, pkgRecords *Recs); - OrderResult DoInstall(); + OrderResult DoInstall(PackageManagerCallback_t callback = nullptr, void *callbackData = nullptr); bool FixMissing(); // If marks updating not supported, skip this step diff --git a/apt-pkg/rpm/rpmpm.cc b/apt-pkg/rpm/rpmpm.cc index 287de77e2..700031e1b 100644 --- a/apt-pkg/rpm/rpmpm.cc +++ b/apt-pkg/rpm/rpmpm.cc @@ -270,7 +270,7 @@ bool pkgRPMPM::RunScriptsWithPkgs(const char *Cnf) // RPMPM::Go - Run the sequence /*{{{*/ // --------------------------------------------------------------------- /* This globs the operations and calls rpm */ -bool pkgRPMPM::Go() +bool pkgRPMPM::Go(PackageManagerCallback_t callback, void *callbackData) { if (List.empty() == true) return true; @@ -356,7 +356,7 @@ bool pkgRPMPM::Go() } #endif - if (Process(install, upgrade, uninstall) == false) + if (Process(install, upgrade, uninstall, callback, callbackData) == false) Ret = false; #ifdef WITH_LUA @@ -685,7 +685,8 @@ bool pkgRPMExtPM::ExecRPM(Item::RPMOps op, const std::vector &files) bool pkgRPMExtPM::Process(const std::vector &install, const std::vector &upgrade, - const std::vector &uninstall) + const std::vector &uninstall, + PackageManagerCallback_t callback, void *callbackData) { if (uninstall.empty() == false) ExecRPM(Item::RPMErase, uninstall); @@ -786,9 +787,82 @@ bool pkgRPMLibPM::AddToTransaction(Item::RPMOps op, const std::vector return true; } +struct CallbackData +{ + PackageManagerCallback_t callback; + void *callbackData; +}; + +void * pkgRPMLibPM::customCallback(const void * h, + const rpmCallbackType what, + const uint64_t amount, + const uint64_t total, + const void * pkgKey, + void * data) +{ + /* When invoking rpmShowProgress, the last parameter is notifyFlags, + which ain't used when callback type is OPEN_FILE or CLOSE_FILE + so it's safe to just pass zero. */ + if (what == RPMCALLBACK_INST_OPEN_FILE || what == RPMCALLBACK_INST_CLOSE_FILE) + return rpmShowProgress(h, what, amount, total, pkgKey, 0); + + CallbackData *s = (CallbackData *) data; + PackageManagerCallback_t func = s->callback; + rpmtd td = nullptr; + + const char* nevra = nullptr; + if (h != nullptr) { + td = rpmtdNew(); + + // Get NEVRA for package + int rc = headerGet((rpmHeader) h, RPMTAG_NEVRA, td, HEADERGET_DEFAULT); + if (rc == 1) + nevra = rpmtdGetString(td); + } + +#define DEF_CASE(name) case RPMCALLBACK_##name: callbackType = APTCALLBACK_##name; break + + aptCallbackType callbackType = APTCALLBACK_UNKNOWN; + switch (what) { + DEF_CASE(INST_PROGRESS); + DEF_CASE(INST_START); + DEF_CASE(INST_STOP); + DEF_CASE(TRANS_PROGRESS); + DEF_CASE(TRANS_START); + DEF_CASE(TRANS_STOP); + DEF_CASE(UNINST_PROGRESS); + DEF_CASE(UNINST_START); + DEF_CASE(UNINST_STOP); + DEF_CASE(UNPACK_ERROR); + DEF_CASE(CPIO_ERROR); + DEF_CASE(SCRIPT_ERROR); + DEF_CASE(SCRIPT_START); + DEF_CASE(SCRIPT_STOP); + DEF_CASE(ELEM_PROGRESS); + +#undef DEF_CASE + default: + break; + } + + try { + func(nevra, callbackType, amount, total, s->callbackData); + } + catch (...) + { + } + + if (h != nullptr) { + rpmtdFreeData(td); + rpmtdFree(td); + } + return nullptr; +} + bool pkgRPMLibPM::Process(const std::vector &install, const std::vector &upgrade, - const std::vector &uninstall) + const std::vector &uninstall, + PackageManagerCallback_t callback, void *callbackData) { int rc = 0; bool Success = false; @@ -906,8 +980,17 @@ bool pkgRPMLibPM::Process(const std::vector &install, probFilter |= rpmtsFilterFlags(TS); rpmtsSetFlags(TS, (rpmtransFlags)(rpmtsFlags(TS) | tsFlags)); rpmtsClean(TS); - rc = rpmtsSetNotifyCallback(TS, rpmShowProgress, - (void *) (unsigned long) notifyFlags); + struct CallbackData data; + + if (callback != nullptr ) { + data.callback = callback; + data.callbackData = callbackData; + + rc = rpmtsSetNotifyCallback(TS, customCallback, &data); + } else { + rc = rpmtsSetNotifyCallback(TS, rpmShowProgress, + (void *) (unsigned long) notifyFlags); + } rc = rpmtsRun(TS, NULL, (rpmprobFilterFlags)probFilter); probs = rpmtsProblems(TS); diff --git a/apt-pkg/rpm/rpmpm.h b/apt-pkg/rpm/rpmpm.h index 8a01b80cc..157e113ee 100644 --- a/apt-pkg/rpm/rpmpm.h +++ b/apt-pkg/rpm/rpmpm.h @@ -49,9 +49,10 @@ class pkgRPMPM : public pkgPackageManager virtual bool Process(const std::vector &install, const std::vector &upgrade, - const std::vector &uninstall) {return false;} + const std::vector &uninstall, + PackageManagerCallback_t callback, void *callbackData) {return false;} - virtual bool Go() override; + virtual bool Go(PackageManagerCallback_t callback, void *callbackData) override; virtual void Reset() override; public: @@ -66,7 +67,8 @@ class pkgRPMExtPM : public pkgRPMPM bool ExecRPM(Item::RPMOps op, const std::vector &files); virtual bool Process(const std::vector &install, const std::vector &upgrade, - const std::vector &uninstall) override; + const std::vector &uninstall, + PackageManagerCallback_t callback, void *callbackData) override; public: pkgRPMExtPM(pkgDepCache *Cache); @@ -80,9 +82,13 @@ class pkgRPMLibPM : public pkgRPMPM bool ParseRpmOpts(const char *Cnf, int *tsFlags, int *probFilter); bool AddToTransaction(Item::RPMOps op, const std::vector &files); + static void * customCallback(const void * h, const rpmCallbackType what, + const uint64_t amount, const uint64_t total, + const void * pkgKey, void * data); virtual bool Process(const std::vector &install, const std::vector &upgrade, - const std::vector &uninstall) override; + const std::vector &uninstall, + PackageManagerCallback_t callback, void *callbackData) override; public: commit 1403c34da1bc0e22762146010a002114c2ac88da (HEAD -> callbacks, tag: 276207.200/0.5.15lorg2-alt73, 276207.200/master) Author: Oleg Solovyov Date: Mon Jun 28 14:47:56 2021 +0300 0.5.15lorg2-alt73 - implement generic callback system diff --git a/apt.spec b/apt.spec index deee52a23..ddda19609 100644 --- a/apt.spec +++ b/apt.spec @@ -7,7 +7,7 @@ Name: apt Version: 0.5.15lorg2 -Release: alt72 +Release: alt73 Summary: Debian's Advanced Packaging Tool with RPM support Summary(ru_RU.UTF-8): Debian APT - õÓÏ×ÅÒÛÅÎÓÔ×Ï×ÁÎÎÏÅ ÓÒÅÄÓÔ×Ï ÕÐÒÁ×ÌÅÎÉÑ ÐÁËÅÔÁÍÉ Ó ÐÏÄÄÅÒÖËÏÊ RPM @@ -406,6 +406,9 @@ popd %_datadir/%name/tests/ %changelog +* Mon Jun 28 2021 Oleg Solovyov 0.5.15lorg2-alt73 +- implement generic callback system + * Thu Mar 18 2021 Ivan Zakharyaschev 0.5.15lorg2-alt72 - Cleaned up the code (thx Dmitry V. Levin ldv@; including quite a few commits cherry-picked from http://apt-rpm.org/scm/apt.git): -- Best regards, Ivan --1807885841-568500546-1625058580=:22813--