[devel] [PATCH for apt] Implemented generic callback system for package manager transactions
Oleg Solovyov
mcpain на altlinux.org
Пт Дек 6 16:12:01 MSK 2019
---
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
Подробная информация о списке рассылки Devel