summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElena Reshetova <elena.reshetova@intel.com>2012-10-17 14:55:39 +0300
committerAnas Nashif <anas.nashif@intel.com>2013-02-02 16:44:44 -0800
commitdca7f1cdfdcdee92e0c4e835e40472f59660d2b4 (patch)
tree335d8b961ea7b755ea148e8458f1be7a542f6a8e
parente5571e11ba2a08eda4c0d3917511d36eab9e2777 (diff)
downloadrpm-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>
-rw-r--r--lib/psm.c11
-rw-r--r--lib/rpmplugins.c93
-rw-r--r--lib/rpmplugins.h63
-rw-r--r--lib/rpmscript.c17
-rw-r--r--lib/rpmscript.h2
-rw-r--r--lib/rpmte.c2
-rw-r--r--lib/transaction.c45
-rw-r--r--plugins/plugin.h14
8 files changed, 230 insertions, 17 deletions
diff --git a/lib/psm.c b/lib/psm.c
index 42a2ad46c..3e4cf9cca 100644
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -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);
diff --git a/plugins/plugin.h b/plugins/plugin.h
index 5156f93c2..cf49f8a97 100644
--- a/plugins/plugin.h
+++ b/plugins/plugin.h
@@ -7,9 +7,23 @@
#include "lib/rpmplugins.h"
#include "lib/rpmchroot.h"
+/* general plugin hooks */
rpmRC PLUGINHOOK_INIT_FUNC(rpmts ts, const char * name, const char * opts);
rpmRC PLUGINHOOK_CLEANUP_FUNC(void);
+
+/* collection plugin hooks */
rpmRC PLUGINHOOK_OPENTE_FUNC(rpmte te);
rpmRC PLUGINHOOK_COLL_POST_ANY_FUNC(void);
rpmRC PLUGINHOOK_COLL_POST_ADD_FUNC(void);
rpmRC PLUGINHOOK_COLL_PRE_REMOVE_FUNC(void);
+
+/* per transaction plugin hooks */
+rpmRC PLUGINHOOK_TSM_PRE_FUNC(rpmts ts);
+rpmRC PLUGINHOOK_TSM_POST_FUNC(rpmts ts);
+
+/* per transaction element plugin hooks */
+rpmRC PLUGINHOOK_PSM_PRE_FUNC(rpmte te);
+rpmRC PLUGINHOOK_PSM_POST_FUNC(rpmte te);
+
+/*per script plugin hooks */
+rpmRC PLUGINHOOK_SCRIPT_SETUP_FUNC(char* path);