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.
113 *[^a-zA-Z0-9._
,+:/@
%=-]*) false
;;
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`
126 trap "$EXIT" EXIT HUP TERM INT QUIT
130 local margs
="$1" ; shift
133 mkdir
-v -p "$WDIR/$D"
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)"
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
171 echo "*** Pausing to allow manual changes. Press any key to continue."
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.
179 echo ">>> Unmounting ext3fs"
180 umount
$WDIR/ex
&& break
181 echo ">>> Unmounting the working file system copy failed"
183 echo "*** Did you forget to 'cd' out of $WDIR/ex?"
185 echo "*** Press any key to repeat the attempt."
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
199 *@
*) warn
"PARAMS contains the @ sed delimiter, be sure it's escaped";;
201 echo ">>> Appending boot parameters"
202 sed -i 's@^ append .*$@& '"$PARAMS@" "$WDIR/cd-w/isolinux/isolinux.cfg"
205 echo ">>> Creating ISO image $ISO"
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 \
215 # The trap ... callbacks will unmount everything.