X-Git-Url: http://git.onelab.eu/?p=bootcd.git;a=blobdiff_plain;f=build.sh;h=a051700d2be0d8790ede14d557ca0dabf3a202ae;hp=c165075c1f1a99e574838fdecfc59b69656325d7;hb=HEAD;hpb=636f223881e5f8593223a25ac3b12bea9736a6c6 diff --git a/build.sh b/build.sh index c165075..a051700 100755 --- a/build.sh +++ b/build.sh @@ -1,314 +1,804 @@ #!/bin/bash +# +# Builds custom BootCD ISO and USB images in the current +# directory. +# +# Aaron Klingaman +# Mark Huang +# Copyright (C) 2004-2007 The Trustees of Princeton University +# +# 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 +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 +NODE_CONFIGURATION_FILE= +CUSTOM_DIR= +OUTPUT_BASE= +DRY_RUN="" +OUTPUT_NAME="" +TYPES="" +KERNEL_ARGS="" + +# various globals +BUILDTMP="" +FULL_VERSION_STRING="" +ISOREF="" +ISOFS="" +OVERLAY="" +IS_SERIAL="" +console_dev="" +console_baud="" +console_spec="" +console_serial_line="" + + +#################### compute all supported types +# removing support for serial in the type +# this is because kargs.txt goes in the overlay, that is computed only once +# so we cannot handle serial and graphic modes within the same invokation of this script + +ALL_TYPES="" +for x in iso usb usb_partition; do for c in "" "_cramfs" ; do + t="${x}${c}" + case $t in + usb_partition_cramfs) + # unsupported + ;; + *) + ALL_TYPES="$ALL_TYPES $t" ;; + esac +done; done + +#################### cleanup utilities +declare -a _CLEANUPS=() +function do_cleanup() { + cd / ; for i in "${_CLEANUPS[@]}"; do $i ; done +} +function push_cleanup() { + _CLEANUPS=( "${_CLEANUPS[@]}" "$*" ) +} +function pop_cleanup() { + unset _CLEANUPS[$((${#_CLEANUPS[@]} - 1))] +} + +#################### initialization +function init_and_check () { + + # Change to our source directory + local srcdir=$(cd $DIRNAME && pwd -P) + pushd $srcdir + + # Root of the isofs + 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 "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 -set -e + # build/version.txt written by prep.sh + BOOTCD_VERSION=$(cat ${VARIANT}/version.txt) -# where the boot cd build config files are stored (and certificats/keys) -CONFIGURATIONS_DIR=configurations/ + if [ -f /etc/planetlab/plc_config ] ; then + # Source PLC configuration + . /etc/planetlab/plc_config + fi -# where built files are stored -BUILD_DIR=build/ + # use /var/tmp that should be large enough on both chroot- or vserver-based myplc + BUILDTMP=/var/tmp -BOOTCD_VERSION="3.0-beta0.4" -FULL_VERSION_STRING="PlanetLab BootCD" -OUTPUT_IMAGE_NAME='PlanetLab-BootCD' - -SYSLINUX_SRC=sources/syslinux-2.11.tar.bz2 + FULL_VERSION_STRING="${PLC_NAME} BootCD ${BOOTCD_VERSION}" -BOOTCD_YUM_GROUP=BootCD +} -CDRECORD_FLAGS="-v -dao" +# NOTE +# the custom-dir feature is designed to let a myplc try/ship a patched bootcd +# without the need for a full devel environment +# for example, you would create /root/custom-bootcd/etc/rc.d/init.d/pl_hwinit +# and run this script with -C /root/custom-bootcd +# this creates a third .img image of the custom dir, that 'hides' the files from +# bootcd.img in the resulting unionfs +# it seems that this feature has not been used nor tested in a long time, use with care + +usage() { + 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" + echo " -a Build all known types as listed below" + echo " -s console-info Enable a serial line as console and also bring up getty on that line" + echo " console-info: tty:baud-rate:parity:bits" + echo " or 'default' shortcut for $SERIAL_CONSOLE" + echo " -S equivalent to -s default" + echo " -O output-base The prefix of the generated files (default: PLC_NAME-BootCD-VERSION)" + echo " useful when multiple types are provided" + 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" + echo "All known types: $ALL_TYPES" + exit 1 +} -CONF_FILES_DIR=conf_files/ +#################### +function parse_command_line () { + + # init + TYPES="" + # Get options + 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" ;; + a) TYPES="$ALL_TYPES" ;; + s) CONSOLE_INFO="$OPTARG" ;; + S) CONSOLE_INFO=$SERIAL_CONSOLE ;; + O) OUTPUT_BASE="$OPTARG" ;; + o) OUTPUT_NAME="$OPTARG" ;; + C) CUSTOM_DIR="$OPTARG" ;; + V) VARIANT="$OPTARG" ;; + k) KERNEL_ARGS="$KERNEL_ARGS $OPTARG" ;; + n) DRY_RUN=true ;; + h|*) usage ;; + esac + done -# size of the ram disk in MB -RAMDISK_SIZE=64 + # 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 -# the bytes per inode ratio (the -i value in mkfs.ext2) for the ramdisk -INITRD_BYTES_PER_INODE=1024 + # check TYPES + local matcher="XXX$(echo $ALL_TYPES | sed -e 's,\W,XXX,g')XXX" + for t in $TYPES; do + echo Checking type $t + echo $matcher | grep XXX${t}XXX &> /dev/null + if [ "$?" != 0 ] ; then + echo Unknown type $t + usage + fi + done +} -function usage() -{ - echo "Usage: build.sh []" - echo "Action: build burn clean" - echo - echo "If configuration is missing, 'default' is loaded" - exit +#################### +function init_serial () { + local console=$1; shift + if [ "$console" == "$GRAPHIC_CONSOLE" ] ; then + IS_SERIAL= + console_spec="" + echo "Standard, graphic, non-serial mode" + else + IS_SERIAL=true + console_dev=$(echo "$console" | awk -F: ' {print $1}') + console_baud=$(echo "$console" | awk -F: ' {print $2}') + [ -z "$console_baud" ] && console_baud="115200" + local console_parity=$(echo "$console" | awk -F: ' {print $3}') + [ -z "$console_parity" ] && console_parity="n" + local console_bits=$(echo "$console" | awk -F: ' {print $4}') + [ -z "$console_bits" ] && console_bits="8" + console_spec="console=${console_dev},${console_baud}${console_parity}${console_bits}" + local tty_nb=$(echo $console_dev | sed -e 's,[a-zA-Z],,g') + console_serial_line="SERIAL ${tty_nb} ${console_baud}" + echo "Serial mode" + echo "console_serial_line=${console_serial_line}" + echo "console_spec=${console_spec}" + fi } +#################### run once : build the overlay image +function build_overlay () { -function build_cdroot() -{ - if [ -f $CD_ROOT/.built ]; then - echo "cd root already built, skipping" - return - fi + BUILDTMP=$(mktemp -d ${BUILDTMP}/bootcd.XXXXXX) + push_cleanup rm -fr "${BUILDTMP}" - clean - - mkdir -p $CD_ROOT/dev/pts - mkdir -p $CD_ROOT/proc - mkdir -p $CD_ROOT/etc - - echo "copy fstab and mtab" - cp -f $CONF_FILES_DIR/fstab $CD_ROOT/etc/ - cp -f $CONF_FILES_DIR/mtab $CD_ROOT/etc/ - - echo "setup rpm to install only en_US locale and no docs" - mkdir -p $CD_ROOT/etc/rpm - cp -f $CONF_FILES_DIR/macros $CD_ROOT/etc/rpm - - echo "initialize rpm db" - mkdir -p $CD_ROOT/var/lib/rpm - rpm --root $CD_ROOT --initdb - - echo "install boot cd base rpms" - yum -c yum.conf --installroot=$CD_ROOT -y groupinstall $BOOTCD_YUM_GROUP - - echo "checking to make sure rpms were installed" - packages=`cat yumgroups.xml | grep packagereq | sed 's#<[^<]*>##g'` - set +e - for package in $packages; do - echo "checking for package $package" - chroot $CD_ROOT /bin/rpm -qi $package > /dev/null - if [[ "$?" -ne 0 ]]; then - echo "package $package was not installed in the cd root." - echo "make sure it exists in the yum repository." - exit 1 - fi + # initialize ISOFS + ISOFS="${BUILDTMP}/isofs" + mkdir -p "$ISOFS" + for i in "$ISOREF"/isofs/{bootcd.img,kernel}; do + 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 + + # Root of the ISO and USB images + echo "* Populating root filesystem..." + OVERLAY="${BUILDTMP}/overlay" + install -d -m 755 $OVERLAY + push_cleanup rm -fr $OVERLAY + + # Create version files + echo "* Creating version files" + + # Boot Manager compares pl_version in both places to make sure that + # the right CD is mounted. We used to boot from an initrd and mount + # the CD on /usr. Now we just run everything out of the initrd. + for file in $OVERLAY/pl_version $OVERLAY/usr/isolinux/pl_version ; do + mkdir -p $(dirname $file) + echo "$FULL_VERSION_STRING" >$file done - set -e - - echo "removing unneccessary build files" - (cd $CD_ROOT/lib/modules && \ - find ./ -type d -name build -maxdepth 2 -exec rm -rf {} \;) - - echo "setting up non-ssh authentication" - mkdir -p $CD_ROOT/etc/samba - chroot $CD_ROOT /usr/sbin/authconfig --nostart --kickstart \ - --enablemd5 --enableshadow - - echo "setting root password" - sed -i "s#root::#root:$ROOT_PASSWORD:#g" $CD_ROOT/etc/shadow - - echo "relocate some large directories out of the root system" - # get /var/lib/rpm out, its 12mb. create in its place a - # symbolic link to /usr/relocated/var/lib/rpm - mkdir -p $CD_ROOT/usr/relocated/var/lib/ - mv $CD_ROOT/var/lib/rpm $CD_ROOT/usr/relocated/var/lib/ - (cd $CD_ROOT/var/lib && ln -s ../../usr/relocated/var/lib/rpm rpm) - - # get /lib/tls out - mkdir -p $CD_ROOT/usr/relocated/lib - mv $CD_ROOT/lib/tls $CD_ROOT/usr/relocated/lib/ - (cd $CD_ROOT/lib && ln -s ../usr/relocated/lib/tls tls) - - echo "extracting syslinux, copying isolinux files to cd" - mkdir -p $CD_ROOT/usr/isolinux/ - mkdir -p $BUILD_DIR/syslinux - tar -C $BUILD_DIR/syslinux -xjvf $SYSLINUX_SRC - find $BUILD_DIR/syslinux -name isolinux.bin \ - -exec cp -f {} $CD_ROOT/usr/isolinux/ \; - - echo "moving kernel to isolinux directory" - KERNEL=$CD_ROOT/boot/vmlinuz-* - mv -f $KERNEL $CD_ROOT/usr/isolinux/kernel - - echo "creating version files" - echo "$FULL_VERSION_STRING" > $CD_ROOT/usr/isolinux/pl_version - echo "$FULL_VERSION_STRING" > $CD_ROOT/pl_version - - touch $CD_ROOT/.built -} -function build_initrd() -{ - echo "building initrd" - rm -f $INITRD - rm -f $INITRD.gz - - echo "copy fstab and mtab" - cp -f $CONF_FILES_DIR/fstab $CD_ROOT/etc/ - cp -f $CONF_FILES_DIR/mtab $CD_ROOT/etc/ - - echo "installing generic modprobe.conf" - cp -f $CONF_FILES_DIR/modprobe.conf $CD_ROOT/etc/ - - echo "installing our own inittab and init scripts" - cp -f $CONF_FILES_DIR/inittab $CD_ROOT/etc - init_scripts="pl_sysinit pl_hwinit pl_netinit pl_validateconf pl_boot" - for script in $init_scripts; do - cp -f $CONF_FILES_DIR/$script $CD_ROOT/etc/init.d/ - chmod +x $CD_ROOT/etc/init.d/$script + # Install boot server configuration files + echo "* Installing boot server configuration files" + + # We always intended to bring up and support backup boot servers, + # but never got around to it. Just install the same parameters for + # both for now. + for dir in $OVERLAY/usr/boot $OVERLAY/usr/boot/backup ; do + install -D -m 644 $PLC_BOOT_CA_SSL_CRT $dir/cacert.pem + install -D -m 644 $PLC_ROOT_GPG_KEY_PUB $dir/pubring.gpg + echo "$PLC_BOOT_HOST" >$dir/boot_server + echo "$PLC_BOOT_SSL_PORT" >$dir/boot_server_port + echo "/boot/" >$dir/boot_server_path done - echo "setup basic networking files" - cp -f $CONF_FILES_DIR/hosts $CD_ROOT/etc/ - - echo "copying sysctl.conf (fix tcp window scaling and broken routers)" - cp -f $CONF_FILES_DIR/sysctl.conf $CD_ROOT/etc/ - - echo "setup default network conf file" - mkdir -p $CD_ROOT/usr/boot - cp -f $CONF_FILES_DIR/default-net.cnf $CD_ROOT/usr/boot/ - - echo "setup boot server configuration" - cp -f $CURRENT_CONFIG_DIR/$PRIMARY_SERVER_CERT $CD_ROOT/usr/boot/cacert.pem - cp -f $CURRENT_CONFIG_DIR/$PRIMARY_SERVER_GPG $CD_ROOT/usr/boot/pubring.gpg - echo "$PRIMARY_SERVER" > $CD_ROOT/usr/boot/boot_server - echo "$PRIMARY_SERVER_PORT" > $CD_ROOT/usr/boot/boot_server_port - echo "$PRIMARY_SERVER_PATH" > $CD_ROOT/usr/boot/boot_server_path - - echo "setup backup boot server configuration" - mkdir -p $CD_ROOT/usr/boot/backup - cp -f $CURRENT_CONFIG_DIR/$BACKUP_SERVER_CERT \ - $CD_ROOT/usr/boot/backup/cacert.pem - cp -f $CURRENT_CONFIG_DIR/$BACKUP_SERVER_GPG \ - $CD_ROOT/usr/boot/backup/pubring.gpg - echo "$BACKUP_SERVER" > $CD_ROOT/usr/boot/backup/boot_server - echo "$BACKUP_SERVER_PORT" > $CD_ROOT/usr/boot/backup/boot_server_port - echo "$BACKUP_SERVER_PATH" > $CD_ROOT/usr/boot/backup/boot_server_path - - echo "copying old boot cd directory bootme (TEMPORARY)" - cp -r bootme_old $CD_ROOT/usr/bootme - echo "$FULL_VERSION_STRING" > $CD_ROOT/usr/bootme/ID - echo "$PRIMARY_SERVER" > $CD_ROOT/usr/bootme/BOOTSERVER - echo "$PRIMARY_SERVER" > $CD_ROOT/usr/bootme/BOOTSERVER_IP - echo "$PRIMARY_SERVER_PORT" > $CD_ROOT/usr/bootme/BOOTPORT - - echo "forcing lvm to make lvm1 partitions (TEMPORARY)" - cp -f $CONF_FILES_DIR/lvm.conf $CD_ROOT/etc/lvm/ - - echo "copying isolinux configuration files" - cp -f $CONF_FILES_DIR/isolinux.cfg $CD_ROOT/usr/isolinux/ - echo "$FULL_VERSION_STRING" > $CD_ROOT/usr/isolinux/message.txt - - echo "writing /etc/issue" - echo "$FULL_VERSION_STRING" > $CD_ROOT/etc/issue - echo "Kernel \r on an \m" >> $CD_ROOT/etc/issue - echo "" >> $CD_ROOT/etc/issue - echo "" >> $CD_ROOT/etc/issue - - if [[ ! -z "$NODE_CONFIGURATION_FILE" ]]; then - echo "Copying node configuration file to cd" - cp -f $CURRENT_CONFIG_DIR/$NODE_CONFIGURATION_FILE \ - $CD_ROOT/usr/boot/plnode.txt + # Install old-style boot server configuration files + # as opposed to what a former comment suggested, + # this is still required, somewhere in the bootmanager apparently + install -D -m 644 $PLC_BOOT_CA_SSL_CRT $OVERLAY/usr/bootme/cacert/$PLC_BOOT_HOST/cacert.pem + echo "$FULL_VERSION_STRING" >$OVERLAY/usr/bootme/ID + echo "$PLC_BOOT_HOST" >$OVERLAY/usr/bootme/BOOTSERVER + echo "$PLC_BOOT_HOST" >$OVERLAY/usr/bootme/BOOTSERVER_IP + echo "$PLC_BOOT_SSL_PORT" >$OVERLAY/usr/bootme/BOOTPORT + + # Generate /etc/issue + echo "* Generating /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 $OVERLAY/etc + cat >$OVERLAY/etc/issue < $OVERLAY/etc/passwd + +# this is more harmful than helpful +# idea being, since we start a full-featured fedora system now, it would +# have been nice to be able to enter sshd very early on - before bm has even been downloaded +# however somehow it appears that these lines ruin all chances to enter ssh at all +# either early or even later on; +# plus, it is unclear what this would give on non=systemd nodes, so I am backing off for now +# # recent bootCDs rely on a standard systemd startup sequence +# # so allow debug key to enter in this context whenever that makes sense +# mkdir -p $OVERLAY/root/.ssh +# chmod 700 $OVERLAY/root/.ssh +# cp $PLC_DEBUG_SSH_KEY_PUB $OVERLAY/root/.ssh/authorized_keys +# chmod 600 $OVERLAY/root/.ssh/authorized_keys + + # 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 + + [ -n "$IS_SERIAL" ] && KERNEL_ARGS="$KERNEL_ARGS ${console_spec}" + + # making sure the network interfaces are still numbered eth0 and above + KERNEL_ARGS="$KERNEL_ARGS biosdevname=0" + # this apparently is required instead (or in addition to) starting with f29 + KERNEL_ARGS="$KERNEL_ARGS net.ifnames=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" + (cd $OVERLAY && find . | cpio --quiet -c -o) | gzip -9 >$ISOFS/overlay.img + + rm -rf $OVERLAY + pop_cleanup + + if [ -n "$CUSTOM_DIR" ]; then + echo "* Compressing custom image" + (cd "$CUSTOM_DIR" && find . | cpio --quiet -c -o) | gzip -9 >$ISOFS/custom.img fi - echo "making the isolinux initrd kernel command line match rd size" - let INITRD_SIZE_KB=$(($RAMDISK_SIZE * 1024)) - sed -i "s#ramdisk_size=0#ramdisk_size=$INITRD_SIZE_KB#g" \ - $CD_ROOT/usr/isolinux/isolinux.cfg - - echo "building pcitable for hardware detection" - pci_map_file=`find $CD_ROOT/lib/modules/ -name modules.pcimap | head -1` - module_dep_file=`find $CD_ROOT/lib/modules/ -name modules.dep | head -1` - pci_table=$CD_ROOT/usr/share/hwdata/pcitable - ./scripts/rewrite-pcitable.py $module_dep_file $pci_map_file $pci_table \ - $CD_ROOT/etc/pl_pcitable - - dd if=/dev/zero of=$INITRD bs=1M count=$RAMDISK_SIZE - mkfs.ext2 -F -m 0 -i $INITRD_BYTES_PER_INODE $INITRD - mkdir -p $INITRD_MOUNT - mount -o loop,rw $INITRD $INITRD_MOUNT - - echo "copy all files except usr to ramdisk" - pushd . - cd $CD_ROOT - find . -path ./usr -prune -o -print | cpio -p -d -u $INITRD_MOUNT + # Calculate ramdisk size (total uncompressed size of both archives) + ramdisk_size=$(gzip -l $ISOFS/bootcd.img $ISOFS/overlay.img ${CUSTOM_DIR:+$ISOFS/custom.img} | tail -1 | awk '{ print $2; }') # bytes + ramdisk_size=$((($ramdisk_size + 1023) / 1024)) # kilobytes + + echo "$FULL_VERSION_STRING" >$ISOFS/pl_version + popd +} - umount $INITRD_MOUNT - rmdir $INITRD_MOUNT - - echo "compressing ramdisk" - gzip $INITRD +#################### plain ISO +function build_iso() { + local iso="$1" ; shift + local custom="$1" + + # Write isolinux configuration + cat >$ISOFS/isolinux.cfg <${BUILDTMP}/mtools.conf<$tmp </dev/null || : + mcopy -i "$usb" "$tmp" z:/syslinux.cfg + rm -f "$tmp" + rm -f "${MTOOLSRC}" + unset MTOOLSRC + + echo "making USB image bootable." + syslinux -o $offset "$usb" -function burn() -{ - cdrecord $CDRECORD_FLAGS -data $ISO } -function clean() -{ - rm -rf $CD_ROOT - rm -rf $BUILD_DIR/syslinux - rm -rf $BUILD_DIR/$INITRD_MOUNT - rm -rf $BUILD_DIR - rm -f $ISO - rmdir --ignore-fail-on-non-empty build +#################### plain USB +function build_usb() { + echo -n "* Creating USB image... " + 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<$tmp </dev/null || : + mcopy -i "$usb" "$tmp" ::/syslinux.cfg + rm -f "$tmp" + rm -f "${MTOOLSRC}" + unset MTOOLSRC + + echo "making USB image bootable." + syslinux "$usb" } -if [[ "$1" == "clean" || "$1" == "burn" || "$1" == "build" ]]; then - action=$1 - configuration=$2 +#################### utility to setup CRAMFS related support +function prepare_cramfs() { + [ -n "$CRAMFS_PREPARED" ] && return 0 + local custom=$1; + + echo "* Setting up CRAMFS-based images" + local tmp="${BUILDTMP}/cramfs-tree" + mkdir -p "$tmp" + push_cleanup rm -rf $tmp + pushd $tmp + gzip -d -c $ISOFS/bootcd.img | cpio -diu + gzip -d -c $ISOFS/overlay.img | cpio -diu + [ -n "$custom" ] && \ + gzip -d -c $ISOFS/custom.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 - if [[ -z "$configuration" ]]; then - configuration=default - fi + 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 - echo "Loading configuration $configuration" - CURRENT_CONFIG_DIR=$CONFIGURATIONS_DIR/$configuration - . $CURRENT_CONFIG_DIR/configuration + # 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 <> etc/inittab + # and let root log in + echo "$console_dev" >> etc/securetty fi - FULL_VERSION_STRING="$FULL_VERSION_STRING $BOOTCD_VERSION" - # destination image - if [[ ! -z "$EXTRA_VERSION" ]]; then - OUTPUT_IMAGE_NAME="$OUTPUT_IMAGE_NAME-$EXTRA_VERSION" - fi - OUTPUT_IMAGE_NAME="$OUTPUT_IMAGE_NAME-$BOOTCD_VERSION" + # calculate the size of /tmp based on the size of /etc & /var + 8MB slack + etcsize=$(du -s ./etc | awk '{ print $1 }') + varsize=$(du -s ./var | awk '{ print $1 }') + let msize=($varsize+$etcsize+8192)/1024 + + # make dhclient happy + for i in $(seq 0 9); do ln -fs /tmp/etc/dhclient-eth${i}.conf etc/dhclient-eth${i}.conf ; done + ln -fs /tmp/etc/resolv.conf etc/resolv.conf + ln -fs /tmp/etc/resolv.conf.predhclient etc/resolv.conf.predhclient + + # generate pl_rsysinit + cat > etc/rc.d/init.d/pl_rsysinit < /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 - # setup build directories - BUILD_DIR=build/$configuration - mkdir -p $BUILD_DIR - ISO=$BUILD_DIR/`echo $OUTPUT_IMAGE_NAME | sed -e "s/%version/$BOOTCD_VERSION/"`.iso + popd + + # create the cramfs image + echo "* Creating cramfs image" + mkfs.cramfs $tmp/ ${BUILDTMP}/cramfs.img + cramfs_size=$(($(du -sk ${BUILDTMP}/cramfs.img | awk '{ print $1; }') + 1)) + rm -rf $tmp + pop_cleanup +} + +#################### Create ISO CRAMFS image +function build_iso_cramfs() { + local iso="$1" ; shift + local custom="$1" + + prepare_cramfs "$custom" + echo "* Creating ISO CRAMFS-based image" + + local tmp="${BUILDTMP}/cramfs-iso" + mkdir -p "$tmp" + push_cleanup rm -rf $tmp + (cd $ISOFS && find . | grep -v "\.img$" | cpio -p -d -u $tmp/) + cat >$tmp/isolinux.cfg <$tmp <