3 # Purpose: create a multiboot grml ISO using grml2usb
4 # Authors: Michael Prokop <mika@grml.org>
5 # Bug-Reports: see http://grml.org/bugs/
6 # License: This file is licensed under the GPL v2 or any later version.
7 ################################################################################
11 # make sure we have the sbin directories in our PATH to find grml2usb ootb
12 PATH="${PATH}:/sbin:/usr/local/sbin:/usr/sbin"
14 # adjust variables if necessary through environment {{{
15 # path to the grml2usb script you'd like to use
16 [ -n "$GRML2USB" ] || GRML2USB='grml2usb'
18 # support mkisofs as well as genisoimage
19 if which xorriso >/dev/null 2>&1 ; then
20 MKISOFS='xorriso -as mkisofs'
21 elif which mkisofs >/dev/null 2>&1; then
23 elif which genisoimage >/dev/null 2>&1; then
26 echo "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO." >&2
30 if ! which isohybrid >/dev/null 2>&1 ; then
31 echo "Error: isohybrid executable not found (install syslinux/isolinux/syslinux-utils?)." >&2
38 echo >&2 "Usage: $0 [OPTIONS] -o target.iso source1.iso [source2.iso ...]"
41 -b Boot Params Additional boot parameters passed to grml2usb
42 -c Directory Copy files from directory to generated ISO
43 -f Force overwrite of existing target.iso
44 -r BootParam Remove specified boot params.
45 Can be specified multiple times.
46 -p <grml2usb param> Add the specified parameter to the grml2usb
47 commandline. For a list of valid parameters have
48 a look at the grml2usb manpage.
49 Can be specified multiple times.
50 -s URI Generate a small ISO file which downloads the squashfs
51 file from the specified URI. Please note that due to
52 restrictions in the bootprocess only IPs are allowed.
53 Supported protocols are: http and ftp
54 -t Directory Directory that should be used for temporary files
55 during build, instead of using a temporary directory
59 $0 -s http://192.168.23.42:8000/grml/ -o small.iso grml64-small_2021.07.iso
61 Will generate a file small.iso which tries to download the squashfs file from
62 http://192.168.23.42:8000/grml/ - the squashfs file is placed in the same
63 output directory as the ISO file.
65 [ -n "$1" ] && exit $1 || exit 1
69 # command line handling {{{
70 [[ $# -gt 2 ]] || usage 1
77 typeset -a GRML2USB_OPTS
78 while getopts fb:c:o:r:p:s:t: name; do
80 o) ISOFILE="$OPTARG";;
81 b) GRML2USB_OPTS+=(--bootoptions="$OPTARG");;
82 c) DIR="$(readlink -f "$OPTARG")"; [ -n "$DIR" ] || { echo "Could not read $OPTARG - exiting" >&2 ; exit 1 ; } ;;
84 r) GRML2USB_OPTS+=(--remove-bootoption="$OPTARG");;
85 p) GRML2USB_OPTS+=("$OPTARG");;
87 t) WRKDIR="$(readlink -f "$OPTARG")";;
92 # test for specified URI
93 if [ -n "$URI" ] ; then
94 GRML2USB_OPTS+=(--bootoptions="fetch=$URI")
97 # make sure -o is specified
98 [ -n "$ISOFILE" ] || usage 1
100 # we don't to override any files by accident
101 if [ -e "$ISOFILE" -a ! -n "$FORCE" ]; then
102 echo "Error: target file $ISOFILE exists already." >&2
106 if [ ! -z "$DIR" -a ! -d "$DIR" ] ; then
107 echo "Error: specified parameter for -c is not a directory" >&2
112 # we need root permissions for executing grml2usb {{{
113 if [[ $(id -u) != 0 ]]; then
114 echo >&2 "Error: please run $0 as root."
119 # check for grml2usb {{{
120 if [ ! -x "$(which $GRML2USB)" ] && [ ! -x "$GRML2USB" ] ; then
121 echo "Error: Could not find grml2usb executable. Is /usr/sbin missing in PATH?" >&2
122 echo "Tip: run GRML2USB=/usr/sbin/grml2usb grml2iso ... as workaround" >&2
123 if [ -x "./$GRML2USB" ] ; then
124 echo >&2 "If you executed grml2iso from the grml2usb repository use"
125 echo >&2 "GRML2USB=./grml2usb $0 $*"
137 *) ISOFILE=$ORIG_DIR/$ISOFILE ;;
141 # ensure to properly set up working directory {{{
142 WRKDIR_EXISTED='false'
143 if [ -z "$WRKDIR" ] ; then
144 WRKDIR="$(mktemp -d)"
146 [ -d "$WRKDIR" ] && WRKDIR_EXISTED='true'
149 GRML2USB_OPTS+=(--tmpdir="$WRKDIR")
151 rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
152 mkdir -p "$WRKDIR/cddir"
155 # execute grml2usb with all ISOs you'd like to install {{{
156 # remove all parameters
157 shift $(($OPTIND - 1))
159 $GRML2USB "${GRML2USB_OPTS[@]}" "$@" "$WRKDIR/cddir"
162 # move syslinux to isolinux {{{
163 mv "$WRKDIR"/cddir/boot/syslinux "$WRKDIR"/cddir/boot/isolinux
164 echo "menu label ^Isolinux prompt" > "$WRKDIR"/cddir/boot/isolinux/promptname.cfg
165 echo "include hd.cfg" >> "$WRKDIR"/cddir/boot/isolinux/grmlmain.cfg
168 # change to $WRKDIR {{{
169 # make sure $WRKDIR is an absolute path, otherwise accessing files
170 # in it will fail later in the code path if user provided a
172 WRKDIR=$(realpath $WRKDIR)
177 # default, independent of UEFI support
178 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
183 echo "Using xorriso for ISO generation."
184 if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then
185 echo "Disabling (U)EFI boot support since xorriso version is not recent enough."
187 echo "xorriso with -eltorito-alt-boot support present"
190 if ! [ -r "${WRKDIR}/cddir/boot/efi.img" ] ; then
191 echo "Warning: File /boot/efi.img not found, not extending boot arguments for (U)EFI boot."
194 echo "/boot/efi.img found, extending boot arguments for (U)EFI boot."
195 if ! [ -r /usr/lib/ISOLINUX/isohdpfx.bin ] ; then
196 echo "Error: /usr/lib/ISOLINUX/isohdpfx.bin not available, required for xorriso/isohybrid though." >&2
197 echo "Hint: make sure isolinux is installed." >&2
200 BOOT_ARGS+=" -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
201 BOOT_ARGS+=" -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin -eltorito-alt-boot -e boot/efi.img -no-emul-boot -isohybrid-gpt-basdat -no-pad"
207 echo "Using $MKISOFS for ISO generation (lacking UEFI option), disabling (U)EFI boot support."
212 # adjust ISO for small output if necessary {{{
213 if [ -n "$URI" ] ; then
214 bootloader_files=$(find . -name "*.cfg" -type f)
215 bootloader_files+=" "
216 bootloader_files+=$(find . -name "*.lst" -type f)
217 output_dir=$(dirname "$ISOFILE")
218 for squashfs in $(find . -name *.squashfs) ; do
219 media_path="$(dirname "$squashfs")"
220 filename="$(basename "$squashfs")"
221 target="$output_dir/$filename"
222 if [ -f "$target" ] && [ ! -n "$FORCE" ] ; then
223 echo >&2 "Warning: $target already exists, and -force not specified, not overwriting"
226 OUTPUT_FILES+=("$target")
228 sed -i -e "s#^\(^.*$media_path.*\)\($URI\)\(.*$\)#\1$URI/$filename\3#g" $bootloader_files
234 # copy specified directory to cd {{{
235 if [ -n "$DIR" ] ; then
236 echo >&2 "Copying ${DIR} to generated ISO"
237 for param in GRML_NAME VERSION RELEASENAME DATE SHORT_NAME \
238 VERSION BOOTID RELEASE_INFO ; do
239 EXCLUDE_PARAM="$EXCLUDE_PARAM --exclude **%${param}%**"
241 rsync -a ${DIR}/ $EXCLUDE_PARAM .
244 # adjust files from overlay directory
245 for GRML_VERSION_FILE in $(find . -name grml-version) ; do
246 GRML_NAME=$(awk '{print $1}' "$GRML_VERSION_FILE")
247 VERSION=$(awk '{print $2}' "$GRML_VERSION_FILE")
248 RELEASENAME=$(sed 's/.*- \(.*\).*\[.*/\1/' "$GRML_VERSION_FILE")
249 DATE=$(sed 's/.*\[\(.*\)].*/\1/' "$GRML_VERSION_FILE")
250 SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
251 RELEASE_INFO="$GRML_NAME $VERSION - $RELEASENAME"
252 BOOTID=$(cat conf/bootid.txt)
254 for param in GRML_NAME VERSION RELEASENAME DATE SHORT_NAME \
255 RELEASE_INFO BOOTID ; do
256 value="$(eval echo '$'"$param")"
258 # copy parameterized files from the overlay directory
259 for file in $(find ${DIR} -name "*%$param%*") ; do
261 target_dir="$(dirname ${file})"
262 mkdir -p "$target_dir" || true
263 cp -r ${DIR}/${file} ./${target_dir}/"$(basename ${file/\%${param}\%/$value})"
266 # adjust config files
267 for file in ./boot/isolinux/*.cfg ./boot/isolinux/*.msg \
268 ./boot/grub/*.cfg ; do
269 sed -i "s/%$param%/$value/g" ${file} 2>/dev/null || true
275 # generate the CD/DVD ISO {{{
276 $MKISOFS -V 'grml-multiboot' -l -r -J $BOOT_ARGS \
283 rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
284 [[ $WRKDIR_EXISTED = 'false' ]] && rmdir "$WRKDIR"
285 echo "Generated $ISOFILE"
286 if [ -n "$URI" ] ; then
290 You requested to generate a small ISO image. Your generated
291 ISO image $ISOFILE does _not_ contain the squashfs files from
292 the source ISO images.
294 You have to provide the extracted squashfs files under $URI.
297 Squashfs files: ${OUTPUT_FILES[@]}
303 ## EOF #########################################################################
304 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=2