[ previous ] [ next ] [ threads ]
 
 From:  Jim Gifford <jim at giffords dot net>
 To:  m0n0wall at lists dot m0n0 dot ch
 Subject:  request for testers
 Date:  Sun, 21 Mar 2004 12:10:52 -0500
I'm working on building a script to automate the writing of m0n0wall
images to block devices.  I've now got it to a point where I need testers
to try it out.

My next step is to build a floppy image containing a kernel and ramdisk
root that can contain this script and (hopefully) be bootable on most x86
platforms.

The next step after that is to build a bootable cdrom image with that
floppy image as the boot image.  This'll help folks without a floppy
drive (like me on my latest laptop).

I chose to develop on linux as that is what I'm most comfortable with and
knowledgable about.  I chose the 2.6 series kernel as the /sys filesystem
gives me information that makes this script much easier.  I chose to
write in shell (bash actually) because php always frustrates me, and perl
won't fit on a floppy, and my C is ugly as sin.

The script makes use of 3 url requests from the m0n0.ch site.  One grabs
the latest.txt file that the m0n0wall software itself uses.  One grabs a
URL that returns a list of mirrors in XML format.  The third grabs a URL
that returns the image file information in XML format.  I use awk to
"parse" the XML into shell arrays to make it easier to deal with in the
shell script.

The script is pretty simple actually.  However, it should hopefully take
some of the guesswork out of writing the actual images.

WARNING!!!!!! This is a shell script that requires root privileges to do
its work.  As such, you should read and understand it before trusting it
on your system!

WARNING!!!!!! This script has the ability to overwrite any block device
on your system.  I've made every effort to double check with the user
before writing, but I'm not responsible if it destroys your system.

If you are willing to help test this script, simply save it from the
attachment as 'mkm0n0wall', and run it as root.  Make sure you have the
block device you want to overwrite already installed in your system.  The
script should accomodate PCMCIA, USB, FireWire, SCSI, and IDE devices,
depending on what your kernel already supports.  Simply run the script
and answer the questions, then let me know what you think about it.
Patches are even better than comments.  :)

What you need in order to test:
    A working linux system with 2.6 kernel that supports all your devices.
    curl, cat, seq, dialog, bash, md5sum, ls
    A device to overwrite attached to this linux system.

Please, any arguments about whether I should have developed with
different {OS, software, language, platform, etc} should be sent to
/dev/null.  I chose what I wanted to use, and that is that.  Anyone is
welcome to take the idea and do their own thing with it.  In fact,
"porting" the script to *BSD shouldn't be *that* difficult.

Thanks,
jim
#!/bin/bash

#
# $Id: mkm0n0wall,v 1.3 2004/03/21 17:10:27 jim Exp $
#
# mkm0n0wall -- attempt to take much of the guesswork out of writing
# a m0n0wall image to a block device.
#
# mkm0n0wall is distributed under the same license and m0n0wall
#
# Author: Jim Gifford, jim at giffords dot net
#

ME='mkm0n0wall'
DIALOG="/usr/bin/dialog"
TEMP="/tmp/foo.$$"

M0N0_LATEST=`curl --silent http://m0n0.ch/wall/latest.txt`

${DIALOG} --infobox "Fetching m0n0wall mirror information" 4 55
eval `curl --silent http://m0n0.ch/wall/mirrors.php | awk '
    BEGIN { i=0 };
    /<mirror>/ { i++ };
    /\t+<.*>.*<\/.*>/ {
        split($0,ta,/[<>]/);
        printf("XML_%s[%i]=\"%s\"\n",toupper(ta[2]),i,ta[3]);
    };
    END { printf("XML_ENTRIES=\"%i\"",i) }
'`
${DIALOG} --infobox "done" 4 50

${DIALOG} --infobox "Fetching Image file MD5 information" 4 55
eval `curl --silent http://m0n0.ch/wall/imageinfo.xml | awk '
    BEGIN { i=0 };
    /<image platform=/ { i++ };
    /\t+<.*>.*<\/.*>/ {
        split($0,ta,/[<>]/);
        printf("XML_MD5_%s[%i]=\"%s\"\n",toupper(ta[2]),i,ta[3]);
    };
    END { printf("XML_MD5_ENTRIES=\"%i\"",i) }
'`
${DIALOG} --infobox "done" 4 50

