#!/usr/bin/env bash # # Stage4 addons setup script # ############################################################################### # Support stage4 addons residing under '/opt/openslx/addons'. # This script will loop over all addons found, in the form of # directories containing directory structures relative to '/' # # Additionally addons are expected to provide: # * /addon-required -> script to check whether the # addon should be installed (exit 0) or not (exit 1). # # * /opt/openslx/etc/.whiteout -> list of files # that were removed during the addon installation and thus need to be # removed after the addon was installed. # # * /opt/openslx/etc/ ld.so.cache -> ld cache containing # the newly installed libraries. CAVE: multiple addons -> ld cache combination # ### CURRENTLY NOT EXECUTED # * /addon-init -> script that will be automatically # be executed after the addon was installed. # NOTE: question remains if this should be done within stage3 # or by chroot'ing into the stage4 before executing it. ### CURRENTLY NOT EXECUTED: Since whiteouts could be handled for _all_addons type emergency_shell >/dev/null 2>&1 || . /lib/dracut-lib.sh # Check if we even have any addons to process if [ ! -d "$NEWROOT/opt/openslx/addons" ]; then info "No stage4 addons found." return 0 fi setup_addons() { local ADDONS_DIR="$NEWROOT/opt/openslx/addons/" cd "$ADDONS_DIR" || return 1 for ADDON in *; do if ! setup_addon "$ADDON"; then info "Failed to setup $ADDON" fi done } setup_addon() { [ -z "$1" -o ! -d "$ADDONS_DIR/$1" ] && return 1 local ADDON="$1" cd "$ADDONS_DIR/$ADDON" || return 1 if ! bash addon-required 2>&1 ; then info "'$ADDONS_DIR/$ADDON/addon-required' missing or returned non-zero, skipping..." return 1 fi for entry in $(find * -not -wholename "addon-*" 2>/dev/null); do if [ -d "$entry" ]; then [ -d "/$entry" ] || mkdir -p "/${entry}" continue fi local dir=${entry%/*} [ -d "$NEWROOT/$dir" ] || mkdir -p "$NEWROOT/$dir" if [ -f "$entry" -a ! -L "$entry" ]; then if [ ! -e "$NEWROOT/${entry}" ] || ! diff -q "$entry" "$NEWROOT/${entry}"; then mv -f -- "$entry" "$NEWROOT/${entry}" fi else # either block dev, char dev or a symlink, just overwrite them "blindly" mv -f -- "$entry" "$NEWROOT/${entry}" fi done # post merge: remove whiteouts from filesystem for WHITEOUT in "$NEWROOT/opt/openslx/etc/"*.whiteout; do [ -e "$WHITEOUT" ] || continue while read line; do rm -f "${NEWROOT}/${line}" done < "$WHITEOUT" done # finally update ld.so.cache expected to be under /opt/openslx/etc/.ld.so.cache # NOTE: if we have more than one addon in the future, we need to be extra # careful with prebuilt ld.caches since they need to match *ALL* addons local ADDON_LD_CACHE="$NEWROOT/opt/openslx/etc/$ADDON.ld.so.cache" if [ ! -e "$ADDON_LD_CACHE" ] || ! mv -f -- "$ADDON_LD_CACHE" "$NEWROOT/etc/ld.so.cache" ; then # Using prebuilt ld cache failed, try hard to find a ldconfig... for LDCONFIG in "$(type -p ldconfig 2>/dev/null)" "${NEWROOT}/sbin/ldconfig.real"; do if [ -x "$LDCONFIG" ] && "$LDCONFIG" -r "$NEWROOT"; then return 0 fi done # try with chroot if we have it local CHROOT_PATH="$(type -p chroot 2>/dev/null)" if [ -x "$CHROOT_PATH" ] && "$CHROOT_PATH" "$NEWROOT" ldconfig; then return 0 fi # very bad indeed, libraries won't be registered in the cache ... warn "Failed to find 'ldconfig' to rebuild the addon's missing ld.so.cache..." return 1 fi } if ! setup_addons; then warn "Failed to fully setup some addons! They will likely malfunction..." fi