remove default console=ttyS0,115200 and systemd.log_target=console from default kargs
[bootcd.git] / build.sh
index 0535962..29aa5bf 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -7,11 +7,27 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2004-2007 The Trustees of Princeton University
 #
-# $Id$
-#
+# Jan 2015 - f21 comes with isolinux 6.03 (was 4.05 in f20)
+# http://www.syslinux.org/wiki/index.php/ISOLINUX
 
+COMMAND=$(basename $0)
+DIRNAME=$(dirname $0)
 PATH=/sbin:/bin:/usr/sbin:/usr/bin
 
+# debugging flags
+# keep KERNEL_DEBUG_ARGS void for production
+KERNEL_DEBUG_ARGS=""
+# add more flags here for debugging
+# KERNEL_DEBUG_ARGS="$KERNEL_DEBUG_ARGS some_other_kernel_arg"
+# see also
+#  (*) GetBootMedium that has some provisions for common
+#      kargs, like e.g. for removing the hangcheck feature,
+#      or for turning on debug messages for systemd
+#      these can be turned on with tags on the node
+#  (*) tests default config, that uses this feature so
+#      the tests can benefit these features, without deploying
+#      them by default in production
+
 # defaults
 DEFAULT_TYPES="usb iso"
 # Leave 4 MB of free space
@@ -19,6 +35,10 @@ GRAPHIC_CONSOLE="graphic"
 SERIAL_CONSOLE="ttyS0:115200:n:8"
 CONSOLE_INFO=$GRAPHIC_CONSOLE
 MKISOFS_OPTS="-R -J -r -f -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table"
+# isolinux-debug.bin is supposedly helpful as well if available,
+# when things don't work as expected
+#MKISOFS_OPTS="-R -J -r -f -b isolinux-debug.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table"
+
 FREE_SPACE=4096
 
 # command-line settable args
@@ -28,7 +48,7 @@ OUTPUT_BASE=
 DRY_RUN=""
 OUTPUT_NAME=""
 TYPES=""
-KARGS_STR=""
+KERNEL_ARGS=""
 
 # various globals
 BUILDTMP=""
@@ -41,7 +61,6 @@ console_dev=""
 console_baud=""
 console_spec=""
 console_serial_line=""
-kernel_args=""
 
 
 #################### compute all supported types
