#!/bin/bash
+# $Id$
isTrue() {
case "$1" in
return 1
}
-
+setColorVars() {
if isTrue ${USECOLOR}
then
-# COLS="`stty size 2> /dev/null`"
-# COLS="`getcols ${COLS}`"
-# COLS=$((${COLS} - 7))
-# ENDCOL=$'\e[A\e['${COLS}'G' # Now, ${ENDCOL} will move us to the end of the
- # column; irregardless of character width
GOOD=$'\e[32;01m'
WARN=$'\e[33;01m'
BAD=$'\e[31;01m'
BOLD=$'\e[0;01m'
UNDER=$'\e[4m'
else
- GOOD=""
- WARN=""
- BAD=""
- NORMAL=""
- BOLD=""
- UNDER=""
+ GOOD=''
+ WARN=''
+ BAD=''
+ NORMAL=''
+ BOLD=''
+ UNDER=''
fi
+}
+setColorVars
+dump_debugcache() {
+ TODEBUGCACHE=0
+ 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
local PREFIXLINE=1
local SCRPRINT=0
- local STR=""
+ local STR=''
# NOT ENOUGH ARGS
- if [ "$#" -lt "2" ] ; then return 1; fi
+ if [ "$#" -lt '2' ] ; then return 1; fi
# IF 3 OR MORE ARGS, CHECK IF WE WANT A NEWLINE AFTER PRINT
- if [ "$#" -gt "2" ]
+ if [ "$#" -gt '2' ]
then
if isTrue "$3"
then
- NEWLINE="1";
+ NEWLINE='1';
else
- NEWLINE="0";
+ NEWLINE='0';
fi
fi
# IF 4 OR MORE ARGS, CHECK IF WE WANT TO PREFIX WITH A *
- if [ "$#" -gt "3" ]
+ if [ "$#" -gt '3' ]
then
if isTrue "$4"
then
- PREFIXLINE="1"
+ PREFIXLINE='1'
else
- PREFIXLINE="0"
+ PREFIXLINE='0'
fi
fi
# IF 5 OR MORE ARGS, CHECK IF WE WANT TO FORCE OUTPUT TO DEBUG
# FILE EVEN IF IT DOESN'T MEET THE MINIMUM DEBUG REQS
- if [ "$#" -gt "4" ]
+ if [ "$#" -gt '4' ]
then
if isTrue "$5"
then
- FORCEFILE="1"
+ FORCEFILE='1'
else
- FORCEFILE="0"
+ FORCEFILE='0'
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"
+ SCRPRINT='1'
fi
# RETURN IF NOT OUTPUTTING ANYWHERE
- if [ "${SCRPRINT}" != "1" -a "${FORCEFILE}" != "1" ]
+ if [ "${SCRPRINT}" != '1' -a "${FORCEFILE}" != '1' ]
then
return 0
fi
# STRUCTURE DATA TO BE OUTPUT TO SCREEN, AND OUTPUT IT
- if [ "${SCRPRINT}" -eq "1" ]
+ if [ "${SCRPRINT}" = '1' ]
then
- if [ "${PREFIXLINE}" = "1" ]
+ if [ "${PREFIXLINE}" = '1' ]
then
STR="${GOOD}*${NORMAL} ${2}"
else
STR="${2}"
fi
- if [ "${NEWLINE}" = "0" ]
+ if [ "${NEWLINE}" = '0' ]
then
echo -ne "${STR}"
else
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}/}
STRR=${STRR//${BOLD}/}
STRR=${STRR//${NORMAL}/}
- if [ "${PREFIXLINE}" = "1" ]
+ if [ "${PREFIXLINE}" = '1' ]
then
STR="* ${STRR}"
else
STR="${STRR}"
fi
- if [ "${NEWLINE}" = "0" ]
+ if [ "${NEWLINE}" = '0' ]
then
- echo -ne "${STR}" >> ${DEBUGFILE}
+ if [ "${TODEBUGCACHE}" = '1' ]; then
+ DEBUGCACHE="${DEBUGCACHE}${STR}"
+ else
+ echo -ne "${STR}" >> ${LOGFILE}
+ fi
else
- echo "${STR}" >> ${DEBUGFILE}
+ if [ "${TODEBUGCACHE}" = '1' ]; then
+ DEBUGCACHE="${DEBUGCACHE}${STR}"$'\n'
+ else
+ echo "${STR}" >> ${LOGFILE}
+ fi
fi
fi
# $1 = variable name
# $2 = variable value
# $3 = string
+
var_replace()
{
- echo "${3}" | sed -e "s/%%${1}%%/${2}/g" -
+ # Escape '\' and '.' in $2 to make it safe to use
+ # 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" -
}
arch_replace() {
var_replace "ARCH" "${ARCH}" "${1}"
}
+cache_replace() {
+ var_replace "CACHE" "${CACHE_DIR}" "${1}"
+}
+
clear_log() {
- rm -f ${DEBUGFILE}
- touch ${DEBUGFILE}
+ if [ -f "${LOGFILE}" ]
+ then
+ (echo > "${LOGFILE}") 2>/dev/null || small_die "Genkernel: Could not write to ${LOGFILE}."
+ fi
}
gen_die() {
- if [ "$#" -gt "0" ]
+ dump_debugcache
+
+ if [ "$#" -gt '0' ]
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 real 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 "DO ${BAD}NOT${NORMAL} REPORT KERNEL COMPILE 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() {
- if [ -e "/dev/loop0" -o -e "/dev/loop/0" ]
+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
}
+
+#
+# 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 [ ! -f "${i}" ]
+ then
+ small_die "Could not find source tarball ${i}. Please refetch."
+ fi
+ done
+}
+
+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}"
+}