From 29ec7bd824b3cb3a09639717e30b543cff92694d Mon Sep 17 00:00:00 2001 From: Michal Domonkos Date: Mon, 8 Jan 2024 13:28:26 +0100 Subject: [PATCH] Pass arg1 to file trigger scripts Pass the number of instances of the source (i.e. triggered) package left after the operation as the first argument ($1) to file trigger scripts, similarly to regular triggers. The %filetrigger{in,un,postun} variants execute at the same time as their regular trigger counterparts so use the same logic to compute the argument. The %transfiletrigger{in,un} variants don't have any regular trigger counterparts but are close relatives of the %posttrans and %preuntrans scriptlets, respectively, so borrow the logic from those. Don't count packages in runImmedFileTriggers() again, though, and just reuse the psm->scriptArg value which is already computed in rpmpsmNew() and used for the normal scriptlets such as %pre. We could/should probably do this in runImmedTriggers(), too, but leave that for later (see issue #2868). Some tests already cover the file trigger arguments so adjust those, and extend the "basic file triggers 2" test with the remaining scenarios to bring it on par with the regular trigger tests. This is easier than extending "basic file trigger scripts" since we don't really need to test the filenames returned on stdin here, just the arguments. Also add a short note about the argument to the file trigger docs. The second argument $2 (triggering package count) will be added in a separate commit. Related: #2755 --- docs/manual/file_triggers.md | 2 + lib/psm.c | 26 ++++++----- lib/rpmtriggers.c | 28 ++++++++--- lib/rpmtriggers.h | 3 +- tests/rpmscript.at | 91 ++++++++++++++++++++++++++++++------ 5 files changed, 115 insertions(+), 35 deletions(-) diff --git a/docs/manual/file_triggers.md b/docs/manual/file_triggers.md index 60bc0505a4..f8f9aa348f 100644 --- a/docs/manual/file_triggers.md +++ b/docs/manual/file_triggers.md @@ -32,6 +32,8 @@ directories, symlinks etc. The file triggers are defined in spec files of packages. E.g. file trigger executing `ldconfig` could be defined in glibc package. +Similarly to regular triggers, file trigger scripts are passed the number of instances of the triggered package (as their first argument `$1`) that will remain when the file trigger has completed. This can be useful in order to perform a certain operation when the triggered package is updated or removed. + As was mentioned above there are more types of file triggers. We have two main types. File triggers execute once for package and file triggers executed once for whole transaction a.k.a transaction file triggers. Further file triggers are dived according to time of execution: before/after installation or erasure of a package or before/after a transaction. Here is a list of all possible types: diff --git a/lib/psm.c b/lib/psm.c index ddc3393573..15854f0262 100644 --- a/lib/psm.c +++ b/lib/psm.c @@ -639,6 +639,7 @@ static rpmpsm rpmpsmNew(rpmts ts, rpmte te, pkgGoal goal) psm->countCorrection = 0; break; case PKG_PREUNTRANS: + case PKG_TRANSFILETRIGGERUN: if (rpmteDependsOn(psm->te)) psm->scriptArg = npkgs_installed; else @@ -654,6 +655,7 @@ static rpmpsm rpmpsmNew(rpmts ts, rpmte te, pkgGoal goal) break; case PKG_VERIFY: case PKG_POSTTRANS: + case PKG_TRANSFILETRIGGERIN: psm->scriptArg = npkgs_installed + isUpdate(psm->ts, psm->te); break; default: @@ -888,8 +890,8 @@ static rpmRC rpmPackageInstall(rpmts ts, rpmpsm psm) if (rc) break; /* Run file triggers in this package other package(s) set off. */ - rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERIN, - RPMSCRIPT_FILETRIGGER, 1); + rc = runImmedFileTriggers(psm->ts, psm->te, psm->scriptArg, + RPMSENSE_TRIGGERIN, RPMSCRIPT_FILETRIGGER, 1); if (rc) break; } @@ -914,8 +916,8 @@ static rpmRC rpmPackageInstall(rpmts ts, rpmpsm psm) if (rc) break; /* Run file triggers in this package other package(s) set off. */ - rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERIN, - RPMSCRIPT_FILETRIGGER, 2); + rc = runImmedFileTriggers(psm->ts, psm->te, psm->scriptArg, + RPMSENSE_TRIGGERIN, RPMSCRIPT_FILETRIGGER, 2); if (rc) break; } @@ -937,8 +939,8 @@ static rpmRC rpmPackageErase(rpmts ts, rpmpsm psm) if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERUN)) { /* Run file triggers in this package other package(s) set off. */ - rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERUN, - RPMSCRIPT_FILETRIGGER, 1); + rc = runImmedFileTriggers(psm->ts, psm->te, psm->scriptArg, + RPMSENSE_TRIGGERUN, RPMSCRIPT_FILETRIGGER, 1); if (rc) break; /* Run file triggers in other package(s) this package sets off. */ @@ -962,8 +964,8 @@ static rpmRC rpmPackageErase(rpmts ts, rpmpsm psm) if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERUN)) { /* Run file triggers in this package other package(s) set off. */ - rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERUN, - RPMSCRIPT_FILETRIGGER, 2); + rc = runImmedFileTriggers(psm->ts, psm->te, psm->scriptArg, + RPMSENSE_TRIGGERUN, RPMSCRIPT_FILETRIGGER, 2); if (rc) break; /* Run file triggers in other package(s) this package sets off. */ @@ -1081,12 +1083,12 @@ static rpmRC runGoal(rpmpsm psm, pkgGoal goal) rc = runInstScript(psm, goal); break; case PKG_TRANSFILETRIGGERIN: - rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERIN, - RPMSCRIPT_TRANSFILETRIGGER, 0); + rc = runImmedFileTriggers(psm->ts, psm->te, psm->scriptArg, + RPMSENSE_TRIGGERIN, RPMSCRIPT_TRANSFILETRIGGER, 0); break; case PKG_TRANSFILETRIGGERUN: - rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERUN, - RPMSCRIPT_TRANSFILETRIGGER, 0); + rc = runImmedFileTriggers(psm->ts, psm->te, psm->scriptArg, + RPMSENSE_TRIGGERUN, RPMSCRIPT_TRANSFILETRIGGER, 0); break; default: break; diff --git a/lib/rpmtriggers.c b/lib/rpmtriggers.c index 51291e73d6..1e3b879e03 100644 --- a/lib/rpmtriggers.c +++ b/lib/rpmtriggers.c @@ -162,6 +162,8 @@ int runPostUnTransFileTrigs(rpmts ts) { int i; Header trigH; + const char * trigName = NULL; + int arg1 = 0; struct rpmtd_s installPrefixes; rpmScript script; rpmtriggers trigs = ts->trigs2run; @@ -186,7 +188,11 @@ int runPostUnTransFileTrigs(rpmts ts) headerGet(trigH, RPMTAG_INSTPREFIXES, &installPrefixes, HEADERGET_ALLOC|HEADERGET_ARGV); - nerrors += runScript(ts, NULL, trigH, installPrefixes.data, script, 0, -1); + trigName = headerGetString(trigH, RPMTAG_NAME); + arg1 = rpmdbCountPackages(rpmtsGetRdb(ts), trigName); + + nerrors += runScript(ts, NULL, trigH, installPrefixes.data, script, + arg1, -1); rpmtdFreeData(&installPrefixes); rpmScriptFree(script); headerFree(trigH); @@ -379,7 +385,7 @@ static matchFilesIter matchFilesIteratorFree(matchFilesIter mfi) */ static int runHandleTriggersInPkg(rpmts ts, rpmte te, Header h, rpmsenseFlags sense, rpmscriptTriggerModes tm, - int searchMode, int ti) + int searchMode, int ti, int arg1) { int nerrors = 0; rpmds rpmdsTriggers, rpmdsTrigger; @@ -434,7 +440,7 @@ static int runHandleTriggersInPkg(rpmts ts, rpmte te, Header h, rpmScriptSetNextFileFunc(script, inputFunc, mfi); nerrors += runScript(ts, NULL, h, installPrefixes.data, - script, 0, -1); + script, arg1, -1); rpmtdFreeData(&installPrefixes); rpmScriptFree(script); } @@ -493,6 +499,8 @@ rpmRC runFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense, char *pfx; size_t keylen; Header trigH; + const char * trigName = NULL; + int arg1 = 0; int (*matchFunc)(rpmts, rpmte, const char*, rpmsenseFlags sense); rpmTagVal priorityTag; rpmtriggers triggers = rpmtriggersCreate(10); @@ -564,12 +572,17 @@ rpmRC runFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense, } trigH = rpmdbGetHeaderAt(rpmtsGetRdb(ts), triggers->triggerInfo[i].hdrNum); + trigName = headerGetString(trigH, RPMTAG_NAME); + arg1 = rpmdbCountPackages(rpmtsGetRdb(ts), trigName); + if (tm == RPMSCRIPT_FILETRIGGER) nerrors += runHandleTriggersInPkg(ts, te, trigH, sense, tm, 0, - triggers->triggerInfo[i].tix); + triggers->triggerInfo[i].tix, + arg1); else nerrors += runHandleTriggersInPkg(ts, te, trigH, sense, tm, 1, - triggers->triggerInfo[i].tix); + triggers->triggerInfo[i].tix, + arg1); headerFree(trigH); } rpmtriggersFree(triggers); @@ -577,7 +590,7 @@ rpmRC runFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense, return (nerrors == 0) ? RPMRC_OK : RPMRC_FAIL; } -rpmRC runImmedFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense, +rpmRC runImmedFileTriggers(rpmts ts, rpmte te, int arg1, rpmsenseFlags sense, rpmscriptTriggerModes tm, int priorityClass) { int nerrors = 0; @@ -616,7 +629,8 @@ rpmRC runImmedFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense, } nerrors += runHandleTriggersInPkg(ts, te, trigH, sense, tm, 2, - triggers->triggerInfo[i].tix); + triggers->triggerInfo[i].tix, + arg1); } rpmtriggersFree(triggers); headerFree(trigH); diff --git a/lib/rpmtriggers.h b/lib/rpmtriggers.h index 5be7339662..e2e81459dc 100644 --- a/lib/rpmtriggers.h +++ b/lib/rpmtriggers.h @@ -65,6 +65,7 @@ rpmRC runFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense, /* Run file triggers in this te other package(s) set off. * @param ts transaction set * @param te transaction entry + * @param arg1 scriptlet argument 1 (number of instances of this pkg) * @param sense defines which triggers should be set off (triggerin, * triggerun, triggerpostun) * @param tm trigger mode, (filetrigger/transfiletrigger) @@ -75,7 +76,7 @@ rpmRC runFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense, * 0 to run all triggers */ RPM_GNUC_INTERNAL -rpmRC runImmedFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense, +rpmRC runImmedFileTriggers(rpmts ts, rpmte te, int arg1, rpmsenseFlags sense, rpmscriptTriggerModes tm, int priorityClass); #ifdef __cplusplus } diff --git a/tests/rpmscript.at b/tests/rpmscript.at index f210b0e5b4..8a07a9390f 100644 --- a/tests/rpmscript.at +++ b/tests/rpmscript.at @@ -403,13 +403,13 @@ filetriggerin(/foo*): /foo/hello-world /foo/zzzz -filetriggerin(/usr/bin*): 0 +filetriggerin(/usr/bin*): 1 /usr/bin/hello -filetriggerin(/usr/bin*): 0 +filetriggerin(/usr/bin*): 1 /usr/bin/hello -transfiletriggerin(/usr/bin*): 0 +transfiletriggerin(/usr/bin*): 1 /usr/bin/hello transfiletriggerin(/foo*): @@ -428,7 +428,7 @@ RPMTEST_CHECK([ runroot rpm -e hello-script hlinktest ], [0], -[transfiletriggerun(/usr/bin*): 0 +[transfiletriggerun(/usr/bin*): 1 /usr/bin/hello transfiletriggerun(/foo*): @@ -458,13 +458,13 @@ filetriggerpostun(/foo*): /foo/hello-world /foo/zzzz -filetriggerun(/usr/bin*): 0 +filetriggerun(/usr/bin*): 1 /usr/bin/hello -filetriggerpostun(/usr/bin*): 0 +filetriggerpostun(/usr/bin*): 1 /usr/bin/hello -transfiletriggerpostun(/usr/bin*): 0 +transfiletriggerpostun(/usr/bin*): 1 transfiletriggerpostun(/foo*): @@ -482,19 +482,80 @@ for v in 1.0 2.0 3.0; do done runroot rpm -U /build/RPMS/noarch/fakeshell-1.0-1.noarch.rpm +runroot rpm -U /build/RPMS/noarch/parallel-trigger-1.0-1.noarch.rpm + +RPMTEST_CHECK([ +runroot rpm -i /build/RPMS/noarch/parallel-1.0-1.noarch.rpm +], +[0], +[%filetriggerin: 1 +12 +%transfiletriggerin: 1 +12 +], +[]) + +RPMTEST_CHECK([ +runroot rpm -U /build/RPMS/noarch/parallel-2.0-1.noarch.rpm +], +[0], +[%transfiletriggerun: 1 +12 +%filetriggerin: 1 +12 +%filetriggerpostun: 1 +11 +%transfiletriggerin: 1 +12 +%transfiletriggerpostun: 1 +0 +], +[]) + +RPMTEST_CHECK([ +runroot rpm -U /build/RPMS/noarch/parallel-trigger-2.0-1.noarch.rpm +], +[0], +[%transfiletriggerun: 1 +12 +%filetriggerin: 2 +12 +%transfiletriggerin: 2 +12 +], +[]) + +RPMTEST_CHECK([ +runroot rpm -e parallel +], +[0], +[%transfiletriggerun: 1 +12 +%filetriggerpostun: 1 +12 +%transfiletriggerpostun: 1 +0 +], +[]) + +RPMTEST_CHECK([ +runroot rpm -e parallel-trigger +], +[0], +[], +[]) + +RPMTEST_CHECK([ runroot rpm -i \ /build/RPMS/noarch/parallel-1.0-1.noarch.rpm \ /build/RPMS/noarch/parallel-2.0-1.noarch.rpm \ /build/RPMS/noarch/parallel-3.0-1.noarch.rpm - -RPMTEST_CHECK([ runroot rpm -U /build/RPMS/noarch/parallel-trigger-1.0-1.noarch.rpm - ], [0], -[%filetriggerin: 0 +[%filetriggerin: 1 36 -%transfiletriggerin: 0 +%transfiletriggerin: 1 36 ], []) @@ -503,11 +564,11 @@ RPMTEST_CHECK([ runroot rpm -U /build/RPMS/noarch/parallel-trigger-2.0-1.noarch.rpm ], [0], -[%transfiletriggerun: 0 +[%transfiletriggerun: 1 36 -%filetriggerin: 0 +%filetriggerin: 2 36 -%transfiletriggerin: 0 +%transfiletriggerin: 2 36 ], [])