Make missing ZFS config file failures into warnings, bug #438200
[genkernel.git] / gen_funcs.sh
index 0d6da0eaf58045d6e0e34f35be97af246836918e..4f0a0fc25f9cf44b83ae3bbc2e75562f84145c1a 100755 (executable)
@@ -1,4 +1,5 @@
 #!/bin/bash
+# $Id$
 
 isTrue() {
        case "$1" in
@@ -21,6 +22,7 @@ isTrue() {
        return 1
 }
 
+setColorVars() {
 if isTrue ${USECOLOR}
 then
        GOOD=$'\e[32;01m'
@@ -37,13 +39,15 @@ else
        BOLD=''
        UNDER=''
 fi
+}
+setColorVars
 
 dump_debugcache() {
        TODEBUGCACHE=0
-       echo "${DEBUGCACHE}" >> ${DEBUGFILE}
+       echo "${DEBUGCACHE}" >> ${LOGFILE}
 }
 
-# print_info(debuglevel, print [, newline [, prefixline [, forcefile ] ] ])
+# print_info(loglevel, print [, newline [, prefixline [, forcefile ] ] ])
 print_info() {
        local NEWLINE=1
        local FORCEFILE=0
@@ -88,9 +92,9 @@ print_info() {
                fi
        fi
 
-       # PRINT TO SCREEN ONLY IF PASSED DEBUGLEVEL IS HIGHER THAN
+       # PRINT TO SCREEN ONLY IF PASSED LOGLEVEL IS HIGHER THAN
        # OR EQUAL TO SET DEBUG LEVEL
-       if [ "$1" -lt "${DEBUGLEVEL}" -o "$1" -eq "${DEBUGLEVEL}" ]
+       if [ "$1" -lt "${LOGLEVEL}" -o "$1" = "${LOGLEVEL}" ]
        then
                SCRPRINT='1'
        fi
@@ -102,7 +106,7 @@ print_info() {
        fi
 
        # STRUCTURE DATA TO BE OUTPUT TO SCREEN, AND OUTPUT IT
-       if [ "${SCRPRINT}" -eq '1' ]
+       if [ "${SCRPRINT}" = '1' ]
        then
                if [ "${PREFIXLINE}" = '1' ]
                then
@@ -120,7 +124,7 @@ print_info() {
        fi
 
        # STRUCTURE DATA TO BE OUTPUT TO FILE, AND OUTPUT IT
-       if [ "${SCRPRINT}" -eq '1' -o "${FORCEFILE}" -eq '1' ]
+       if [ "${SCRPRINT}" = '1' -o "${FORCEFILE}" = '1' ]
        then
                STRR=${2//${WARN}/}
                STRR=${STRR//${BAD}/}
@@ -136,16 +140,16 @@ print_info() {
 
                if [ "${NEWLINE}" = '0' ]
                then
-                       if [ "${TODEBUGCACHE}" -eq 1 ]; then
+                       if [ "${TODEBUGCACHE}" = '1' ]; then
                                DEBUGCACHE="${DEBUGCACHE}${STR}"
                        else
-                               echo -ne "${STR}" >> ${DEBUGFILE}
-                       fi      
+                               echo -ne "${STR}" >> ${LOGFILE}
+                       fi
                else
-                       if [ "${TODEBUGCACHE}" -eq 1 ]; then
+                       if [ "${TODEBUGCACHE}" = '1' ]; then
                                DEBUGCACHE="${DEBUGCACHE}${STR}"$'\n'
                        else
-                               echo "${STR}" >> ${DEBUGFILE}
+                               echo "${STR}" >> ${LOGFILE}
                        fi
                fi
        fi
@@ -174,9 +178,8 @@ var_replace()
   # in the later sed expression
   local SAFE_VAR
   SAFE_VAR=`echo "${2}" | sed -e 's/\([\/\.]\)/\\\\\\1/g'`
-  
+
   echo "${3}" | sed -e "s/%%${1}%%/${SAFE_VAR}/g" -
-  echo "${3}" | sed -e "s/%%${1}%%/${SAFE_VAR}/g" >> /tmp/out
 }
 
 arch_replace() {
@@ -188,7 +191,10 @@ cache_replace() {
 }
 
 clear_log() {
-       [ -f "${DEBUGFILE}" ] && echo > "${DEBUGFILE}"
+    if [ -f "${LOGFILE}" ]
+    then
+       (echo > "${LOGFILE}") 2>/dev/null || small_die "Genkernel: Could not write to ${LOGFILE}."
+    fi
 }
 
 gen_die() {
@@ -198,52 +204,324 @@ gen_die() {
        then
                print_error 1 "ERROR: ${1}"
        fi
-       echo
-       print_info 1 "-- Grepping log... --"
-       echo
+       print_error 1 ''
+       print_error 1 "-- Grepping log... --"
+       print_error 1 ''
 
        if isTrue ${USECOLOR}
        then
-               GREP_COLOR='1' grep -B5 -E --colour=always "([Ww][Aa][Rr][Nn][Ii][Nn][Gg]|[Ee][Rr][Rr][Oo][Rr][ :,!]|[Ff][Aa][Ii][Ll][Ee]?[Dd]?)" ${DEBUGFILE}
+               GREP_COLOR='1' grep -B5 -E --colour=always "([Ww][Aa][Rr][Nn][Ii][Nn][Gg]|[Ee][Rr][Rr][Oo][Rr][ :,!]|[Ff][Aa][Ii][Ll][Ee]?[Dd]?)" ${LOGFILE} \
+                               | sed -s "s|^\(*\)\?|${BAD}*${NORMAL}|"
        else
-               grep -B5 -E "([Ww][Aa][Rr][Nn][Ii][Nn][Gg]|[Ee][Rr][Rr][Oo][Rr][ :,!]|[Ff][Aa][Ii][Ll][Ee]?[Dd]?)" ${DEBUGFILE}
+               grep -B5 -E "([Ww][Aa][Rr][Nn][Ii][Nn][Gg]|[Ee][Rr][Rr][Oo][Rr][ :,!]|[Ff][Aa][Ii][Ll][Ee]?[Dd]?)" ${LOGFILE}
        fi
-       echo
-       print_info 1 "-- End log... --"
-       echo
-       print_info 1 "Please consult ${DEBUGFILE} for more information and any"
-       print_info 1 "errors that were reported above."
-       echo
-       print_info 1 "Report any genkernel bugs to bugs.gentoo.org and"
-       print_info 1 "assign your bug to genkernel@gentoo.org. Please include"
-       print_info 1 "as much information as you can in your bug report; attaching"
-       print_info 1 "${DEBUGFILE} so that your issue can be dealt with effectively."
-       print_info 1 ''
-       print_info 1 'Please do *not* report compilation failures as genkernel bugs!'
-       print_info 1 ''
+       print_error 1 ''
+       print_error 1 "-- End log... --"
+       print_error 1 ''
+       print_error 1 "Please consult ${LOGFILE} for more information and any"
+       print_error 1 "errors that were reported above."
+       print_error 1 ''
+       print_error 1 "Report any genkernel bugs to bugs.gentoo.org and"
+       print_error 1 "assign your bug to genkernel@gentoo.org. Please include"
+       print_error 1 "as much information as you can in your bug report; attaching"
+       print_error 1 "${LOGFILE} so that your issue can be dealt with effectively."
+       print_error 1 ''
+       print_error 1 'Please do *not* report compilation failures as genkernel bugs!'
+       print_error 1 ''
+
+       # Cleanup temp dirs and caches if requested
+       cleanup
        exit 1
 }
 
-has_loop() {
-       dmesg | egrep -q '^loop:'
-       if [ -e '/dev/loop0' -o -e '/dev/loop/0' -a $? ]
+isBootRO()
+{
+       return $(awk '( $2 == "'${BOOTDIR}'" && $4 ~ /(^|,)ro(,|$)/){ I=1; exit }END{print !I }' /proc/mounts);
+}
+
+setup_cache_dir()
+{
+
+[ ! -d "${CACHE_DIR}" ] && mkdir -p "${CACHE_DIR}"
+
+if [ "${CLEAR_CACHE_DIR}" == 'yes' ]
+then
+       print_info 1 "Clearing cache dir contents from ${CACHE_DIR}"
+       while read i
+       do
+               print_info 1 "   >> removing ${i}"
+               rm "${i}"
+       done < <(find "${CACHE_DIR}" -maxdepth 1 -type f -name '*.tar.*' -o -name '*.bz2')
+fi
+
+}
+
+clear_tmpdir()
+{
+if isTrue ${CMD_INSTALL}
+then
+       TMPDIR_CONTENTS=`ls ${TMPDIR}`
+       print_info 1 "Removing tmp dir contents"
+       for i in ${TMPDIR_CONTENTS}
+       do
+               print_info 1 "   >> removing ${i}"
+               rm ${TMPDIR}/${i}
+       done
+fi
+}
+
+#
+# Function to copy various kernel boot image products to the boot directory,
+# preserve a generation of old images (just like the manual kernel build's
+# "make install" does), and maintain the symlinks (if enabled).
+#
+# Arguments:
+#     $1  Symlink name.  Symlink on the boot directory. Path not included.
+#     $2  Source image.  Fully qualified path name of the source image.
+#     $3  Dest image.    Name of the destination image in the boot directory,
+#         no path included.  This script pushd's into ${BOOTDIR} in order to
+#         create relative symlinks just like the manual kernel build.
+#
+# - JRG
+#
+copy_image_with_preserve() {
+       local symlinkName=$1
+       local newSrceImage=$2
+       local fullDestName=$3
+
+       local currDestImage
+       local prevDestImage
+       local currDestImageExists=0
+       local prevDestImageExists=0
+
+       print_info 4 "Copying new ${symlinkName} image, " 0
+
+       # Old product might be a different version.  If so, we need to read
+       # the symlink to see what it's name is, if there are symlinks.
+       cd ${KERNEL_OUTPUTDIR}
+       if [ "${SYMLINK}" = '1' ]
        then
-               # We found devfs or standard dev loop device, assume
-               # loop is compiled into the kernel or the module is loaded
-               return 0
+               print_info 4 "automatically managing symlinks and old images." 1 0
+               if [ -e "${BOOTDIR}/${symlinkName}" ]
+               then
+                       # JRG: Do I need a special case here for when the standard symlink
+                       # name is, in fact, not a symlink?
+                       currDestImage=`readlink --no-newline ${BOOTDIR}/${symlinkName}`
+                       print_info 5 "  Current ${symlinkName} symlink exists:"
+                       print_info 5 "    ${currDestImage}"
+               else
+                       currDestImage="${fullDestName}"
+                       print_info 5 "  Current ${symlinkName} symlink did not exist."
+                       print_info 5 "    Defaulted to: ${currDestImage}"
+               fi
+               if [ -e "${BOOTDIR}/${currDestImage}" ]
+               then
+                       currDestImageExists=1
+                       print_info 5 "  Actual image file exists."
+               fi
+
+               if [ -e "${BOOTDIR}/${symlinkName}.old" ]
+               then
+                       # JRG: Do I need a special case here for when the standard symlink
+                       # name is, in fact, not a symlink?
+                       prevDestImage=`readlink --no-newline ${BOOTDIR}/${symlinkName}.old`
+                       print_info 5 "  Old ${symlinkName} symlink exists:"
+                       print_info 5 "    ${prevDestImage}"
+               else
+                       prevDestImage="${fullDestName}.old"
+                       print_info 5 "  Old ${symlinkName} symlink did not exist."
+                       print_info 5 "    Defaulted to: ${prevDestImage}"
+               fi
+               if [ -e "${BOOTDIR}/${prevDestImage}" ]
+               then
+                       prevDestImageExists=1
+                       print_info 5 "  Actual old image file exists."
+               fi
+       else
+               print_info 4 "symlinks not being handled by genkernel." 1 0
+               currDestImage="${fullDestName}"
+               prevDestImage="${fullDestName}.old"
+       fi
+
+       # When symlinks are not being managed by genkernel, old symlinks might
+    # still be useful.  Leave 'em alone unless managed.
+       if [ "${SYMLINK}" = '1' ]
+       then
+               print_info 5 "  Deleting old symlinks, if any."
+               rm -f "${BOOTDIR}/${symlinkName}"
+               rm -f "${BOOTDIR}/${symlinkName}.old"
+       fi
+
+       # We only erase the .old image when it is the exact same version as the
+       # current and new images.  Different version .old (and current) images are
+       # left behind.  This is consistent with how "make install" of the manual
+       # kernel build works.
+       if [ "${currDestImage}" == "${fullDestName}" ]
+       then
+               #
+               # Case for new and currrent of the same base version.
+               #
+               print_info 5 "  Same base version.  May have to delete old image to make room."
+
+               if [ "${currDestImageExists}" = '1' ]
+               then
+                       if [ -e "${BOOTDIR}/${currDestImage}.old" ]
+                       then
+                               print_info 5 "  Deleting old identical version ${symlinkName}."
+                               rm -f "${BOOTDIR}/${currDestImage}.old"
+                       fi
+                       print_info 5 "  Moving ${BOOTDIR}/${currDestImage}"
+                       print_info 5 "    to ${BOOTDIR}/${currDestImage}.old"
+                       mv "${BOOTDIR}/${currDestImage}" "${BOOTDIR}/${currDestImage}.old" ||
+                           gen_die "Could not rename the old ${symlinkName} image!"
+                       prevDestImage="${currDestImage}.old"
+                       prevDestImageExists=1
+               fi
        else
-               return 1
+               #
+               # Case for new / current not of the same base version.
+               #
+               print_info 5 "  Different base version.  Do not delete old images."
+               prevDestImage="${currDestImage}"
+               currDestImage="${fullDestName}"
+       fi
+
+       print_info 5 "  Copying ${symlinkName}: ${newSrceImage}"
+       print_info 5 "    to ${BOOTDIR}/${currDestImage}"
+       cp "${newSrceImage}" "${BOOTDIR}/${currDestImage}" ||
+           gen_die "Could not copy the ${symlinkName} image to ${BOOTDIR}!"
+
+       if [ "${SYMLINK}" = '1' ]
+       then
+               print_info 5 "  Make new symlink(s) (from ${BOOTDIR}):"
+               print_info 5 "    ${symlinkName} -> ${currDestImage}"
+               pushd ${BOOTDIR} >/dev/null
+               ln -s "${currDestImage}" "${symlinkName}" || 
+                   gen_die "Could not create the ${symlinkName} symlink!"
+               if [ "${prevDestImageExists}" = '1' ]
+               then
+                       print_info 5 "    ${symlinkName}.old -> ${prevDestImage}"
+                       ln -s "${prevDestImage}" "${symlinkName}.old" ||
+                           gen_die "Could not create the ${symlinkName}.old symlink!"
+               fi
+               popd >/dev/null
        fi
 }
 
-isBootRO()
-{
-       for mo in `grep ' /boot ' /proc/mounts | cut -d ' ' -f 4 | sed -e 's/,/ /'`
+#
+# Helper function to allow command line arguments to override configuration
+# file specified values and to apply defaults.
+#
+# Arguments:
+#     $1  Argument type:
+#           1  Switch type arguments (e.g., --color / --no-color).
+#           2  Value type arguments (e.g., --debuglevel=5).
+#     $2  Config file variable name.
+#     $3  Command line variable name.
+#     $4  Default.  If both the config file variable and the command line
+#         option are not present, then the config file variable is set to
+#         this default value.  Optional.
+#
+# The order of priority of these three sources (highest first) is:
+#     Command line, which overrides
+#     Config file (/etc/genkernel.conf), which overrides
+#     Default.
+#
+# Arguments $2 and $3 are variable *names*, not *values*.  This function uses
+# various forms of indirection to access the values.
+#
+# For switch type arguments, all forms of "True" are converted to a numeric 1
+# and all forms of "False" (everything else, really) to a numeric 0.
+#
+# - JRG
+#
+set_config_with_override() {
+       local VarType=$1
+       local CfgVar=$2
+       local OverrideVar=$3
+       local Default=$4
+       local Result
+
+       #
+       # Syntax check the function arguments.
+       #
+       case "$VarType" in
+               BOOL|STRING)
+                       ;;
+               *)
+                       gen_die "Illegal variable type \"$VarType\" passed to set_config_with_override()."
+                       ;;
+       esac
+
+       if [ -n "${!OverrideVar}" ]
+       then
+               Result=${!OverrideVar}
+               if [ -n "${!CfgVar}" ]
+               then
+                       print_info 5 "  $CfgVar overridden on command line to \"$Result\"."
+               else
+                       print_info 5 "  $CfgVar set on command line to \"$Result\"."
+               fi
+       else
+               if [ -n "${!CfgVar}" ]
+               then
+                       Result=${!CfgVar}
+                       # we need to set the CMD_* according to configfile...
+                       eval ${OverrideVar}=\"${Result}\"
+                       print_info 5 "  $CfgVar set in config file to \"${Result}\"."
+               else
+                       if [ -n "$Default" ]
+                       then
+                               Result=${Default}
+                               # set OverrideVar to Result, otherwise CMD_* may not be initialized...
+                               eval ${OverrideVar}=\"${Result}\"
+                               print_info 5 "  $CfgVar defaulted to \"${Result}\"."
+                       else
+                               print_info 5 "  $CfgVar not set."
+                       fi
+               fi
+       fi
+
+       if [ "${VarType}" = BOOL ]
+       then
+               if isTrue "${Result}"
+               then
+                       Result=1
+               else
+                       Result=0
+               fi
+       fi
+
+       eval ${CfgVar}=\"${Result}\"
+}
+
+check_distfiles() {
+       for i in $BUSYBOX_SRCTAR $MULTIPATH_SRCTAR $LVM_SRCTAR $DMRAID_SRCTAR $ISCSI_SRCTAR $GPG_SRCTAR
        do
-               if [ "x${mo}x" == "xrox" ]
+               if [ ! -f "${i}" ]
                then
-                       return 0
+                       small_die "Could not find source tarball ${i}. Please refetch."
                fi
        done
-       return 1
+}
+
+find_kernel_binary() {
+       local kernel_binary=$*
+       local curdir=$(pwd)
+
+       cd "${KERNEL_OUTPUTDIR}"
+       for i in ${kernel_binary}
+       do
+               if [ -e "${i}" ]
+               then
+                       tmp_kernel_binary=$i
+                       break
+               fi
+       done
+#      if [ -z "${tmp_kernel_binary}" ]
+#      then
+#              gen_die "Cannot locate kernel binary!"
+#      fi
+       cd "${curdir}"
+       echo "${tmp_kernel_binary}"
 }