@@ -77,41 +96,36 @@ function pop_cleanup() {
 function init_and_check () {
 
     # Change to our source directory
-    local srcdir=$(cd $(dirname $0) && pwd -P)
+    local srcdir=$(cd $DIRNAME && pwd -P)
     pushd $srcdir
 
     # Root of the isofs
-    ISOREF=$PWD/build
+    ISOREF=$PWD/${VARIANT}
 
     # The reference image is expected to have been built by prep.sh (see .spec)
     # we disable the initial logic that called prep.sh if that was not the case
     # this is because prep.sh needs to know pldistro 
     if [ ! -f $ISOREF/isofs/bootcd.img -o ! -f $ISOREF/version.txt ] ; then
-       echo "You have to run prep.sh prior to calling $0 - exiting"
+       echo "Could not find isofs and version.txt in $ISOREF"
+       if [ "$VARIANT" == "build" ] ; then
+           echo "You have to run prep.sh prior to calling $COMMAND"
+       else
+           echo "You need to create your variant image, see kvariant.sh"
+       fi
+       echo "Exiting .."
        exit 1
     fi
 
     # build/version.txt written by prep.sh
-    BOOTCD_VERSION=$(cat build/version.txt)
+    BOOTCD_VERSION=$(cat ${VARIANT}/version.txt)
 
     if [ -f /etc/planetlab/plc_config ] ; then
         # Source PLC configuration
        . /etc/planetlab/plc_config
     fi
 
-    # From within a myplc chroot /usr/tmp is too small 
-    # to build all possible images, whereas /data is part of the host
-    # filesystem and usually has sufficient space.  What we
-    # should do is check whether the expected amount of space
-    # is available.
-    BUILDTMP=/usr/tmp
-    if [ -d /data/tmp ] ; then
-       isreadonly=$(mktemp /data/tmp/isreadonly.XXXXXX || /bin/true)
-       if [ -n "$isreadonly" ] ; then
-            rm -f "$isreadonly"
-            BUILDTMP=/data/tmp
-       fi
-    fi
+    # use /var/tmp that should be large enough on both chroot- or vserver-based myplc
+    BUILDTMP=/var/tmp
 
     FULL_VERSION_STRING="${PLC_NAME} BootCD ${BOOTCD_VERSION}"
 
@@ -127,7 +141,7 @@ function init_and_check () {
 # it seems that this feature has not been used nor tested in a long time, use with care
 
 usage() {
-    echo "Usage: build.sh [OPTION]..."
+    echo "Usage: $COMMAND [OPTION]..."
     echo "    -f plnode.txt    Node to customize CD for (default: none)"
     echo "    -t 'types'       Build the specified images (default: $DEFAULT_TYPES)"
     echo "                     NOTE: mentioning 'serial' as part of the type is not supported anymore"
@@ -141,6 +155,7 @@ usage() {
     echo "                     can be a full path"
     echo "    -o output-name   The full name of the generated file"
     echo "    -C custom-dir    Custom directory"
+    echo "    -V variant       Use a variant - see kvariant.sh"
     echo "    -n               Dry run - mostly for debug/test purposes"
     echo "    -k               Add additional parameters to the kargs.txt file"
     echo "    -h               This message"
@@ -154,7 +169,7 @@ function parse_command_line () {
     # init
     TYPES=""
     # Get options
-    while getopts "f:t:as:SO:o:C:k:nh" opt ; do
+    while getopts "f:t:as:SO:o:C:V:k:nh" opt ; do
        case $opt in
            f) NODE_CONFIGURATION_FILE=$OPTARG ;;
            t) TYPES="$TYPES $OPTARG" ;;
@@ -164,7 +179,8 @@ function parse_command_line () {
            O) OUTPUT_BASE="$OPTARG" ;;
            o) OUTPUT_NAME="$OPTARG" ;;
            C) CUSTOM_DIR="$OPTARG" ;;
-           k) KARGS_STR="$OPTARG" ;;
+           V) VARIANT="$OPTARG" ;;
+           k) KERNEL_ARGS="$KERNEL_ARGS $OPTARG" ;;
            n) DRY_RUN=true ;;
            h|*) usage ;;
        esac
