Skip to content

Commit

Permalink
Pass arg1 to file trigger scripts
Browse files Browse the repository at this point in the history
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 rpm-software-management#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.

Argument no. 2 (triggering package count) will be added in a separate
commit.

Related: rpm-software-management#2755
  • Loading branch information
dmnks committed Jan 22, 2024
1 parent 4ef45cd commit b4f4bee
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 35 deletions.
2 changes: 2 additions & 0 deletions docs/manual/file_triggers.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
26 changes: 14 additions & 12 deletions lib/psm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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. */
Expand All @@ -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. */
Expand Down Expand Up @@ -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;
Expand Down
28 changes: 21 additions & 7 deletions lib/rpmtriggers.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ int runPostUnTransFileTrigs(rpmts ts)
{
int i;
Header trigH;
const char * trigName = NULL;
int pkgCount = 0;
struct rpmtd_s installPrefixes;
rpmScript script;
rpmtriggers trigs = ts->trigs2run;
Expand All @@ -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);
pkgCount = rpmdbCountPackages(rpmtsGetRdb(ts), trigName);

nerrors += runScript(ts, NULL, trigH, installPrefixes.data, script,
pkgCount, -1);
rpmtdFreeData(&installPrefixes);
rpmScriptFree(script);
headerFree(trigH);
Expand Down Expand Up @@ -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, unsigned int pkgCount)
{
int nerrors = 0;
rpmds rpmdsTriggers, rpmdsTrigger;
Expand Down Expand Up @@ -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, pkgCount, -1);
rpmtdFreeData(&installPrefixes);
rpmScriptFree(script);
}
Expand Down Expand Up @@ -493,6 +499,8 @@ rpmRC runFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense,
char *pfx;
size_t keylen;
Header trigH;
const char * trigName = NULL;
int pkgCount = 0;
int (*matchFunc)(rpmts, rpmte, const char*, rpmsenseFlags sense);
rpmTagVal priorityTag;
rpmtriggers triggers = rpmtriggersCreate(10);
Expand Down Expand Up @@ -564,20 +572,25 @@ rpmRC runFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense,
}

trigH = rpmdbGetHeaderAt(rpmtsGetRdb(ts), triggers->triggerInfo[i].hdrNum);
trigName = headerGetString(trigH, RPMTAG_NAME);
pkgCount = rpmdbCountPackages(rpmtsGetRdb(ts), trigName);

if (tm == RPMSCRIPT_FILETRIGGER)
nerrors += runHandleTriggersInPkg(ts, te, trigH, sense, tm, 0,
triggers->triggerInfo[i].tix);
triggers->triggerInfo[i].tix,
pkgCount);
else
nerrors += runHandleTriggersInPkg(ts, te, trigH, sense, tm, 1,
triggers->triggerInfo[i].tix);
triggers->triggerInfo[i].tix,
pkgCount);
headerFree(trigH);
}
rpmtriggersFree(triggers);

return (nerrors == 0) ? RPMRC_OK : RPMRC_FAIL;
}

rpmRC runImmedFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense,
rpmRC runImmedFileTriggers(rpmts ts, rpmte te, int pkgCount, rpmsenseFlags sense,
rpmscriptTriggerModes tm, int priorityClass)
{
int nerrors = 0;
Expand Down Expand Up @@ -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,
pkgCount);
}
rpmtriggersFree(triggers);
headerFree(trigH);
Expand Down
3 changes: 2 additions & 1 deletion lib/rpmtriggers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 pkgCount number of instances of this package (scriptlet arg 1)
* @param sense defines which triggers should be set off (triggerin,
* triggerun, triggerpostun)
* @param tm trigger mode, (filetrigger/transfiletrigger)
Expand All @@ -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 pkgCount, rpmsenseFlags sense,
rpmscriptTriggerModes tm, int priorityClass);
#ifdef __cplusplus
}
Expand Down
91 changes: 76 additions & 15 deletions tests/rpmscript.at
Original file line number Diff line number Diff line change
Expand Up @@ -403,13 +403,13 @@ filetriggerin(/foo*)<lua>:
/foo/hello-world
/foo/zzzz

filetriggerin(/usr/bin*): 0
filetriggerin(/usr/bin*): 1
/usr/bin/hello

filetriggerin(/usr/bin*)<lua>: 0
filetriggerin(/usr/bin*)<lua>: 1
/usr/bin/hello

transfiletriggerin(/usr/bin*): 0
transfiletriggerin(/usr/bin*): 1
/usr/bin/hello

transfiletriggerin(/foo*):
Expand All @@ -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*):
Expand Down Expand Up @@ -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*):

Expand All @@ -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
],
[])
Expand All @@ -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
],
[])
Expand Down

0 comments on commit b4f4bee

Please sign in to comment.