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."
36 if ! which isohybrid >/dev/null 2>&1 ; then
37 echo "Error: isohybrid executable not found (install syslinux?)." >&2
46 echo >&2 "Usage: $0 [OPTIONS] -o target.iso source1.iso [source2.iso ...]"
49 -b Boot Params Additional boot parameters passed to grml2usb
50 -c Directory Copy files from directory to generated ISO
51 -f Force overwrite of existing target.iso
52 -r BootParam Remove specified boot params.
53 Can be specified multiple times.
54 -p <grml2usb param> Add the specified parameter to the grml2usb
55 commandline. For a list of valid parameters have
56 a look at the grml2usb manpage.
57 Can be specified multiple times.
58 -s URI Generate a small ISO file which downloads the squashfs
59 file from the specified URI. Please note that due to
60 restrictions in the bootprocess only IPs are allowed.
61 Supported protocols are: http and ftp
62 -t Directory Directory that should be used for temporary files
63 during build. Defaults to /tmp/grml2iso.tmp if unset.
66 $0 -s http://192.168.23.42:8000/grml/ -o small.iso grml64_2010.12.iso
68 Will generate a file small.iso which tries to download the squashfs file from
69 http://192.168.23.42:8000/grml/ - the squashfs file is placed in the same
70 output directory as the ISO file.
72 [ -n "$1" ] && exit $1 || exit 1
76 # command line handling {{{
77 [[ $# -gt 2 ]] || usage 1
84 typeset -a GRML2USB_OPTS
85 while getopts fb:c:o:r:p:s:t: name; do
87 o) ISOFILE="$OPTARG";;
88 b) GRML2USB_OPTS+=(--bootoptions="$OPTARG");;
89 c) DIR="$(readlink -f "$OPTARG")";;
91 r) GRML2USB_OPTS+=(--remove-bootoption="$OPTARG");;
92 p) GRML2USB_OPTS+=("$OPTARG");;
98 # test for specified URI
99 if [ -n "$URI" ] ; then
100 GRML2USB_OPTS+=(--bootoptions="fetch=$URI")
103 if [ -n "$WRKDIR" ] ; then
104 GRML2USB_OPTS+=(--tmpdir="$WRKDIR")
107 # make sure -o is specified
108 [ -n "$ISOFILE" ] || usage 1
110 # we don't to override any files by accident
111 if [ -e "$ISOFILE" -a ! -n "$FORCE" ]; then
112 echo "Error: target file $ISOFILE exists already." >&2
116 if [ ! -z "$DIR" -a ! -d "$DIR" ] ; then
117 echo "Error: specified parameter for -c is not a directory" >&2
122 # we need root permissions for executing grml2usb {{{
123 if [[ $(id -u) != 0 ]]; then
124 echo >&2 "Error: please run $0 as root."
129 # check for grml2usb {{{
130 if [ ! -x "$(which $GRML2USB)" ] && [ ! -x "$GRML2USB" ] ; then
131 echo >&2 "Error: Could not find grml2usb"
132 if [ -x "./$GRML2USB" ] ; then
133 echo >&2 "If you executed grml2iso from the grml2usb repository use"
134 echo >&2 "GRML2USB=./grml2usb $0 $*"
146 *) ISOFILE=$ORIG_DIR/$ISOFILE ;;
150 # create necessary stuff under WRKDIR {{{
151 [ -d "$WRKDIR" ] && WRKDIR_EXISTED='true' || WRKDIR_EXISTED='false'
152 rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
153 mkdir -p "$WRKDIR/cddir"
156 # execute grml2usb with all ISOs you'd like to install {{{
157 # remove all parameters
158 shift $(($OPTIND - 1))
160 $GRML2USB "${GRML2USB_OPTS[@]}" "$@" "$WRKDIR/cddir"
163 # move syslinux to isolinux {{{
164 mv "$WRKDIR"/cddir/boot/syslinux "$WRKDIR"/cddir/boot/isolinux
167 echo "menu label ^Isolinux prompt" > boot/isolinux/promptname.cfg
168 echo "include hd.cfg" >> boot/isolinux/grmlmain.cfg
172 # default, independent of UEFI support
173 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
177 echo "Using xorriso for ISO generation."
178 if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then
179 echo "Disabling (U)EFI boot support since xorriso version is not recent enough."
181 echo "xorriso with -eltorito-alt-boot support present"
183 if ! [ -r "${WRKDIR}/cddir/boot/efi.img" ] ; then
184 echo "File /boot/efi.img not found, not extending boot arguments for (U)EFI boot."
186 echo "/boot/efi.img found, extending boot arguments for (U)EFI boot."
187 BOOT_ARGS="$BOOT_ARGS -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
194 # adjust ISO for small output if necessary {{{
195 if [ -n "$URI" ] ; then
196 bootloader_files=$(find . -name "*.cfg" -type f)
197 bootloader_files+=" "
198 bootloader_files+=$(find . -name "*.lst" -type f)
199 output_dir=$(dirname "$ISOFILE")
200 for squashfs in $(find . -name *.squashfs) ; do
201 media_path="$(dirname "$squashfs")"
202 filename="$(basename "$squashfs")"
203 target="$output_dir/$filename"
204 if [ -f "$target" ] && [ ! -n "$FORCE" ] ; then
205 echo >&2 "Warning: $target already exists, and -force not specified, not overwriting"
208 OUTPUT_FILES+=("$target")
210 sed -i -e "s#^\(^.*$media_path.*\)\($URI\)\(.*$\)#\1$URI/$filename\3#g" $bootloader_files
216 # copy specified directory to cd {{{
217 if [ -n "$DIR" ] ; then
218 echo >&2 "Copying ${DIR} to generated ISO"
219 for param in GRML_NAME VERSION RELEASENAME DATE SHORT_NAME \
220 VERSION BOOTID RELEASE_INFO ; do
221 EXCLUDE_PARAM="$EXCLUDE_PARAM --exclude **%${param}%**"
223 rsync -a ${DIR}/ $EXCLUDE_PARAM .
226 # adjust files from overlay directory
227 for GRML_VERSION_FILE in $(find . -name grml-version) ; do
228 GRML_NAME=$(awk '{print $1}' "$GRML_VERSION_FILE")
229 VERSION=$(awk '{print $2}' "$GRML_VERSION_FILE")
230 RELEASENAME=$(sed 's/.*- \(.*\).*\[.*/\1/' "$GRML_VERSION_FILE")
231 DATE=$(sed 's/.*\[\(.*\)].*/\1/' "$GRML_VERSION_FILE")
232 SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
233 RELEASE_INFO="$GRML_NAME $VERSION - $RELEASENAME"
234 BOOTID=$(cat conf/bootid.txt)
236 for param in GRML_NAME VERSION RELEASENAME DATE SHORT_NAME \
237 RELEASE_INFO BOOTID ; do
238 value="$(eval echo '$'"$param")"
240 # copy parameterized files from the overlay directory
241 for file in $(find ${DIR} -name "*%$param%*") ; do
243 target_dir="$(dirname ${file})"
244 mkdir -p "$target_dir" || true
245 cp -r ${DIR}/${file} ./${target_dir}/"$(basename ${file/\%${param}\%/$value})"
248 # adjust config files
249 for file in ./boot/isolinux/*.cfg ./boot/isolinux/*.msg \
250 ./boot/grub/*.cfg ; do
251 sed -i "s/%$param%/$value/g" ${file} 2>/dev/null || true
257 # generate the CD/DVD ISO {{{
258 $MKISOFS -V 'grml-multiboot' -l -r -J -no-pad $BOOT_ARGS \
262 # pad the output ISO to multiples of 256 KiB for partition table support {{{
263 siz=$($getfilesize "$ISOFILE")
264 cyls=$(($siz / 512 / 32 / 16 + 1)) # C=$cyls H=16 S=32
265 ofs=$(($cyls * 16 * 32 * 512 - 1)) # padding offset (size - 1)
266 dd if=/dev/zero bs=1 count=1 seek=$ofs of="$ISOFILE" 2>/dev/null
269 # make ISO dd-able {{{
270 if isohybrid --help | grep -q -- --uefi ; then
271 echo "isohybrid version supports --uefi option, enabling"
272 ISOHYBRID_OPTIONS=--uefi
274 echo "isohybrid version does NOT support --uefi option, disabling"
277 echo "Creating dd-able ISO using isohybrid"
278 isohybrid $ISOHYBRID_OPTIONS "$ISOFILE"
284 rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
285 [[ $WRKDIR_EXISTED = 'false' ]] && rmdir "$WRKDIR"
286 echo "Generated $ISOFILE"
287 if [ -n "$URI" ] ; then
291 You requested to generate a small ISO image. Your generated
292 ISO image $ISOFILE does _not_ contain the squashfs files from
293 the source ISO images.
295 You have to provide the extracted squashfs files under $URI.
298 Squashfs files: ${OUTPUT_FILES[@]}
304 ## EOF #########################################################################
305 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=3