Don't force df line to end in $WORKDIR in sysresccd-custom.
[systemrescuecd.git] / portage-overlay / sys-apps / sysresccd-scripts / files / sysresccd-custom
1 #!/bin/bash
2 # Project page: http://www.sysresccd.org/
3 # (C) 2003-2008 Francois Dupoux
4 # This scipt is available under the GPL-2 license
5
6 ## HELP AND BASIC ARGUMENT PROCESSING
7 #####################################
8
9 PROG="${0}"
10 ISODIR="/livemnt/boot"
11 ROOTDIR="/livemnt/squashfs"
12 WORKDIR="/mnt/custom"
13 ISOLINUX="isolinux"
14 USB_ISOLINUX="syslinux"
15 MKSQUASHFS="mksquashfs"
16
17 usage()
18 {
19         cat <<EOF
20 sysresccd-custom: SystemRescueCd customization script for x86
21 Syntax:           ${PROG} [options] <command> ...
22
23 Please, read the manual for help about how to use this script.
24 http://www.sysresccd.org/Sysresccd-manual-en_How_to_personalize_SystemRescueCd
25 This script must be executed outside of the chroot environment.
26
27 Commands (execute in that order):
28  1) extract                    Extract files from the squashfs into your disk
29  2) squashfs                   Recreate the compressed loopback squashfs image
30  3) setkmap <keymap-code>      Force a keymap to be loaded without prompt
31  4) isogen <cd_volume_name>    Generate the final bootable ISO image
32
33  -h|--help                     Display this screen and exit
34  -u                            Use the USB "$USB_ISOLINUX" rather than the CD "$ISOLINUX"
35  -i ISODIR                     Set the mount directory for the stock SysRescCD iso ($ISODIR)
36  -r ROOTDIR                    Set the source directory for the stock SysRescCD root ($ROOTDIR)
37  -w WORKDIR                    Set the work directory for the custom CD (${WORKDIR})
38  -m MKSQUASHFS                 Set the squashfs compression program ($MKSQUASHFS)
39
40 Distributed under the GNU Public License version 2 - http://www.sysresccd.org
41 EOF
42 }
43
44 ## MISC FUNCTIONS: Many utilities functions
45 ###########################################
46
47 # show the error message ($1 = first line of the message)
48 help_readman()
49 {
50         echo "$1"
51         echo "Please, read the manual for more help about this script"
52         echo "Web: http://www.sysresccd.org"
53         exit 1
54 }
55
56 ## ERROR HANDLING
57 #####################################
58
59 die()
60 {
61         if [ -n "$1" ]
62         then
63                 echo "${PROG}: error: $1"
64         else
65                 echo "${PROG}: aborting."
66         fi
67         exit 1
68 }
69
70 ## MISC FUNCTIONS: Many utilities functions
71 ###########################################
72
73 # $1 == MB required by the function
74 check_freespace()
75 {
76         SIZE=`(df -m -P ${WORKDIR}) | tail -n 1 | awk '{print $4}'`
77         if [ -z "$SIZE" ]
78         then
79                 help_readman "Could not determine amount of room in ${WORKDIR}"
80         fi
81         if [ "$SIZE" -gt $1 ]
82         then
83                 echo "there is enough estimated free space here ($SIZE MB) -> ok"
84         else
85                 echo "${PROG}: not enough room in ${WORKDIR}"
86                 help_readman "You only have $SIZE MB free, and the script needs at least $1 MB free"
87         fi
88 }
89
90 ## MAIN FUNCTIONS: Check if squashfs extraction is possible
91 ########################################################
92 do_extract_check()
93 {
94         # check for free space
95         check_freespace 900
96 }
97
98 ## MAIN FUNCTIONS: Extract the squashfs to the hard disk
99 ########################################################
100 do_extract()
101 {
102         # ---- check the original contents
103         for curfile in ${ISODIR}/sysrcd.dat ${ISODIR}/sysrcd.md5 ${ISODIR}/${ISOLINUX}/rescuecd
104         do
105                 if [ ! -f "${curfile}" ]
106                 then
107                         die "File ${curfile} was not found. All the original sysresccd files must be available in ${ISODIR}"
108                 fi
109         done
110         
111         # ---- copy the original contents
112         mkdir -p ${WORKDIR}/customcd/isoroot/
113         rm -rf ${WORKDIR}/customcd/isoroot/*
114         
115         # ---- copy critical files and directories
116         for curfile in version $ISOLINUX
117         do
118                 cp -a ${ISODIR}/${curfile} ${WORKDIR}/customcd/isoroot/ || die "copy: cannot copy ${curfile} to ${WORKDIR}/customcd/isoroot/"
119         done
120         
121         # ---- copy optional files and directories
122         for curfile in bootprog bootdisk ntpasswd
123         do
124                 if ! cp -a ${ISODIR}/${curfile} ${WORKDIR}/customcd/isoroot/ 2>/dev/null
125                 then
126                         echo "cannot copy ${curfile} to ${WORKDIR}/customcd/isoroot/ (non critical error)"
127                         rm -rf ${WORKDIR}/customcd/isoroot/${curfile}
128                         break
129                 fi
130         done
131         
132         # ---- extract files (/livemnt/squashfs is the mount point of sysrcd.dat)
133         mkdir -p ${WORKDIR}/customcd/files/
134         rm -rf ${WORKDIR}/customcd/files/*
135         cp -a ${ROOTDIR}/* ${WORKDIR}/customcd/files/ || die "cannot copy the files from the squashfs filesystem."
136 }
137
138 ## MAIN FUNCTIONS: Create the new squashfs
139 ########################################################
140 do_squashfs()
141 {
142         # check for free space
143         check_freespace 350
144
145         # prepare the directories
146         mkdir -p ${WORKDIR}/customcd/
147         mkdir -p ${WORKDIR}/customcd/files/
148         mkdir -p ${WORKDIR}/customcd/isoroot/
149         touch "${WORKDIR}/customcd/files/customized"
150         
151         # check that the files have been extracted
152         if [ "$(ls -A ${WORKDIR}/customcd/files/ 2>/dev/null | wc -l)" -eq 0 ]
153         then
154                 die "squashfs: ${WORKDIR}/customcd/files/ is empty, your must extract the files first."
155         fi
156
157         # check that there are no remaining filesystems mounted
158         for curfs in proc
159         do
160                 curpath="${WORKDIR}/customcd/files/${curfs}"
161                 dircnt="$(ls -A ${curpath} 2>/dev/null | wc -l)"
162                 if [ "${dircnt}" -gt 0 ]
163                 then
164                         die "squashfs: the directory ${curpath} must be empty"
165                 fi
166         done
167
168         rm -f ${WORKDIR}/customcd/isoroot/sysrcd.dat
169         cmd="${MKSQUASHFS} ${WORKDIR}/customcd/files/ ${WORKDIR}/customcd/isoroot/sysrcd.dat"
170         echo "${cmd}"
171         ${cmd} || die
172         (cd ${WORKDIR}/customcd/isoroot/ ; md5sum sysrcd.dat > sysrcd.md5)
173
174         # Change permissions to allow the file to be sent by thttpd for PXE-boot
175         chmod 644 ${WORKDIR}/customcd/isoroot/sysrcd.{dat,md5}
176 }
177
178 ## MAIN FUNCTIONS: Force a keymap to be loaded without prompt
179 ########################################################
180 do_setkmap()
181 {
182         KEYMAP="${1}"
183
184         if [ -z "${KEYMAP}" ]
185         then
186                 die "do_setkmap: you must specify the keymap you want to use (eg: \"${PROG} setkmap uk\")"
187         fi
188
189         if [ ! -d "${WORKDIR}/customcd/isoroot/${ISOLINUX}" ]
190         then
191                 die "do_setkmap: you have to run command copy before setkmap"
192         fi
193
194         echo "Keymap to be loaded: ${KEYMAP}"
195
196         # Set keymap in ${ISOLINUX}.cfg
197         cp ${WORKDIR}/customcd/isoroot/${ISOLINUX}/${ISOLINUX}.cfg ${WORKDIR}/customcd/isoroot/${ISOLINUX}/${ISOLINUX}.bak
198         sed -i -r -e "s:setkmap=[a-z0-9]+ ::g ; s:append:append setkmap=${KEYMAP}:g" ${WORKDIR}/customcd/isoroot/${ISOLINUX}/${ISOLINUX}.cfg
199 }
200
201 ## MAIN FUNCTIONS: Create the new ISO image
202 ########################################################
203 do_isogen()
204 {
205         ISO_VOLUME="${1}"
206         curtime="$(date +%Y%m%d-%H%M)"
207
208         # check for free space
209         check_freespace 400
210
211         if [ -z "${ISO_VOLUME}" ]
212         then
213                 die "do_isogen: you must specify the name of the volume you want to use for the iso image."
214         fi
215
216         mkdir -p ${WORKDIR}/customcd/isofile/
217         rm -rf ${WORKDIR}/customcd/isofile/*.iso
218
219         if [ ! -d "${WORKDIR}/customcd/isoroot/${ISOLINUX}" ]
220         then
221                 die "do_isogen: you must create a squashfs filesystem before you run isogen"
222         fi
223
224         touch "${WORKDIR}/customcd/isoroot/customized"
225
226         echo "Volume name of the CDRom: ${ISO_VOLUME}"
227
228         cmd="mkisofs -J -l -o ${WORKDIR}/customcd/isofile/sysresccd-${curtime}.iso \
229                 -b ${ISOLINUX}/isolinux.bin -c ${ISOLINUX}/boot.cat -input-charset utf-8 \
230                 -no-emul-boot -boot-load-size 4 -boot-info-table \
231                 -V \"${ISO_VOLUME}\" ${WORKDIR}/customcd/isoroot"
232         ${cmd}
233         res="$?"
234         echo "${cmd} --> $res"
235         if [ "${res}" != '0' ]
236         then
237                 die "mkisofs failed"
238         fi
239
240         md5sum ${WORKDIR}/customcd/isofile/sysresccd-${curtime}.iso > ${WORKDIR}/customcd/isofile/sysresccd-${curtime}.md5
241
242         echo "Final ISO image: ${WORKDIR}/customcd/isofile/sysresccd-${curtime}.iso"
243 }
244
245 ## MAIN SHELL FUNCTION
246 ########################################################
247
248 if [ $# -eq 0 ]    # Script invoked with no command-line args?
249 then
250         usage
251         exit 1
252 fi
253
254 while getopts ":ui:r:w:m:" Option
255 do
256         case $Option in
257                 u ) ISOLINUX="$USB_ISOLINUX";;
258                 i ) ISODIR="$OPTARG";;
259                 r ) ROOTDIR="$OPTARG";;
260                 w ) WORKDIR="$OPTARG";;
261                 * ) usage; exit 1;;  # Default, handles -h
262         esac
263 done
264 shift $(($OPTIND - 1))
265
266 COMMAND="${1}"
267 shift
268
269 if [ "$(whoami)" != "root" ]
270 then
271         help_readman "${PROG}: This script requires root privileges to operate."
272 fi
273
274 if [ ! -d "${WORKDIR}" ]
275 then
276         help_readman "${PROG}: You need to mount a partition with free space on ${WORKDIR}"
277 fi
278
279 case "${COMMAND}" in
280         extract)
281                 do_extract_check "$@"
282                 do_extract
283                 ;;
284         extract-nosizecheck)
285                 do_extract "$@"
286                 ;;
287         squashfs)
288                 do_squashfs "$@"
289                 ;;
290         setkmap)
291                 do_setkmap "$@"
292                 ;;
293         isogen)
294                 do_isogen "$@"
295                 ;;
296         *)  # Default, handles --help
297                 usage 
298                 exit 1
299                 ;;
300 esac
301 exit 0