force iso9660 for trigger ISO media check
[ovirt-node-image.git] / edit-livecd
blob6d6498a5ae3d953ea941cceea2cf8c0e2548face
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 -o OUTPUT.iso specify the output file (required)
38 -p CODE Arbitrary CODE that is eval'd while 'cd'd into the root of
39 the livecd root filesystem. Note; the code is not run in
40 a chroot environment, so it can access the host filesystem.
41 If this option is omitted, this program pauses and allows
42 the user (in another terminal) to modify the filesystem
43 manually. Type <enter> when done, and the script
44 re-packages the ISO.
45 -h display this help and exit
47 EXAMPLES
49 Example Script:
50 #!/bin/sh
51 touch etc/sysconfig/foo
52 Save as foo and make executable:
53 chmod a+x foo
54 Run this to create a file /etc/sysconfig/foo in the livecd filesystem
55 (note the use of "\$PWD/foo", not "./foo", since it will be run from a
56 different directory):
58 $ME -i input.iso -o /tmp/result.iso -p "\$PWD/foo"
60 or, equivalently, but without a separate script:
62 $ME -i input.iso -o /tmp/result.iso -p 'touch etc/sysconfig/foo'
64 EOF
67 # exit after any error:
68 set -e
70 CODE=
71 OUTPUT_FILE=
73 err=0 help=0
74 while getopts :b:hi:o:p: c; do
75 case $c in
76 i) CD=$OPTARG;;
77 b) PARAMS=$OPTARG;;
78 o) OUTPUT_FILE=$OPTARG;;
79 p) CODE=$OPTARG;;
80 h) help=1;;
81 '?') err=1; warn "invalid option: \`-$OPTARG'";;
82 :) err=1; warn "missing argument to \`-$OPTARG' option";;
83 *) err=1; warn "internal error: \`-$OPTARG' not handled";;
84 esac
85 done
86 test $err = 1 && { try_h; exit 1; }
87 test $help = 1 && { usage; exit 0; }
89 # Require "-o OUTPUT_FILE"
90 test -z "$OUTPUT_FILE" \
91 && { warn "no output file specified; use -o FILE.iso"; try_h; exit 1; }
93 # Fail if there are any extra command-line arguments.
94 if test $OPTIND -le $#; then
95 bad_arg=$(eval "echo \$$OPTIND")
96 warn "extra argument '$bad_arg'"; try_h; exit 1
99 # first, check to see we are root
100 if [ $( id -u ) -ne 0 ]; then
101 die "Must run as root"
104 # Check for some prerequisites.
105 # "type" prints "PROG not found" if it's not in $PATH.
106 type mkisofs
107 type mksquashfs
108 type sed
110 sane_name()
112 case $1 in
113 *[^a-zA-Z0-9._,+:/@%=-]*) false;;
114 *) true;;
115 esac
118 # Fail if names we'll use contain white space or shell meta-characters
119 sane_name "$PWD" || die "invalid working directory name: $PWD"
120 sane_name "$CD" || die "invalid ISO name: $CD"
122 WDIR=`mktemp -d $PWD/livecd.XXXXXXXXXX`
124 addExit() {
125 EXIT="$@ ; $EXIT"
126 trap "$EXIT" EXIT HUP TERM INT QUIT
129 mnt() {
130 local margs="$1" ; shift
131 local mp="$WDIR/$1"
132 for D in "$@" ; do
133 mkdir -v -p "$WDIR/$D"
134 done
135 eval mount -v $margs "$mp"
136 addExit "df | grep $mp > /dev/null 2>&1 && umount -v $mp"
139 addExit "rm -rf $WDIR"
141 ID_FS_LABEL= # initialize, in case vol_id fails
142 eval "$(/lib/udev/vol_id $CD)"
143 LABEL=$ID_FS_LABEL
145 # mount the CD image
146 mnt "-t auto $CD -o loop,ro" cd
148 # mount compressed filesystem
149 mnt "-t squashfs $WDIR/cd/LiveOS/squashfs.img -o ro,loop" sq
151 # create writable copy of the new filesystem for the CD
152 cp -a $WDIR/cd $WDIR/cd-w
154 # create writable copy of the filesystem for the new compressed
155 # squashfs filesystem
156 cp -a $WDIR/sq $WDIR/sq-w
158 # mount ext3 filesystem
159 mnt "-t auto $WDIR/sq-w/LiveOS/ext3fs.img -o rw,loop" ex
161 echo ">>> Updating CD content"
162 if [ -n "$CODE" ]; then
164 cd $WDIR/ex
165 set +e
166 eval "$CODE"
167 set -e
169 else
170 echo "***"
171 echo "*** Pausing to allow manual changes. Press any key to continue."
172 echo "***"
173 read
176 # Try to unmount. But this is likely to fail, so let the user retry,
177 # e.g., if he forgot to "cd" out of $WDIR/ex.
178 while :; do
179 echo ">>> Unmounting ext3fs"
180 umount $WDIR/ex && break
181 echo ">>> Unmounting the working file system copy failed"
182 echo "***"
183 echo "*** Did you forget to 'cd' out of $WDIR/ex?"
184 echo "***"
185 echo "*** Press any key to repeat the attempt."
186 echo "***"
187 read
188 done
190 echo ">>> Compressing filesystem"
191 mksquashfs $WDIR/sq-w/ $WDIR/cd-w/LiveOS/squashfs.img -noappend
193 echo ">>> Recomputing MD5 sums"
194 ( cd $WDIR/cd-w && find . -type f -not -name md5sum.txt \
195 -not -path '*/isolinux/*' -print0 | xargs -0 -- md5sum > md5sum.txt )
197 if [ -n "$PARAMS" ]; then
198 case $PARAMS in
199 *@*) warn "PARAMS contains the @ sed delimiter, be sure it's escaped";;
200 esac
201 echo ">>> Appending boot parameters"
202 sed -i 's@^ append .*$@& '"$PARAMS@" "$WDIR/cd-w/isolinux/isolinux.cfg"
205 echo ">>> Creating ISO image $ISO"
206 mkisofs \
207 -V "$LABEL" \
208 -r -cache-inodes -J -l \
209 -b isolinux/isolinux.bin \
210 -c isolinux/boot.cat \
211 -no-emul-boot -boot-load-size 4 -boot-info-table \
212 -o "$OUTPUT_FILE" \
213 $WDIR/cd-w
215 # The trap ... callbacks will unmount everything.
216 set +e