From 7561770d43cf1cb0d988c9f095f924aac13ba60a Mon Sep 17 00:00:00 2001 From: Mark Hatle Date: Thu, 10 Nov 2011 10:30:21 -0600 Subject: [PATCH] rootfs_rpm.bbclass: Enable pre and post install scripts [YOCTO #1755] We change the want the RPM rootfs install works to install pre and post install scripts. The new method uses a script helper that is invoked by RPM outside of the normal chroot. The wrapper is dynamically generated prior to the install starting. It will check the return code of the script. If the script fails, it will store a copy to be executed on the first system boot. This is similar to the previous mechanism. In addition, a line of debug was added to the scripts as written by package_rpm to list which package and which script for later debugging, if necessary. (From OE-Core rev: 3e7120d6a9fd5e46214673d0a6e1085a7314ff42) (From OE-Core rev: 5d74a2bbe036cf586b76aef0d9907ecb3d4a5f1d) Signed-off-by: Mark Hatle Signed-off-by: Richard Purdie --- meta/classes/package_rpm.bbclass | 33 +++- meta/classes/rootfs_rpm.bbclass | 25 +-- .../rpm/rpm/rpm-scriptletexechelper.patch | 159 ++++++++++++++++++ meta/recipes-devtools/rpm/rpm_5.4.0.bb | 3 +- 4 files changed, 199 insertions(+), 21 deletions(-) create mode 100644 meta/recipes-devtools/rpm/rpm/rpm-scriptletexechelper.patch diff --git a/meta/classes/package_rpm.bbclass b/meta/classes/package_rpm.bbclass index 2679e9f480..e4e80984fc 100644 --- a/meta/classes/package_rpm.bbclass +++ b/meta/classes/package_rpm.bbclass @@ -382,13 +382,39 @@ package_install_internal_rpm () { cat ${target_rootfs}/install/install_solution.manifest > ${target_rootfs}/install/total_solution.manifest cat ${target_rootfs}/install/install_multilib_solution.manifest >> ${target_rootfs}/install/total_solution.manifest + # Construct install scriptlet wrapper + cat << EOF > ${WORKDIR}/scriptlet_wrapper +#!/bin/bash + +export PATH="${PATH}" +export D="${target_rootfs}" +export OFFLINE_ROOT="\$D" +export IPKG_OFFLINE_ROOT="\$D" +export OPKG_OFFLINE_ROOT="\$D" + +\$2 \$1/\$3 \$4 +if [ \$? -ne 0 ]; then + mkdir -p \$1/etc/rpm-postinsts + num=100 + while [ -e \$1/etc/rpm-postinsts/\${num} ]; do num=\$((num + 1)); done + echo "#!\$2" > \$1/etc/rpm-postinsts/\${num} + echo "# Arg: \$4" >> \$1/etc/rpm-postinsts/\${num} + cat \$1/\$3 >> \$1/etc/rpm-postinsts/\${num} + chmod +x \$1/etc/rpm-postinsts/\${num} +fi +EOF + + chmod 0755 ${WORKDIR}/scriptlet_wrapper + # Attempt install ${RPM} --root ${target_rootfs} \ --predefine "_rpmds_sysinfo_path ${target_rootfs}/etc/rpm/sysinfo" \ --predefine "_rpmrc_platform_path ${target_rootfs}/etc/rpm/platform" \ + -D "_var ${localstatedir}" \ -D "_dbpath ${rpmlibdir}" \ - --noscripts --notriggers --noparentdirs --nolinktos --replacepkgs \ + --noparentdirs --nolinktos --replacepkgs \ -D "__dbi_txn create nofsync private" \ + -D "_cross_scriptlet_wrapper ${WORKDIR}/scriptlet_wrapper" \ -Uhv ${target_rootfs}/install/total_solution.manifest } @@ -685,6 +711,7 @@ python write_specfile () { elif script == 'postrm': spec_scriptlets_bottom.append('%%postun -n %s' % splitname) scriptvar = wrap_uninstall(scriptvar) + spec_scriptlets_bottom.append('# %s - %s' % (splitname, script)) spec_scriptlets_bottom.append(scriptvar) spec_scriptlets_bottom.append('') @@ -762,19 +789,23 @@ python write_specfile () { if srcpreinst: spec_scriptlets_top.append('%pre') + spec_scriptlets_top.append('# %s - preinst' % srcname) spec_scriptlets_top.append(srcpreinst) spec_scriptlets_top.append('') if srcpostinst: spec_scriptlets_top.append('%post') + spec_scriptlets_top.append('# %s - postinst' % srcname) spec_scriptlets_top.append(srcpostinst) spec_scriptlets_top.append('') if srcprerm: spec_scriptlets_top.append('%preun') + spec_scriptlets_top.append('# %s - prerm' % srcname) scriptvar = wrap_uninstall(srcprerm) spec_scriptlets_top.append(scriptvar) spec_scriptlets_top.append('') if srcpostrm: spec_scriptlets_top.append('%postun') + spec_scriptlets_top.append('# %s - postrm' % srcname) scriptvar = wrap_uninstall(srcpostrm) spec_scriptlets_top.append(scriptvar) spec_scriptlets_top.append('') diff --git a/meta/classes/rootfs_rpm.bbclass b/meta/classes/rootfs_rpm.bbclass index 9f50764886..9530e1b972 100644 --- a/meta/classes/rootfs_rpm.bbclass +++ b/meta/classes/rootfs_rpm.bbclass @@ -20,8 +20,6 @@ do_rootfs[depends] += "opkg-native:do_populate_sysroot" do_rootfs[recrdeptask] += "do_package_write_rpm" -AWKPOSTINSTSCRIPT = "${COREBASE}/scripts/rootfs_rpm-extract-postinst.awk" - RPM_PREPROCESS_COMMANDS = "package_update_index_rpm; package_generate_rpm_conf; " RPM_POSTPROCESS_COMMANDS = "" @@ -108,19 +106,9 @@ EOF ${ROOTFS_POSTINSTALL_COMMAND} - mkdir -p ${IMAGE_ROOTFS}/etc/rpm-postinsts/ - ${RPM} --root ${IMAGE_ROOTFS} -D '_dbpath ${rpmlibdir}' -qa \ - -D "__dbi_txn create nofsync private" \ - --qf 'Name: %{NAME}\n%|POSTIN?{postinstall scriptlet%|POSTINPROG?{ (using %{POSTINPROG})}|:\n%{POSTIN}\n}:{%|POSTINPROG?{postinstall program: %{POSTINPROG}\n}|}|' \ - > ${IMAGE_ROOTFS}/etc/rpm-postinsts/combined - awk -f ${AWKPOSTINSTSCRIPT} < ${IMAGE_ROOTFS}/etc/rpm-postinsts/combined - rm ${IMAGE_ROOTFS}/etc/rpm-postinsts/combined - - for i in ${IMAGE_ROOTFS}/etc/rpm-postinsts/*.sh; do - if [ -f $i ] && sh $i; then - # rm $i - mv $i $i.done - fi + # Report delayed package scriptlets + for i in ${IMAGE_ROOTFS}/etc/rpm-postinsts/*; do + echo "Delayed package scriptlet: `head -n 3 $i | tail -n 1`" done install -d ${IMAGE_ROOTFS}/${sysconfdir}/rcS.d @@ -128,11 +116,10 @@ EOF i=\$i cat > ${IMAGE_ROOTFS}${sysconfdir}/rcS.d/S${POSTINSTALL_INITPOSITION}configure << EOF #!/bin/sh -for i in /etc/rpm-postinsts/*.sh; do +for i in /etc/rpm-postinsts/*; do echo "Running postinst $i..." - if [ -f $i ] && sh $i; then - # rm $i - mv $i $i.done + if [ -f $i ] && $i; then + rm $i else echo "ERROR: postinst $i failed." fi diff --git a/meta/recipes-devtools/rpm/rpm/rpm-scriptletexechelper.patch b/meta/recipes-devtools/rpm/rpm/rpm-scriptletexechelper.patch new file mode 100644 index 0000000000..e4db0e4211 --- /dev/null +++ b/meta/recipes-devtools/rpm/rpm/rpm-scriptletexechelper.patch @@ -0,0 +1,159 @@ +Enable a cross-install scriptlet helper. + +The helper is called from outside of the chroot with the arguments: + +