#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 {
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);
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);
(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:
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;
}
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;
+}
#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,
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;
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
*/
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
#include "rpmio/rpmlua.h"
#include "lib/rpmscript.h"
+#include "lib/rpmplugins.h" /* rpm plugins hooks */
+
#include "debug.h"
struct rpmScript_s {
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];
}
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) */
/**
* 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)
{
} 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 {
}
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;
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);
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);
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;
}
#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
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 */
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))
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);
#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);