3 # Purpose: create a multiboot grml ISO using grml2usb
4 # Authors: Michael Prokop <mika@grml.org>,
5 # Thorsten Glaser <tg@mirbsd.org>
6 # Bug-Reports: see http://grml.org/bugs/
7 # License: This file is licensed under the GPL v2 or any later version.
8 ################################################################################
10 # define function getfilesize before "set -e" {{{
11 if stat --help >/dev/null 2>&1; then
12 getfilesize='stat -c %s' # GNU stat
14 getfilesize='stat -f %z' # BSD stat
18 # adjust variables if necessary through environment {{{
19 # path to the grml2usb script you'd like to use
20 [ -n "$GRML2USB" ] || GRML2USB='grml2usb'
21 # work directory for creating the filesystem
22 [ -n "$WRKDIR" ] || WRKDIR='/tmp/grml2iso.tmp'
23 # support mkisofs as well as genisoimage
24 if which xorriso >/dev/null 2>&1 ; then
25 MKISOFS='xorriso -as mkisofs'
26 elif which mkisofs >/dev/null 2>&1; then
28 elif which genisoimage >/dev/null 2>&1; then
31 echo >&2 "Error: neither mkisofs nor genisoimage available - can not create ISO."
40 echo >&2 "Usage: $0 [OPTIONS] -o target.iso source1.iso [source2.iso ...]"
43 -b Boot Params Additional boot parameters passed to grml2usb
44 -c Directory Copy files from directory to generated ISO
45 -f Force overwrite of existing target.iso
46 -r BootParam Remove specified boot params.
47 Could be specfied multiple times.
48 -p <grml2usb param> Add the specified parameter to the grml2usb
49 commandline. For a list of valid parameters have
50 a look at the grml2usb manpage.
51 Can be specified multiple times.
52 -s URI Generate a small ISO file which downloads the squashfs
53 file from the specified URI. Please note that due to
54 restrictions in the bootprocess only IPs are allowed.
55 Supported protocols are: http and ftp
58 $0 -s http://192.168.23.42:8000/grml/ -o small.iso grml64_2010.12.iso
60 Will generate a file small.iso which tries to download the squashfs file from
61 http://192.168.23.42:8000/grml/ - the squashfs file is placed in the same
62 output directory as the ISO file.
64 [ -n "$1" ] && exit $1 || exit 1
68 # command line handling {{{
69 [[ $# -gt 2 ]] || usage 1
76 typeset -a GRML2USB_OPTS
77 while getopts fb:c:o:r:p:s: name; do
79 o) ISOFILE="$OPTARG";;
80 b) GRML2USB_OPTS+=(--bootoptions="$OPTARG");;
81 c) DIR="$(readlink -f "$OPTARG")";;
83 r) GRML2USB_OPTS+=(--remove-bootoption="$OPTARG");;
84 p) GRML2USB_OPTS+=("$OPTARG");;
89 # test for specified URI
90 if [ -n "$URI" ] ; then
91 GRML2USB_OPTS+=(--bootoptions="fetch=$URI")
94 # make sure -o is specified
95 [ -n "$ISOFILE" ] || usage 1
97 # we don't to override any files by accident
98 if [ -e "$ISOFILE" -a ! -n "$FORCE" ]; then
99 echo "Error: target file $ISOFILE exists already." >&2
103 if [ ! -z "$DIR" -a ! -d "$DIR" ] ; then
104 echo "Error: specified parameter for -c is not a directory" >&2
109 # we need root permissions for executing grml2usb {{{
110 if [[ $(id -u) != 0 ]]; then
111 echo >&2 "Error: please run $0 as root."
116 # check for grml2usb {{{
117 if [ ! -x "$(which $GRML2USB)" ] && [ ! -x "$GRML2USB" ] ; then
118 echo >&2 "Error: Could not find grml2usb"
119 if [ -x "./$GRML2USB" ] ; then
120 echo >&2 "If you executed grml2iso from the grml2usb repository use"
121 echo >&2 "GRML2USB=./grml2usb $0 $*"
133 *) ISOFILE=$ORIG_DIR/$ISOFILE ;;
137 # create necessary stuff under WRKDIR {{{
138 [ -d "$WRKDIR" ] && WRKDIR_EXISTED='true' || WRKDIR_EXISTED='false'
139 rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
140 mkdir -p "$WRKDIR/cddir"
143 # execute grml2usb with all ISOs you'd like to install {{{
144 # remove all parameters
145 shift $(($OPTIND - 1))
147 $GRML2USB "${GRML2USB_OPTS[@]}" "$@" "$WRKDIR/cddir"
150 # move syslinux to isolinux {{{
151 mv "$WRKDIR"/cddir/boot/syslinux "$WRKDIR"/cddir/boot/isolinux
154 echo "menu label ^Isolinux prompt" > boot/isolinux/promptname.cfg
155 echo "include hd.cfg" >> boot/isolinux/grmlmain.cfg
159 # default, independent of UEFI support
160 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
164 echo "Using xorriso for ISO generation."
165 if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then
166 echo "Disabling (U)EFI boot support since xorriso version is not recent enough."
168 echo "xorriso with -eltorito-alt-boot support present"
170 if ! [ -r "${WRKDIR}/cddir/boot/efi.img" ] ; then
171 echo "File /boot/efi.img not found, not extending boot arguments for (U)EFI boot."
173 echo "/boot/efi.img found, extending boot arguments for (U)EFI boot."
174 BOOT_ARGS="$BOOT_ARGS -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
181 # adjust ISO for small output if necessary {{{
182 if [ -n "$URI" ] ; then
183 bootloader_files=$(find . -name "*.cfg" -type f)
184 bootloader_files+=" "
185 bootloader_files+=$(find . -name "*.lst" -type f)
186 output_dir=$(dirname "$ISOFILE")
187 for squashfs in $(find . -name *.squashfs) ; do
188 media_path="$(dirname "$squashfs")"
189 filename="$(basename "$squashfs")"
190 target="$output_dir/$filename"
191 if [ -f "$target" ] && [ ! -n "$FORCE" ] ; then
192 echo >&2 "Warning: $target already exists, and -force not specified, not overwriting"
195 OUTPUT_FILES+=("$target")
197 sed -i -e "s#^\(^.*$media_path.*\)\($URI\)\(.*$\)#\1$URI/$filename\3#g" $bootloader_files
203 # copy specified directory to cd {{{
204 if [ -n "$DIR" ] ; then
205 echo >&2 "Copying ${DIR} to generated ISO"
206 for param in GRML_NAME VERSION RELEASENAME DATE SHORT_NAME \
207 VERSION BOOTID RELEASE_INFO ; do
208 EXCLUDE_PARAM="$EXCLUDE_PARAM --exclude **%${param}%**"
210 rsync -a ${DIR}/ $EXCLUDE_PARAM .
213 # adjust files from overlay directory
214 for GRML_VERSION_FILE in $(find . -name grml-version) ; do
215 GRML_NAME=$(awk '{print $1}' "$GRML_VERSION_FILE")
216 VERSION=$(awk '{print $2}' "$GRML_VERSION_FILE")
217 RELEASENAME=$(sed 's/.*- \(.*\).*\[.*/\1/' "$GRML_VERSION_FILE")
218 DATE=$(sed 's/.*\[\(.*\)].*/\1/' "$GRML_VERSION_FILE")
219 SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
220 RELEASE_INFO="$GRML_NAME $VERSION - $RELEASENAME"
221 BOOTID=$(cat conf/bootid.txt)
223 for param in GRML_NAME VERSION RELEASENAME DATE SHORT_NAME \
224 RELEASE_INFO BOOTID ; do
225 value="$(eval echo '$'"$param")"
227 # copy parameterized files from the overlay directory
228 for file in $(find ${DIR} -name "*%$param%*") ; do
230 target_dir="$(dirname ${file})"
231 mkdir -p "$target_dir" || true
232 cp -r ${DIR}/${file} ./${target_dir}/"$(basename ${file/\%${param}\%/$value})"
235 # adjust config files
236 for file in ./boot/isolinux/*.cfg ./boot/isolinux/*.msg \
237 ./boot/grub/*.cfg ; do
238 sed -i "s/%$param%/$value/g" ${file} 2>/dev/null || true
244 # generate the CD/DVD ISO {{{
245 $MKISOFS -V 'grml-multiboot' -l -r -J -no-pad $BOOT_ARGS \
249 # pad the output ISO to multiples of 256 KiB for partition table support {{{
250 siz=$($getfilesize "$ISOFILE")
251 cyls=$(echo "$siz / 512 / 32 / 16 + 1" | bc) # C=$cyls H=16 S=32
252 ofs=$(echo "$cyls * 16 * 32 * 512 - 1" | bc) # padding offset (size - 1)
253 dd if=/dev/zero bs=1 count=1 seek=$ofs of="$ISOFILE" 2>/dev/null
259 rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
260 [[ $WRKDIR_EXISTED = 'false' ]] && rmdir "$WRKDIR"
261 echo "Generated $ISOFILE"
262 if [ -n "$URI" ] ; then
266 You requested to generate a small ISO image. Your generated
267 ISO image $ISOFILE does _not_ contain the squashfs files from
268 the source ISO images.
270 You have to provide the extracted squashfs files under $URI.
273 Squashfs files: ${OUTPUT_FILES[@]}
279 ## EOF #########################################################################
280 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=3