X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=build.sh;h=bff2262edfcd0ac6103639486bcee1b67ad7b569;hb=38d28a2ffec0d8715e69c76d7e71e0736a0c3ce6;hp=09fac148944665f345e1a27a50115de80ad5b7d0;hpb=a8d579eef01f8e2b272c5c77ffbe287820d0d0e8;p=bootcd.git diff --git a/build.sh b/build.sh index 09fac14..bff2262 100755 --- a/build.sh +++ b/build.sh @@ -1,254 +1,549 @@ #!/bin/bash +# +# Builds custom BootCD ISO and USB images in the current +# directory. For backward compatibility, if an old-style static +# configuration is specified, that configuration file will be parsed +# instead of the current PLC configuration in +# /etc/planetlab/plc_config. +# +# Aaron Klingaman +# Mark Huang +# Copyright (C) 2004-2006 The Trustees of Princeton University +# +# $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:ah" opt ; do + case $opt in + c) + CONFIGURATION=$OPTARG + ;; + f) + NODE_CONFIGURATION_FILE=$OPTARG + ;; + a) + ALL=1 + ;; + h|*) + usage + ;; + esac +done + +# Do not tolerate errors set -e -BOOTCD_VERSION="3.0-beta0.3" -FULL_VERSION_STRING="PlanetLab BootCD $BOOTCD_VERSION" - -# which boot server to contact -BOOTSERVER='boot.planet-lab.org' - -# and on which port (protocol will be https) -BOOTSERVER_PORT='443' - -# finally, what path to request from the server -BOOTSERVER_PATH='boot/' - -SYSLINUX_SRC=sources/syslinux-2.11.tar.bz2 - -ISO=cd.iso - -CD_ROOT=`pwd`/cdroot -ROOT_PASSWD='$1$IdEn2srw$/TfrjZSPUC1xP244YCuIi0' +# Change to our source directory +srcdir=$(cd $(dirname $0) && pwd -P) +pushd $srcdir -BOOTCD_YUM_GROUP=BootCD +# Root of the isofs +isofs=$PWD/build/isofs -CDRECORD_FLAGS="-v -dao" - -CONF_FILES_DIR=conf_files/ - -# location of the uncompressed ramdisk image -INITRD=$CD_ROOT/usr/isolinux/initrd - -# temporary mount point for rd -INITRD_MOUNT=`pwd`/rd +# Build reference image if it does not exist. This should only need to +# be executed once at build time, never at run time. +if [ ! -f $isofs/bootcd.img ] ; then + ./prep.sh +fi -# size of the ram disk in MB -RAMDISK_SIZE=64 +# build/version.txt written by prep.sh +BOOTCD_VERSION=$(cat build/version.txt) -# the bytes per inode ratio (the -i value in mkfs.ext2) for the ramdisk -INITRD_BYTES_PER_INODE=1024 +if [ -f /etc/planetlab/plc_config ] ; then + # Source PLC configuration + . /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 -function build_cdroot() -{ - if [ -f $CD_ROOT/.built ]; then - echo "cd root already built, skipping" - return +# 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 + . configurations/$CONFIGURATION/configuration + PLC_NAME="PlanetLab" + PLC_MAIL_SUPPORT_ADDRESS="support@planet-lab.org" + PLC_WWW_HOST="www.planet-lab.org" + PLC_WWW_PORT=80 + if [ -n "$EXTRA_VERSION" ] ; then + BOOTCD_VERSION="$BOOTCD_VERSION $EXTRA_VERSION" fi - - 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 - 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_PASSWD:#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 syslinux - mkdir -p $CD_ROOT/usr/isolinux/ - tar -C syslinux -xjvf $SYSLINUX_SRC - find 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 - 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 $CONF_FILES_DIR/cacert.pem $CD_ROOT/usr/boot/ - cp -f $CONF_FILES_DIR/pubring.gpg $CD_ROOT/usr/boot/ - echo "$BOOTSERVER" > $CD_ROOT/usr/boot/boot_server - echo "$BOOTSERVER_PORT" > $CD_ROOT/usr/boot/boot_server_port - echo "$BOOTSERVER_PATH" > $CD_ROOT/usr/boot/boot_server_path - - echo "copying old boot cd directory bootme (TEMPORARY)" - cp -r bootme_old $CD_ROOT/usr/bootme - - 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 - - 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 - popd - - umount $INITRD_MOUNT - rmdir $INITRD_MOUNT - - echo "compressing ramdisk" - gzip $INITRD -} - -function build_iso() -{ - echo "building iso" - rm -f $ISO - mkisofs -o $ISO -R -allow-leading-dots -J -r -b isolinux/isolinux.bin \ - -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table \ - -V PlanetLab-3-0 $CD_ROOT/usr -} - -function burn() -{ - cdrecord $CDRECORD_FLAGS -data $ISO -} - -function clean() -{ - echo "removing built files" - rm -rf cdroot - rm -rf syslinux - rm -rf $INITRD_MOUNT - rm -f $ISO -} - - -if [ "$1" == "clean" ]; then - clean - exit + PLC_BOOT_HOST=$PRIMARY_SERVER + PLC_BOOT_SSL_PORT=$PRIMARY_SERVER_PORT + PLC_BOOT_CA_SSL_CRT=configurations/$CONFIGURATION/$PRIMARY_SERVER_CERT + PLC_ROOT_GPG_KEY_PUB=configurations/$CONFIGURATION/$PRIMARY_SERVER_GPG fi -if [ "$1" == "burn" ]; then - burn - exit +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 +echo "* Populating root filesystem..." +overlay=$(mktemp -d ${BUILDTMP}/overlay.XXXXXX) +install -d -m 755 $overlay +trap "rm -rf $overlay" ERR INT + +# 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 + +# 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 + +# (Deprecated) Install old-style boot server configuration files +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 -if [ "$1" == "force" ]; then - clean +mkdir -p $overlay/etc +cat >$overlay/etc/issue <$overlay/etc/passwd -# always build/rebuild initrd -build_initrd +# 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" + install -D -m 644 $NODE_CONFIGURATION_FILE $overlay/usr/boot/plnode.txt +fi -build_iso +# 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 +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 + 1023) / 1024)) # kilobytes + +# Write isolinux configuration +echo "$FULL_VERSION_STRING" >$isofs/pl_version +cat >$isofs/isolinux.cfg <$isofs/isolinux.cfg <$tmp/syslinux.cfg <$tmp/syslinux.cfg <./etc/fstab < 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 + +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 <$tmp/isolinux.cfg <$tmp/syslinux.cfg <$tmp/syslinux.cfg <