Add debian/control headers Origin, Bugs
[grml2usb.git] / grml2iso
1 #!/usr/bin/env bash
2 # Filename:      grml2iso
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 ################################################################################
9
10 # define function getfilesize before "set -e" {{{
11   if stat --help >/dev/null 2>&1; then
12     getfilesize='stat -c %s'        # GNU stat
13   else
14     getfilesize='stat -f %z'        # BSD stat
15   fi
16 # }}}
17
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 "$WRKDIR" ]   || WRKDIR='/tmp/grml2iso.tmp'
23 # support mkisofs as well as genisoimage
24   if which mkisofs >/dev/null 2>&1; then
25     MKISOFS='mkisofs'
26   elif which genisoimage >/dev/null 2>&1; then
27     MKISOFS='genisoimage'
28   else
29     echo >&2 "Error: neither mkisofs nor genisoimage available - can not create ISO."
30     exit 1
31 fi
32 # }}}
33
34 # helper stuff {{{
35   set -e
36
37   usage() {
38     echo >&2 "Usage: $0 [OPTIONS] -o target.iso source1.iso [source2.iso ...]"
39     echo >&2 "
40 Options:
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                          Could be specfied 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
55      Examples:
56      $0 -s http://192.168.23.42:8000/grml/ -o small.iso grml64_2010.12.iso
57
58      Will generate a file small.iso which tries to download the squashfs file from
59      http://192.168.23.42:8000/grml/ - the squashfs file is placed in the same
60      output directory as the ISO file.
61 "
62     [ -n "$1" ] && exit $1 || exit 1
63   }
64 # }}}
65
66 # command line handling {{{
67   [[ $# -gt 2 ]] || usage 1
68
69   ISOFILE=''
70   DIR=''
71   ADD_OPTS=''
72   FORCE=''
73   URI=''
74   typeset -a GRML2USB_OPTS
75   while getopts fb:c:o:r:p:s: name; do
76     case $name in
77       o)   ISOFILE="$OPTARG";;
78       b)   GRML2USB_OPTS+=(--bootoptions="$OPTARG");;
79       c)   DIR="$OPTARG";;
80       f)   FORCE='true';;
81       r)   GRML2USB_OPTS+=(--remove-bootoption="$OPTARG");;
82       p)   GRML2USB_OPTS+=("$OPTARG");;
83       s)   URI="$OPTARG";;
84       ?)   usage 2;;
85     esac
86   done
87   # test for specified URI
88   if [ -n "$URI" ] ; then
89     GRML2USB_OPTS+=(--bootoptions="fetch=$URI")
90   fi
91
92 # make sure -o is specified
93   [ -n "$ISOFILE" ] || usage 1
94
95 # we don't to override any files by accident
96   if [ -e "$ISOFILE" -a ! -n "$FORCE" ]; then
97     echo "Error: target file $ISOFILE exists already." >&2
98     exit 1
99   fi
100
101   if [ ! -z "$DIR" -a ! -d "$DIR" ] ; then
102      echo "Error: specified parameter for -c is not a directory" >&2
103      exit 1
104   fi
105 # }}}
106
107 # we need root permissions for executing grml2usb {{{
108   if [[ $(id -u) != 0 ]]; then
109     echo >&2 "Error: please run $0 as root."
110     exit 1
111   fi
112 # }}}
113
114 # check for grml2usb {{{
115   if [ ! -x "$(which $GRML2USB)" ] || [ ! -x "$GRML2USB" ] ; then
116     echo >&2 "Error: Could not find grml2usb"
117     if [ -x "./$GRML2USB" ] ; then
118       echo >&2 "If you executed grml2iso from the grml2usb repository use"
119       echo >&2 "GRML2USB=./grml2usb $0 $*"
120     fi
121     exit 1
122   fi
123 # }}}
124
125 # variables {{{
126   ORIG_DIR="$(pwd)"
127   # note: grub-pc_1.96+20090603-1 seems to be b0rken
128   GRUB_VERSION="grub-pc_1.96+20080724-16"
129
130 # normalise path
131   case $ISOFILE in
132     /*) ;;
133     *) ISOFILE=$ORIG_DIR/$ISOFILE ;;
134   esac
135 # }}}
136
137 # create necessary stuff under WRKDIR {{{
138   [ -d "$WRKDIR" ] && WRKDIR_EXISTED='true' || WRKDIR_EXISTED='false'
139   rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
140   mkdir -p "$WRKDIR/cddir"
141 # }}}}
142
143 # execute grml2usb with all ISOs you'd like to install {{{
144   # remove all parameters
145   shift $(($OPTIND - 1))
146
147   $GRML2USB "${GRML2USB_OPTS[@]}" "$@" "$WRKDIR/cddir"
148 # }}}
149
150 # move syslinux to isolinux {{{
151   mv "$WRKDIR"/cddir/boot/syslinux "$WRKDIR"/cddir/boot/isolinux
152
153   cd "$WRKDIR/cddir"
154   echo "menu label ^Isolinux prompt" > boot/isolinux/promptname.cfg
155   echo "include hd.cfg" >> boot/isolinux/grmlmain.cfg
156 # }}}
157
158 # adjust ISO for small output if necessary {{{
159   if [ -n "$URI" ] ; then
160      bootloader_files=$(find . -name "*.cfg" -type f)
161      bootloader_files+=" "
162      bootloader_files+=$(find . -name "*.lst" -type f)
163      output_dir=$(dirname "$ISOFILE")
164      for squashfs in $(find . -name *.squashfs) ; do
165         media_path="$(dirname "$squashfs")"
166         filename="$(basename "$squashfs")"
167         target="$output_dir/$filename"
168         if [ -f "$target" ] && [ ! -n "$FORCE" ] ; then
169            echo >&2 "Warning: $target already exists, and -force not specified, not overwriting"
170         else
171            mv $squashfs $target
172            OUTPUT_FILES+=("$target")
173         fi
174         sed -i -e "s#^\(^.*$media_path.*\)\($URI\)\(.*$\)#\1$URI/$filename\3#g" $bootloader_files
175
176    done
177   fi
178 # }}}
179
180 # copy specified directory to cd {{{
181   if [ -n "$DIR" ] ; then
182      echo >&2 "Copying ${DIR} to generated ISO"
183      rsync -a ${DIR}/ .
184   fi
185
186 # }}}
187
188 # generate the CD/DVD ISO {{{
189   $MKISOFS -V 'grml-multiboot' -l -r -J -no-pad \
190     -no-emul-boot -boot-load-size 4 -boot-info-table \
191     -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat \
192     -o "$ISOFILE" .
193 # }}}
194
195 # pad the output ISO to multiples of 256 KiB for partition table support {{{
196   siz=$($getfilesize "$ISOFILE")
197   cyls=$(echo "$siz / 512 / 32 / 16 + 1" | bc)  # C=$cyls H=16 S=32
198   ofs=$(echo "$cyls * 16 * 32 * 512 - 1" | bc)  # padding offset (size - 1)
199   dd if=/dev/zero bs=1 count=1 seek=$ofs of="$ISOFILE" 2>/dev/null
200 # }}}
201
202 # cleanup {{{
203   cd "$ORIG_DIR"
204   sync
205   rm -rf "$WRKDIR/cddir" "$WRKDIR/grub_tmp"
206   [[ $WRKDIR_EXISTED = 'false' ]] && rmdir "$WRKDIR"
207   echo "Generated $ISOFILE"
208   if [ -n "$URI" ] ; then
209      echo "
210 Information:
211 ==============
212 You requested to generate a small ISO image. Your generated
213 ISO image $ISOFILE does _not_ contain the squashfs files from
214 the source ISO images.
215
216 You have to provide the extracted squashfs files under $URI.
217
218 ISO image: $ISOFILE
219 Squashfs files: ${OUTPUT_FILES[@]}
220 URI: $URI
221 "
222   fi
223 # }}}
224
225 ## EOF #########################################################################
226 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=3