This commit was manufactured by cvs2svn to create branch
Planet-Lab Support [Wed, 8 Aug 2007 20:22:12 +0000 (20:22 +0000)]
'planetlab-4_0-branch'.

bootcd.spec
bootcustom.sh [new file with mode: 0755]
build.sh
cdcustom.sh
conf_files/pl_netinit
conf_files/pl_validateconf
newbuild.sh [new file with mode: 0755]
prep.sh

index d3ca071..fee373a 100644 (file)
@@ -58,7 +58,7 @@ pushd bootcd
 # Install the reference image and build scripts
 install -d -m 755 $RPM_BUILD_ROOT/%{_datadir}/%{name}
 install -m 755 build.sh $RPM_BUILD_ROOT/%{_datadir}/%{name}/
-find \
+tar cpf - \
     build/isofs/bootcd.img \
     build/isofs/isolinux.bin \
     build/isofs/kernel \
@@ -66,7 +66,7 @@ find \
     build/version.txt \
     configurations \
     syslinux/unix/syslinux | \
-    cpio -p -d -u $RPM_BUILD_ROOT/%{_datadir}/%{name}/
+    tar -C $RPM_BUILD_ROOT/%{_datadir}/%{name}/ -xpf -
 
 # Install the default images in the download/ directory
 install -d -m 755 $RPM_BUILD_ROOT/var/www/html/download
@@ -81,12 +81,12 @@ rm -rf $RPM_BUILD_ROOT
 # If run under sudo
 if [ -n "$SUDO_USER" ] ; then
     # Allow user to delete the build directory
-    chown -R $SUDO_USER .
+    chown -h -R $SUDO_USER .
     # Some temporary cdroot files like /var/empty/sshd and
     # /usr/bin/sudo get created with non-readable permissions.
     find . -not -perm +0600 -exec chmod u+rw {} \;
     # Allow user to delete the built RPM(s)
-    chown -R $SUDO_USER %{_rpmdir}/%{_arch}
+    chown -h -R $SUDO_USER %{_rpmdir}/%{_arch}
 fi
 
 %post planetlab
