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.
21 PATH
=$PATH:/sbin
:/usr
/sbin
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
32 case $# in 1) warn
"$1"; try_h
; exit 1;; esac
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
45 -h display this help and exit
51 touch etc/sysconfig/foo
52 Save as foo and make executable:
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
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'
67 # exit after any error:
74 while getopts :b
:hi
:o
:p
: c
; do
78 o
) OUTPUT_FILE
=$OPTARG;;
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";;
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.
114 *[^a-zA-Z0-9._
,+:/@
%=-]*) false
;;
119 # Fail if names we'll use contain white space or shell meta-characters
120 sane_name
"$PWD" || die
"invalid working directory name: $PWD"
121 sane_name
"$CD" || die
"invalid ISO name: $CD"
123 WDIR
=`mktemp -d $PWD/livecd.XXXXXXXXXX`
127 trap "$EXIT" EXIT HUP TERM INT QUIT
131 local margs
="$1" ; shift
134 mkdir
-v -p "$WDIR/$D"
136 eval mount
-v $margs "$mp"
137 addExit
"df | grep $mp > /dev/null 2>&1 && umount -v $mp"
140 addExit
"rm -rf $WDIR"
142 ID_FS_LABEL
= # initialize, in case vol_id fails
143 eval "$(/lib/udev/vol_id $CD)"
147 mnt
"-t iso9660 $CD -o loop,ro" cd
149 # mount compressed filesystem
150 mnt
"-t squashfs $WDIR/cd/LiveOS/squashfs.img -o ro,loop" sq
152 # create writable copy of the new filesystem for the CD
153 cp -pr $WDIR/cd $WDIR/cd-w
155 # create writable copy of the filesystem for the new compressed
156 # squashfs filesystem
157 cp -pr $WDIR/sq $WDIR/sq-w
159 # mount root filesystem
160 mnt
"-t ext2 $WDIR/sq-w/LiveOS/ext3fs.img -o rw,loop" ex
162 echo ">>> Updating CD content"
163 if [ -n "$CODE" ]; then
172 echo "*** Pausing to allow manual changes. Press any key to continue."
177 # Try to unmount. But this is likely to fail, so let the user retry,
178 # e.g., if he forgot to "cd" out of $WDIR/ex.
180 echo ">>> Unmounting ext3fs"
181 umount
$WDIR/ex
&& break
182 echo ">>> Unmounting the working file system copy failed"
184 echo "*** Did you forget to 'cd' out of $WDIR/ex?"
186 echo "*** Press any key to repeat the attempt."
191 echo ">>> Compressing filesystem"
192 mksquashfs
$WDIR/sq-w
/ $WDIR/cd-w
/LiveOS
/squashfs.img
-noappend
194 echo ">>> Recomputing MD5 sums"
195 ( cd $WDIR/cd-w
&& find .
-type f
-not -name md5sum.txt \
196 -not -path '*/isolinux/*' -print0 |
xargs -0 -- md5sum > md5sum.txt
)
198 if [ -n "$PARAMS" ]; then
200 *@
*) warn
"PARAMS contains the @ sed delimiter, be sure it's escaped";;
202 echo ">>> Appending boot parameters"
203 sed -i 's@^ append .*$@& '"$PARAMS@" "$WDIR/cd-w/isolinux/isolinux.cfg"
206 echo ">>> Creating ISO image $ISO"
209 -r -cache-inodes -J -l \
210 -b isolinux
/isolinux.bin \
211 -c isolinux
/boot.
cat \
212 -no-emul-boot -boot-load-size 4 -boot-info-table \
216 echo ">>> Implanting ISO MD5 Sum"
217 implantisomd5
--force "$OUTPUT_FILE"
219 # The trap ... callbacks will unmount everything.