@@ -172,8 +188,21 @@ function parse_command_line () {
 
     # use defaults if not set
     [ -z "$TYPES" ] && TYPES="$DEFAULT_TYPES"
+    [ -z "$VARIANT" ] && VARIANT="build"
     [ "$CONSOLE_INFO" == "default" ] && CONSOLE_INFO=$SERIAL_CONSOLE
 
+    if [ -n "$NODE_CONFIGURATION_FILE" ] ; then
+    # check existence of NODE_CONFIGURATION_FILE and normalize as we will change directory
+       if [ ! -f "$NODE_CONFIGURATION_FILE" ] ; then
+           echo "Node configuration file $NODE_CONFIGURATION_FILE not found - exiting"
+           exit 1
+       fi
+       cf_dir="$(dirname $NODE_CONFIGURATION_FILE)"
+       cf_dir="$(cd $cf_dir; pwd -P)"
+       cf_file="$(basename $NODE_CONFIGURATION_FILE)"
+       NODE_CONFIGURATION_FILE="$cf_dir"/"$cf_file"
+    fi
+
     # check TYPES 
     local matcher="XXX$(echo $ALL_TYPES | sed -e 's,\W,XXX,g')XXX"
     for t in $TYPES; do
@@ -217,12 +246,26 @@ function build_overlay () {
 
     BUILDTMP=$(mktemp -d ${BUILDTMP}/bootcd.XXXXXX)
     push_cleanup rm -fr "${BUILDTMP}"
-    mkdir "${BUILDTMP}/isofs"
+
+    # initialize ISOFS
+    ISOFS="${BUILDTMP}/isofs"
+    mkdir -p "$ISOFS"
     for i in "$ISOREF"/isofs/{bootcd.img,kernel}; do
-       ln -s "$i" "${BUILDTMP}/isofs"
+       ln -s "$i" "$ISOFS"
+    done
+    # use new location as of fedora 12
+    # used to be in /usr/lib/syslinux/isolinux.bin
+    # removed backward compat in jan. 2015
+    # as of syslinux 6.05 (fedora 21) ldlinux.c32 is required by isolinux.bin
+    # the debug version can come in handy at times, and is 40k as well
+    isolinuxdir="/usr/share/syslinux"
+    # ship only what is mandatory, and forget about
+    # (*) isolinux-debug.bin as its name confuses mkisofs
+    # (*) memdisk that is not useful
+    isolinuxfiles="isolinux.bin ldlinux.c32"
+    for isolinuxfile in $isolinuxfiles; do
+       [ -f $isolinuxdir/$isolinuxfile ] && cp $isolinuxdir/$isolinuxfile "${BUILDTMP}/isofs"
     done
-    cp "/usr/lib/syslinux/isolinux.bin" "${BUILDTMP}/isofs"
-    ISOFS="${BUILDTMP}/isofs"
 
     # Root of the ISO and USB images
     echo "* Populating root filesystem..."
@@ -308,22 +351,28 @@ EOF
     fi
 
     # build/passwd copied out by prep.sh
-    sed -e "s@^root:[^:]*:\(.*\)@root:$ROOT_PASSWORD:\1@" build/passwd >$OVERLAY/etc/passwd
+    sed -e "s@^root:[^:]*:\(.*\)@root:$ROOT_PASSWORD:\1@" ${VARIANT}/passwd >$OVERLAY/etc/passwd
 
     # Install node configuration file (e.g., if node has no floppy disk or USB slot)
     if [ -f "$NODE_CONFIGURATION_FILE" ] ; then
        echo "* Installing node configuration file $NODE_CONFIGURATION_FILE -> /usr/boot/plnode.txt of the bootcd image"
        install -D -m 644 $NODE_CONFIGURATION_FILE $OVERLAY/usr/boot/plnode.txt
+       NODE_ID=$(source $NODE_CONFIGURATION_FILE; echo $NODE_ID)
+       echo "* Building network configuration for $NODE_ID"
+       plnet -- --root $OVERLAY --files-only --program BootCD $NODE_ID
     fi
 
-    if [ -n "$IS_SERIAL" ] ; then
-       KARGS_STR="$KARGS_STR ${console_spec}"
-    fi
+    [ -n "$IS_SERIAL" ] && KERNEL_ARGS="$KERNEL_ARGS ${console_spec}"
 
-    if [ -n "$KARGS_STR" ] ; then
-       echo "$KARGS_STR" > $OVERLAY/kargs.txt
-       kernel_args=$KARGS_STR
-    fi
+    # tmp: should be restricted to f15 nodes and above
+    # making sure the network interfaces are still numbered eth0 and above
+    KERNEL_ARGS="$KERNEL_ARGS biosdevname=0"
+    # making sure selinux is turned off - somehow this is needed with lxc/f14
+    KERNEL_ARGS="$KERNEL_ARGS selinux=0"
+    # add any debug flag if any (defined in the header of this script)
+    KERNEL_ARGS="$KERNEL_ARGS $KERNEL_DEBUG_ARGS"
+    # propagate kernel args for later boot stages
+    [ -n "$KERNEL_ARGS" ] && echo "$KERNEL_ARGS" > $OVERLAY/kargs.txt
 
     # Pack overlay files into a compressed archive
     echo "* Compressing overlay image"
@@ -354,18 +403,22 @@ function build_iso() {
     # Write isolinux configuration
     cat >$ISOFS/isolinux.cfg <<EOF
 ${console_serial_line}
-DEFAULT kernel
-APPEND ramdisk_size=$ramdisk_size initrd=bootcd.img,overlay.img${custom:+,custom.img} root=/dev/ram0 rw ${kernel_args}
-DISPLAY pl_version
 PROMPT 0
-TIMEOUT 40
+DEFAULT planetlab-bootcd
+
+LABEL planetlab-bootcd
+  DISPLAY pl_version
+  LINUX kernel
+  APPEND ramdisk_size=$ramdisk_size initrd=bootcd.img,overlay.img${custom:+,custom.img} root=/dev/ram0 rw ${KERNEL_ARGS}
 EOF
 
     # Create ISO image
-    echo "* Creating ISO image"
-    mkisofs -o "$iso" \
-        $MKISOFS_OPTS \
-        $ISOFS
+    echo "* Generated isolinux.cfg -------------------- BEG"
+    cat $ISOFS/isolinux.cfg
+    echo "* Generated isolinux.cfg -------------------- END"
+    echo "* Creating ISO image in pwd=$(pwd)"
+    echo "* with command mkisofs -o $iso $MKISOFS_OPTS $ISOFS"
+    mkisofs -o "$iso" $MKISOFS_OPTS $ISOFS
 }
 
 #################### USB with partitions
@@ -382,8 +435,12 @@ function build_usb_partition() {
     local cylinders=$(( ($size*1024*2)/($heads*$sectors) ))
     local offset=$(( $sectors*512 ))
 
-    /usr/lib/syslinux/mkdiskimage -M -4 "$usb" $size $heads $sectors
-    
+    if [ -f  /usr/lib/syslinux/mkdiskimage ] ; then
+        /usr/lib/syslinux/mkdiskimage -M -4 "$usb" $size $heads $sectors
+    else
+        mkdiskimage -M -4 "$usb" $size $heads $sectors
+    fi
+
     cat >${BUILDTMP}/mtools.conf<<EOF
 drive z:
 file="${usb}"
@@ -392,6 +449,7 @@ heads=$heads
 sectors=$sectors
 offset=$offset
 mformat_only
+mtools_skip_check=1
 EOF
     # environment variable for mtools
     export MTOOLSRC="${BUILDTMP}/mtools.conf"
@@ -404,16 +462,18 @@ EOF
     tmp="${BUILDTMP}/syslinux.cfg"
     cat >$tmp <<EOF
 ${console_serial_line}
-DEFAULT kernel
-APPEND ramdisk_size=$ramdisk_size initrd=bootcd.img,overlay.img${custom:+,custom.img} root=/dev/ram0 rw ${kernel_args}
-DISPLAY pl_version
 PROMPT 0
-TIMEOUT 40
+DEFAULT planetlab-bootcd
+
+LABEL planetlab-bootcd
+  DISPLAY pl_version
+  LINUX kernel
+  APPEND ramdisk_size=$ramdisk_size initrd=bootcd.img,overlay.img${custom:+,custom.img} root=/dev/ram0 rw ${KERNEL_ARGS}
 EOF
     mdel -i "$usb" z:/isolinux.cfg 2>/dev/null || :
     mcopy -i "$usb" "$tmp" z:/syslinux.cfg
     rm -f "$tmp"
-    rm -f "${BUILDTMP}/mtools.conf"
+    rm -f "${MTOOLSRC}"
     unset MTOOLSRC
 
     echo "making USB image bootable."
@@ -427,8 +487,15 @@ function build_usb() {
     local usb="$1" ; shift
     local custom="$1"
 
+    rm -f "$usb"
     mkfs.vfat -C "$usb" $(($(du -Lsk $ISOFS | awk '{ print $1; }') + $FREE_SPACE))
 
+    cat >${BUILDTMP}/mtools.conf<<EOF
+mtools_skip_check=1
+EOF
+    # environment variable for mtools
+    export MTOOLSRC="${BUILDTMP}/mtools.conf"
+
     # Populate it
     echo -n " populating USB image... "
     mcopy -bsQ -i "$usb" "$ISOFS"/* ::/
@@ -437,15 +504,19 @@ function build_usb() {
     tmp="${BUILDTMP}/syslinux.cfg"
     cat >$tmp <<EOF
 ${console_serial_line}
-DEFAULT kernel
-APPEND ramdisk_size=$ramdisk_size initrd=bootcd.img,overlay.img${custom:+,custom.img} root=/dev/ram0 rw ${kernel_args}
-DISPLAY pl_version
 PROMPT 0
-TIMEOUT 40
+DEFAULT planetlab-bootcd
+
+LABEL planetlab-bootcd
+  DISPLAY pl_version
+  LINUX kernel
+  APPEND ramdisk_size=$ramdisk_size initrd=bootcd.img,overlay.img${custom:+,custom.img} root=/dev/ram0 rw ${KERNEL_ARGS}
 EOF
     mdel -i "$usb" ::/isolinux.cfg 2>/dev/null || :
     mcopy -i "$usb" "$tmp" ::/syslinux.cfg
     rm -f "$tmp"
+    rm -f "${MTOOLSRC}"
+    unset MTOOLSRC
 
     echo "making USB image bootable."
     syslinux "$usb"
@@ -519,9 +590,12 @@ EOF
     popd
 
     # update etc/inittab to start with pl_rsysinit
-    sed -i 's,pl_sysinit,pl_rsysinit,' etc/inittab
+    for file in etc/inittab etc/event.d/rcS etc/init/rcS.conf; do
+       [ -f $file ] && sed -i 's,pl_sysinit,pl_rsysinit,' $file
+    done
 
     # modify inittab to have a serial console
+    # xxx this might well be broken with f12 and above xxx
     if [ -n "$serial" ] ; then
        echo "T0:23:respawn:/sbin/agetty -L $console_dev $console_baud vt100" >> etc/inittab
         # and let root log in
@@ -541,7 +615,7 @@ EOF
     # generate pl_rsysinit
     cat > etc/rc.d/init.d/pl_rsysinit <<EOF
 #!/bin/sh
-# generated by build.sh
+# generated by $COMMAND
 echo -n "pl_rsysinit: preparing /etc and /var for pl_sysinit..."
 mount -t tmpfs -orw,size=${msize}M,mode=1777 tmpfs /tmp
 mkdir -p /tmp/root
@@ -594,11 +668,13 @@ function build_iso_cramfs() {
     (cd $ISOFS && find . | grep -v "\.img$" | cpio -p -d -u $tmp/)
     cat >$tmp/isolinux.cfg <<EOF
 ${console_serial_line}
-DEFAULT kernel
-APPEND ramdisk_size=$cramfs_size initrd=cramfs.img root=/dev/ram0 ro ${kernel_args}
-DISPLAY pl_version
 PROMPT 0
-TIMEOUT 40
+DEFAULT planetlab-bootcd
+
+LABEL planetlab-bootcd
+  DISPLAY pl_version
+  LINUX kernel
+  APPEND ramdisk_size=$ramdisk_size initrd=cramfs.img root=/dev/ram0 rw ${KERNEL_ARGS}
 EOF
 
     cp ${BUILDTMP}/cramfs.img $tmp
@@ -632,11 +708,13 @@ function build_usb_cramfs() {
     tmp="${BUILDTMP}/syslinux.cfg"
     cat >$tmp <<EOF
 ${console_serial_line}
-DEFAULT kernel
-APPEND ramdisk_size=$cramfs_size initrd=cramfs.img root=/dev/ram0 ro ${kernel_args}
-DISPLAY pl_version
 PROMPT 0
-TIMEOUT 40
+DEFAULT planetlab-bootcd
+
+LABEL planetlab-bootcd
+  DISPLAY pl_version
+  LINUX kernel
+  APPEND ramdisk_size=$ramdisk_size initrd=cramfs.img root=/dev/ram0 rw ${KERNEL_ARGS}
 EOF
 
     mcopy -bsQ -i "$usb" "$tmp" ::/syslinux.cfg
@@ -692,11 +770,11 @@ function build_types () {
 #################### 
 function main () {
 
-    init_and_check
-
     parse_command_line "$@"
 
-    echo "* Building images for $FULL_VERSION_STRING"
+    init_and_check
+
+    echo "* Building bootcd images for $NODE_CONFIGURATION_FILE ($FULL_VERSION_STRING) - $(date +%H-%M:%S)"
     # Do not tolerate errors
     set -e
     trap "do_cleanup" ERR INT EXIT
@@ -705,6 +783,7 @@ function main () {
     build_overlay
     build_types
 
+    echo "* Done with bootcd images for $NODE_CONFIGURATION_FILE - $(date +%H-%M:%S)"
     exit 0
 }