[Ovirt-devel] [PATCH node-image] edit-livecd: add -o OUTPUT.iso option, required
Jim Meyering
jim at meyering.net
Wed Dec 3 12:45:34 UTC 2008
The new -o OUTPUT.iso option is now required.
Allow the '-p CODE' option to specify bourne shell code, not just
a file/script. This permits a common idiom: to avoid writing a
separate shell script for a simple task, and instead include a
quoted multi-line snippet in the invoking script, e.g.,
edit-livecd ...other-options... -p '
d=etc/foo
mkdir -p $d &&
touch $d/file
'
Also,
in the boot params substitution,
- use @ rather than / in the sed
- warn if the selected string contains @
Update -h (help) output, and add examples.
Evaluate $CODE in a subshell (safer and doesn't rely on pushd,popd).
Guard against uninitialized ID_FS_LABEL.
Don't use "function" keyword.
Fail if there are any extra command-line arguments.
Ensure that $PWD and $CD are double-eval safe (else fail),
so that we don't have to quote them everywhere.
Ensure that a $CODE (renamed from $PROG) definition doesn't
leak in from the environment.
---
edit-livecd | 117 ++++++++++++++++++++++++++++++++++++++---------------------
1 files changed, 75 insertions(+), 42 deletions(-)
diff --git a/edit-livecd b/edit-livecd
index ce9e65b..6d6498a 100755
--- a/edit-livecd
+++ b/edit-livecd
@@ -34,38 +34,49 @@ usage() {
Usage: $ME -i LiveCD.iso [-b bootparams] [-p program]
-b BOOTPARAMS optional parameters appended to the kernel command line
-i LIVECD.iso LiveCD ISO to edit (default: $NODEIMG_DEFAULT)
- -p PROGRAM Arbitrary program/script that is run inside of the livecd root
- filesystem. This script is not run in a chroot environment so
- it can access the host filesystem. The program should be executable
- If program is omitted the script will pause and allow the user in
- another terminal to edit the filesystem manually. After enter is
- pushed the script will re-package up the ISO.
+ -o OUTPUT.iso specify the output file (required)
+ -p CODE Arbitrary CODE that is eval'd while 'cd'd into the root of
+ the livecd root filesystem. Note; the code is not run in
+ a chroot environment, so it can access the host filesystem.
+ If this option is omitted, this program pauses and allows
+ the user (in another terminal) to modify the filesystem
+ manually. Type <enter> when done, and the script
+ re-packages the ISO.
-h display this help and exit
+EXAMPLES
+
Example Script:
#!/bin/sh
touch etc/sysconfig/foo
+ Save as foo and make executable:
+ chmod a+x foo
+ Run this to create a file /etc/sysconfig/foo in the livecd filesystem
+ (note the use of "\$PWD/foo", not "./foo", since it will be run from a
+ different directory):
+
+ $ME -i input.iso -o /tmp/result.iso -p "\$PWD/foo"
+
+ or, equivalently, but without a separate script:
+
+ $ME -i input.iso -o /tmp/result.iso -p 'touch etc/sysconfig/foo'
- This will create a file /etc/sysconfig/foo in the livecd filesystem.
EOF
}
-# FIXME: instead of requiring a PROGRAM, allow arbitrary shell code,
-# so we can invoke $0 -p 'touch etc/sysconfig/foo' ...
-# This means that if you *do* have a program in the current directory
-# running "$0 -p ./my-script" won't work, since it'll be run with
-# a different working dir. However, *this* will:
-# $0 -p "$PWD/my-script"
-
# exit after any error:
set -e
+CODE=
+OUTPUT_FILE=
+
err=0 help=0
-while getopts :b:i:p:h c; do
+while getopts :b:hi:o:p: c; do
case $c in
i) CD=$OPTARG;;
b) PARAMS=$OPTARG;;
- p) PROG=$OPTARG;;
+ o) OUTPUT_FILE=$OPTARG;;
+ p) CODE=$OPTARG;;
h) help=1;;
'?') err=1; warn "invalid option: \`-$OPTARG'";;
:) err=1; warn "missing argument to \`-$OPTARG' option";;
@@ -75,39 +86,59 @@ done
test $err = 1 && { try_h; exit 1; }
test $help = 1 && { usage; exit 0; }
+# Require "-o OUTPUT_FILE"
+test -z "$OUTPUT_FILE" \
+ && { warn "no output file specified; use -o FILE.iso"; try_h; exit 1; }
+
+# Fail if there are any extra command-line arguments.
+if test $OPTIND -le $#; then
+ bad_arg=$(eval "echo \$$OPTIND")
+ warn "extra argument '$bad_arg'"; try_h; exit 1
+fi
+
# first, check to see we are root
if [ $( id -u ) -ne 0 ]; then
die "Must run as root"
fi
-# FIXME: don't use which: with bash, it's a separate program
-# FIXME: When failing due to a missing required program, tell the user why.
-which mkisofs mksquashfs sed > /dev/null 2>&1
+# Check for some prerequisites.
+# "type" prints "PROG not found" if it's not in $PATH.
+type mkisofs
+type mksquashfs
+type sed
+
+sane_name()
+{
+ case $1 in
+ *[^a-zA-Z0-9._,+:/@%=-]*) false;;
+ *) true;;
+ esac
+}
+
+# Fail if names we'll use contain white space or shell meta-characters
+sane_name "$PWD" || die "invalid working directory name: $PWD"
+sane_name "$CD" || die "invalid ISO name: $CD"
WDIR=`mktemp -d $PWD/livecd.XXXXXXXXXX`
-# FIXME: fail if $WDIR contains white space or shell meta-characters
-# FIXME: do the same for $CD.
-
-ISO="${CD##*/}"
-ISO="${ISO%.iso}-custom.iso"
-function addExit() {
+addExit() {
EXIT="$@ ; $EXIT"
trap "$EXIT" EXIT HUP TERM INT QUIT
}
-function mnt() {
+mnt() {
local margs="$1" ; shift
local mp="$WDIR/$1"
for D in "$@" ; do
mkdir -v -p "$WDIR/$D"
done
- mount -v $margs "$mp"
+ eval mount -v $margs "$mp"
addExit "df | grep $mp > /dev/null 2>&1 && umount -v $mp"
}
addExit "rm -rf $WDIR"
+ID_FS_LABEL= # initialize, in case vol_id fails
eval "$(/lib/udev/vol_id $CD)"
LABEL=$ID_FS_LABEL
@@ -120,21 +151,21 @@ mnt "-t squashfs $WDIR/cd/LiveOS/squashfs.img -o ro,loop" sq
# create writable copy of the new filesystem for the CD
cp -a $WDIR/cd $WDIR/cd-w
-# create writable copy of the filesystem for the new compressed squashfs filesystem
+# create writable copy of the filesystem for the new compressed
+# squashfs filesystem
cp -a $WDIR/sq $WDIR/sq-w
# mount ext3 filesystem
mnt "-t auto $WDIR/sq-w/LiveOS/ext3fs.img -o rw,loop" ex
echo ">>> Updating CD content"
-if [ -n "$PROG" ]; then
- cp -av $PROG $WDIR/ex
- pushd $WDIR/ex
- set +e
- ./$(basename $PROG)
- set -e
- popd
- rm -f $WDIR/ex/$PROG
+if [ -n "$CODE" ]; then
+ (
+ cd $WDIR/ex
+ set +e
+ eval "$CODE"
+ set -e
+ )
else
echo "***"
echo "*** Pausing to allow manual changes. Press any key to continue."
@@ -147,7 +178,7 @@ fi
while :; do
echo ">>> Unmounting ext3fs"
umount $WDIR/ex && break
- echo ">>> Unmounting ext3fs failed"
+ echo ">>> Unmounting the working file system copy failed"
echo "***"
echo "*** Did you forget to 'cd' out of $WDIR/ex?"
echo "***"
@@ -160,13 +191,15 @@ echo ">>> Compressing filesystem"
mksquashfs $WDIR/sq-w/ $WDIR/cd-w/LiveOS/squashfs.img -noappend
echo ">>> Recomputing MD5 sums"
-( cd $WDIR/cd-w && find . -type f -not -name md5sum.txt -not -path '*/isolinux/*' -print0 | xargs -0 -- md5sum > md5sum.txt )
+( cd $WDIR/cd-w && find . -type f -not -name md5sum.txt \
+ -not -path '*/isolinux/*' -print0 | xargs -0 -- md5sum > md5sum.txt )
if [ -n "$PARAMS" ]; then
- # FIXME: make the script fail -- or maybe try to
- # find a usable sed delimiter if $PARAMS contains a slash
+ case $PARAMS in
+ *@*) warn "PARAMS contains the @ sed delimiter, be sure it's escaped";;
+ esac
echo ">>> Appending boot parameters"
- sed -i 's/^ append .*$/& '"$PARAMS/" "$WDIR/cd-w/isolinux/isolinux.cfg"
+ sed -i 's@^ append .*$@& '"$PARAMS@" "$WDIR/cd-w/isolinux/isolinux.cfg"
fi
echo ">>> Creating ISO image $ISO"
@@ -176,7 +209,7 @@ mkisofs \
-b isolinux/isolinux.bin \
-c isolinux/boot.cat \
-no-emul-boot -boot-load-size 4 -boot-info-table \
- -o "$ISO" \
+ -o "$OUTPUT_FILE" \
$WDIR/cd-w
# The trap ... callbacks will unmount everything.
--
1.6.1.rc1.279.g45d11
More information about the ovirt-devel
mailing list