diff --git a/bootcustom.sh b/bootcustom.sh
new file mode 100755 (executable)
index 0000000..7a210c3
--- /dev/null
@@ -0,0 +1,438 @@
+#!/bin/bash
+
+# purpose : create a node-specific boot image
+
+# NOTE (see also bootcd/build.sh)
+# If you run your own myplc instance, and you dont need to
+# customize the bootcd, you might wish to use bootcd/build.sh
+# with the -f option
+# However cdcustom.sh might turn out useful if
+# (*) you only have an iso or usb image and nothing else
+# (*) or you want to generate several images in a single run
+# (*) or you run myplc rpm, but need to customize the bootcd image,
+#     because the myplc rpm does not come with the required sources
+
+# See usage for full details
+
+######## Implementation notes
+# (*) as of may 2007, this script supports both iso and usb images
+#     this becomes a bit tricky sometimes
+#     in particular the startup is only partially lazy..
+#     most names are kept from former version for easier merge
+# (*) in a former release (iso only) it was possible to perform faster by
+# loopback-mounting the generic iso image
+# Unfortunately mkisofs cannot graft a file that already exists on the
+# original tree (so overlay.img cannot be overridden)
+# to make things worse we cannot loopback-mount the cpio-gzipped
+# overlay image either, so all this stuff is way more complicated
+# than it used to be.
+#
+# (*) as of 2006 jun 28 we use a third image named custom.img for
+# overriding files in bootcd.img, which let us use bootcd.img intact
+# and thus notably speeds things up 
+#
+######## Logic
+# here is how we do this for ISO
+# for efficiency, we do only once:
+#   (*) mount the generic image
+#   (*) copy it into a temp dir
+#   (*) unzip/unarchive overlay image into another temp dir
+#   (*) if required prepare a custom.img 
+# then for each node, we
+#   (*) insert plnode.txt at the right place if not a default iso
+#   (*) rewrap a gzipped/cpio overlay.img, that we push onto the
+#       copied iso tree
+#   (*) rewrap this into an iso image
+
+# for USB
+# in principle it's simpler here, but for better code factorization we
+# do the same startup thing, but slightly different
+# only once:
+#   (*) mount the generic image
+#   (*) unzip/unarchive overlay image into another temp dir
+# then for each node, we
+#   (*) copy the generic image into the node-dep image
+#   (*) loopback mount it (write enabled)
+#   (*) insert plnode.txt at the right place, 
+#   (*) rewrap a gzipped/cpio overlay.img, that we push onto the
+#       mounted image
+#   (*) unmount
+
+set -e 
+COMMANDSH=$(basename $0)
+COMMAND=$(basename $0 .sh)
+REVISION="$Id$"
+
+function usage () {
+
+   echo "Usage: $COMMANDSH [-f] [ -c bootcd-dir] [generic-image|image-dir] node-config [.. node-configs]"
+   echo " Creates a node-specific boot (iso or usb) image"
+   echo "*Options"
+   echo -e " -f\r\t\tForces overwrite of output images"
+   echo -e " -c bootcd-dir\r\t\tis taken as the root of a set of custom bootcd files"
+   echo -e "\t\ti.e. the files under dir take precedence"
+   echo -e "\t\tover the ones in the generic bootcd"
+   echo -e "\t\tThis is available for ISO images only, and is experimental code"
+   echo -e "-C dir\r\t\tlike make -C, performs chdir prior to running anything"
+   echo -e "-O isoname\r\t\tWrite iso output image to isoname. Does not work with"
+   echo -e "\t\tmultiple node-config files."
+   echo "*Arguments"
+   echo -e " generic-image or image-dir\n\r\t\tThe generic image as downloaded from myplc"
+   echo -e "\t\ttypically from http://myplc.domain.org/download/"
+   echo -e "\t\tor, the already mounted or copied contents in a directory."
+   echo -e " node-config(s)\r\t\tnode config files (plnode.txt format)"
+   echo -e " default\r\t\tmentioned instead of a plnode.txt file, for generating"
+   echo -e "\t\ta node-independent iso image when -c is provided"
+   echo -e "\t\tThis is default behaviour when no node-config are provided"
+   echo "*Outputs"
+   echo " node-specific images are named after nodename[-bootcd-dir]"
+   echo " node-independant image is named after bootcd-dir"
+   echo " with extension .iso or .usb accordingly"
+   echo "*Examples"
+   echo "# $COMMANDSH /plc/data/var/www/html/download/Onelab-BootCD-4.0.usb node1.txt node2.txt"
+   echo "  Creates node1.usb and node2.usb that are self-contained USB images for both nodes"
+   echo "# $COMMANDSH -c onelab-bootcd /plc/data/var/www/html/download/onelab-BootCD-4.0.iso"
+   echo "  Creates onelab-bootcd.iso that has no plnode.txt embedded and that uses"
+   echo "  the hw init scripts located under onelab-bootcd/etc/rc.d/init.d/"
+   echo "*Version $REVISION"
+   exit 1
+}
+
+### read config file in a subshell and echoes host_name
+function host_name () {
+  export CONFIG="$1"; shift
+  ( . "$CONFIG" ; echo "${HOST_NAME}.${DOMAIN_NAME}" )
+}
+
+### Globals
+# we set this to iso or usb according to the generic-image provided
+IMAGE_TYPE=
+PLNODE_PATH=/usr/boot
+PLNODE=plnode.txt
+DEFAULT_TARGET=default
+# defined on the command-line
+CUSTOM_DIR=
+## arg-provided generic iso
+ISO_GENERIC=
+# node-dep conf file
+NODE_CONFIG=
+# resulting iso image and log
+NODE_ISO=
+NODE_LOG=
+## mount points and temps
+ISO_MOUNT="/tmp/$COMMAND-$$-mount"
+ISO_ROOT="/tmp/$COMMAND-$$-iso"
+OVERLAY_ROOT="/tmp/$COMMAND-$$-overlay"
+# node-dep cpio/gzip image
+NODE_OVERLAY=
+
+CPIO_OARGS="-oc --quiet"
+CPIO_IARGS="-id --quiet"
+CPIO_PARGS="-pdu --quiet"
+
+# export DEBUG=true
+# for enabling debug messages (set -x)
+
+# export VERBOSE=true for enabling this
+function verbose () {
+   if [ -n "$VERBOSE" ] ; then
+     echo "$@"
+   fi
+ }
+
+function message () { echo -e "$COMMAND : $@" ; }
+function message-n () { echo -en "$COMMAND : $@" ; }
+function message-done () { echo Done ; }
+function error () { echo -e "$COMMAND : ERROR $@ - exiting" ; exit 1 ;}
+
+# lazy startup
+STARTED_UP=
+function startup () {
+
+   trap abort int hup quit err
+   set -e
+   
+   [[ -n "$DEBUG" ]] && set -x
+
+   # lazy : run only once
+   if [ -z "$STARTED_UP" ] ; then
+     message "lazy start up"
+
+     ### checking
+     [ ! -f "$ISO_GENERIC" ] && [ ! -d "$ISO_GENERIC" ] && error "Could not find template ISO image"
+     [ -d "$ISO_MOUNT" ] && error "$ISO_MOUNT already exists" 
+     [ -d "$ISO_ROOT" ] && [ ! -d "$ISO_GENERIC" ] && error "$ISO_ROOT already exists" 
+     [ -d "$OVERLAY_ROOT" ] && error "$OVERLAY_ROOT already exists"
+     
+     verbose "Creating temp dirs"
+     mkdir -p "$ISO_MOUNT" "$ISO_ROOT" "$OVERLAY_ROOT"
+
+     if [[ "$IMAGE_TYPE" = "usb" || "$IMAGE_TYPE" = "iso" ]] ; then
+         verbose "Mounting generic ISO $ISO_GENERIC under $ISO_MOUNT"
+         mount -o ro,loop "$ISO_GENERIC" "$ISO_MOUNT"
+     else
+         # the iso_generic name is the directory from which files are available
+         ISO_MOUNT=$ISO_GENERIC
+     fi
+     
+     if [[ "$IMAGE_TYPE" = "iso" || "$IMAGE_TYPE" = "dir" ]] ; then
+       ### ISO
+       ### DONT!! use tar for duplication
+       message "Duplicating ISO image in $ISO_ROOT"
+       (cd "$ISO_MOUNT" ; find . | cpio $CPIO_PARGS "$ISO_ROOT" )
+     
+       if [ -n "$CUSTOM_DIR" ] ; then
+        [ -d "$CUSTOM_DIR" ] || error "Directory $CUSTOM_DIR not found"
+        prepare_custom_image
+       fi
+     fi
+     ### USB specifics are done unconditionnally, see below
+     
+     message "Extracting generic overlay image in $OVERLAY_ROOT"
+     gzip -d -c "$ISO_MOUNT/overlay.img" | ( cd "$OVERLAY_ROOT" ; cpio $CPIO_IARGS )
+     
+     STARTED_UP=true
+   fi
+
+   # for USB: do this for every node
+   if [ "$IMAGE_TYPE" = "usb" ] ; then
+     message "Duplicating $ISO_GENERIC into $NODE_ISO"
+     cp "$ISO_GENERIC" "$NODE_ISO"
+     message "Mounting write-enabled"
+     mount -o loop "$NODE_ISO" "$ISO_ROOT"
+   fi
+   
+}   
+
+function prepare_custom_image () {
+
+   # Cleaning any sequel
+   rm -f custom.img
+   [ -f custom.img ] && error "Could not cleanup custom.img"
+   
+   message "WARNING : You are creating *custom* boot CDs"
+
+   message-n "Creating $ISO_ROOT/custom.img"
+   (cd $"CUSTOM_DIR" ; find . | cpio $CPIO_OARGS) | gzip -9 > "$ISO_ROOT"/custom.img
+   message-done
+   
+}
+
+function node_cleanup () {
+   verbose "Cleaning node-dependent cpio image"
+   rm -rf "$NODE_OVERLAY"
+  
+}
+
+function cleanup () {
+
+   echo "$COMMAND : cleaning up"
+   [[ -n "$DEBUG" ]] && set -x
+
+   verbose "Cleaning overlay image"
+   rm -rf "$OVERLAY_ROOT"
+   verbose "Cleaning ISO image"
+   rm -rf "$ISO_ROOT"
+   verbose "Cleaning node-dep overlay image"
+   rm -f "$NODE_OVERLAY"
+   if [[ "$IMAGE_TYPE" = "iso" || "$IMAGE_TYPE" = "usb" ]]; then
+       verbose "Unmounting $ISO_MOUNT"
+       umount "$ISO_MOUNT" 2> /dev/null
+       rmdir "$ISO_MOUNT"
+   fi
+   exit
+}
+
+function abort () {
+   echo "$COMMAND : Aborting"
+   message "Cleaning $NODE_ISO"
+   rm -f "$NODE_ISO"
+   cleanup
+}
+
+function main () {
+
+   trap abort int hup quit err
+   set -e
+
+   [[ -n "$DEBUG" ]] && set -x
+
+   # accept -b as -c, I am used to it now
+   while getopts "c:b:O:C:fh" opt ; do
+     case "$opt" in
+       c|b)
+# not sure about the status of this, you are warned
+#       echo "The custom option in $COMMAND is broken " ; exit 1
+        echo "WARNING : The custom option in $COMMAND is maybe broken "
+        echo -n "You will have been warned, proceed ? "
+        read answer
+        CUSTOM_DIR="$OPTARG" ;;
+       C)
+        cd "$OPTARG" ;;
+       O)
+        NODEOUTPUT="$OPTARG" ;;
+       f)
+        FORCE_OUTPUT=true ;;
+       h|*)
+        usage ;;
+     esac
+   done
+
+   shift $(($OPTIND-1))
+   
+   [[ -z "$@" ]] && usage
+   ISO_GENERIC="$1"; shift
+
+   if [[ -z "$@" ]] ; then
+     nodes="$DEFAULT_TARGET"
+   else
+     nodes="$@"
+   fi
+
+   ### getting image type
+   iso="${ISO_GENERIC%.iso}"
+   usb="${ISO_GENERIC%.usb}"
+   
+   if [ -d "$ISO_GENERIC" ] ; then
+     IMAGE_TYPE=dir
+   elif [ "$ISO_GENERIC" != "$iso" ] ; then
+     IMAGE_TYPE=iso
+   elif [ "$ISO_GENERIC" != "$usb" ] ; then
+     IMAGE_TYPE=usb
+   else
+     echo "Could not figure type of $ISO_GENERIC -- exiting"
+     exit 1
+   fi
+
+#  perform that later (lazily)
+#  so that (1st) node-dep checking are done before we bother to unpack
+#   startup
+
+   for NODE_CONFIG in $nodes ; do
+
+     if [ "$NODE_CONFIG" = "$DEFAULT_TARGET" ] ; then
+       NODE_DEP=""
+       # default node without customization does not make sense
+       if [ -z "$CUSTOM_DIR" ] ; then
+        message "creating a non-custom node-indep. image refused\n(Would have no effect)"
+        continue
+       else
+        NODENAME="$DEFAULT_TARGET"
+        NODEOUTPUT=$(basename "$CUSTOM_DIR")
+       fi
+     else
+       NODE_DEP=true
+       NODENAME=$(host_name "$NODE_CONFIG")
+       case "$NODENAME" in
+        .*|*.)
+          message "HOST_NAME or DOMAIN_NAME not found in $NODE_CONFIG - skipped"
+          continue ;;
+       esac
+       if [ -z "$NODEOUTPUT" ] ; then
+           if [ -z "$CUSTOM_DIR" ] ; then
+              NODEOUTPUT="$NODENAME"
+           else
+              NODEOUTPUT="${NODENAME}"-$(basename "$CUSTOM_DIR")
+           fi
+       fi
+     fi
+
+     message "$COMMAND : dealing with node $NODENAME"
+
+     if [[ "$IMAGE_TYPE" = "iso" ||  "$IMAGE_TYPE" = "dir" ]] ; then
+       NODE_ISO="$NODEOUTPUT.iso"
+       NODE_LOG="$NODEOUTPUT-iso.log"
+     else
+       NODE_ISO="$NODEOUTPUT.usb"
+       NODE_LOG="$NODEOUTPUT-usb.log"
+     fi
+
+     ### checking
+     if [ -e  "$NODE_ISO" ] ; then
+       if [ -n "$FORCE_OUTPUT" ] ; then
+        message "$NODE_ISO exists, will overwrite (-f)"
+        rm "$NODE_ISO"
+       else
+        message "$NODE_ISO exists, please remove first - skipped" ; continue
+       fi
+     fi
+     if [ -n "$NODE_DEP" -a ! -f "$NODE_CONFIG" ] ; then
+       message "Could not find node-specifig config - skipped" ; continue
+     fi
+     
+     startup
+
+     if [ -n "$NODE_DEP" ] ; then
+       verbose "Pushing node config into overlay image"
+       mkdir -p "$OVERLAY_ROOT"/"$PLNODE_PATH"
+       cp "$NODE_CONFIG" "$OVERLAY_ROOT"/"$PLNODE_PATH"/"$PLNODE"
+     else
+       verbose "Cleaning node config for node-indep. image"
+       rm -f "$OVERLAY_ROOT"/"$PLNODE_PATH"/"$PLNODE"
+     fi
+
+     echo "$COMMAND : Creating overlay image for $NODENAME"
+     (cd "$OVERLAY_ROOT" ; find . | cpio $CPIO_OARGS) | gzip -9 > "$ISO_ROOT"/overlay.img
+
+     if [[ "$IMAGE_TYPE" = "iso"  || "$IMAGE_TYPE" = "dir" ]] ; then
+       ### ISO
+       message "Refreshing isolinux.cfg"
+       # Calculate ramdisk size (total uncompressed size of both archives)
+       
+       ##########
+       # N.B. Thierry Parmentelat - 2006-06-28
+       # the order in which these images need to be mentioned here for
+       # isolinux involved some - not so educated - guesses
+       # as per syslinux source code in syslinux/runkernel.inc, the
+       # config file is parsed left to right, and indeed it's in that
+       # order that the files are loaded right off the CD
+       # This does not tell however, in case a given file is present in
+       # two different images - and that's the very purpose here - which
+       # one will take precedence over the other
+       # I came up with this order on a trial-and-error basis, I would
+       # have preferred to find it described somewhere
+       # Might be worth checking with other versions of syslinux in case
+       # the custom files would turn out to not be taken into account
+       ##########
+
+       if [ -n "$CUSTOM_DIR" ] ; then
+        images="bootcd.img custom.img overlay.img"
+       else
+        images="bootcd.img overlay.img"
+       fi
+       
+       ramdisk_size=$(cd "$ISO_ROOT" ; gzip -l $images | tail -1 | awk '{ print $2; }') # bytes
+       # keep safe, provision for cpio's block size
+       ramdisk_size=$(($ramdisk_size / 1024 + 1)) # kilobytes
+       
+       initrd_images=$(echo "$images" | sed -e 's/ /,/g')
+       # Write isolinux configuration
+       cat > "$ISO_ROOT"/isolinux.cfg <<EOF
+DEFAULT kernel
+APPEND ramdisk_size=$ramdisk_size initrd=$initrd_images root=/dev/ram0 rw
+DISPLAY pl_version
+PROMPT 0
+TIMEOUT 40
+EOF
+
+       message-n "Writing custom image, log on $NODE_LOG .. "
+       mkisofs -o "$NODE_ISO" -R -allow-leading-dots -J -r -b isolinux.bin \
+       -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table \
+       "$ISO_ROOT" > "$NODE_LOG" 2>&1
+       message-done
+
+     else
+       ### USB
+       umount "$NODE_ISO"
+     fi
+     node_cleanup
+     
+     message "Image for $NODENAME in $NODE_ISO"
+   done
+
+   cleanup
+
+}
+
+####################
+main "$@"
index dded060..0e1f598 100755 (executable)
--- a/build.sh
+++ b/build.sh
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2004-2006 The Trustees of Princeton University
 #