# now choose an image
${DIALOG} \
    --backtitle "${ME} -- image selection for version: ${M0N0_LATEST}" \
    --menu "Select a target platform:" 14 50 5 \
                net45xx "Soekris net45xx platform" \
                net48xx "Soekris net48xx platform" \
                wrap    "PC Engines WRAP platform" \
                generic-pc "Generic PC system" \
                2>${TEMP} || exit $?
PLATFORM=`cat ${TEMP}`
rm ${TEMP}
IMAGE="${PLATFORM}-${M0N0_LATEST}.img"
FILENAME="/tmp/${IMAGE}"

for x in `seq 1 ${XML_MD5_ENTRIES}` ; do
    if [ "${XML_MD5_FILENAME[${x}]}" == "${IMAGE}" ] ; then
        CORRECT_MD5_HASH=${XML_MD5_MD5[${x}]}
        FILE_SIZE=${XML_MD5_SIZE[${x}]}
        break
    fi
done

${DIALOG} --msgbox "Platform: ${PLATFORM:->NULL<}
Version: ${M0N0_LATEST}
Image filename: ${IMAGE}
MD5: ${CORRECT_MD5_HASH}
Size: ${FILE_SIZE}" 8 50

# now choose a mirror site
MIRRORS=()
for x in `seq 1 ${XML_ENTRIES}`; do
    DESC="${XML_NAME[${x}]} -- Hosted by: ${XML_HOSTEDBY[${x}]}"
    MIRRORS=("${MIRRORS[@]}" ${x} "${DESC}")
done
${DIALOG} \
    --backtitle "${ME} -- mirror selection for ${IMAGE}:" \
    --menu "Please select a mirror:" 20 70 15 \
    "${MIRRORS[@]}" \
    2>${TEMP} || exit $?
CHOICE=`cat ${TEMP}`
rm ${TEMP}

echo "You chose ${XML_NAME[${CHOICE}]} located in ${XML_LOCATION[${CHOICE}]}."
echo "${XML_NAME[${CHOICE}]} is hosted by ${XML_HOSTEDBY[${CHOICE}]}."
URL="${XML_URL[${CHOICE}]}/${IMAGE}"
if [ ! -f ${FILENAME} ]; then
    curl -o ${FILENAME} ${URL}
else
    echo "${FILENAME} found!  Assuming this is a test system and not re-downloading"
    sleep 1
fi

${DIALOG} --infobox "Calculating MD5 hash" 4 55
MY_MD5_HASH=`md5sum ${FILENAME} | awk '{print $1}'`
${DIALOG} --infobox "done" 4 50

if [ "${MY_MD5_HASH}" != "${CORRECT_MD5_HASH}" ]; then
    rm -f ${FILENAME}
    ${DIALOG} --msgbox "MD5 Hash incorrect for ${IMAGE}.  Please choose a new mirror." 6 55
    exec $0
else
    ${DIALOG} --msgbox "MD5 Hash correct for ${IMAGE}." 6 55
fi

${DIALOG} --infobox "Fetching block device information" 4 55
BLOCKS=`ls /sys/block`
${DIALOG} --infobox "done" 4 50

# now choose a block device
DEVICES=()
for x in $BLOCKS; do
    case $x in
        hd*)
                DESC=`hdparm -i /dev/${x} | awk '/Model=/{ split($0,a,/[=,]/); print a[2]; }'`
                DEVICES=("${DEVICES[@]}" "/dev/${x}" "${DESC}")
                ;;
        sd*)
                DESC=`cat /sys/block/$x/device/model`
                DEVICES=("${DEVICES[@]}" "/dev/${x}" "${DESC}")
                ;;
        dm*)
                # device mapper nodes... don't touch these
                ;;
    esac
done
${DIALOG} \
    --backtitle "${ME} -- block device to write ${IMAGE} to:" \
    --menu "Please select a block device to OVERWRITE:" 20 70 15 \
    "${DEVICES[@]}" \
    2>${TEMP} || exit $?
DEV=`cat ${TEMP}`
rm ${TEMP}

echo "You chose to OVERWRITE ${DEV}."
$DIALOG --backtitle "${ME} -- Overwrite ${DEV} with ${IMAGE}?" \
        --defaultno \
        --yesno "Are you SURE you want to overwrite ${DEV} with ${IMAGE}?" 5 65
${DIALOG} --infobox "Overwriting ${DEV} with ${IMAGE}..." 4 55
gunzip -c ${FILENAME} | dd of=${DEV} bs=16k
${DIALOG} --infobox "done" 4 50

echo "You should now be able to shut the system down and remove the device"
echo "from ${DEV} and install it in the destination machine for use."