rpm/posttrans.diff

377 lines
13 KiB
Diff

--- include/rpm/rpmcli.h.orig 2022-04-07 11:13:18.983517774 +0000
+++ include/rpm/rpmcli.h 2022-12-02 13:43:44.899359176 +0000
@@ -306,6 +306,7 @@ enum rpmInstallFlags_e {
INSTALL_ALLMATCHES = (1 << 9), /*!< from --allmatches */
INSTALL_REINSTALL = (1 << 10), /*!< from --reinstall */
INSTALL_RESTORE = (1 << 11), /*!< from --restore */
+ INSTALL_RUNPOSTTRANS = (1 << 12), /*!< from --runposttrans */
};
typedef rpmFlags rpmInstallFlags;
@@ -396,6 +397,15 @@ int rpmErase(rpmts ts, struct rpmInstall
int rpmRestore(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_const_t argv);
/** \ingroup rpmcli
+ * Run posttrans scriptlets
+ * @param ts transaction set
+ * @param ia control args/bits
+ * @param argv array of trigger manifest file names (NULL terminated)
+ * @return 0 on success
+ */
+int rpmRunPostTrans(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_const_t argv);
+
+/** \ingroup rpmcli
*/
extern struct rpmInstallArguments_s rpmIArgs;
--- include/rpm/rpmts.h.orig 2022-12-02 13:27:05.109729552 +0000
+++ include/rpm/rpmts.h 2022-12-02 13:27:08.881720646 +0000
@@ -249,6 +249,15 @@ int rpmtsOrder(rpmts ts);
int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet);
/** \ingroup rpmts
+ * Run all posttrans scriptlets described in the manifest data.
+ *
+ * @param ts transaction set
+ * @param manifest the manifest data
+ * @return 0 on success, -1 on error
+ */
+int rpmtsRunPostTrans(rpmts ts, ARGV_const_t manifest);
+
+/** \ingroup rpmts
* Reference a transaction set instance.
* @param ts transaction set
* @return new transaction set reference
--- lib/poptI.c.orig 2022-04-07 11:13:19.010517957 +0000
+++ lib/poptI.c 2022-12-02 13:27:08.877720656 +0000
@@ -273,6 +273,10 @@ struct poptOption rpmInstallPoptTable[]
&rpmIArgs.installInterfaceFlags, (INSTALL_RESTORE),
N_("restore package(s)"),
N_("<packagefile>+") },
+ { "runposttrans", '\0', POPT_BIT_SET,
+ &rpmIArgs.installInterfaceFlags, INSTALL_RUNPOSTTRANS,
+ N_("run posttrans scriptlet"),
+ N_("<posttransmanifest>") },
POPT_TABLEEND
};
--- lib/psm.c.orig 2022-12-02 13:27:05.093729590 +0000
+++ lib/psm.c 2022-12-02 13:27:08.877720656 +0000
@@ -826,7 +826,7 @@ static rpmRC rpmPackageErase(rpmts ts, r
}
if (rc) break;
- if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERPOSTUN))) {
+ if (ts->dump_posttrans || !(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERPOSTUN))) {
/* Prepare post transaction uninstall triggers */
rpmtriggersPrepPostUnTransFileTrigs(psm->ts, psm->te);
}
--- lib/rpminstall.c.orig 2022-09-02 05:48:29.712846716 +0000
+++ lib/rpminstall.c 2022-12-02 13:27:08.877720656 +0000
@@ -6,6 +6,8 @@
#include <string.h>
+#include <errno.h>
+
#include <rpm/rpmcli.h>
#include <rpm/rpmtag.h>
#include <rpm/rpmlib.h> /* rpmReadPackageFile, vercmp etc */
@@ -812,3 +814,32 @@ int rpmInstallSource(rpmts ts, const cha
return rc;
}
+int rpmRunPostTrans(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_const_t fileArgv)
+{
+ ARGV_t manifest = NULL;
+ FILE *f;
+ char line[BUFSIZ], *s, *p;
+ int rc = 1;
+
+ if (fileArgv == NULL) return 0;
+ if (!fileArgv[0] || fileArgv[1] != NULL) {
+ rpmlog(RPMLOG_ERR, _("runposttrans needs exactly one manifest file\n"));
+ goto exit;
+ }
+ if (!(f = fopen(fileArgv[0], "r"))) {
+ rpmlog(RPMLOG_ERR, _("cannot open %s: %s\n"), fileArgv[0], strerror(errno));
+ goto exit;
+ }
+ while ((s = fgets(line, sizeof(line) - 1, f)) != 0) {
+ if (p = strrchr(s, '\n'))
+ *p = 0;
+ argvAdd(&manifest, s);
+ }
+ fclose(f);
+ rpmlog(RPMLOG_DEBUG, "running posttrans scriptlets\n");
+ rpmtsClean(ts);
+ rc = rpmtsRunPostTrans(ts, manifest);
+exit:
+ argvFree(manifest);
+ return rc;
+}
--- lib/rpmtriggers.c.orig 2022-04-07 11:13:19.020518024 +0000
+++ lib/rpmtriggers.c 2022-12-02 13:27:08.877720656 +0000
@@ -1,5 +1,6 @@
#include "system.h"
+#include <rpm/rpmlog.h>
#include <rpm/rpmts.h>
#include <rpm/rpmdb.h>
#include <rpm/rpmds.h>
@@ -34,7 +35,7 @@ rpmtriggers rpmtriggersFree(rpmtriggers
return NULL;
}
-static void rpmtriggersAdd(rpmtriggers trigs, unsigned int hdrNum,
+void rpmtriggersAdd(rpmtriggers trigs, unsigned int hdrNum,
unsigned int tix, unsigned int priority)
{
if (trigs->count == trigs->alloced) {
@@ -178,6 +179,14 @@ int runPostUnTransFileTrigs(rpmts ts)
if (trigH == NULL)
continue;
+ if (ts->dump_posttrans) {
+ char *trigNEVRA = headerGetAsString(trigH, RPMTAG_NEVRA);
+ rpmlog(RPMLOG_NOTICE, "dump_posttrans: transfiletriggerpostun %u %u %s\n", trigs->triggerInfo[i].tix, trigs->triggerInfo[i].hdrNum, trigNEVRA);
+ free(trigNEVRA);
+ headerFree(trigH);
+ continue;
+ }
+
/* Prepare and run script */
script = rpmScriptFromTriggerTag(trigH,
triggertag(RPMSENSE_TRIGGERPOSTUN),
@@ -587,6 +596,16 @@ rpmRC runImmedFileTriggers(rpmts ts, rpm
rpmTagVal priorityTag;
rpmtriggers triggers;
+ if (sense == RPMSENSE_TRIGGERIN && tm == RPMSCRIPT_TRANSFILETRIGGER && ts->dump_posttrans) {
+ unsigned int hdrNum = headerGetInstance(trigH);
+ if (hdrNum) {
+ char *trigNEVRA = headerGetAsString(trigH, RPMTAG_NEVRA);
+ rpmlog(RPMLOG_NOTICE, "dump_posttrans: install %u %s\n", hdrNum, trigNEVRA);
+ free(trigNEVRA);
+ }
+ headerFree(trigH);
+ return RPMRC_OK;
+ }
if (tm == RPMSCRIPT_FILETRIGGER) {
priorityTag = RPMTAG_FILETRIGGERPRIORITIES;
} else {
--- lib/rpmtriggers.h.orig 2022-04-07 11:13:19.020518024 +0000
+++ lib/rpmtriggers.h 2022-12-02 13:27:08.881720646 +0000
@@ -27,6 +27,10 @@ rpmtriggers rpmtriggersCreate(unsigned i
RPM_GNUC_INTERNAL
rpmtriggers rpmtriggersFree(rpmtriggers triggers);
+RPM_GNUC_INTERNAL
+void rpmtriggersAdd(rpmtriggers trigs, unsigned int hdrNum,
+ unsigned int tix, unsigned int priority);
+
/*
* Prepare post trans uninstall file triggers. After transcation uninstalled
* files are not saved anywhere. So we need during uninstalation of every
--- lib/rpmts_internal.h.orig 2022-04-07 11:13:19.021518031 +0000
+++ lib/rpmts_internal.h 2022-12-02 13:44:39.803225928 +0000
@@ -94,6 +94,8 @@ struct rpmts_s {
int min_writes; /*!< macro minimize_writes used */
time_t overrideTime; /*!< Time value used when overriding system clock. */
+
+ int dump_posttrans; /*!< macro dump_posttrans used */
};
#ifdef __cplusplus
--- lib/transaction.c.orig 2022-08-30 11:42:23.784853830 +0000
+++ lib/transaction.c 2022-12-02 13:27:08.881720646 +0000
@@ -1478,6 +1478,8 @@ static int rpmtsSetup(rpmts ts, rpmprobF
/* Get available space on mounted file systems. */
(void) rpmtsInitDSI(ts);
+ /* Initialize the dump_posttrans flag */
+ ts->dump_posttrans = (rpmExpandNumeric("%{?_dump_posttrans}") > 0);
return 0;
}
@@ -1856,22 +1858,26 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rp
/* Actually install and remove packages */
nfailed = rpmtsProcess(ts);
+ if (ts->dump_posttrans) {
+ rpmlog(RPMLOG_NOTICE, "dump_posttrans: enabled\n");
+ }
+
/* Run %posttrans scripts unless disabled */
- if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS))) {
+ if (!ts->dump_posttrans && !(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS))) {
rpmlog(RPMLOG_DEBUG, "running post-transaction scripts\n");
runTransScripts(ts, PKG_POSTTRANS);
}
/* Run %transfiletriggerpostun scripts unless disabled */
- if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERIN))) {
+ if (!ts->dump_posttrans && !(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERIN))) {
runFileTriggers(ts, NULL, RPMSENSE_TRIGGERIN, RPMSCRIPT_TRANSFILETRIGGER, 0);
}
- if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERPOSTUN))) {
+ if (ts->dump_posttrans || !(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERPOSTUN))) {
runPostUnTransFileTrigs(ts);
}
/* Run %transfiletriggerin scripts unless disabled */
- if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERIN))) {
+ if (ts->dump_posttrans || !(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERIN))) {
runTransScripts(ts, PKG_TRANSFILETRIGGERIN);
}
/* Final exit code */
@@ -1894,3 +1900,110 @@ exit:
sigaction(SIGPIPE, &oact, NULL);
return rc;
}
+
+static unsigned int runPostTransFindPkgNum(const char **lpp)
+{
+ const char *lp = *lpp;
+ unsigned int num = strtoul(lp, 0, 10);
+ while (*lp >= '0' && *lp <= '9')
+ lp++;
+ while (*lp == ' ')
+ lp++;
+ *lpp = lp;
+ return num;
+}
+
+static Header runPostTransFindPkg(rpmts ts, const char *lp)
+{
+ rpmdbMatchIterator mi;
+ Header h = NULL;
+ unsigned int hdrnum = runPostTransFindPkgNum(&lp);
+ if (!*lp)
+ return NULL;
+ if (hdrnum) {
+ mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, &hdrnum, sizeof(hdrnum));
+ h = headerLink(rpmdbNextIterator(mi));
+ rpmdbFreeIterator(mi);
+ }
+ if (h) {
+ char *NEVRA = headerGetAsString(h, RPMTAG_NEVRA);
+ if (!NEVRA || strcmp(NEVRA, lp) != 0)
+ h = headerFree(h);
+ _free(NEVRA);
+ }
+ if (!h) {
+ mi = rpmtsInitIterator(ts, RPMDBI_LABEL, lp, strlen(lp));
+ h = headerLink(rpmdbNextIterator(mi));
+ rpmdbFreeIterator(mi);
+ }
+ if (!h)
+ rpmlog(RPMLOG_WARNING, "package %s is not installed\n", lp);
+ return h;
+}
+
+int rpmtsRunPostTrans(rpmts ts, ARGV_const_t manifest)
+{
+ int rc = -1; /* assume failure */
+ /* setup */
+ tsMembers tsmem = rpmtsMembers(ts);
+ rpmtxn txn = NULL;
+ /* Ignore SIGPIPE for the duration of transaction */
+ rpmsqAction_t oact = rpmsqSetAction(SIGPIPE, RPMSQ_IGN);
+ /* Force default 022 umask during transaction for consistent results */
+ mode_t oldmask = umask(022);
+
+ if (tsmem->orderCount)
+ goto exit;
+ char *line;
+ while ((line = *manifest++) != 0) {
+ if (!strncmp(line, "dump_posttrans: install ", 24)) {
+ const char *lp = line + 24;
+ Header h = runPostTransFindPkg(ts, lp);
+ if (!h)
+ continue;
+ rpmte p = rpmteNew(ts, h, TR_ADDED, line + 45, NULL, RPMTE_INSTALL);
+ if (tsmem->orderCount >= tsmem->orderAlloced) {
+ tsmem->orderAlloced += (tsmem->orderCount - tsmem->orderAlloced) + tsmem->delta;
+ tsmem->order = xrealloc(tsmem->order, tsmem->orderAlloced * sizeof(*tsmem->order));
+ }
+ tsmem->order[tsmem->orderCount++] = p;
+
+ if (tsmem->addedPackages == NULL)
+ tsmem->addedPackages = rpmalCreate(ts, 5);
+ rpmalAdd(tsmem->addedPackages, p);
+ packageHashAddEntry(tsmem->installedPackages, headerGetInstance(h), p);
+ } else if (!strncmp(line, "dump_posttrans: transfiletriggerpostun ", 39)) {
+ const char *lp = line + 39;
+ unsigned int tix = runPostTransFindPkgNum(&lp);
+ Header h = runPostTransFindPkg(ts, lp);
+ struct rpmtd_s priorities;
+ if (!h)
+ continue;
+ headerGet(h, RPMTAG_TRANSFILETRIGGERPRIORITIES, &priorities, HEADERGET_MINMEM);
+ if (rpmtdSetIndex(&priorities, tix) >= 0)
+ rpmtriggersAdd(ts->trigs2run, headerGetInstance(h), tix, *rpmtdGetUint32(&priorities));
+ headerFree(h);
+ }
+ }
+
+ if (!(txn = rpmtxnBegin(ts, RPMTXN_WRITE)))
+ goto exit;
+
+ /* run posttrans scripts */
+ rpmlog(RPMLOG_DEBUG, "running post-transaction scripts\n");
+ runTransScripts(ts, PKG_POSTTRANS);
+ /* run %transfiletriggerin scripts */
+ runFileTriggers(ts, NULL, RPMSENSE_TRIGGERIN, RPMSCRIPT_TRANSFILETRIGGER, 0);
+ /* run %transfiletriggerpostun scrips */
+ runPostUnTransFileTrigs(ts);
+ /* Run immed %transfiletriggerin scripts */
+ runTransScripts(ts, PKG_TRANSFILETRIGGERIN);
+ rc = 0;
+
+exit:
+ (void) umask(oldmask);
+ rpmtxnEnd(txn);
+ rpmsqSetAction(SIGPIPE, oact);
+ rpmtsEmpty(ts);
+ return rc;
+}
--- rpm.c.orig 2022-04-07 11:13:19.067518343 +0000
+++ rpm.c 2022-12-02 13:55:52.969592594 +0000
@@ -21,6 +21,7 @@ enum modes {
MODE_ERASE = (1 << 2),
MODE_RESTORE = (1 << 4),
#define MODES_IE (MODE_INSTALL | MODE_ERASE)
+ MODE_RUNPOSTTRANS = (1 << 5),
MODE_UNKNOWN = 0
};
@@ -115,6 +116,11 @@ int main(int argc, char *argv[])
int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);
int rflags = (ia->installInterfaceFlags & INSTALL_RESTORE);
+ if (ia->installInterfaceFlags & INSTALL_RUNPOSTTRANS) {
+ if (iflags || eflags || rflags)
+ argerror(_("only one major mode may be specified"));
+ bigMode = MODE_RUNPOSTTRANS;
+ }
if (iflags & eflags & rflags)
argerror(_("only one major mode may be specified"));
else if (iflags)
@@ -293,6 +299,14 @@ int main(int argc, char *argv[])
ec = rpmcliVerify(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
} break;
+ case MODE_RUNPOSTTRANS:
+ if (!poptPeekArg(optCon)) {
+ argerror(_("need posttrans manifest for --runposttrans"));
+ } else {
+ ec += rpmRunPostTrans(ts, ia, (ARGV_const_t) poptGetArgs(optCon));
+ }
+ break;
+
case MODE_UNKNOWN:
if (poptPeekArg(optCon) != NULL || argc <= 1) {
printUsage(optCon, stderr, 0);