-# $Id: build.sh,v 1.39 2006/07/13 17:51:49 mlhuang Exp $
+# $Id: build.sh,v 1.40 2006/07/25 23:51:39 mlhuang Exp $
 #
 
 PATH=/sbin:/bin:/usr/sbin:/usr/bin
 
 CONFIGURATION=default
 NODE_CONFIGURATION_FILE=
+ALL=0
 
 usage()
 {
     echo "Usage: build.sh [OPTION]..."
     echo "     -c name         (Deprecated) Static configuration to use (default: $CONFIGURATION)"
     echo "     -f planet.cnf   Node to customize CD for (default: none)"
+    echo "      -a              Build all images (default: only base images)"
     echo "     -h              This message"
     exit 1
 }
 
 # Get options
-while getopts "c:f:h" opt ; do
+while getopts "c:f:ah" opt ; do
     case $opt in
        c)
            CONFIGURATION=$OPTARG
@@ -36,6 +38,9 @@ while getopts "c:f:h" opt ; do
        f)
            NODE_CONFIGURATION_FILE=$OPTARG
            ;;
+       a)
+           ALL=1
+           ;;
        h|*)
            usage
            ;;
@@ -66,6 +71,14 @@ if [ -f /etc/planetlab/plc_config ] ; then
     . /etc/planetlab/plc_config
 fi
 
