From ed61ee28d088299bbd5bc99d2cc104e3979ff32f Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Thu, 20 Jan 2022 15:54:46 +0200 Subject: [PATCH] Support relocatable packages in Lua scriptlets too (#1531) Pass relocatable package prefixes as RPM_INSTALL_PREFIX Lua table to Lua scriptlets, add a test-case. In Lua, indexes start at 1 rather than 0, so the numbers appear off by one which is annoying, but consistent within Lua and our other similar Lua constructs such as scriptlet arg. Fixes: #1531 --- docs/manual/lua.md | 4 ++++ lib/rpmscript.c | 15 +++++++++++++++ tests/Makefile.am | 1 + tests/data/SPECS/reloc.spec | 31 +++++++++++++++++++++++++++++++ tests/rpmi.at | 31 +++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+) create mode 100644 tests/data/SPECS/reloc.spec diff --git a/docs/manual/lua.md b/docs/manual/lua.md index c471e150c..3896c9a20 100644 --- a/docs/manual/lua.md +++ b/docs/manual/lua.md @@ -29,6 +29,10 @@ The point? Remember, Lua is embedded in rpm. This means the Lua scriptlets run i Scriptlet arguments are accessible from a global 'arg' table. Note: in Lua, indexes customarily start at 1 (one) instead of 0 (zero), and for the better or worse, the rpm implementation follows this practise. Thus the scriptlet arg indexes are off by one from general expectation based on traditional scriptlet arguments. The argument containing number of installed package instances is arg[2] and the similar argument for trigger targets is arg[3], whereas traditionally they are 1 and 2 (eg $1 and $2 in shell scripts). +Scriptlets of relocatable packages additionally carry a global +`RPM_INSTALL_PREFIX` table containing all the possible prefixes of the +package. (rpm >= 4.18.0) + While scriptlets shouldn't be allowed to fail normally, you can signal scriptlet failure status by using Lua's error(msg, [level]) function if you need to. As scriptlets run within the rpm process itself, care needs to be taken within the scripts - eg os.exit() must not be called (see ticket #167). In newer rpm versions (>= 4.9.0) this is not an issue as rpm protects itself by returning errors on unsafe os.exit() and posix.exec(). ## Lua macros diff --git a/lib/rpmscript.c b/lib/rpmscript.c index 978a3c6dd..f57f90c41 100644 --- a/lib/rpmscript.c +++ b/lib/rpmscript.c @@ -125,6 +125,16 @@ static rpmRC runLuaScript(rpmPlugins plugins, ARGV_const_t prefixes, lua_setfield(L, -2, "next_file"); } + if (prefixes) { + lua_newtable(L); + for (ARGV_const_t p = prefixes; p && *p; p++) { + int i = p - prefixes + 1; + lua_pushstring(L, *p); + lua_rawseti(L, -2, i); + } + lua_setglobal(L, "RPM_INSTALL_PREFIX"); + } + if (arg1 >= 0) argvAddNum(argvp, arg1); if (arg2 >= 0) @@ -165,6 +175,11 @@ static rpmRC runLuaScript(rpmPlugins plugins, ARGV_const_t prefixes, } free(scriptbuf); + if (prefixes) { + lua_pushnil(L); + lua_setglobal(L, "RPM_INSTALL_PREFIX"); + } + if (nextFileFunc) { lua_pushnil(L); lua_setfield(L, -2, "next_file"); diff --git a/tests/Makefile.am b/tests/Makefile.am index e7f484286..f78e17c3e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -75,6 +75,7 @@ EXTRA_DIST += data/SPECS/scriptfile.spec EXTRA_DIST += data/SPECS/selfconflict.spec EXTRA_DIST += data/SPECS/shebang.spec EXTRA_DIST += data/SPECS/suicidal.spec +EXTRA_DIST += data/SPECS/reloc.spec EXTRA_DIST += data/SPECS/replacetest.spec EXTRA_DIST += data/SPECS/triggers.spec EXTRA_DIST += data/SPECS/filetriggers.spec diff --git a/tests/data/SPECS/reloc.spec b/tests/data/SPECS/reloc.spec new file mode 100644 index 000000000..c565ad179 --- /dev/null +++ b/tests/data/SPECS/reloc.spec @@ -0,0 +1,31 @@ +Name: reloc +Version: 1.0 +Release: 1 +Summary: Testing relocation behavior +Group: Testing +License: GPL +Prefixes: /opt/bin /opt/etc /opt/lib +BuildArch: noarch + +%description +%{summary} + +%install +mkdir -p $RPM_BUILD_ROOT/opt/{bin,lib,etc} +touch $RPM_BUILD_ROOT/opt/bin/typo +touch $RPM_BUILD_ROOT/opt/lib/notlib +touch $RPM_BUILD_ROOT/opt/etc/conf + +%pre -p +for i, p in ipairs(RPM_INSTALL_PREFIX) do + print(i..": "..p) +end + +%post +echo 0: $RPM_INSTALL_PREFIX0 +echo 1: $RPM_INSTALL_PREFIX1 +echo 2: $RPM_INSTALL_PREFIX2 + +%files +%defattr(-,root,root,-) +/opt diff --git a/tests/rpmi.at b/tests/rpmi.at index cfc05dab6..b36a73219 100644 --- a/tests/rpmi.at +++ b/tests/rpmi.at @@ -690,6 +690,37 @@ runroot rpm -U --test --ignoreos --badreloc --relocate /usr=/opt \ []) AT_CLEANUP +AT_SETUP([rpm -i relocatable package]) +AT_KEYWORDS([install relocate]) +AT_CHECK([ +RPMDB_INIT + +runroot rpmbuild --quiet -bb /data/SPECS/reloc.spec +runroot rpmbuild --quiet -bb /data/SPECS/fakeshell.spec + +runroot rpm -U /build/RPMS/noarch/fakeshell-1.0-1.noarch.rpm +runroot rpm -U \ + /build/RPMS/noarch/reloc-1.0-1.noarch.rpm +runroot rpm -e reloc +runroot rpm -U --relocate /opt/bin=/bin \ + /build/RPMS/noarch/reloc-1.0-1.noarch.rpm +], +[0], +[1: /opt/bin +2: /opt/etc +3: /opt/lib +0: /opt/bin +1: /opt/etc +2: /opt/lib +1: /bin +2: /opt/etc +3: /opt/lib +0: /bin +1: /opt/etc +2: /opt/lib +], +[]) +AT_CLEANUP AT_SETUP([rpm -i with/without --excludedocs]) AT_KEYWORDS([install excludedocs]) AT_CHECK([