#!/bin/sh # /usr/bin/dphys3cd - # - build dphys3 boot CD .iso image for Debian 3.1 (sarge) # author Neil Franklin, last modification 2006.11.16 # copyright ETH Zuerich Physics Departement, # use under either BSD or GPL license ### ------ configuration for this site # first CONF_* various site or subnet dependant user config variables # then DEBUG_* various debugging settings # last SYS_* various system internal values # some of these are overridable by command line options # --- CONF_* various site or subnet dependant user config variables # this is the directory to use, within the dists/.../disks-i386 directory # vary this for multiple sets of files (say multiple kernels or configs) # naming schemes maybe by subnets, or by kernel options, or by compiling user CONF_DISKSVERSION=dphys3-custom # base URL from which our generated stuff can be downloaded # used for generating the URLs. to access our packages web server # the end result should parallel the scp login@server:/basedir above CONF_OWNSERVER=http://not-configured-server/not/configured/directory # install CD drive, where our generated .iso image goes # this should be the drive on the install generating system, not on target(s) # this line contains the drive ID and whatever options the drive needs # config for no burnproof and CD-R (no blank=fast): # CONF_CD_DRV=dev=0,0,0 # config for burnproof and CD-RW (blank=fast): # CONF_CD_DRV="-driveropts=burnfree blank=fast dev=0,0,0" CONF_CD_DRV="dev=0,0,0" # --- DEBUG_*, various debugging settings # these can be set to "yes" by -D option, followed by name without DEBUG_ # such as like this: dphys3cd -D PRINT_STEP -D LEAVE_TEMPFILES -g # set this to sleep after displaying each steps header #DEBUG_SLEEP=yes # set this to output debug state info after each step #DEBUG_PRINT_STEP=yes # set this to wait after each debug state info #DEBUG_WAIT_STEP=yes # set this to not delete temporary files (workdir) after -g #DEBUG_LEAVE_TEMPFILES=yes # --- SYS_*, various system internal values # where we want to do all the unpack/modify/pack stuff # this must be a directory that root can access (not a root-squash NFS mount) # and there should be about 10MByte free space in its filesystem SYS_WORKDIR="/var/tmp/dphys3cd-$$-work" # note: this program has only been designed for and tested with i386 # others at own risk, I expect them to fail badly SYS_ARCH=i386 ### ------ actual implementation from here on # no user settings any more below this point set -e # --- get ready to work # sanitise this place, else some commands may fail # must be before any commands are executed, incl config/input processing PATH=/sbin:/bin:/usr/sbin:/usr/bin export PATH # --- tidy up some commands, make systematic, common infrastructure # stuff that goes wrong, not expected by user, not in data output, use >&2 # so also with $0 in case this script was called by an other script # something within the system that user does not expect, give up CMD_FATAL="echo $0: FATAL:" # something from users input, user will correct this and continue CMD_ERROR="echo $0: ERROR:" # something we can continue with, but may be wrong, and user may not suspect it CMD_WARNING="echo $0: WARNING:" # something most likely not wrong, but tell user for the odd case it is wrong CMD_NOTE="echo $0: NOTE:" # normal stuff users expect, so to stdout as normal output, no $0, no marking CMD_INFO="echo" # stuff users asked for, so add to stdout as normal output, no $0, but mark it CMD_DEBUG="echo DEBUG:" # other stuff we may want to use CMD_SLEEP="sleep 2" CMD_WAIT="read -p ---DEBUG-wait-after-step--- dummy" # DEBUG_* or option controllable stuff CMD_INFO_PRINT="${CMD_INFO}" CMD_VERBOSE_PRINT=true CMD_DEBUG_SLEEP=true CMD_DEBUG_PRINT=true CMD_DEBUG_WAIT=true # set debug option controllable stuff here if [ "${DEBUG_SLEEP}" = yes ] ; then CMD_DEBUG_SLEEP="${CMD_SLEEP}" fi if [ "${DEBUG_PRINT_STEP}" = yes ] ; then CMD_DEBUG_PRINT="${CMD_DEBUG}" fi if [ "${DEBUG_WAIT_STEP}" = yes ] ; then CMD_DEBUG_WAIT="${CMD_WAIT}" fi # --- config file stuff # what we are NAME=dphys3cd PNAME=dphys3 # check user config file(s), let user override settings # same config files used in dphys3[kernel|preseed|boot|root|cd|pxe] if [ -f /etc/"${PNAME}" ] ; then . /etc/"${PNAME}" fi if [ -f ~/."${PNAME}" ] ; then . ~/."${PNAME}" fi if [ -f ./"${PNAME}" ] ; then . ./"${PNAME}" fi # --- parse command line # so long next parameter is a set of options (= begins with an - character) while [ "`echo "$1" | cut -c 1`" = - ] ; do # extract options from parameter (cut off the "-") OPTS="`echo "$1" | cut -c 2-`" shift 1 # so long still unprocessed option characters while [ "${OPTS}" != "" ] ; do # first option to process OPT="`echo "${OPTS}" | cut -c 1`" # and rest of options for later OPTS="`echo "${OPTS}" | cut -c 2-`" case "${OPT}" in d) # download: download files from server DO_DOWN=yes COMMAND_OPTION=yes ;; g) # generate: generate own CD image DO_GEN=yes COMMAND_OPTION=yes ;; b) # burn: burn image onto CD DO_BURN=yes COMMAND_OPTION=yes ;; r) # remove: remove file, after installing DO_REMOVE=yes COMMAND_OPTION=yes ;; q) # quiet: don't inform user what we are doing CMD_INFO_PRINT=true ;; v) # verbose: detailed inform user what we are doing CMD_VERBOSE_PRINT="${CMD_INFO}" ;; D) # Debug: set an debug option to yes eval "DEBUG_$1"=yes if [ "DEBUG_$1" = DEBUG_SLEEP ] ; then CMD_DEBUG_SLEEP="${CMD_SLEEP}" fi if [ "DEBUG_$1" = DEBUG_PRINT_STEP ] ; then CMD_DEBUG_PRINT="${CMD_DEBUG}" fi if [ "DEBUG_$1" = DEBUG_WAIT_STEP ] ; then CMD_DEBUG_WAIT="${CMD_WAIT}" fi shift 1 ;; h) # help: give out help how this script can be used cat << END-HELP-TEXT Usage is: $0 command [option]... [command [option]... ]... command/function/action letters: one or multiple of the following commands must be used, default nothing done if multiple of these are used, they are processed in the row they appear here, not the row they are typed on the command line -d download: download original Debian or own files from distribution server -g generate: generate CD .iso image -b burn: burn .iso image onto CD -r remove: remove Debian and own files, after installing options: -q quiet: don't give user an running report of what we are doing -v verbose: give user detailed running report -D Debug: activate an debug option -h help: give out help how this script can be used END-HELP-TEXT exit 0 ;; *) # not one of our recognized options ${CMD_ERROR} "unknown option: ${OPT}" >&2 ${CMD_INFO} >&2 # call self with -h to display help "$0" -h exit 1 ;; esac done done if [ "${COMMAND_OPTION}" = "" ] ; then ${CMD_ERROR} "no command option selected, will not do anything" >&2 ${CMD_INFO} >&2 # call self with -h to display help "$0" -h >&2 exit 1 fi ${CMD_DEBUG_PRINT} "options are:" \ "DO_DOWN: ${DO_DOWN}, DO_GEN: ${DO_GEN}," \ "DO_BURN: ${DO_BURN}, DO_REMOVE: ${DO_REMOVE}" ${CMD_DEBUG_WAIT} # --- test if we can work # this script is intended to be run as root, it will fail if run as user! if [ ! "`whoami`" = root ] ; then ${CMD_ERROR} "sorry, you need to run this as root, aborting ..." >&2 exit 1 fi # --- compute paths on disk image server # path for Debian directory we download from server DEBINST="dists/sarge/main/installer-${SYS_ARCH}/current" # path for our directory we upload to and download from server OWNINST="dists/sarge/local/main/installer-${SYS_ARCH}/${CONF_DISKSVERSION}" # actual files inside all of these BOOTIMG=images/floppy/boot.img ROOTIMG=images/floppy/root.img DRIVIMG=images/floppy/net-drivers.img # --- download own boot disk image to work on # this allways uses our boot floppy image, because we allways want auto install BOOT_URL="${CONF_OWNSERVER}/${OWNINST}/${BOOTIMG}" # in current dir, not workdir, as user wants to see this BOOT="`basename "${BOOT_URL}"`" if [ "${DO_DOWN}" != "" ] ; then ${CMD_INFO_PRINT} "downloading boot disk image ..." ${CMD_DEBUG_SLEEP} # check if we can download if ! which wget > /dev/null ; then ${CMD_FATAL} "failed to find wget, can not download, aborting ..." >&2 ${CMD_LOG_FATAL} "failed to find wget, can not download, aborting ..." exit 1 fi # -N so only newer is got, save waisting bandwidth if already here # if user wants to force download, use an make clean before # downloaded and to-upload files should end in current directory # this is also most likely where config and kernel archive will be # everything else in work directory and then deleted at the end wget -q -N "${BOOT_URL}" -O "${BOOT}" ${CMD_DEBUG_PRINT} "`ls -al "${BOOT}"`" ${CMD_DEBUG_WAIT} fi # --- download own root disk image to work on # this allways uses our root floppy image, because we allways want auto install ROOT_URL="${CONF_OWNSERVER}/${OWNINST}/${ROOTIMG}" ROOT="`basename "${ROOT_URL}"`" if [ "${DO_DOWN}" != "" ] ; then ${CMD_INFO_PRINT} "downloading root disk image ..." ${CMD_DEBUG_SLEEP} # -N so only newer is got, save waisting bandwidth if already here # if user wants to force download, use an make clean before wget -q -N "${ROOT_URL}" -O "${ROOT}" ${CMD_DEBUG_PRINT} "`ls -al "${ROOT}"`" ${CMD_DEBUG_WAIT} fi # --- space to work in if [ "${DO_GEN}" != "" ] ; then mkdir -p "${SYS_WORKDIR}" fi # --- generate and mount 2.88MByte boot image # where we will make our 2.88MB combined boot and root image for the CD BOOT288="${SYS_WORKDIR}/boot288.img" if [ "${DO_GEN}" != "" ] ; then ${CMD_INFO_PRINT} "generating 2880kByte boot image ..." ${CMD_DEBUG_SLEEP} # get pseudo disk ready for making floppy image # need 2880kByte to fit boot and root, as ElTorito allows only 1 floppy dd if=/dev/zero of="${BOOT288}" bs=1024 count=2880 # format this disk image as MSDOS FAT as SYSLINUX wants it so mkfs -t msdos "${BOOT288}" # open boot image BOOT288FLOPPY="${SYS_WORKDIR}/boot288" mkdir -p "${BOOT288FLOPPY}" mount -o loop "${BOOT288}" "${BOOT288FLOPPY}" ${CMD_DEBUG_PRINT} "+++ begin directory overview +++" if [ "${DEBUG_PRINT_STEP}" = yes ] ; then ls -al "${SYS_WORKDIR}" "${BOOT288FLOPPY}" fi ${CMD_DEBUG_PRINT} "+++ end directory overview +++" ${CMD_DEBUG_WAIT} fi # --- copy boot from 1.44 to 2.88MByte boot image if [ "${DO_GEN}" != "" ] ; then ${CMD_INFO_PRINT} "copying boot image to 2880kByte from 1440kByte ..." ${CMD_DEBUG_SLEEP} # get stuff from 1440k BOOTFLOPPY="${SYS_WORKDIR}/boot" mkdir -p "${BOOTFLOPPY}" mount -o loop "${BOOT}" "${BOOTFLOPPY}" cp -p "${BOOTFLOPPY}"/* "${BOOT288FLOPPY}" umount "${BOOTFLOPPY}" rm -rf "${BOOTFLOPPY}" ${CMD_DEBUG_PRINT} "+++ begin startup script listing +++" if [ "${DEBUG_PRINT_STEP}" = yes ] ; then ls -al "${BOOT288FLOPPY}" fi ${CMD_DEBUG_PRINT} "+++ end startup script listing +++" ${CMD_DEBUG_WAIT} fi # --- insert root image into boot image if [ "${DO_GEN}" != "" ] ; then ${CMD_INFO_PRINT} "inserting root image into boot image ..." ${CMD_DEBUG_SLEEP} # insert root image file into boot image ROOTFLOPPY="${SYS_WORKDIR}/root" mkdir -p "${ROOTFLOPPY}" mount -o loop "${ROOT}" "${ROOTFLOPPY}" # boot intrd init only loads modules for vfat loop and floppy and usb # then loads root initrd into ramdisk, links init to busybox, runs that # root intrd init copies itsself into ramdisk, runs busybox init # so it can directly replace boot intrd, no need for merging both cp -p "${ROOTFLOPPY}"/* "${BOOT288FLOPPY}" umount "${ROOTFLOPPY}" rm -rf "${ROOTFLOPPY}" ${CMD_DEBUG_PRINT} "+++ begin startup script listing +++" if [ "${DEBUG_PRINT_STEP}" = yes ] ; then ls -al "${BOOT288FLOPPY}" fi ${CMD_DEBUG_PRINT} "+++ end startup script listing +++" ${CMD_DEBUG_WAIT} fi # --- umount 2.88 boot floppy image if [ "${DO_GEN}" != "" ] ; then ${CMD_INFO_PRINT} "unmounting boot 2.88 image ..." ${CMD_DEBUG_SLEEP} # finished with operations, now unmount umount "${BOOT288FLOPPY}" rm -rf "${BOOT288FLOPPY}" touch "${BOOT288}" ${CMD_DEBUG_PRINT} "`ls -al "${BOOT288}"`" ${CMD_DEBUG_WAIT} fi # --- install syslinux boot sector if [ "${DO_GEN}" != "" ] ; then ${CMD_INFO_PRINT} "installing syslinux on ${BOOT288} ..." ${CMD_DEBUG_SLEEP} syslinux "${BOOT288}" ${CMD_DEBUG_PRINT} "`ls -al "${BOOT288}"`" ${CMD_DEBUG_WAIT} fi # --- make the .iso image # name for new CD image # used also in other places BOOTISO=boot.iso if [ "${DO_GEN}" != "" ] ; then ${CMD_INFO_PRINT} "making .iso image from ${BOOT288} ..." ${CMD_DEBUG_SLEEP} BOOTCD="${SYS_WORKDIR}/bootcd" mkdir -p "${BOOTCD}" mv "${BOOT288}" "${BOOTCD}" mkisofs -o "${BOOTISO}" -b "`basename "${BOOT288}"`" "${BOOTCD}" rm -rf "${BOOTCD}" ${CMD_DEBUG_PRINT} "`ls -al "${BOOTISO}"`" ${CMD_DEBUG_WAIT} fi # --- tidy up after working if [ "${DO_GEN}" != "" ] ; then ${CMD_INFO_PRINT} "tidying up from working ..." ${CMD_DEBUG_SLEEP} ${CMD_DEBUG_PRINT} "+++ begin workdirectory listing +++" if [ "${DEBUG_PRINT_STEP}" = yes ] ; then ls -al "${SYS_WORKDIR}" fi ${CMD_DEBUG_PRINT} "+++ end workdirectory listing +++" ${CMD_DEBUG_WAIT} # remove all temporary directories and their contents, to save space # must be after debug printout if [ "${DEBUG_LEAVE_TEMPFILES}" != yes ] ; then # but offer to leave them to investigate bugs rm -rf "${SYS_WORKDIR}" fi fi # --- burn .iso image onto an CD if [ "${DO_BURN}" != "" ] ; then ${CMD_INFO_PRINT} "burning .iso image on CD ..." ${CMD_DEBUG_SLEEP} # ${CONF_CD_DRV} is CD drive, where our generated .iso image goes # this also contains the drive ID and whatever options it needs cdrecord "${CONF_CD_DRV}" "${BOOTISO}" ${CMD_DEBUG_PRINT} "`ls -al "${BOOTISO}"`" ${CMD_DEBUG_WAIT} fi # --- remove disk and .iso images if [ "${DO_REMOVE}" != "" ] ; then ${CMD_INFO_PRINT} "removing .iso image ..." ${CMD_DEBUG_PRINT} "`ls -al "${BOOT}" 2> /dev/null`" ${CMD_DEBUG_PRINT} "`ls -al "${ROOT}" 2> /dev/null`" ${CMD_DEBUG_PRINT} "`ls -al "${BOOTISO}" 2> /dev/null`" ${CMD_DEBUG_WAIT} rm -f "${BOOT}" "${ROOT}" "${BOOTISO}" fi exit 0