+### This support for backwards compatibility can be taken out in the
+### future. RC1 based MyPLCs set $PLC_BOOT_SSL_CRT in the plc_config
+### file, but >=RC2 based bootcd assumes that $PLC_BOOT_CA_SSL_CRT is
+### set.
+if [ -z "$PLC_BOOT_CA_SSL_CRT" -a ! -z "$PLC_BOOT_SSL_CRT" ] ; then
+    PLC_BOOT_CA_SSL_CRT=$PLC_BOOT_SSL_CRT
+fi
+
 # If PLC configuration is not valid, try a static configuration
 if [ -z "$PLC_BOOT_CA_SSL_CRT" -a -d configurations/$CONFIGURATION ] ; then
     # (Deprecated) Source static configuration
@@ -85,10 +98,20 @@ fi
 
 FULL_VERSION_STRING="$PLC_NAME BootCD $BOOTCD_VERSION"
 
+echo "* Building images for $FULL_VERSION_STRING"
+
+# From within a myplc chroot /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.
+[ -d /data ] && BUILDTMP=/data || BUILDTMP=/tmp
+
 # Root of the ISO and USB images
-overlay=$(mktemp -d /tmp/overlay.XXXXXX)
+echo "* Populating root filesystem..."
+overlay=$(mktemp -d ${BUILDTMP}/overlay.XXXXXX)
 install -d -m 755 $overlay
-trap "rm -rf $overlay" ERR
+trap "rm -rf $overlay" ERR INT
 
 # Create version files
 echo "* Creating version files"
@@ -180,11 +203,11 @@ echo "* Compressing overlay image"
 (cd $overlay && find . | cpio --quiet -c -o) | gzip -9 >$isofs/overlay.img
 
 rm -rf $overlay
-trap - ERR
+trap - ERR INT
 
 # Calculate ramdisk size (total uncompressed size of both archives)
 ramdisk_size=$(gzip -l $isofs/bootcd.img $isofs/overlay.img | tail -1 | awk '{ print $2; }') # bytes
-ramdisk_size=$(($ramdisk_size / 1024)) # kilobytes
+ramdisk_size=$((($ramdisk_size + 1023) / 1024)) # kilobytes
 
 # Write isolinux configuration
 echo "$FULL_VERSION_STRING" >$isofs/pl_version
@@ -208,29 +231,325 @@ mkisofs -o "$iso" \
     -no-emul-boot -boot-load-size 4 -boot-info-table \
     $isofs
 
+echo "* Creating ISO image with serial line support"
+iso="$PLC_NAME-BootCD-$BOOTCD_VERSION-serial.iso"
+cat >$isofs/isolinux.cfg <<EOF
+SERIAL 0 115200
+PROMPT 0
+TIMEOUT 120
+DISPLAY pl_version
+DEFAULT serial
+LABEL serial
+       KERNEL kernel
+       APPEND ramdisk_size=$ramdisk_size initrd=bootcd.img,overlay.img root=/dev/ram0 rw  console=ttyS0,115200n8
+EOF
+mkisofs -o "$iso" \
+    -R -allow-leading-dots -J -r \
+    -b isolinux.bin -c boot.cat \
+    -no-emul-boot -boot-load-size 4 -boot-info-table \
+    $isofs
+
 # Create USB image
