diff options
author | Elena Reshetova <elena.reshetova@intel.com> | 2012-10-17 14:55:39 +0300 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2013-02-02 16:44:44 -0800 |
commit | dca7f1cdfdcdee92e0c4e835e40472f59660d2b4 (patch) | |
tree | 335d8b961ea7b755ea148e8458f1be7a542f6a8e /lib | |
parent | e5571e11ba2a08eda4c0d3917511d36eab9e2777 (diff) | |
download | rpm-dca7f1cdfdcdee92e0c4e835e40472f59660d2b4.tar.gz rpm-dca7f1cdfdcdee92e0c4e835e40472f59660d2b4.tar.bz2 rpm-dca7f1cdfdcdee92e0c4e835e40472f59660d2b4.zip |
Extending rpm plugin interface, part 1
This change adds a new type of the rpm plugin, called transaction plugin
and a set of initial hooks for this plugin. The hooks are:
PLUGINHOOK_TSM_PRE
Pre-transaction hook that is called before an rpm transaction begins
PLUGINHOOK_TSM_POST
Post-transaction hook that is called after an rpm transaction ends
PLUGINHOOK_PSM_PRE
Pre-transaction-element hook that is called before an rpm
transaction-element is processed
PLUGINHOOK_PSM_POST
Post-transaction-element hook that is called after an rpm
transaction-element is processed
PLUGINHOOK_SCRIPT_SETUP
Per-script hook that is called once for each rpm mainainers script
that is present in the package
Each hook is called for every plugin that have this hook registered.
The avaliable transaction plugins can be specified in macros.in via
transaction_plugins element.
Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/psm.c | 11 | ||||
-rw-r--r-- | lib/rpmplugins.c | 93 | ||||
-rw-r--r-- | lib/rpmplugins.h | 63 | ||||
-rw-r--r-- | lib/rpmscript.c | 17 | ||||
-rw-r--r-- | lib/rpmscript.h | 2 | ||||
-rw-r--r-- | lib/rpmte.c | 2 | ||||
-rw-r--r-- | lib/transaction.c | 45 |
7 files changed, 216 insertions, 17 deletions
@@ -23,8 +23,11 @@ #include "lib/rpmfi_internal.h" /* XXX replaced/states... */ #include "lib/rpmte_internal.h" /* XXX internal apis */ #include "lib/rpmdb_internal.h" /* rpmdbAdd/Remove */ +#include "lib/rpmts_internal.h" /* ts->plugins */ #include "lib/rpmscript.h" +#include "lib/rpmplugins.h" + #include "debug.h" typedef enum pkgStage_e { @@ -422,7 +425,7 @@ static rpmRC runScript(rpmpsm psm, ARGV_const_t prefixes, rpmtsSuspendResumeDBLock(psm->ts, 0); rpmswEnter(rpmtsOp(psm->ts, RPMTS_OP_SCRIPTLETS), 0); rc = rpmScriptRun(script, arg1, arg2, sfd, - prefixes, warn_only, selinux); + prefixes, warn_only, selinux, psm->ts->plugins); rpmswExit(rpmtsOp(psm->ts, RPMTS_OP_SCRIPTLETS), 0); rpmtsSuspendResumeDBLock(psm->ts, 1); @@ -1044,6 +1047,9 @@ rpmRC rpmpsmRun(rpmts ts, rpmte te, pkgGoal goal) switch (goal) { case PKG_INSTALL: case PKG_ERASE: + /* Run pre transaction element hook for all plugins */ + if (rpmpluginsCallPsmPre(ts->plugins, te) == RPMRC_FAIL) + break; op = (goal == PKG_INSTALL) ? RPMTS_OP_INSTALL : RPMTS_OP_ERASE; rpmswEnter(rpmtsOp(psm->ts, op), 0); @@ -1054,6 +1060,9 @@ rpmRC rpmpsmRun(rpmts ts, rpmte te, pkgGoal goal) (void) rpmpsmNext(psm, PSM_FINI); rpmswExit(rpmtsOp(psm->ts, op), 0); + /* Run post transaction element hook for all plugins */ + if (!rc) rc = rpmpluginsCallPsmPost(ts->plugins, te); + break; case PKG_PRETRANS: case PKG_POSTTRANS: diff --git a/lib/rpmplugins.c b/lib/rpmplugins.c index 9098aa5ca..d533b708a 100644 --- a/lib/rpmplugins.c +++ b/lib/rpmplugins.c @@ -76,16 +76,16 @@ rpmRC rpmpluginsAdd(rpmPlugins plugins, const char *name, const char *path, return rpmpluginsCallInit(plugins, name, opts); } -rpmRC rpmpluginsAddCollectionPlugin(rpmPlugins plugins, const char *name) +rpmRC rpmpluginsAddPlugin(rpmPlugins plugins, const char *type, const char *name) { char *path; char *options; rpmRC rc = RPMRC_FAIL; - path = rpmExpand("%{?__collection_", name, "}", NULL); + path = rpmExpand("%{?__", type, "_", name, "}", NULL); if (!path || rstreq(path, "")) { - rpmlog(RPMLOG_ERR, _("Failed to expand %%__collection_%s macro\n"), - name); + rpmlog(RPMLOG_ERR, _("Failed to expand %%__%s_%s macro\n"), + type, name); goto exit; } @@ -195,3 +195,88 @@ rpmRC rpmpluginsCallCollectionPreRemove(rpmPlugins plugins, const char *name) RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_COLL_PRE_REMOVE); return hookFunc(); } + +rpmRC rpmpluginsCallTsmPre(rpmPlugins plugins, rpmts ts) +{ + rpmRC (*hookFunc)(rpmts); + int i; + rpmRC rc = RPMRC_OK; + const char *name = NULL; + + for (i = 0; i < plugins->count; i++) { + name = plugins->names[i]; + RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_TSM_PRE); + if (hookFunc(ts) == RPMRC_FAIL) + rc = RPMRC_FAIL; + } + + return rc; +} + +rpmRC rpmpluginsCallTsmPost(rpmPlugins plugins, rpmts ts) +{ + rpmRC (*hookFunc)(rpmts); + int i; + rpmRC rc = RPMRC_OK; + const char *name = NULL; + + for (i = 0; i < plugins->count; i++) { + name = plugins->names[i]; + RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_TSM_POST); + if (hookFunc(ts) == RPMRC_FAIL) + rc = RPMRC_FAIL; + } + + return rc; +} + +rpmRC rpmpluginsCallPsmPre(rpmPlugins plugins, rpmte te) +{ + rpmRC (*hookFunc)(rpmte); + int i; + rpmRC rc = RPMRC_OK; + const char *name = NULL; + + for (i = 0; i < plugins->count; i++) { + name = plugins->names[i]; + RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_PSM_PRE); + if (hookFunc(te) == RPMRC_FAIL) + rc = RPMRC_FAIL; + } + + return rc; +} + +rpmRC rpmpluginsCallPsmPost(rpmPlugins plugins, rpmte te) +{ + rpmRC (*hookFunc)(rpmte); + int i; + rpmRC rc = RPMRC_OK; + const char *name = NULL; + + for (i = 0; i < plugins->count; i++) { + name = plugins->names[i]; + RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_PSM_POST); + if (hookFunc(te) == RPMRC_FAIL) + rc = RPMRC_FAIL; + } + + return rc; +} + +rpmRC rpmpluginsCallScriptSetup(rpmPlugins plugins, char* path) +{ + rpmRC (*hookFunc)(char*); + int i; + rpmRC rc = RPMRC_OK; + const char *name = NULL; + + for (i = 0; i < plugins->count; i++) { + name = plugins->names[i]; + RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_SCRIPT_SETUP); + if (hookFunc(path) == RPMRC_FAIL) + rc = RPMRC_FAIL; + } + + return rc; +} diff --git a/lib/rpmplugins.h b/lib/rpmplugins.h index 79855596c..153b8a99b 100644 --- a/lib/rpmplugins.h +++ b/lib/rpmplugins.h @@ -11,11 +11,20 @@ extern "C" { #define PLUGINHOOK_INIT_FUNC pluginhook_init #define PLUGINHOOK_CLEANUP_FUNC pluginhook_cleanup + #define PLUGINHOOK_OPENTE_FUNC pluginhook_opente #define PLUGINHOOK_COLL_POST_ADD_FUNC pluginhook_coll_post_add #define PLUGINHOOK_COLL_POST_ANY_FUNC pluginhook_coll_post_any #define PLUGINHOOK_COLL_PRE_REMOVE_FUNC pluginhook_coll_pre_remove +#define PLUGINHOOK_TSM_PRE_FUNC pluginhook_tsm_pre +#define PLUGINHOOK_TSM_POST_FUNC pluginhook_tsm_post + +#define PLUGINHOOK_PSM_PRE_FUNC pluginhook_psm_pre +#define PLUGINHOOK_PSM_POST_FUNC pluginhook_psm_post + +#define PLUGINHOOK_SCRIPT_SETUP_FUNC pluginhook_script_setup + enum rpmPluginHook_e { PLUGINHOOK_NONE = 0, PLUGINHOOK_INIT = 1 << 0, @@ -23,7 +32,12 @@ enum rpmPluginHook_e { PLUGINHOOK_OPENTE = 1 << 2, PLUGINHOOK_COLL_POST_ADD = 1 << 3, PLUGINHOOK_COLL_POST_ANY = 1 << 4, - PLUGINHOOK_COLL_PRE_REMOVE = 1 << 5 + PLUGINHOOK_COLL_PRE_REMOVE = 1 << 5, + PLUGINHOOK_TSM_PRE = 1 << 6, + PLUGINHOOK_TSM_POST = 1 << 7, + PLUGINHOOK_PSM_PRE = 1 << 8, + PLUGINHOOK_PSM_POST = 1 << 9, + PLUGINHOOK_SCRIPT_SETUP = 1 << 10 }; typedef rpmFlags rpmPluginHook; @@ -53,12 +67,13 @@ rpmPlugins rpmpluginsFree(rpmPlugins plugins); rpmRC rpmpluginsAdd(rpmPlugins plugins, const char *name, const char *path, const char *opts); /** \ingroup rpmplugins - * Add and open a collection plugin + * Add and open a rpm plugin * @param plugins plugins structure to add a collection plugin to - * @param name name of collection to open + * @param type type of plugin + * @param name name of plugin * @return RPMRC_OK on success, RPMRC_FAIL otherwise */ -rpmRC rpmpluginsAddCollectionPlugin(rpmPlugins plugins, const char *name); +rpmRC rpmpluginsAddPlugin(rpmPlugins plugins, const char *type, const char *name); /** \ingroup rpmplugins * Determine if a plugin has been added already @@ -119,6 +134,46 @@ rpmRC rpmpluginsCallCollectionPostAny(rpmPlugins plugins, const char *name); */ rpmRC rpmpluginsCallCollectionPreRemove(rpmPlugins plugins, const char *name); +/** \ingroup rpmplugins + * Call the pre transaction plugin hook + * @param plugins plugins structure + * @param ts processed transaction + * @return RPMRC_OK on success, RPMRC_FAIL otherwise + */ +rpmRC rpmpluginsCallTsmPre(rpmPlugins plugins, rpmts ts); + +/** \ingroup rpmplugins + * Call the post transaction plugin hook + * @param plugins plugins structure + * @param ts processed transaction + * @return RPMRC_OK on success, RPMRC_FAIL otherwise + */ +rpmRC rpmpluginsCallTsmPost(rpmPlugins plugins, rpmts ts); + +/** \ingroup rpmplugins + * Call the pre transaction element plugin hook + * @param plugins plugins structure + * @param te processed transaction element + * @return RPMRC_OK on success, RPMRC_FAIL otherwise + */ +rpmRC rpmpluginsCallPsmPre(rpmPlugins plugins, rpmte te); + +/** \ingroup rpmplugins + * Call the post transaction element plugin hook + * @param plugins plugins structure + * @param te processed transaction element + * @return RPMRC_OK on success, RPMRC_FAIL otherwise + */ +rpmRC rpmpluginsCallPsmPost(rpmPlugins plugins, rpmte te); + +/** \ingroup rpmplugins + * Call the script setup plugin hook + * @param plugins plugins structure + * @param path script path + * @return RPMRC_OK on success, RPMRC_FAIL otherwise + */ +rpmRC rpmpluginsCallScriptSetup(rpmPlugins plugins, char* path); + #ifdef __cplusplus } #endif diff --git a/lib/rpmscript.c b/lib/rpmscript.c index 57c24c674..f8c5fc74a 100644 --- a/lib/rpmscript.c +++ b/lib/rpmscript.c @@ -14,6 +14,8 @@ #include "rpmio/rpmlua.h" #include "lib/rpmscript.h" +#include "lib/rpmplugins.h" /* rpm plugins hooks */ + #include "debug.h" struct rpmScript_s { @@ -91,7 +93,7 @@ static rpmRC runLuaScript(int selinux, ARGV_const_t prefixes, static const char * const SCRIPT_PATH = "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin"; -static void doScriptExec(int selinux, ARGV_const_t argv, ARGV_const_t prefixes, +static void doScriptExec(rpmPlugins plugins, int selinux, ARGV_const_t argv, ARGV_const_t prefixes, FD_t scriptFd, FD_t out) { int pipes[2]; @@ -169,7 +171,10 @@ static void doScriptExec(int selinux, ARGV_const_t argv, ARGV_const_t prefixes, } if (xx == 0) { - xx = execv(argv[0], argv); + /* Run script setup hook for all plugins */ + if (rpmpluginsCallScriptSetup(plugins, argv[0]) != RPMRC_FAIL) { + xx = execv(argv[0], argv); + } } } _exit(127); /* exit 127 for compatibility with bash(1) */ @@ -202,7 +207,7 @@ exit: /** * Run an external script. */ -static rpmRC runExtScript(int selinux, ARGV_const_t prefixes, +static rpmRC runExtScript(rpmPlugins plugins, int selinux, ARGV_const_t prefixes, const char *sname, rpmlogLvl lvl, FD_t scriptFd, ARGV_t * argvp, const char *script, int arg1, int arg2) { @@ -258,7 +263,7 @@ static rpmRC runExtScript(int selinux, ARGV_const_t prefixes, } else if (pid == 0) {/* Child */ rpmlog(RPMLOG_DEBUG, "%s: execv(%s) pid %d\n", sname, *argvp[0], (unsigned)getpid()); - doScriptExec(selinux, *argvp, prefixes, scriptFd, out); + doScriptExec(plugins, selinux, *argvp, prefixes, scriptFd, out); } do { @@ -297,7 +302,7 @@ exit: } rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2, FD_t scriptFd, - ARGV_const_t prefixes, int warn_only, int selinux) + ARGV_const_t prefixes, int warn_only, int selinux, rpmPlugins plugins) { ARGV_t args = NULL; rpmlogLvl lvl = warn_only ? RPMLOG_WARNING : RPMLOG_ERR; @@ -315,7 +320,7 @@ rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2, FD_t scriptFd, if (rstreq(args[0], "<lua>")) { rc = runLuaScript(selinux, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2); } else { - rc = runExtScript(selinux, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2); + rc = runExtScript(plugins, selinux, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2); } argvFree(args); diff --git a/lib/rpmscript.h b/lib/rpmscript.h index 7d584bcd9..852735b8d 100644 --- a/lib/rpmscript.h +++ b/lib/rpmscript.h @@ -29,7 +29,7 @@ rpmScript rpmScriptFree(rpmScript script); RPM_GNUC_INTERNAL rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2, FD_t scriptFd, - ARGV_const_t prefixes, int warn_only, int selinux); + ARGV_const_t prefixes, int warn_only, int selinux, rpmPlugins plugins); RPM_GNUC_INTERNAL rpmTagVal rpmScriptTag(rpmScript script); diff --git a/lib/rpmte.c b/lib/rpmte.c index 6afd69e97..da6f48c5c 100644 --- a/lib/rpmte.c +++ b/lib/rpmte.c @@ -889,7 +889,7 @@ rpmRC rpmteSetupCollectionPlugins(rpmte te) rpmteOpen(te, 0); for (; colls && *colls; colls++) { if (!rpmpluginsPluginAdded(plugins, *colls)) { - rc = rpmpluginsAddCollectionPlugin(plugins, *colls); + rc = rpmpluginsAddPlugin(plugins, "collection", *colls); if (rc != RPMRC_OK) { break; } diff --git a/lib/transaction.c b/lib/transaction.c index 5e43880ab..87287478b 100644 --- a/lib/transaction.c +++ b/lib/transaction.c @@ -22,6 +22,8 @@ #include "lib/rpmts_internal.h" #include "rpmio/rpmhook.h" +#include "lib/rpmplugins.h" + /* XXX FIXME: merge with existing (broken?) tests in system.h */ /* portability fiddles */ #if STATFS_IN_SYS_STATVFS @@ -1436,6 +1438,35 @@ static int rpmtsProcess(rpmts ts) return rc; } +static rpmRC rpmtsSetupTransactionPlugins(rpmts ts) +{ + rpmRC rc = RPMRC_OK; + char *plugins = NULL, *plugin = NULL; + const char *delims = ","; + + plugins = rpmExpand("%{?__transaction_plugins}", NULL); + if (!plugins || rstreq(plugins, "")) { + goto exit; + } + + plugin = strtok(plugins, delims); + while(plugin != NULL) { + rpmlog(RPMLOG_DEBUG, "plugin is %s\n", plugin); + if (!rpmpluginsPluginAdded(ts->plugins, (const char*)plugin)) { + if (rpmpluginsAddPlugin(ts->plugins, "transaction", + (const char*)plugin) == RPMRC_FAIL) { + /* any configured plugin failing to load is a failure */ + rc = RPMRC_FAIL; + } + } + plugin = strtok(NULL, delims); + } + +exit: + free(plugins); + return rc; +} + int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet) { int rc = -1; /* assume failure */ @@ -1463,11 +1494,20 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet) goto exit; } + if (rpmtsSetupTransactionPlugins(ts) == RPMRC_FAIL) { + goto exit; + } + rpmtsSetupCollections(ts); /* Check package set for problems */ tsprobs = checkProblems(ts); + /* Run pre transaction hook for all plugins */ + if (rpmpluginsCallTsmPre(ts->plugins, ts) == RPMRC_FAIL) { + goto exit; + } + /* Run pre-transaction scripts, but only if there are no known * problems up to this point and not disabled otherwise. */ if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_NOPRE)) @@ -1511,6 +1551,11 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet) runTransScripts(ts, PKG_POSTTRANS); } + /* Run post transaction hook for all plugins */ + if (rpmpluginsCallTsmPost(ts->plugins, ts) == RPMRC_FAIL) { + goto exit; + } + exit: /* Finish up... */ (void) umask(oldmask); |