From: Oleg Solovyov <mcpain@altlinux.org> To: devel@lists.altlinux.org Cc: Oleg Solovyov <mcpain@altlinux.org> Subject: [devel] [PATCH for apt] Implemented generic callback system for package manager transactions Date: Fri, 6 Dec 2019 16:12:01 +0300 Message-ID: <20191206131201.525279-1-mcpain@altlinux.org> (raw) --- apt/apt-pkg/packagemanager.cc | 4 +- apt/apt-pkg/packagemanager.h | 30 +++++++- apt/apt-pkg/rpm/rpmpm.cc | 137 ++++++++++++++++++++++++++++++++-- apt/apt-pkg/rpm/rpmpm.h | 16 ++-- 4 files changed, 170 insertions(+), 17 deletions(-) diff --git a/apt/apt-pkg/packagemanager.cc b/apt/apt-pkg/packagemanager.cc index 0bcd902..f5adbfd 100644 --- a/apt/apt-pkg/packagemanager.cc +++ b/apt/apt-pkg/packagemanager.cc @@ -665,11 +665,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/apt-pkg/packagemanager.h b/apt/apt-pkg/packagemanager.h index 917dbc1..e60ba51 100644 --- a/apt/apt-pkg/packagemanager.h +++ b/apt/apt-pkg/packagemanager.h @@ -49,6 +49,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: @@ -80,7 +106,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: @@ -88,7 +114,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/apt-pkg/rpm/rpmpm.cc b/apt/apt-pkg/rpm/rpmpm.cc index a6a3837..d5ff786 100644 --- a/apt/apt-pkg/rpm/rpmpm.cc +++ b/apt/apt-pkg/rpm/rpmpm.cc @@ -278,7 +278,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; @@ -364,7 +364,7 @@ bool pkgRPMPM::Go() } #endif - if (Process(install, upgrade, uninstall) == false) + if (Process(install, upgrade, uninstall, callback, callbackData) == false) Ret = false; #ifdef WITH_LUA @@ -687,7 +687,8 @@ bool pkgRPMExtPM::ExecRPM(Item::RPMOps op, const std::vector<apt_item> &files) bool pkgRPMExtPM::Process(const std::vector<apt_item> &install, const std::vector<apt_item> &upgrade, - const std::vector<apt_item> &uninstall) + const std::vector<apt_item> &uninstall, + PackageManagerCallback_t callback, void *callbackData) { if (uninstall.empty() == false) ExecRPM(Item::RPMErase, uninstall); @@ -827,9 +828,108 @@ bool pkgRPMLibPM::AddToTransaction(Item::RPMOps op, const std::vector<apt_item> 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); + } + + aptCallbackType callbackType = APTCALLBACK_UNKNOWN; + switch (what) { + case RPMCALLBACK_INST_PROGRESS: + callbackType = APTCALLBACK_INST_PROGRESS; + break; + case RPMCALLBACK_INST_START: + callbackType = APTCALLBACK_INST_START; + break; + case RPMCALLBACK_TRANS_PROGRESS: + callbackType = APTCALLBACK_TRANS_PROGRESS; + break; + case RPMCALLBACK_TRANS_START: + callbackType = APTCALLBACK_TRANS_START; + break; + case RPMCALLBACK_TRANS_STOP: + callbackType = APTCALLBACK_TRANS_STOP; + break; + case RPMCALLBACK_UNINST_PROGRESS: + callbackType = APTCALLBACK_UNINST_PROGRESS; + break; + case RPMCALLBACK_UNINST_START: + callbackType = APTCALLBACK_UNINST_START; + break; + case RPMCALLBACK_UNINST_STOP: + callbackType = APTCALLBACK_UNINST_STOP; + break; + case RPMCALLBACK_UNPACK_ERROR: + callbackType = APTCALLBACK_UNPACK_ERROR; + break; + case RPMCALLBACK_CPIO_ERROR: + callbackType = APTCALLBACK_CPIO_ERROR; + break; + case RPMCALLBACK_SCRIPT_ERROR: + callbackType = APTCALLBACK_SCRIPT_ERROR; + break; + case RPMCALLBACK_SCRIPT_START: + callbackType = APTCALLBACK_SCRIPT_START; + break; + case RPMCALLBACK_SCRIPT_STOP: + callbackType = APTCALLBACK_SCRIPT_STOP; + break; + case RPMCALLBACK_INST_STOP: + callbackType = APTCALLBACK_INST_STOP; + break; + case RPMCALLBACK_ELEM_PROGRESS: + callbackType = APTCALLBACK_ELEM_PROGRESS; + break; + 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<apt_item> &install, const std::vector<apt_item> &upgrade, - const std::vector<apt_item> &uninstall) + const std::vector<apt_item> &uninstall, + PackageManagerCallback_t callback, void *callbackData) { int rc = 0; bool Success = false; @@ -990,13 +1090,34 @@ bool pkgRPMLibPM::Process(const std::vector<apt_item> &install, probFilter |= rpmtsFilterFlags(TS); rpmtsSetFlags(TS, (rpmtransFlags)(rpmtsFlags(TS) | tsFlags)); rpmtsClean(TS); - rc = rpmtsSetNotifyCallback(TS, rpmShowProgress, (void *)notifyFlags); + + struct CallbackData data; + + if (callback != nullptr ) { + data.callback = callback; + data.callbackData = callbackData; + + rc = rpmtsSetNotifyCallback(TS, customCallback, &data); + } else { + rc = rpmtsSetNotifyCallback(TS, rpmShowProgress, (void *)notifyFlags); + } + rc = rpmtsRun(TS, NULL, (rpmprobFilterFlags)probFilter); probs = rpmtsProblems(TS); #else - rc = rpmRunTransactions(TS, rpmShowProgress, (void *)notifyFlags, NULL, - &probs, (rpmtransFlags)tsFlags, - (rpmprobFilterFlags)probFilter); + if (callback != nullptr ) { + struct CallbackData data; + data.callback = callback; + data.callbackData = callbackData; + + rc = rpmRunTransactions(TS, customCallback, &data, NULL, + &probs, (rpmtransFlags)tsFlags, + (rpmprobFilterFlags)probFilter); + } else { + rc = rpmRunTransactions(TS, rpmShowProgress, (void *)notifyFlags, NULL, + &probs, (rpmtransFlags)tsFlags, + (rpmprobFilterFlags)probFilter); + } #endif if (rc > 0) { diff --git a/apt/apt-pkg/rpm/rpmpm.h b/apt/apt-pkg/rpm/rpmpm.h index e6968b8..692b9a9 100644 --- a/apt/apt-pkg/rpm/rpmpm.h +++ b/apt/apt-pkg/rpm/rpmpm.h @@ -54,12 +54,13 @@ class pkgRPMPM : public pkgPackageManager virtual bool Install(PkgIterator Pkg,const string &File) override; virtual bool Configure(PkgIterator Pkg) override; virtual bool Remove(PkgIterator Pkg,bool Purge = false) override; - + virtual bool Process(const std::vector<apt_item> &install, const std::vector<apt_item> &upgrade, - const std::vector<apt_item> &uninstall) {return false;}; + const std::vector<apt_item> &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: @@ -74,7 +75,8 @@ class pkgRPMExtPM : public pkgRPMPM bool ExecRPM(Item::RPMOps op, const std::vector<apt_item> &files); virtual bool Process(const std::vector<apt_item> &install, const std::vector<apt_item> &upgrade, - const std::vector<apt_item> &uninstall) override; + const std::vector<apt_item> &uninstall, + PackageManagerCallback_t callback, void *callbackData) override; public: pkgRPMExtPM(pkgDepCache *Cache); @@ -93,9 +95,13 @@ class pkgRPMLibPM : public pkgRPMPM bool ParseRpmOpts(const char *Cnf, int *tsFlags, int *probFilter); bool AddToTransaction(Item::RPMOps op, const std::vector<apt_item> &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<apt_item> &install, const std::vector<apt_item> &upgrade, - const std::vector<apt_item> &uninstall) override; + const std::vector<apt_item> &uninstall, + PackageManagerCallback_t callback, void *callbackData) override; public: -- 2.24.0
next reply other threads:[~2019-12-06 13:12 UTC|newest] Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-12-06 13:12 Oleg Solovyov [this message] 2019-12-10 0:30 ` Dmitry V. Levin 2019-12-10 7:27 ` Oleg Solovyov 2019-12-10 22:39 ` Dmitry V. Levin 2019-12-10 7:37 ` Aleksei Nikiforov 2019-12-10 14:38 ` [devel] [PATCH for apt v2] " Oleg Solovyov 2019-12-11 9:15 ` [devel] [PATCH for apt v3] " Oleg Solovyov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20191206131201.525279-1-mcpain@altlinux.org \ --to=mcpain@altlinux.org \ --cc=devel@lists.altlinux.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
ALT Linux Team development discussions This inbox may be cloned and mirrored by anyone: git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \ devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru public-inbox-index devel Example config snippet for mirrors. Newsgroup available over NNTP: nntp://lore.altlinux.org/org.altlinux.lists.devel AGPL code for this site: git clone https://public-inbox.org/public-inbox.git