-echo "* Creating USB image"
+echo -n "* Creating USB image... "
 usb="$PLC_NAME-BootCD-$BOOTCD_VERSION.usb"
 
 # Leave 1 MB of free space on the VFAT filesystem
 mkfs.vfat -C "$usb" $(($(du -sk $isofs | awk '{ print $1; }') + 1024))
 
 # Mount it
-tmp=$(mktemp -d /tmp/bootcd.XXXXXX)
+tmp=$(mktemp -d ${BUILDTMP}/bootcd.XXXXXX)
 mount -o loop "$usb" $tmp
-trap "umount $tmp; rm -rf $tmp" ERR
+trap "umount $tmp; rm -rf $tmp" ERR INT
 
 # Populate it
-echo "* Populating USB image"
+echo -n " populating USB image... "
 (cd $isofs && find . | cpio -p -d -u $tmp/)
 
 # Use syslinux instead of isolinux to make the image bootable
-mv $tmp/isolinux.cfg $tmp/syslinux.cfg
+rm -f $tmp/isolinux.cfg
+cat >$tmp/syslinux.cfg <<EOF
+DEFAULT kernel
+APPEND ramdisk_size=$ramdisk_size initrd=bootcd.img,overlay.img root=/dev/ram0 rw
+DISPLAY pl_version
+PROMPT 0
+TIMEOUT 40
+EOF
+umount $tmp
+rmdir $tmp
+trap - ERR INT
+
+echo "making USB image bootable."
+$srcdir/syslinux/unix/syslinux "$usb"
+
+
+# Create USB image with serial line support
+echo -n "* Creating USB image... "
+usb="$PLC_NAME-BootCD-$BOOTCD_VERSION-serial.usb"
+
+# Leave 1 MB of free space on the VFAT filesystem
+mkfs.vfat -C "$usb" $(($(du -sk $isofs | awk '{ print $1; }') + 1024))
+
+# Mount it
+tmp=$(mktemp -d ${BUILDTMP}/bootcd.XXXXXX)
+mount -o loop "$usb" $tmp
+trap "umount $tmp; rm -rf $tmp" ERR INT
+
+# Populate it
+echo -n " populating USB image... "
+(cd $isofs && find . | cpio -p -d -u $tmp/)
+
+# Use syslinux instead of isolinux to make the image bootable
+rm -f $tmp/isolinux.cfg
+cat >$tmp/syslinux.cfg <<EOF
+SERIAL 0 115200
+PROMPT 0
+TIMEOUT 120
+DISPLAY pl_version
+DEFAULT serial
+LABEL serial
+       KERNEL kernel
+       APPEND ramdisk_size=$ramdisk_size initrd=bootcd.img,overlay.img root=/dev/ram0 rw  console=ttyS0,115200n8
+EOF
+
+umount $tmp
+rmdir $tmp
+trap - ERR INT
+
+echo "making USB image with serial line support bootable."
+$srcdir/syslinux/unix/syslinux "$usb"
+
+[ $ALL -eq 0 ] && exit 0
+
+# Setup CRAMFS related support
+echo "* Setting up CRAMFS-based images"
+tmp=$(mktemp -d ${BUILDTMP}/bootcd.XXXXXX)
+cramfs=$(mktemp ${BUILDTMP}/cramfs.XXXXXX)
+trap "$tmp; rm -rf $tmp $cramfs" ERR INT
+pushd $tmp
+gzip -d -c $isofs/bootcd.img  | cpio -diu
+gzip -d -c $isofs/overlay.img | cpio -diu
+
+# clean out unnecessary rpm lib
+echo "* clearing var/lib/rpm/*"
+rm -f var/lib/rpm/*
+
+# bootcd requires this directory
+mkdir -p mnt/confdevice
+
+# relocate various directory to /tmp
+rm -rf root
+ln -fs /tmp/root root
+ln -fs /sbin/init linuxrc 
+ln -fs /tmp/resolv.conf etc/resolv.conf
+ln -fs /tmp/etc/mtab etc/mtab
+
+# have pl_rsysinit copy over appropriate etc & var directories into /tmp/etc/
+# make /tmp/etc
+echo "* renaming dirs in ./etc"
+pushd etc
+for dir in `find * -type d -prune | grep -v rc.d`; do mv ${dir} ${dir}_o; ln -fs /tmp/etc/${dir} ${dir} ; done
+popd
+
+echo "* renaming dirs in ./var"
+# rename all top-level directories and put in a symlink to /tmp/var
+pushd var
+for dir in `find * -type d -prune`; do mv ${dir} ${dir}_o; ln -fs /tmp/var/${dir} ${dir} ; done
+popd
+
+#overwrite fstab to mount / as cramfs and /tmp as tmpfs
+echo "* Overwriting etc/fstab to use cramfs and tmpfs"
+rm -f ./etc/fstab
+cat >./etc/fstab <<EOF
+/dev/ram0     /              cramfs     ro              0 0
+none          /dev/pts       devpts     gid=5,mode=620  0 0
+none          /proc          proc       defaults        0 0
+none          /sys           sysfs      defaults        0 0
+EOF
+
+pushd dev
+rm -f console
+mknod console c 5 1
+#for i in 0 1 2 3 4 5 6 7 8; do rm -f ram${i} ; done
+#for i in 0 1 2 3 4 5 6 7 8; do mknod ram${i} b 1 ${i} ; done
+#ln -fs ram1 ram
+#ln -fs ram0 ramdisk
+popd
+
+# update etc/inittab to start with pl_rsysinit
+sed -i 's,pl_sysinit,pl_rsysinit,' etc/inittab
+
+# modify inittab to have a serial console
+echo "T0:23:respawn:/sbin/agetty -L ttyS0 9600 vt100" >> etc/inittab
+# and let root log in
+echo "ttyS0" >> etc/securetty
+
+#calculate the size of /tmp based on the size of /etc & /var + 8MB slack
+etcsize=$(du -s ./etc | awk '{ print $1 }')
+varsize=$(du -s ./etc | awk '{ print $1 }')
+let msize=($vsize+$esize+8192)/1024
+
+
+# generate pl_rsysinit
+cat > etc/rc.d/init.d/pl_rsysinit <<EOF
+#!/bin/sh
+# generated by build.sh
+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
+mkdir -p /tmp/etc
+touch /tmp/etc/resolv.conf
+touch /tmp/etc/mtab
+mkdir -p /tmp/var
+
+# make mtab happy
+echo "tmpfs /tmp tmpfs rw,size=${msize}M,mode=1777 1 1" > /tmp/etc/mtab
+
+# copy over directory contents of all _o directories from /etc and /var
+# /tmp/etc and /tmp/var
+pushd /etc
+for odir in \$(cd /etc && ls -d *_o); do dir=\$(echo \$odir | sed 's,\_o$,,'); (mkdir -p /tmp/etc/\$dir && cd \$odir && find . | cpio -p -d -u /tmp/etc/\$dir); done
+popd
+pushd /var
+for odir in \$(cd /var && ls -d *_o); do dir=\$(echo \$odir | sed 's,\_o$,,'); (mkdir -p /tmp/var/\$dir && cd \$odir && find . | cpio -p -d -u /tmp/var/\$dir); done
+popd
+
+echo "done"
+# hand over to pl_sysinit
+echo "pl_rsysinit: handing over to pl_sysinit"
+/etc/init.d/pl_sysinit
+EOF
+chmod +x etc/rc.d/init.d/pl_rsysinit
+
+popd
+
+chown -R 0.0 $cramfs
+
+#create the cramfs image
+echo "* Creating cramfs image"
+mkfs.cramfs $tmp/ $cramfs
+# Leave 1 MB of free space on the VFAT filesystem
+cramfs_size=$(($(du -sk $cramfs | awk '{ print $1; }')))
+mv $cramfs ${BUILDTMP}/cramfs.img
+rm -rf $tmp
+trap - ERR INT
+
+# Create ISO CRAMFS image
+echo "* Creating ISO CRAMFS-based image"
+iso="$PLC_NAME-BootCD-$BOOTCD_VERSION-cramfs.iso"
+
+tmp=$(mktemp -d ${BUILDTMP}/bootcd.XXXXXX)
+trap "$tmp; rm -rf $tmp" ERR INT
+(cd $isofs && find . | grep -v "\.img$" | cpio -p -d -u $tmp/)
+cat >$tmp/isolinux.cfg <<EOF
+DEFAULT kernel
+APPEND ramdisk_size=$cramfs_size initrd=cramfs.img root=/dev/ram0 ro
+DISPLAY pl_version
+PROMPT 0
+TIMEOUT 40
+EOF
+
+cp ${BUILDTMP}/cramfs.img $tmp
+mkisofs -o "$iso" \
+    -R -allow-leading-dots -J -r \
+    -b isolinux.bin -c boot.cat \
+    -no-emul-boot -boot-load-size 4 -boot-info-table \
+    $tmp
+
+# Create ISO CRAMFS image with serial line support
+echo "* Creating ISO image with cramfs and serial line support"
+cat >$tmp/isolinux.cfg <<EOF
+SERIAL 0 115200
+PROMPT 0
+TIMEOUT 120
+DISPLAY pl_version
+DEFAULT serial
+LABEL serial
+       KERNEL kernel
+       APPEND ramdisk_size=$cramfs_size initrd=cramfs.img root=/dev/ram0 ro  console=ttyS0,115200n8
+EOF
+
+iso="$PLC_NAME-BootCD-$BOOTCD_VERSION-cramfs-serial.iso"
+mkisofs -o "$iso" \
+    -R -allow-leading-dots -J -r \
+    -b isolinux.bin -c boot.cat \
+    -no-emul-boot -boot-load-size 4 -boot-info-table \
+    $tmp
+
+rm -rf $tmp
+trap - ERR INT
+
+# Create USB CRAMFS based image
+echo "* Creating USB CRAMFS based image"
+usb="$PLC_NAME-BootCD-$BOOTCD_VERSION-cramfs.usb"
+
+# leave 1MB of space on the USB VFAT
+let vfat_size=${cramfs_size}+2048
+
+# Make VFAT filesystem for USB
+mkfs.vfat -C "$usb" $vfat_size
+
+# Mount it
+tmp=$(mktemp -d ${BUILDTMP}/bootcd.XXXXXX)
+mount -o loop "$usb" $tmp
+trap "umount $tmp; rm -rf $tmp ${BUILDTMP}/cramfs.img" ERR INT
+
+# Populate it
+echo "* Populating USB with overlay images and cramfs"
+(cd $isofs && find . | grep -v "\.img$" | cpio -p -d -u $tmp/)
+cp ${BUILDTMP}/cramfs.img $tmp/
+
+# Use syslinux instead of isolinux to make the image bootable
+cat >$tmp/syslinux.cfg <<EOF
+TIMEOUT 120
+DISPLAY pl_version
+DEFAULT vga
+LABEL vga
+       KERNEL kernel
+       APPEND ramdisk_size=$cramfs_size initrd=cramfs.img root=/dev/ram0 ro
+EOF
+umount $tmp
+rmdir $tmp
+trap - ERR INT
+
+echo "* Making USB CRAMFS based image bootable"
+$srcdir/syslinux/unix/syslinux "$usb"
+
+# Create USB CRAMFS based image w/ serial line support
+echo "* Creating USB CRAMFS based image w/ serial line support"
+usb="$PLC_NAME-BootCD-$BOOTCD_VERSION-cramfs-serial.usb"
+
+# leave 4MB of space on the USB VFAT
+let vfat_size=${cramfs_size}+2048
+
+# Make VFAT filesystem for USB
+mkfs.vfat -C "$usb" $vfat_size
+
+# Mount it
+tmp=$(mktemp -d ${BUILDTMP}/bootcd.XXXXXX)
+mount -o loop "$usb" $tmp
+trap "umount $tmp; rm -rf $tmp ${BUILDTMP}/cramfs.img" ERR INT
+
+# Populate it
+echo "* Populating USB with overlay images and cramfs"
+(cd $isofs && find . | grep -v "\.img$" | cpio -p -d -u $tmp/)
+cp ${BUILDTMP}/cramfs.img $tmp/
+
+# Use syslinux instead of isolinux to make the image bootable
+cat >$tmp/syslinux.cfg <<EOF
+SERIAL 0 9600
+PROMPT 0
+TIMEOUT 120
+DISPLAY pl_version
+DEFAULT serial
+LABEL serial
+       KERNEL kernel
+       APPEND ramdisk_size=$cramfs_size initrd=cramfs.img root=/dev/ram0 ro  console=ttyS0,9600n8
+EOF
 umount $tmp
 rmdir $tmp
-trap - ERR
+trap - ERR INT
 
-echo "* Making USB image bootable"
+echo "* Making USB CRAMFS based image /w serial line support bootable"
 $srcdir/syslinux/unix/syslinux "$usb"
 
 exit 0
index f9e4559..fb34e6c 100755 (executable)
@@ -45,7 +45,7 @@
 set -e 
 COMMANDSH=$(basename $0)
 COMMAND=$(basename $0 .sh)
-REVISION="$Id: cdcustom.sh,v 1.7 2006/06/28 14:18:11 thierry Exp $"
+REVISION="$Id: cdcustom.sh,v 1.8 2006/06/28 15:01:01 thierry Exp $"
 
 function usage () {
 
@@ -227,7 +227,7 @@ function main () {
    [[ -z "$@" ]] && usage
    ISO_GENERIC=$1; shift
 
-   if [ -z "$@" ] ; then
+   if [[ -z "$@" ]] ; then
      nodes="$DEFAULT_TARGET"
    else
      nodes="$@"
index bf662d2..3d5ea77 100644 (file)
@@ -125,11 +125,11 @@ find_node_config()
 
     echo "pl_netinit: looking for node configuration file on flash based devices"
 
-    # make the sd* expansion fail to an empty string if there are no sd
+    # make the sd* hd* expansion fail to an empty string if there are no sd
     # devices
     shopt -s nullglob
 
-    for device in /sys/block/sd*; do
+    for device in /sys/block/[hs]d*; do
        removable=`cat $device/removable`
        if [[ $removable -ne 1 ]]; then
            continue
@@ -235,6 +235,17 @@ if [[ $DEFAULT_NET_CONF -eq 1 ]]; then
     /bin/rm -f $USED_NET_CONF
 fi
 
+# initialize IPMI device
+if [[ -n "$IPMI_ADDRESS" ]] ; then
+    echo -n "pl_netinit: initializing IPMI: "
+    cmd="ipnmac -i $IPMI_ADDRESS"
+    if [[ -n "$IPMI_MAC" ]] ; then
+       cmd="$cmd -m $IPMI_MAC"
+    fi
+    echo $cmd
+    $cmd
+fi
+
 # now, we need to find which device to use (ie, eth0 or eth1). start out
 # by defaulting to eth0, then see if the network configuration file specified
 # either a mac address (in which case we will need to find the device), or
@@ -243,14 +254,14 @@ fi
 if [[ -n "$NET_DEVICE" ]]; then
     # the user specified a mac address we should use. find the network
     # device for it.
-    echo "pl_netinit: looking for a device with mac address $NET_DEVICE"
+    NET_DEVICE=$(tr A-Z a-z <<<$NET_DEVICE)
 
     pushd /sys/class/net
     for device in *; do
-       dev_address=`cat $device/address`
-       if [[ "$dev_address" == "$NET_DEVICE" ]]; then
+       dev_address=`cat $device/address | tr A-Z a-z`
+       if [ "$device" == "$NET_DEVICE" -o "$dev_address" == "$NET_DEVICE" ]; then
            ETH_DEVICE=$device
-           echo "pl_netinit: found device $ETH_DEVICE"
+           echo "pl_netinit: found device $ETH_DEVICE with mac address $dev_address"
            break
        fi
     done
index b3a56ec..48e3d5b 100644 (file)
@@ -3,7 +3,8 @@
 # Valid environment variables to appear in a planetlab config file
 TAGS='IP_METHOD HOST_NAME DOMAIN_NAME PROXY_SERVER
       IP_ADDRESS IP_GATEWAY IP_NETMASK IP_NETADDR IP_BROADCASTADDR 
-      IP_DNS1 IP_DNS2 NET_DEVICE NODE_KEY NODE_ID'
+      IP_DNS1 IP_DNS2 NET_DEVICE NODE_KEY NODE_ID
+      IPMI_ADDRESS IPMI_MAC'
 
 # Valid characters that variable can be set to
 CHARS='[:alnum:]\.: _-'
diff --git a/newbuild.sh b/newbuild.sh
new file mode 100755 (executable)
index 0000000..4747582
--- /dev/null
@@ -0,0 +1,162 @@
+#!/bin/bash
+#
+# Builds custom BootCD ISO and USB images in the current
+# directory.
+#
+# Mark Huang <mlhuang@cs.princeton.edu>
+# Copyright (C) 2004-2006 The Trustees of Princeton University
+#
+# $Id: newbuild.sh,v 1.2 2006/12/04 20:07:18 mlhuang Exp $
+#
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+
+BOOTCD_VERSION=4.0
+
+if [ -f /etc/planetlab/plc_config ] ; then
+    # Source PLC configuration
+    . /etc/planetlab/plc_config
+else
+    echo "Could not find /etc/planetlab/plc_config."
+    echo "This file defines the configuration of your PlanetLab installation."
+    exit 1
+fi
+
+# This support for backwards compatibility can be taken out in the
+# future. RC1 based MyPLCs set $PLC_BOOT_SSL_CRT in the plc_config
+# file, but >=RC2 based bootcd assumes that $PLC_BOOT_CA_SSL_CRT is
+# set.
+if [ -z "$PLC_BOOT_CA_SSL_CRT" -a ! -z "$PLC_BOOT_SSL_CRT" ] ; then
+    PLC_BOOT_CA_SSL_CRT=$PLC_BOOT_SSL_CRT
+    PLC_API_CA_SSL_CRT=$PLC_API_SSL_CRT
+fi
+
+output="$PLC_NAME-BootCD-$BOOTCD_VERSION.iso"
+
+usage()
+{
+    echo "Usage: build.sh [OPTION]..."
+    eceho "    -o file         Output file (default: $output)"
+    echo "     -h              This message"
+    exit 1
+}
+
+# Get options
+while getopts "o:h" opt ; do
+    case $opt in
+       o)
+           output=$OPTARG
+           ;;
+       h|*)
+           usage
+           ;;
+    esac
+done
+
+FULL_VERSION_STRING="$PLC_NAME BootCD $BOOTCD_VERSION"
+echo "* Building image for $FULL_VERSION_STRING"
+
+# Do not tolerate errors
+set -e
+
+# Change to our source directory
+srcdir=$(cd $(dirname $0) && pwd -P)
+pushd $srcdir >/dev/null
+
+# Root of the isofs
+isofs=$PWD/isofs
+
+# Miscellaneous files
+misc=$(mktemp -d /tmp/misc.XXXXXX)
+trap "rm -rf $misc" ERR INT
+
+# initramfs requires that /init be present
+ln -sf /sbin/init $misc/init
+
+# Create version file
+echo "$FULL_VERSION_STRING" >$misc/.bootcd
+
+# Install GPG, boot, and API server public keys and certificates
+install -D -m 644 $PLC_ROOT_GPG_KEY_PUB $misc/$PLC_ROOT_GPG_KEY_PUB
+install -D -m 644 $PLC_BOOT_CA_SSL_CRT $misc/$PLC_BOOT_CA_SSL_CRT
+install -D -m 644 $PLC_API_CA_SSL_CRT $misc/$PLC_API_CA_SSL_CRT
+
+cat > $misc/etc/planetlab/plc_config <<EOF
+PLC_ROOT_GPG_KEY_PUB='$PLC_ROOT_GPG_KEY_PUB'
+
+PLC_BOOT_HOST='$PLC_BOOT_HOST'
+PLC_BOOT_IP='$PLC_BOOT_IP'
+PLC_BOOT_PORT=$PLC_BOOT_PORT
+PLC_BOOT_SSL_PORT=$PLC_BOOT_SSL_PORT
+PLC_BOOT_CA_SSL_CRT='$PLC_BOOT_CA_SSL_CRT'
+
+PLC_API_HOST='$PLC_API_HOST'
+PLC_API_IP='$PLC_API_IP'
+PLC_API_PORT=$PLC_API_PORT
+PLC_API_PATH='$PLC_API_PATH'
+PLC_API_CA_SSL_CRT='$PLC_API_CA_SSL_CRT'
+EOF
+
+# Generate /etc/issue
+if [ "$PLC_WWW_PORT" = "443" ] ; then
+    PLC_WWW_URL="https://$PLC_WWW_HOST/"
+elif [ "$PLC_WWW_PORT" != "80" ] ; then
+    PLC_WWW_URL="http://$PLC_WWW_HOST:$PLC_WWW_PORT/"
+else
+    PLC_WWW_URL="http://$PLC_WWW_HOST/"
+fi
+
+mkdir -p $misc/etc
+cat >$misc/etc/issue <<EOF
+$FULL_VERSION_STRING
+$PLC_NAME Node: \n
+Kernel \r on an \m
+$PLC_WWW_URL
+
+This machine is a node in the $PLC_NAME distributed network.  It has
+not fully booted yet. If you have cancelled the boot process at the
+request of $PLC_NAME Support, please follow the instructions provided
+to you. Otherwise, please contact $PLC_MAIL_SUPPORT_ADDRESS.
+
+Console login at this point is restricted to root. Provide the root
+password of the default $PLC_NAME Central administrator account at the
+time that this CD was created.
+
+EOF
+
+# Pack miscellaneous files into a compressed archive
+echo "* Compressing miscellaneous files image"
+(cd $misc && find . | cpio --quiet -H newc -o) | \
+    python ../filesystem/cpiochown.py --owner root:root - | \
+    gzip -9 >$isofs/misc.img
+
+rm -rf $misc
+trap - ERR INT
+
+# Calculate ramdisk size (total uncompressed size of all initrds)
+ramdisk_size=$(gzip -l $isofs/*.img | tail -1 | awk '{ print $2; }') # bytes
+ramdisk_size=$((($ramdisk_size + 1023) / 1024)) # kilobytes
+
+# Write isolinux configuration
+echo "$FULL_VERSION_STRING" >$isofs/version
+cat >$isofs/isolinux.cfg <<EOF
+DEFAULT kernel
+APPEND ramdisk_size=$ramdisk_size initrd=base.img,bootcd.img,misc.img root=/dev/ram0 rw console=tty0
+DISPLAY version
+PROMPT 0
+TIMEOUT 40
+EOF
+
+popd >/dev/null
+
+# Create ISO image
+echo "* Creating ISO image"
+mkisofs -o "$output" \
+    -R -allow-leading-dots -J -r \
+    -b isolinux.bin -c boot.cat \
+    -no-emul-boot -boot-load-size 4 -boot-info-table \
+    $isofs
+
+# XXX Create USB image
+
+exit 0
diff --git a/prep.sh b/prep.sh
index 2688d4d..883e10f 100755 (executable)
--- a/prep.sh
+++ b/prep.sh
@@ -8,7 +8,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2004-2006 The Trustees of Princeton University
 #
-# $Id: prep.sh,v 1.10 2006/07/24 15:33:07 mlhuang Exp $
+# $Id: prep.sh,v 1.12 2006/08/21 20:24:09 mlhuang Exp $
 #
 
 PATH=/sbin:/bin:/usr/sbin:/usr/bin
@@ -32,7 +32,7 @@ basearch=i386
 
 # Packages to install
 packagelist=(
-dev
+udev
 dhclient
 bash
 coreutils
@@ -73,6 +73,7 @@ dosfstools
 dos2unix
 bind-utils
 sharutils
+vconfig
 )
 
 # Unnecessary junk
@@ -167,6 +168,10 @@ popd
 # Disable all services in reference image
 chroot $bootcd sh -c "/sbin/chkconfig --list | awk '{ print \$1 }' | xargs -i /sbin/chkconfig {} off"
 
+# Install ipnmac (for SuperMicro machines with IPMI)
+echo "* Installing IPMI utilities"
+install -D -m 755 ipnmac/ipnmac.x86 $bootcd/usr/sbin/ipnmac
+
 # Install configuration files
 echo "* Installing configuration files"
 for file in fstab mtab modprobe.conf inittab hosts sysctl.conf ; do