edit-livecd: optionally append kernel boot params
[ovirt-node-image.git] / edit-livecd
blobc122eee680b4f50f0c4f9dd992d075b997be848f
1 #!/bin/bash
3 # Edit a livecd to insert files
4 # Copyright 2008 Red Hat, Inc.
5 # Written by Perry Myers <pmyers@redhat.com>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; version 2 of the License.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Library General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #!/bin/bash
21 PATH=$PATH:/sbin:/usr/sbin
23 ME=$(basename "$0")
24 warn() { printf '%s: %s\n' "$ME" "$*" >&2; }
25 try_h() { printf "Try \`$ME -h' for more information.\n" >&2; }
26 die() { warn "$@"; try_h; exit 1; }
28 NODEIMG_DEFAULT=/usr/share/ovirt-node-image/ovirt-node-image.iso
29 CD=$NODEIMG_DEFAULT
31 usage() {
32 case $# in 1) warn "$1"; try_h; exit 1;; esac
33 cat <<EOF
34 Usage: $ME -i LiveCD.iso [-b bootparams] [-p program]
35 -b BOOTPARAMS optional parameters appended to the kernel command line
36 -i LIVECD.iso LiveCD ISO to edit (default: $NODEIMG_DEFAULT)
37 -p PROGRAM Arbitrary program/script that is run inside of the livecd root
38 filesystem. This script is not run in a chroot environment so
39 it can access the host filesystem. The program should be executable
40 If program is omitted the script will pause and allow the user in
41 another terminal to edit the filesystem manually. After enter is
42 pushed the script will re-package up the ISO.
43 -h display this help and exit
45 Example Script:
46 #!/bin/sh
47 touch etc/sysconfig/foo
49 This will create a file /etc/sysconfig/foo in the livecd filesystem.
50 EOF
53 # FIXME: instead of requiring a PROGRAM, allow arbitrary shell code,
54 # so we can invoke $0 -p 'touch etc/sysconfig/foo' ...
55 # This means that if you *do* have a program in the current directory
56 # running "$0 -p ./my-script" won't work, since it'll be run with
57 # a different working dir. However, *this* will:
58 # $0 -p "$PWD/my-script"
60 # exit after any error:
61 set -e
63 err=0 help=0
64 while getopts :b:i:p:h c; do
65 case $c in
66 i) CD=$OPTARG;;
67 b) PARAMS=$OPTARG;;
68 p) PROG=$OPTARG;;
69 h) help=1;;
70 '?') err=1; warn "invalid option: \`-$OPTARG'";;
71 :) err=1; warn "missing argument to \`-$OPTARG' option";;
72 *) err=1; warn "internal error: \`-$OPTARG' not handled";;
73 esac
74 done
75 test $err = 1 && { try_h; exit 1; }
76 test $help = 1 && { usage; exit 0; }
78 # first, check to see we are root
79 if [ $( id -u ) -ne 0 ]; then
80 die "Must run as root"
83 # FIXME: don't use which: with bash, it's a separate program
84 # FIXME: When failing due to a missing required program, tell the user why.
85 which mkisofs mksquashfs sed > /dev/null 2>&1
87 WDIR=`mktemp -d $PWD/livecd.XXXXXXXXXX`
88 # FIXME: fail if $WDIR contains white space or shell meta-characters
89 # FIXME: do the same for $CD.
91 ISO="${CD##*/}"
92 ISO="${ISO%.iso}-custom.iso"
94 function addExit() {
95 EXIT="$@ ; $EXIT"
96 trap "$EXIT" EXIT HUP TERM INT QUIT
99 function mnt() {
100 local margs="$1" ; shift
101 local mp="$WDIR/$1"
102 for D in "$@" ; do
103 mkdir -v -p "$WDIR/$D"
104 done
105 mount -v $margs "$mp"
106 addExit "df | grep $mp > /dev/null 2>&1 && umount -v $mp"
109 addExit "rm -rf $WDIR"
111 eval "$(/lib/udev/vol_id $CD)"
112 LABEL=$ID_FS_LABEL
114 # mount the CD image
115 mnt "-t auto $CD -o loop,ro" cd
117 # mount compressed filesystem
118 mnt "-t squashfs $WDIR/cd/LiveOS/squashfs.img -o ro,loop" sq
120 # create writable copy of the new filesystem for the CD
121 cp -a $WDIR/cd $WDIR/cd-w
123 # create writable copy of the filesystem for the new compressed squashfs filesystem
124 cp -a $WDIR/sq $WDIR/sq-w
126 # mount ext3 filesystem
127 mnt "-t auto $WDIR/sq-w/LiveOS/ext3fs.img -o rw,loop" ex
129 echo ">>> Updating CD content"
130 if [ -n "$PROG" ]; then
131 cp -av $PROG $WDIR/ex
132 pushd $WDIR/ex
133 set +e
134 ./$(basename $PROG)
135 set -e
136 popd
137 rm -f $WDIR/ex/$PROG
138 else
139 echo "***"
140 echo "*** Pausing to allow manual changes. Press any key to continue."
141 echo "***"
142 read
144 echo ">>> Unmounting ext3fs"
145 umount $WDIR/ex
147 echo ">>> Compressing filesystem"
148 mksquashfs $WDIR/sq-w/ $WDIR/cd-w/LiveOS/squashfs.img -noappend
150 echo ">>> Recomputing MD5 sums"
151 ( cd $WDIR/cd-w && find . -type f -not -name md5sum.txt -not -path '*/isolinux/*' -print0 | xargs -0 -- md5sum > md5sum.txt )
153 if [ -n "$PARAMS" ]; then
154 # FIXME: make the script fail -- or maybe try to
155 # find a usable sed delimiter if $PARAMS contains a slash
156 echo ">>> Appending boot parameters"
157 sed -i 's/^ append .*$/& '"$PARAMS/" "$WDIR/cd-w/isolinux/isolinux.cfg"
160 echo ">>> Creating ISO image $ISO"
161 mkisofs \
162 -V "$LABEL" \
163 -r -cache-inodes -J -l \
164 -b isolinux/isolinux.bin \
165 -c isolinux/boot.cat \
166 -no-emul-boot -boot-load-size 4 -boot-info-table \
167 -o "$ISO" \
168 $WDIR/cd-w
170 # The trap ... callbacks will unmount everything.
171 set +e