#!/bin/sh # /usr/bin/dphys3pxe - # - extract dphys3 PXE/TFTP boot server files 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 # upload server for PXE, where our extracted files go # the -u option uploads everything relative to this # we upload via ssh/scp, as this is most likely available on boot servers # so this line needs to be in user@server:/directory format for scp CONF_PXE_SERVER=not-configured-user@server:/dir # make sure multiple users (group of them) can upload files on boot server # if this is set, chgrp files to this group and chmod g+w CONF_PXE_GROUP="" # --- DEBUG_*, various debugging settings # these can be set to "yes" by -D option, followed by name without DEBUG_ # such as like this: dphys3pxe -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 # set this to leave temporary directories undeleted after -i #DEBUG_LEAVE_TEMPDIRS=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/dphys3pxe-$$-work" # where we want to put together stuff for upload # not ./upload as this may collide with something user already has SYS_UPLOADDIR="/var/tmp/dphys3pxe-$$-upload" # 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=dphys3pxe 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 file from server DO_DOWN=yes COMMAND_OPTION=yes ;; x) # extract: extract kernel and initrd DO_EXTRACT=yes COMMAND_OPTION=yes ;; u) # upload: upload files onto boot server DO_UPLOAD=yes COMMAND_OPTION=yes ;; r) # remove: remove file, after uploading 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 -x extract: extract kernel and initrd -u upload: upload extracted files onto PXE/TFTP boot server -r remove: remove Debian and own files, after uploading 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_EXTRACT: ${DO_EXTRACT}," \ "DO_UPLOAD: ${DO_UPLOAD}, 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 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_EXTRACT}" != "" ] ; then mkdir -p "${SYS_WORKDIR}" fi # --- extract kernel from boot floppy image # name for kernel to be extracted # also used in other places KERNEL=linux if [ "${DO_EXTRACT}" != "" ] ; then ${CMD_INFO_PRINT} "extracting kernel from boot floppy ..." ${CMD_DEBUG_SLEEP} # open boot floppy image BOOTFLOPPY="${SYS_WORKDIR}/boot" mkdir -p "${BOOTFLOPPY}" mount -o loop "${BOOT}" "${BOOTFLOPPY}" cp -p "${BOOTFLOPPY}/${KERNEL}" . umount "${BOOTFLOPPY}" rm -rf "${BOOTFLOPPY}" ${CMD_DEBUG_PRINT} "`ls -al "${KERNEL}"`" ${CMD_DEBUG_WAIT} fi # --- extract kernel from boot floppy image # name for initrd to be extracted # also used in other places INITRD=initrd.gz if [ "${DO_EXTRACT}" != "" ] ; then ${CMD_INFO_PRINT} "extracting initrd from root floppy ..." ${CMD_DEBUG_SLEEP} # open root floppy image ROOTFLOPPY="${SYS_WORKDIR}/boot" mkdir -p "${ROOTFLOPPY}" mount -o loop "${ROOT}" "${ROOTFLOPPY}" cp -p "${ROOTFLOPPY}/${INITRD}" . umount "${ROOTFLOPPY}" rm -rf "${ROOTFLOPPY}" ${CMD_DEBUG_PRINT} "`ls -al "${INITRD}"`" ${CMD_DEBUG_WAIT} fi # --- tidy up after working if [ "${DO_EXTRACT}" != "" ] ; 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 # --- upload PXE files onto an boot server if [ "${DO_UPLOAD}" != "" ] ; then ${CMD_INFO_PRINT} "uploading PXE files onto boot server" \ "${CONF_PXE_SERVER} ..." ${CMD_DEBUG_SLEEP} # put together stuff to upload, needs an temp dir mkdir -p "${SYS_UPLOADDIR}" if [ -f "${KERNEL}" -a -f "${INITRD}" ] ; then cp -p "${KERNEL}" "${INITRD}" "${SYS_UPLOADDIR}" if [ "${CONF_PXE_GROUP}" != "" ] ; then chgrp "${CONF_PXE_GROUP}" "${SYS_UPLOADDIR}"/* chmod 664 "${SYS_UPLOADDIR}"/* fi else ${CMD_ERROR} "files for upload are missing, not extracted?" >&2 exit 1 fi # ${CONF_PXE_SERVER} is upload user@server:/directory for PXE # this line needs to be in format for first part of scp command if [ "${CONF_PXE_SERVER}" != "" ] ; then scp -p "${SYS_UPLOADDIR}"/* "${CONF_PXE_SERVER}" else ${CMD_FATAL} "no server to upload PXE boot files to" >&2 exit 1 fi ${CMD_DEBUG_PRINT} "`ls -al "${SYS_UPLOADDIR}/${KERNEL}"`" ${CMD_DEBUG_PRINT} "`ls -al "${SYS_UPLOADDIR}/${INITRD}"`" ${CMD_DEBUG_WAIT} # remove temporary directory and its contents, to save space # must be after debug printout if [ "${DEBUG_LEAVE_TEMPDIRS}" != yes ] ; then # but offer to leave this to investigate bugs rm -rf "${SYS_UPLOADDIR}" fi fi # --- remove PXE boot files if [ "${DO_REMOVE}" != "" ] ; then ${CMD_INFO_PRINT} "removing PXE files ..." ${CMD_DEBUG_PRINT} "`ls -al "${BOOT}" 2> /dev/null`" ${CMD_DEBUG_PRINT} "`ls -al "${ROOT}" 2> /dev/null`" ${CMD_DEBUG_PRINT} "`ls -al "${KERNEL}" 2> /dev/null`" ${CMD_DEBUG_PRINT} "`ls -al "${INITRD}" 2> /dev/null`" ${CMD_DEBUG_WAIT} rm -f "${BOOT}" "${ROOT}" "${KERNEL}" "${INITRD}" fi exit 0