mkrescue

Mikolaj Golub golub@inec.kharkov.com
05 Jul 2005 10:08:49 +0300


--=-=-=

Hi!

I have written simple script that can be used to create a bootable rescue
iso image using grub image from grub-disk package. If you like it,
it would be nice to have it in grub-disk package in example dir.

The script is attached.


--=-=-=
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=mkrescue
Content-Description: mkrescue script

#!/bin/sh

#
# Make a bootable rescue iso image using the currently run kernel.
#
# By default the script searches "template" grub iso image in the
# directory of grub-disk package.
#

# Variables that wil be used

PROGNAME=`basename $0`
TMPDIR=/tmp/mkrescue-$$
RELEASE=`uname -r`
ROOT=`awk '$2 == "/" {print $1}' /etc/fstab`
INITRDSTR=
NOINITRD=
KERNEL=
INITRD=
GRUBISO=
ISO=
ZIPPED=

print_help () {
    echo "Usage: $PROGNAME [OPTIONS]"
    echo "Make a bootable rescue iso image using the currently run kernel."
    echo
    echo " -h, --help            display this help and exit"
    echo " -r, --release=RELEASE install this release of kernel and initrd image"
    echo " -k, --kernel=KERNEL   kernel image to install"
    echo " -i, --initrd=INITRD   initrd image to install"
    echo " -s, --without-initrd  don't install initrd image"
    echo " -R, --root=ROOTDEV    device that will be mounted as root"
    echo " -g, --grub-iso=PATH   path to grub iso image"
    echo " -o, --iso-name=NAME   name of produced image"
    echo
}

clean () {
    # umount grub iso image if it has been mounted
    mount |
    awk -v dir=$TMPDIR/iso.orig \
	'$3 == dir {
             system("umount " dir);
             exit;
         }'
    rm -Rf $TMPDIR
}

# Parse command line options

OPTS=`getopt -o hr:k:i:sR:g:o: \
      --long help,release:,kernel:,initrd:,without-initrd,root:,grub-iso:,iso-name: \
      -n $PROGNAME -- "$@"`

if [ $? != 0 ] ; then 
    echo "Try \`$PROGNAME --help' for more information." >&2
    exit 1
fi

eval set -- "$OPTS"

while true ; do
    case "$1" in
	-h|--help) print_help; exit ;;
	-r|--release)        RELEASE="$2" ; shift 2 ;;
	-k|--kernel)         KERNEL="$2"  ; shift 2 ;;
	-i|--initrd)         INITRD="$2"  ; shift 2 ;;
	-s|--without-initrd) NOINITRD=YES ; shift   ;;
	-R|--root)           ROOT="$2"    ; shift 2 ;;
	-g|-grub-iso)        GRUBISO="$2" ; shift 2 ;;
	-o|-iso-name)        ISO="$2"     ; shift 2 ;;
	--)                  shift        ; break   ;;
	*)  echo "$PROGNAME: invalid option -- $1" >&2
	    echo "Try \`$PROGNAME --help' for more information." >&2
	    exit 1 ;;
    esac
done

if [ -n "$1" ]; then
    echo "$PROGNAME: invalid arguments" >&2
    echo "Try \`$PROGNAME --help' for more information." >&2
    exit 1
fi

[[ -z "$KERNEL"  ]] && KERNEL=/boot/vmlinuz-$RELEASE
[[ -z "$INITRD"  ]] && INITRD=/boot/initrd.img-$RELEASE
[[ -z "$ISO"     ]] && ISO=rescue-$RELEASE.iso
[[ -z "$GRUBISO" ]] && GRUBISO=`ls /usr/share/grub-disk/grub-*.iso.gz |tail -1`

# Check some paths

if ! [ -f "$GRUBISO" ]; then
    echo "Grub iso image \`$GRUBISO' does not exist!"
    echo "Specify path to initrd image using --grub-iso option."
    echo "Exiting..."
    exit 1
fi

if ! [ -f "$KERNEL" ]; then
    echo "Kernel image \`$KERNEL' does not exist!"
    echo "Exiting..."
    exit 1
fi

if [[ -z $NOINITRD ]] && ! [[ -f "$INITRD" ]]; then
    echo "Initrd image \`$INITRD' does not exist!"
    echo "Specify path to initrd image using --initrd option"
    echo "or use --without-initrd directive."
    echo "Exiting..."
    exit 1
fi

# Test if grub-iso image is gzipped

gunzip -t "$GRUBISO" 2>/dev/null && ZIPPED=YES

# Well, now make a real work: mount grub iso, copy its content
# in temporary directory, add kernel and initrd, edit grub/menu.lst
# and then make iso.

mkdir $TMPDIR &&
mkdir $TMPDIR/iso.orig &&
mkdir $TMPDIR/iso &&
if ! [ -z $ZIPPED ]; then
    gunzip -c "$GRUBISO" > $TMPDIR/grub.iso &&
    GRUBISO=$TMPDIR/grub.iso
fi &&
mount -o loop "$GRUBISO" $TMPDIR/iso.orig &&
cp -a $TMPDIR/iso.orig/* $TMPDIR/iso &&
cp "$KERNEL" $TMPDIR/iso &&
if [ -z $NOINITRD ]; then
    INITRDSTR="initrd /$(basename $INITRD)";
    cp "$INITRD" $TMPDIR/iso;
fi &&
cat <<EOF > $TMPDIR/iso/boot/grub/menu.lst &&
#
# Rescue disk boot menu configuration file
#

# Boot automatically after 30 secs.
timeout 30

# By default, boot the first entry.
default 0

# For booting GNU/Linux
title  Boot system from rescue iso
kernel /$(basename $KERNEL) root=$ROOT
$INITRDSTR

EOF
mkisofs \
    -b boot/grub/stage2_eltorito \
    -no-emul-boot -boot-load-size 4 -boot-info-table \
    -o "$ISO" -r $TMPDIR/iso

if [ $? != 0 ]; then
    clean
    echo "Exiting..." >&2
    exit 1
fi

clean

exit 0

--=-=-=


Regards,

-- 
Mikolaj Golub

--=-=-=--