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 "$TMPDIR" ] && WRKDIR="${TMPDIR}/grml2iso.tmp"
23 [ -n "$WRKDIR" ] || WRKDIR='/tmp/grml2iso.tmp'
24 # support mkisofs as well as genisoimage
25 if which xorriso >/dev/null 2>&1 ; then
26 MKISOFS='xorriso -as mkisofs'
27 elif which mkisofs >/dev/null 2>&1; then
29 elif which genisoimage >/dev/null 2>&1; then
32 echo >&2 "Error: neither mkisofs nor genisoimage available - can not create ISO."
41 echo >&2 "Usage: $0 [OPTIONS] -o target.iso source1.iso [source2.iso ...]"
44 -b Boot Params Additional boot parameters passed to grml2usb
45 -c Directory Copy files from directory to generated ISO
46 -f Force overwrite of existing target.iso
47 -r BootParam Remove specified boot params.
48 Can be specified multiple times.
49 -p <grml2usb param> Add the specified parameter to the grml2usb
50 commandline. For a list of valid parameters have
51 a look at the grml2usb manpage.
52 Can be specified multiple times.
53 -s URI Generate a small ISO file which downloads the squashfs
54 file from the specified URI. Please note that due to
55 restrictions in the bootprocess only IPs are allowed.
56 Supported protocols are: http and ftp
57 -t Directory Directory that should be used for temporary files
58 during build. Defaults to /tmp/grml2iso.tmp if unset.
61 $0 -s http://192.168.23.42:8000/grml/ -o small.iso grml64_2010.12.iso
63 Will generate a file small.iso which tries to download the squashfs file from
64 http://192.168.23.42:8000/grml/ - the squashfs file is placed in the same
65 output directory as the ISO file.
67 [ -n "$1" ] && exit $1 || exit 1
71 # command line handling {{{
72 [[ $# -gt 2 ]] || usage 1
79 typeset -a GRML2USB_OPTS
80 while getopts fb:c:o:r:p:s:t: name; do
82 o) ISOFILE="$OPTARG";;
83 b) GRML2USB_OPTS+=(--bootoptions="$OPTARG");;
84 c) DIR="$(readlink -f "$OPTARG")";;
86 r) GRML2USB_OPTS+=(--remove-bootoption="$OPTARG");;
87 p) GRML2USB_OPTS+=("$OPTARG");;
93 # test for specified URI
94 if [ -n "$URI" ] ; then
95 GRML2USB_OPTS+=(--bootoptions="fetch=$URI")
98 if [ -n "$WRKDIR" ] ; then
99 GRML2USB_OPTS+=(--tmpdir="$WRKDIR")
102 # make sure -o is specified
103 [ -n "$ISOFILE" ] || usage 1
105 # we don't to override any files by accident
106 if [ -e "$ISOFILE" -a ! -n "$FORCE" ]; then
107 echo "Error: target file $ISOFILE exists already." >&2
111 if [ ! -z "$DIR" -a ! -d "$DIR" ] ; then
112 echo "Error: specified parameter for -c is not a directory" >&2
117 # we need root permissions for executing grml2usb {{{
118 if [[ $(id -u) != 0 ]]; then
119 echo >&2 "Error: please run $0 as root."
124 # check for grml2usb {{{
125 if [ ! -x "$(which $GRML2USB)" ] && [ ! -x "$GRML2USB" ] ; then
126 echo >&2 "Error: Could not find grml2usb"
127 if [ -x "./$GRML2USB" ] ; then
128 echo >&2 "If you executed grml2iso from the grml2usb repository use"
129 echo >&2 "GRML2USB=./grml2usb $0 $*"
141 *) ISOFILE=$ORIG_DIR/$ISOFILE ;;
145 # create necessary stuff under WRKDIR {{{
146 [ -d "$WRKDIR" ] && WRKDIR_EXISTED='true' || WRKDIR_EXISTED='false'
147 rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
148 mkdir -p "$WRKDIR/cddir"
151 # execute grml2usb with all ISOs you'd like to install {{{
152 # remove all parameters
153 shift $(($OPTIND - 1))
155 $GRML2USB "${GRML2USB_OPTS[@]}" "$@" "$WRKDIR/cddir"
158 # move syslinux to isolinux {{{
159 mv "$WRKDIR"/cddir/boot/syslinux "$WRKDIR"/cddir/boot/isolinux
162 echo "menu label ^Isolinux prompt" > boot/isolinux/promptname.cfg
163 echo "include hd.cfg" >> boot/isolinux/grmlmain.cfg
167 # default, independent of UEFI support
168 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
172 echo "Using xorriso for ISO generation."
173 if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then
174 echo "Disabling (U)EFI boot support since xorriso version is not recent enough."
176 echo "xorriso with -eltorito-alt-boot support present"
178 if ! [ -r "${WRKDIR}/cddir/boot/efi.img" ] ; then
179 echo "File /boot/efi.img not found, not extending boot arguments for (U)EFI boot."
181 echo "/boot/efi.img found, extending boot arguments for (U)EFI boot."
182 BOOT_ARGS="$BOOT_ARGS -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
189 # adjust ISO for small output if necessary {{{
190 if [ -n "$URI" ] ; then
191 bootloader_files=$(find . -name "*.cfg" -type f)
192 bootloader_files+=" "
193 bootloader_files+=$(find . -name "*.lst" -type f)
194 output_dir=$(dirname "$ISOFILE")
195 for squashfs in $(find . -name *.squashfs) ; do
196 media_path="$(dirname "$squashfs")"
197 filename="$(basename "$squashfs")"
198 target="$output_dir/$filename"
199 if [ -f "$target" ] && [ ! -n "$FORCE" ] ; then
200 echo >&2 "Warning: $target already exists, and -force not specified, not overwriting"
203 OUTPUT_FILES+=("$target")
205 sed -i -e "s#^\(^.*$media_path.*\)\($URI\)\(.*$\)#\1$URI/$filename\3#g" $bootloader_files
211 # copy specified directory to cd {{{
212 if [ -n "$DIR" ] ; then
213 echo >&2 "Copying ${DIR} to generated ISO"
214 for param in GRML_NAME VERSION RELEASENAME DATE SHORT_NAME \
215 VERSION BOOTID RELEASE_INFO ; do
216 EXCLUDE_PARAM="$EXCLUDE_PARAM --exclude **%${param}%**"
218 rsync -a ${DIR}/ $EXCLUDE_PARAM .
221 # adjust files from overlay directory
222 for GRML_VERSION_FILE in $(find . -name grml-version) ; do
223 GRML_NAME=$(awk '{print $1}' "$GRML_VERSION_FILE")
224 VERSION=$(awk '{print $2}' "$GRML_VERSION_FILE")
225 RELEASENAME=$(sed 's/.*- \(.*\).*\[.*/\1/' "$GRML_VERSION_FILE")
226 DATE=$(sed 's/.*\[\(.*\)].*/\1/' "$GRML_VERSION_FILE")
227 SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
228 RELEASE_INFO="$GRML_NAME $VERSION - $RELEASENAME"
229 BOOTID=$(cat conf/bootid.txt)
231 for param in GRML_NAME VERSION RELEASENAME DATE SHORT_NAME \
232 RELEASE_INFO BOOTID ; do
233 value="$(eval echo '$'"$param")"
235 # copy parameterized files from the overlay directory
236 for file in $(find ${DIR} -name "*%$param%*") ; do
238 target_dir="$(dirname ${file})"
239 mkdir -p "$target_dir" || true
240 cp -r ${DIR}/${file} ./${target_dir}/"$(basename ${file/\%${param}\%/$value})"
243 # adjust config files
244 for file in ./boot/isolinux/*.cfg ./boot/isolinux/*.msg \
245 ./boot/grub/*.cfg ; do
246 sed -i "s/%$param%/$value/g" ${file} 2>/dev/null || true
252 # generate the CD/DVD ISO {{{
253 $MKISOFS -V 'grml-multiboot' -l -r -J -no-pad $BOOT_ARGS \
257 # pad the output ISO to multiples of 256 KiB for partition table support {{{
258 siz=$($getfilesize "$ISOFILE")
259 cyls=$(($siz / 512 / 32 / 16 + 1)) # C=$cyls H=16 S=32
260 ofs=$(($cyls * 16 * 32 * 512 - 1)) # padding offset (size - 1)
261 dd if=/dev/zero bs=1 count=1 seek=$ofs of="$ISOFILE" 2>/dev/null
267 rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
268 [[ $WRKDIR_EXISTED = 'false' ]] && rmdir "$WRKDIR"
269 echo "Generated $ISOFILE"
270 if [ -n "$URI" ] ; then
274 You requested to generate a small ISO image. Your generated
275 ISO image $ISOFILE does _not_ contain the squashfs files from
276 the source ISO images.
278 You have to provide the extracted squashfs files under $URI.
281 Squashfs files: ${OUTPUT_FILES[@]}
287 ## EOF #########################################################################
288 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=3