From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on sa.local.altlinux.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.1 From: Oleg Solovyov To: devel@lists.altlinux.org Date: Fri, 6 Dec 2019 16:12:01 +0300 Message-Id: <20191206131201.525279-1-mcpain@altlinux.org> X-Mailer: git-send-email 2.24.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Cc: Oleg Solovyov Subject: [devel] [PATCH for apt] Implemented generic callback system for package manager transactions 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: Fri, 06 Dec 2019 13:12:16 -0000 Archived-At: List-Archive: List-Post: --- 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 &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); @@ -827,9 +828,108 @@ 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); + } + + 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 &install, const std::vector &upgrade, - const std::vector &uninstall) + const std::vector &uninstall, + PackageManagerCallback_t callback, void *callbackData) { int rc = 0; bool Success = false; @@ -990,13 +1090,34 @@ bool pkgRPMLibPM::Process(const std::vector &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 &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: @@ -74,7 +75,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); @@ -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 &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: -- 2.24.0