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 "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO." >&2
36 if ! which isohybrid >/dev/null 2>&1 ; then
37 echo "Error: isohybrid executable not found (install syslinux/isolinux?)." >&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")"; [ -n "$DIR" ] || { echo "Could not read $OPTARG - exiting" >&2 ; exit 1 ; } ;;
91 r) GRML2USB_OPTS+=(--remove-bootoption="$OPTARG");;
92 p) GRML2USB_OPTS+=("$OPTARG");;
94 t) WRKDIR="$(readlink -f "$OPTARG")";;
99 # test for specified URI
100 if [ -n "$URI" ] ; then
101 GRML2USB_OPTS+=(--bootoptions="fetch=$URI")
104 if [ -n "$WRKDIR" ] ; then
105 GRML2USB_OPTS+=(--tmpdir="$WRKDIR")
108 # make sure -o is specified
109 [ -n "$ISOFILE" ] || usage 1
111 # we don't to override any files by accident
112 if [ -e "$ISOFILE" -a ! -n "$FORCE" ]; then
113 echo "Error: target file $ISOFILE exists already." >&2
117 if [ ! -z "$DIR" -a ! -d "$DIR" ] ; then
118 echo "Error: specified parameter for -c is not a directory" >&2
123 # we need root permissions for executing grml2usb {{{
124 if [[ $(id -u) != 0 ]]; then
125 echo >&2 "Error: please run $0 as root."
130 # check for grml2usb {{{
131 if [ ! -x "$(which $GRML2USB)" ] && [ ! -x "$GRML2USB" ] ; then
132 echo "Error: Could not find grml2usb executable. Is /usr/sbin missing in PATH?" >&2
133 echo "Tip: run GRML2USB=/usr/sbin/grml2usb grml2iso ... as workaround" >&2
134 if [ -x "./$GRML2USB" ] ; then
135 echo >&2 "If you executed grml2iso from the grml2usb repository use"
136 echo >&2 "GRML2USB=./grml2usb $0 $*"
148 *) ISOFILE=$ORIG_DIR/$ISOFILE ;;
152 # create necessary stuff under WRKDIR {{{
153 [ -d "$WRKDIR" ] && WRKDIR_EXISTED='true' || WRKDIR_EXISTED='false'
154 rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
155 mkdir -p "$WRKDIR/cddir"
158 # execute grml2usb with all ISOs you'd like to install {{{
159 # remove all parameters
160 shift $(($OPTIND - 1))
162 $GRML2USB "${GRML2USB_OPTS[@]}" "$@" "$WRKDIR/cddir"
165 # move syslinux to isolinux {{{
166 mv "$WRKDIR"/cddir/boot/syslinux "$WRKDIR"/cddir/boot/isolinux
167 echo "menu label ^Isolinux prompt" > "$WRKDIR"/cddir/boot/isolinux/promptname.cfg
168 echo "include hd.cfg" >> "$WRKDIR"/cddir/boot/isolinux/grmlmain.cfg
171 # change to $WRKDIR {{{
172 # make sure $WRKDIR is an absolute path, otherwise accessing files
173 # in it will fail later in the code path if user provided a
175 WRKDIR=$(realpath $WRKDIR)
180 # default, independent of UEFI support
181 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
186 echo "Using xorriso for ISO generation."
187 if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then
188 echo "Disabling (U)EFI boot support since xorriso version is not recent enough."
190 echo "xorriso with -eltorito-alt-boot support present"
193 if ! [ -r "${WRKDIR}/cddir/boot/efi.img" ] ; then
194 echo "Warning: File /boot/efi.img not found, not extending boot arguments for (U)EFI boot."
197 echo "/boot/efi.img found, extending boot arguments for (U)EFI boot."
198 BOOT_ARGS="$BOOT_ARGS -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
203 echo "Using $MKISOFS for ISO generation (lacking UEFI option), disabling (U)EFI boot support."
208 # adjust ISO for small output if necessary {{{
209 if [ -n "$URI" ] ; then
210 bootloader_files=$(find . -name "*.cfg" -type f)
211 bootloader_files+=" "
212 bootloader_files+=$(find . -name "*.lst" -type f)
213 output_dir=$(dirname "$ISOFILE")
214 for squashfs in $(find . -name *.squashfs) ; do
215 media_path="$(dirname "$squashfs")"
216 filename="$(basename "$squashfs")"
217 target="$output_dir/$filename"
218 if [ -f "$target" ] && [ ! -n "$FORCE" ] ; then
219 echo >&2 "Warning: $target already exists, and -force not specified, not overwriting"
222 OUTPUT_FILES+=("$target")
224 sed -i -e "s#^\(^.*$media_path.*\)\($URI\)\(.*$\)#\1$URI/$filename\3#g" $bootloader_files
230 # copy specified directory to cd {{{
231 if [ -n "$DIR" ] ; then
232 echo >&2 "Copying ${DIR} to generated ISO"
233 for param in GRML_NAME VERSION RELEASENAME DATE SHORT_NAME \
234 VERSION BOOTID RELEASE_INFO ; do
235 EXCLUDE_PARAM="$EXCLUDE_PARAM --exclude **%${param}%**"
237 rsync -a ${DIR}/ $EXCLUDE_PARAM .
240 # adjust files from overlay directory
241 for GRML_VERSION_FILE in $(find . -name grml-version) ; do
242 GRML_NAME=$(awk '{print $1}' "$GRML_VERSION_FILE")
243 VERSION=$(awk '{print $2}' "$GRML_VERSION_FILE")
244 RELEASENAME=$(sed 's/.*- \(.*\).*\[.*/\1/' "$GRML_VERSION_FILE")
245 DATE=$(sed 's/.*\[\(.*\)].*/\1/' "$GRML_VERSION_FILE")
246 SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
247 RELEASE_INFO="$GRML_NAME $VERSION - $RELEASENAME"
248 BOOTID=$(cat conf/bootid.txt)
250 for param in GRML_NAME VERSION RELEASENAME DATE SHORT_NAME \
251 RELEASE_INFO BOOTID ; do
252 value="$(eval echo '$'"$param")"
254 # copy parameterized files from the overlay directory
255 for file in $(find ${DIR} -name "*%$param%*") ; do
257 target_dir="$(dirname ${file})"
258 mkdir -p "$target_dir" || true
259 cp -r ${DIR}/${file} ./${target_dir}/"$(basename ${file/\%${param}\%/$value})"
262 # adjust config files
263 for file in ./boot/isolinux/*.cfg ./boot/isolinux/*.msg \
264 ./boot/grub/*.cfg ; do
265 sed -i "s/%$param%/$value/g" ${file} 2>/dev/null || true
271 # generate the CD/DVD ISO {{{
272 $MKISOFS -V 'grml-multiboot' -l -r -J -no-pad $BOOT_ARGS \
276 # pad the output ISO to multiples of 256 KiB for partition table support {{{
277 siz=$($getfilesize "$ISOFILE")
278 cyls=$(($siz / 512 / 32 / 16 + 1)) # C=$cyls H=16 S=32
279 ofs=$(($cyls * 16 * 32 * 512 - 1)) # padding offset (size - 1)
280 dd if=/dev/zero bs=1 count=1 seek=$ofs of="$ISOFILE" 2>/dev/null
283 # make ISO dd-able {{{
284 if ! $UEFI_ENABLE ; then
285 echo "Skipping check for --uefi option in isohybrid since prerequisites are not fulfilled."
287 if ! isohybrid --help | grep -q -- --uefi ; then
288 echo "isohybrid version does NOT support --uefi option, disabling"
290 echo "isohybrid version supports --uefi option"
291 ISOHYBRID_OPTIONS=--uefi
294 echo "Creating dd-able ISO using isohybrid"
295 isohybrid $ISOHYBRID_OPTIONS "$ISOFILE"
302 rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
303 [[ $WRKDIR_EXISTED = 'false' ]] && rmdir "$WRKDIR"
304 echo "Generated $ISOFILE"
305 if [ -n "$URI" ] ; then
309 You requested to generate a small ISO image. Your generated
310 ISO image $ISOFILE does _not_ contain the squashfs files from
311 the source ISO images.
313 You have to provide the extracted squashfs files under $URI.
316 Squashfs files: ${OUTPUT_FILES[@]}
322 ## EOF #########################################################################
323 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=2