Merge branch 'iscsi'
[genkernel.git] / gen_funcs.sh
1 #!/bin/bash
2 # $Id$
3
4 isTrue() {
5         case "$1" in
6                 [Tt][Rr][Uu][Ee])
7                         return 0
8                 ;;
9                 [Tt])
10                         return 0
11                 ;;
12                 [Yy][Ee][Ss])
13                         return 0
14                 ;;
15                 [Yy])
16                         return 0
17                 ;;
18                 1)
19                         return 0
20                 ;;
21         esac
22         return 1
23 }
24
25 setColorVars() { 
26 if isTrue ${USECOLOR}
27 then
28         GOOD=$'\e[32;01m'
29         WARN=$'\e[33;01m'
30         BAD=$'\e[31;01m'
31         NORMAL=$'\e[0m'
32         BOLD=$'\e[0;01m'
33         UNDER=$'\e[4m'
34 else
35         GOOD=''
36         WARN=''
37         BAD=''
38         NORMAL=''
39         BOLD=''
40         UNDER=''
41 fi
42 }
43 setColorVars
44
45 dump_debugcache() {
46         TODEBUGCACHE=0
47         echo "${DEBUGCACHE}" >> ${LOGFILE}
48 }
49
50 # print_info(loglevel, print [, newline [, prefixline [, forcefile ] ] ])
51 print_info() {
52         local NEWLINE=1
53         local FORCEFILE=0
54         local PREFIXLINE=1
55         local SCRPRINT=0
56         local STR=''
57
58         # NOT ENOUGH ARGS
59         if [ "$#" -lt '2' ] ; then return 1; fi
60
61         # IF 3 OR MORE ARGS, CHECK IF WE WANT A NEWLINE AFTER PRINT
62         if [ "$#" -gt '2' ]
63         then
64                 if isTrue "$3"
65                 then
66                         NEWLINE='1';
67                 else
68                         NEWLINE='0';
69                 fi
70         fi
71
72         # IF 4 OR MORE ARGS, CHECK IF WE WANT TO PREFIX WITH A *
73         if [ "$#" -gt '3' ]
74         then
75                 if isTrue "$4"
76                 then
77                         PREFIXLINE='1'
78                 else
79                         PREFIXLINE='0'
80                 fi
81         fi
82
83         # IF 5 OR MORE ARGS, CHECK IF WE WANT TO FORCE OUTPUT TO DEBUG
84         # FILE EVEN IF IT DOESN'T MEET THE MINIMUM DEBUG REQS
85         if [ "$#" -gt '4' ]
86         then
87                 if isTrue "$5"
88                 then
89                         FORCEFILE='1'
90                 else
91                         FORCEFILE='0'
92                 fi
93         fi
94
95         # PRINT TO SCREEN ONLY IF PASSED LOGLEVEL IS HIGHER THAN
96         # OR EQUAL TO SET DEBUG LEVEL
97         if [ "$1" -lt "${LOGLEVEL}" -o "$1" -eq "${LOGLEVEL}" ]
98         then
99                 SCRPRINT='1'
100         fi
101
102         # RETURN IF NOT OUTPUTTING ANYWHERE
103         if [ "${SCRPRINT}" != '1' -a "${FORCEFILE}" != '1' ]
104         then
105                 return 0
106         fi
107
108         # STRUCTURE DATA TO BE OUTPUT TO SCREEN, AND OUTPUT IT
109         if [ "${SCRPRINT}" -eq '1' ]
110         then
111                 if [ "${PREFIXLINE}" = '1' ]
112                 then
113                         STR="${GOOD}*${NORMAL} ${2}"
114                 else
115                         STR="${2}"
116                 fi
117
118                 if [ "${NEWLINE}" = '0' ]
119                 then
120                         echo -ne "${STR}"
121                 else
122                         echo "${STR}"
123                 fi
124         fi
125
126         # STRUCTURE DATA TO BE OUTPUT TO FILE, AND OUTPUT IT
127         if [ "${SCRPRINT}" -eq '1' -o "${FORCEFILE}" -eq '1' ]
128         then
129                 STRR=${2//${WARN}/}
130                 STRR=${STRR//${BAD}/}
131                 STRR=${STRR//${BOLD}/}
132                 STRR=${STRR//${NORMAL}/}
133
134                 if [ "${PREFIXLINE}" = '1' ]
135                 then
136                         STR="* ${STRR}"
137                 else
138                         STR="${STRR}"
139                 fi
140
141                 if [ "${NEWLINE}" = '0' ]
142                 then
143                         if [ "${TODEBUGCACHE}" -eq '1' ]; then
144                                 DEBUGCACHE="${DEBUGCACHE}${STR}"
145                         else
146                                 echo -ne "${STR}" >> ${LOGFILE}
147                         fi      
148                 else
149                         if [ "${TODEBUGCACHE}" -eq '1' ]; then
150                                 DEBUGCACHE="${DEBUGCACHE}${STR}"$'\n'
151                         else
152                                 echo "${STR}" >> ${LOGFILE}
153                         fi
154                 fi
155         fi
156
157         return 0
158 }
159
160 print_error()
161 {
162         GOOD=${BAD} print_info "$@"
163 }
164
165 print_warning()
166 {
167         GOOD=${WARN} print_info "$@"
168 }
169
170 # var_replace(var_name, var_value, string)
171 # $1 = variable name
172 # $2 = variable value
173 # $3 = string
174
175 var_replace()
176 {
177   # Escape '\' and '.' in $2 to make it safe to use
178   # in the later sed expression
179   local SAFE_VAR
180   SAFE_VAR=`echo "${2}" | sed -e 's/\([\/\.]\)/\\\\\\1/g'`
181   
182   echo "${3}" | sed -e "s/%%${1}%%/${SAFE_VAR}/g" -
183 }
184
185 arch_replace() {
186   var_replace "ARCH" "${ARCH}" "${1}"
187 }
188
189 kv_replace() {
190   var_replace "KV" "${KV}" "${1}"
191 }
192
193 cache_replace() {
194   var_replace "CACHE" "${CACHE_DIR}" "${1}"
195 }
196
197 clear_log() {
198     if [ -f "${LOGFILE}" ]
199     then
200         (echo > "${LOGFILE}") 2>/dev/null || small_die "Genkernel: Could not write to ${LOGFILE}."
201     fi   
202 }
203
204 gen_die() {
205         dump_debugcache
206
207         if [ "$#" -gt '0' ]
208         then
209                 print_error 1 "ERROR: ${1}"
210         fi
211         echo
212         print_info 1 "-- Grepping log... --"
213         echo
214
215         if isTrue ${USECOLOR}
216         then
217                 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}
218         else
219                 grep -B5 -E "([Ww][Aa][Rr][Nn][Ii][Nn][Gg]|[Ee][Rr][Rr][Oo][Rr][ :,!]|[Ff][Aa][Ii][Ll][Ee]?[Dd]?)" ${LOGFILE}
220         fi
221         echo
222         print_info 1 "-- End log... --"
223         echo
224         print_info 1 "Please consult ${LOGFILE} for more information and any"
225         print_info 1 "errors that were reported above."
226         echo
227         print_info 1 "Report any genkernel bugs to bugs.gentoo.org and"
228         print_info 1 "assign your bug to genkernel@gentoo.org. Please include"
229         print_info 1 "as much information as you can in your bug report; attaching"
230         print_info 1 "${LOGFILE} so that your issue can be dealt with effectively."
231         print_info 1 ''
232         print_info 1 'Please do *not* report compilation failures as genkernel bugs!'
233         print_info 1 ''
234
235         # Cleanup temp dirs and caches if requested
236         cleanup
237         exit 1
238 }
239
240 isBootRO()
241 {
242         return $(awk '( $2 == "'${BOOTDIR}'" && $4 ~ /(^|,)ro(,|$)/){ I=1; exit }END{print !I }' /proc/mounts);
243 }
244
245 setup_cache_dir()
246 {
247
248 [ ! -d "${CACHE_DIR}" ] && mkdir -p "${CACHE_DIR}"
249
250 if [ "${CLEAR_CACHE_DIR}" == 'yes' ]
251 then
252         print_info 1 "Clearing cache dir contents from ${CACHE_DIR}"
253         CACHE_DIR_CONTENTS=`ls ${CACHE_DIR}|grep -v CVS|grep -v cpio|grep -v README`
254         
255         for i in ${CACHE_DIR_CONTENTS}
256         do
257                 print_info 1 "   >> removing ${i}"
258                 rm ${CACHE_DIR}/${i}
259         done
260 fi
261
262 }
263
264 clear_tmpdir()
265 {
266 if ! isTrue ${CMD_NOINSTALL}
267 then
268     TMPDIR_CONTENTS=`ls ${TMPDIR}`
269     print_info 1 "Removing tmp dir contents"
270     for i in ${TMPDIR_CONTENTS}
271     do
272         print_info 1 "   >> removing ${i}"
273         rm ${TMPDIR}/${i}
274     done
275 fi
276 }       
277
278 #
279 # Function to copy various kernel boot image products to the boot directory,
280 # preserve a generation of old images (just like the manual kernel build's
281 # "make install" does), and maintain the symlinks (if enabled).
282 #
283 # Arguments:
284 #     $1  Symlink name.  Symlink on the boot directory. Path not included.
285 #     $2  Source image.  Fully qualified path name of the source image.
286 #     $3  Dest image.    Name of the destination image in the boot directory,
287 #         no path included.  This script pushd's into ${BOOTDIR} in order to
288 #         create relative symlinks just like the manual kernel build.
289 #
290 # - JRG
291 #
292 copy_image_with_preserve() {
293         local symlinkName=$1
294         local newSrceImage=$2
295         local fullDestName=$3
296
297         local currDestImage
298         local prevDestImage
299         local currDestImageExists=0
300         local prevDestImageExists=0
301
302         print_info 4 "Copying new ${symlinkName} image, " 0
303
304         # Old product might be a different version.  If so, we need to read
305         # the symlink to see what it's name is, if there are symlinks.
306         if [ "${SYMLINK}" -eq '1' ]
307         then
308                 print_info 4 "automatically managing symlinks and old images." 1 0
309                 if [ -e "${BOOTDIR}/${symlinkName}" ]
310                 then
311                         # JRG: Do I need a special case here for when the standard symlink
312                         # name is, in fact, not a symlink?
313                         currDestImage=`readlink --no-newline ${BOOTDIR}/${symlinkName}`
314                         print_info 5 "  Current ${symlinkName} symlink exists:"
315                         print_info 5 "    ${currDestImage}"
316                 else
317                         currDestImage="${fullDestName}"
318                         print_info 5 "  Current ${symlinkName} symlink did not exist."
319                         print_info 5 "    Defaulted to: ${currDestImage}"
320                 fi
321                 if [ -e "${BOOTDIR}/${currDestImage}" ]
322                 then
323                         currDestImageExists=1
324                         print_info 5 "  Actual image file exists."
325                 fi
326
327                 if [ -e "${BOOTDIR}/${symlinkName}.old" ]
328                 then
329                         # JRG: Do I need a special case here for when the standard symlink
330                         # name is, in fact, not a symlink?
331                         prevDestImage=`readlink --no-newline ${BOOTDIR}/${symlinkName}.old`
332                         print_info 5 "  Old ${symlinkName} symlink exists:"
333                         print_info 5 "    ${prevDestImage}"
334                 else
335                         prevDestImage="${fullDestName}.old"
336                         print_info 5 "  Old ${symlinkName} symlink did not exist."
337                         print_info 5 "    Defaulted to: ${prevDestImage}"
338                 fi
339                 if [ -e "${BOOTDIR}/${prevDestImage}" ]
340                 then
341                         prevDestImageExists=1
342                         print_info 5 "  Actual old image file exists."
343                 fi
344         else
345                 print_info 4 "symlinks not being handled by genkernel." 1 0
346                 currDestImage="${fullDestName}"
347                 prevDestImage="${fullDestName}.old"
348         fi
349
350         # When symlinks are not being managed by genkernel, old symlinks might
351     # still be useful.  Leave 'em alone unless managed.
352         if [ "${SYMLINK}" -eq '1' ]
353         then
354                 print_info 5 "  Deleting old symlinks, if any."
355                 rm -f "${BOOTDIR}/${symlinkName}"
356                 rm -f "${BOOTDIR}/${symlinkName}.old"
357         fi
358
359         # We only erase the .old image when it is the exact same version as the
360         # current and new images.  Different version .old (and current) images are
361         # left behind.  This is consistent with how "make install" of the manual
362         # kernel build works.
363         if [ "${currDestImage}" == "${fullDestName}" ]
364         then
365                 #
366                 # Case for new and currrent of the same base version.
367                 #
368                 print_info 5 "  Same base version.  May have to delete old image to make room."
369
370                 if [ "${currDestImageExists}" -eq '1' ]
371                 then
372                         if [ -e "${BOOTDIR}/${currDestImage}.old" ]
373                         then
374                                 print_info 5 "  Deleting old identical version ${symlinkName}."
375                                 rm -f "${BOOTDIR}/${currDestImage}.old"
376                         fi
377                         print_info 5 "  Moving ${BOOTDIR}/${currDestImage}"
378                         print_info 5 "    to ${BOOTDIR}/${currDestImage}.old"
379                         mv "${BOOTDIR}/${currDestImage}" "${BOOTDIR}/${currDestImage}.old" ||
380                             gen_die "Could not rename the old ${symlinkName} image!"
381                         prevDestImage="${currDestImage}.old"
382                         prevDestImageExists=1
383                 fi
384         else
385                 #
386                 # Case for new / current not of the same base version.
387                 #
388                 print_info 5 "  Different base version.  Do not delete old images."
389                 prevDestImage="${currDestImage}"
390                 currDestImage="${fullDestName}"
391         fi
392
393         print_info 5 "  Copying ${symlinkName}: ${newSrceImage}"
394         print_info 5 "    to ${BOOTDIR}/${currDestImage}"
395         cp "${newSrceImage}" "${BOOTDIR}/${currDestImage}" ||
396             gen_die "Could not copy the ${symlinkName} image to ${BOOTDIR}!"
397
398         if [ "${SYMLINK}" -eq '1' ]
399         then
400                 print_info 5 "  Make new symlink(s) (from ${BOOTDIR}):"
401                 print_info 5 "    ${symlinkName} -> ${currDestImage}"
402                 pushd ${BOOTDIR} >/dev/null
403                 ln -s "${currDestImage}" "${symlinkName}" || 
404                     gen_die "Could not create the ${symlinkName} symlink!"
405                 if [ "${prevDestImageExists}" -eq '1' ]
406                 then
407                         print_info 5 "    ${symlinkName}.old -> ${prevDestImage}"
408                         ln -s "${prevDestImage}" "${symlinkName}.old" ||
409                             gen_die "Could not create the ${symlinkName}.old symlink!"
410                 fi
411                 popd >/dev/null
412         fi
413 }
414
415 #
416 # Helper function to allow command line arguments to override configuration
417 # file specified values and to apply defaults.
418 #
419 # Arguments:
420 #     $1  Argument type:
421 #           1  Switch type arguments (e.g., --color / --no-color).
422 #           2  Value type arguments (e.g., --debuglevel=5).
423 #     $2  Config file variable name.
424 #     $3  Command line variable name.
425 #     $4  Default.  If both the config file variable and the command line
426 #         option are not present, then the config file variable is set to
427 #         this default value.  Optional.
428 #
429 # The order of priority of these three sources (highest first) is:
430 #     Command line, which overrides
431 #     Config file (/etc/genkernel.conf), which overrides
432 #     Default.
433 #
434 # Arguments $2 and $3 are variable *names*, not *values*.  This function uses
435 # various forms of indirection to access the values.
436 #
437 # For switch type arguments, all forms of "True" are converted to a numeric 1
438 # and all forms of "False" (everything else, really) to a numeric 0.
439 #
440 # - JRG
441 #
442 set_config_with_override() {
443         local VarType=$1
444         local CfgVar=$2
445         local OverrideVar=$3
446         local Default=$4
447         local Result
448
449         #
450         # Syntax check the function arguments.
451         #
452         case "$VarType" in
453                 1|2)
454                         ;;
455                 *)
456                         gen_die "Illegal variable type \"$VarType\" passed to set_config_with_override()."
457                         ;;
458         esac
459
460         if [ -n "${!OverrideVar}" ]
461         then
462                 Result=${!OverrideVar}
463                 if [ -n "${!CfgVar}" ]
464                 then
465                         print_info 5 "  $CfgVar overridden on command line to \"$Result\"."
466                 else
467                         print_info 5 "  $CfgVar set on command line to \"$Result\"."
468                 fi
469         else
470                 if [ -n "${!CfgVar}" ]
471                 then
472                         Result=${!CfgVar}
473                         # we need to set the CMD_* according to configfile...
474                         eval ${OverrideVar}=\"${Result}\"
475                         print_info 5 "  $CfgVar set in config file to \"${Result}\"."
476                 else
477                         if [ -n "$Default" ]
478                         then
479                                 Result=${Default}
480                                 # set OverrideVar to Result, otherwise CMD_* may not be initialized...
481                                 eval ${OverrideVar}=\"${Result}\"
482                                 print_info 5 "  $CfgVar defaulted to \"${Result}\"."
483                         else
484                                 print_info 5 "  $CfgVar not set."
485                         fi
486                 fi
487         fi
488
489         if [ "$VarType" -eq "1" ]
490         then
491                 if isTrue "${Result}"
492                 then
493                         Result=1
494                 else
495                         Result=0
496                 fi
497         fi
498
499         eval ${CfgVar}=\"${Result}\"
500 }
501
502 check_distfiles() {
503         for i in $BUSYBOX_SRCTAR $DEVICE_MAPPER_SRCTAR $MULTIPATH_SRCTAR $LVM_SRCTAR $DMRAID_SRCTAR $E2FSPROGS_SRCTAR $ISCSI_SRCTAR
504         do
505                 if [ ! -f "${i}" ]
506                 then
507                         small_die "Could not find source tarball ${i}. Please refetch."
508                 fi
509         done
510 }
511
512 find_kernel_binary() {
513         local kernel_binary=$*
514         local curdir=$(pwd)
515
516         cd "${KERNEL_DIR}"
517         for i in ${kernel_binary}
518         do
519                 if [ -e "${i}" ]
520                 then
521                         tmp_kernel_binary=$i
522                         break
523                 fi
524         done
525 #       if [ -z "${tmp_kernel_binary}" ]
526 #       then
527 #               gen_die "Cannot locate kernel binary!"
528 #       fi
529         cd "${curdir}"
530         echo "${tmp_kernel_binary}"
531 }