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 ################################################################################
9 # make sure we have the sbin directories in our PATH to find grml2usb ootb
10 PATH="${PATH}:/sbin:/usr/local/sbin:/usr/sbin"
12 # adjust variables if necessary through environment {{{
13 # path to the grml2usb script you'd like to use
14 [ -n "$GRML2USB" ] || GRML2USB='grml2usb'
15 # work directory for creating the filesystem
16 [ -n "$TMPDIR" ] && WRKDIR="${TMPDIR}/grml2iso.tmp"
17 [ -n "$WRKDIR" ] || WRKDIR='/tmp/grml2iso.tmp'
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
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 Can be specified 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
56 -t Directory Directory that should be used for temporary files
57 during build. Defaults to /tmp/grml2iso.tmp if unset.
60 $0 -s http://192.168.23.42:8000/grml/ -o small.iso grml64-small_2018.12.iso
62 Will generate a file small.iso which tries to download the squashfs file from
63 http://192.168.23.42:8000/grml/ - the squashfs file is placed in the same
64 output directory as the ISO file.
66 [ -n "$1" ] && exit $1 || exit 1
70 # command line handling {{{
71 [[ $# -gt 2 ]] || usage 1
78 typeset -a GRML2USB_OPTS
79 while getopts fb:c:o:r:p:s:t: name; do
81 o) ISOFILE="$OPTARG";;
82 b) GRML2USB_OPTS+=(--bootoptions="$OPTARG");;
83 c) DIR="$(readlink -f "$OPTARG")"; [ -n "$DIR" ] || { echo "Could not read $OPTARG - exiting" >&2 ; exit 1 ; } ;;
85 r) GRML2USB_OPTS+=(--remove-bootoption="$OPTARG");;
86 p) GRML2USB_OPTS+=("$OPTARG");;
88 t) WRKDIR="$(readlink -f "$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 "Error: Could not find grml2usb executable. Is /usr/sbin missing in PATH?" >&2
127 echo "Tip: run GRML2USB=/usr/sbin/grml2usb grml2iso ... as workaround" >&2
128 if [ -x "./$GRML2USB" ] ; then
129 echo >&2 "If you executed grml2iso from the grml2usb repository use"
130 echo >&2 "GRML2USB=./grml2usb $0 $*"
142 *) ISOFILE=$ORIG_DIR/$ISOFILE ;;
146 # create necessary stuff under WRKDIR {{{
147 [ -d "$WRKDIR" ] && WRKDIR_EXISTED='true' || WRKDIR_EXISTED='false'
148 rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
149 mkdir -p "$WRKDIR/cddir"
152 # execute grml2usb with all ISOs you'd like to install {{{
153 # remove all parameters
154 shift $(($OPTIND - 1))
156 $GRML2USB "${GRML2USB_OPTS[@]}" "$@" "$WRKDIR/cddir"
159 # move syslinux to isolinux {{{
160 mv "$WRKDIR"/cddir/boot/syslinux "$WRKDIR"/cddir/boot/isolinux
161 echo "menu label ^Isolinux prompt" > "$WRKDIR"/cddir/boot/isolinux/promptname.cfg
162 echo "include hd.cfg" >> "$WRKDIR"/cddir/boot/isolinux/grmlmain.cfg
165 # change to $WRKDIR {{{
166 # make sure $WRKDIR is an absolute path, otherwise accessing files
167 # in it will fail later in the code path if user provided a
169 WRKDIR=$(realpath $WRKDIR)
174 # default, independent of UEFI support
175 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
180 echo "Using xorriso for ISO generation."
181 if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then
182 echo "Disabling (U)EFI boot support since xorriso version is not recent enough."
184 echo "xorriso with -eltorito-alt-boot support present"
187 if ! [ -r "${WRKDIR}/cddir/boot/efi.img" ] ; then
188 echo "Warning: File /boot/efi.img not found, not extending boot arguments for (U)EFI boot."
191 echo "/boot/efi.img found, extending boot arguments for (U)EFI boot."
192 if ! [ -r /usr/lib/ISOLINUX/isohdpfx.bin ] ; then
193 echo "Error: /usr/lib/ISOLINUX/isohdpfx.bin not available, required for xorriso/isohybrid though." >&2
194 echo "Hint: make sure isolinux is installed." >&2
197 BOOT_ARGS+=" -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
198 BOOT_ARGS+=" -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin -eltorito-alt-boot -e boot/efi.img -no-emul-boot -isohybrid-gpt-basdat -no-pad"
204 echo "Using $MKISOFS for ISO generation (lacking UEFI option), disabling (U)EFI boot support."
209 # adjust ISO for small output if necessary {{{
210 if [ -n "$URI" ] ; then
211 bootloader_files=$(find . -name "*.cfg" -type f)
212 bootloader_files+=" "
213 bootloader_files+=$(find . -name "*.lst" -type f)
214 output_dir=$(dirname "$ISOFILE")
215 for squashfs in $(find . -name *.squashfs) ; do
216 media_path="$(dirname "$squashfs")"
217 filename="$(basename "$squashfs")"
218 target="$output_dir/$filename"
219 if [ -f "$target" ] && [ ! -n "$FORCE" ] ; then
220 echo >&2 "Warning: $target already exists, and -force not specified, not overwriting"
223 OUTPUT_FILES+=("$target")
225 sed -i -e "s#^\(^.*$media_path.*\)\($URI\)\(.*$\)#\1$URI/$filename\3#g" $bootloader_files
231 # copy specified directory to cd {{{
232 if [ -n "$DIR" ] ; then
233 echo >&2 "Copying ${DIR} to generated ISO"
234 for param in GRML_NAME VERSION RELEASENAME DATE SHORT_NAME \
235 VERSION BOOTID RELEASE_INFO ; do
236 EXCLUDE_PARAM="$EXCLUDE_PARAM --exclude **%${param}%**"
238 rsync -a ${DIR}/ $EXCLUDE_PARAM .
241 # adjust files from overlay directory
242 for GRML_VERSION_FILE in $(find . -name grml-version) ; do
243 GRML_NAME=$(awk '{print $1}' "$GRML_VERSION_FILE")
244 VERSION=$(awk '{print $2}' "$GRML_VERSION_FILE")
245 RELEASENAME=$(sed 's/.*- \(.*\).*\[.*/\1/' "$GRML_VERSION_FILE")
246 DATE=$(sed 's/.*\[\(.*\)].*/\1/' "$GRML_VERSION_FILE")
247 SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
248 RELEASE_INFO="$GRML_NAME $VERSION - $RELEASENAME"
249 BOOTID=$(cat conf/bootid.txt)
251 for param in GRML_NAME VERSION RELEASENAME DATE SHORT_NAME \
252 RELEASE_INFO BOOTID ; do
253 value="$(eval echo '$'"$param")"
255 # copy parameterized files from the overlay directory
256 for file in $(find ${DIR} -name "*%$param%*") ; do
258 target_dir="$(dirname ${file})"
259 mkdir -p "$target_dir" || true
260 cp -r ${DIR}/${file} ./${target_dir}/"$(basename ${file/\%${param}\%/$value})"
263 # adjust config files
264 for file in ./boot/isolinux/*.cfg ./boot/isolinux/*.msg \
265 ./boot/grub/*.cfg ; do
266 sed -i "s/%$param%/$value/g" ${file} 2>/dev/null || true
272 # generate the CD/DVD ISO {{{
273 $MKISOFS -V 'grml-multiboot' -l -r -J $BOOT_ARGS \
280 rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
281 [[ $WRKDIR_EXISTED = 'false' ]] && rmdir "$WRKDIR"
282 echo "Generated $ISOFILE"
283 if [ -n "$URI" ] ; then
287 You requested to generate a small ISO image. Your generated
288 ISO image $ISOFILE does _not_ contain the squashfs files from
289 the source ISO images.
291 You have to provide the extracted squashfs files under $URI.
294 Squashfs files: ${OUTPUT_FILES[@]}
300 ## EOF #########################################################################
301 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=2