c165075c1f1a99e574838fdecfc59b69656325d7
[bootcd.git] / build.sh
1 #!/bin/bash
2
3 set -e
4
5 # where the boot cd build config files are stored (and certificats/keys)
6 CONFIGURATIONS_DIR=configurations/
7
8 # where built files are stored
9 BUILD_DIR=build/
10
11 BOOTCD_VERSION="3.0-beta0.4"
12 FULL_VERSION_STRING="PlanetLab BootCD"
13 OUTPUT_IMAGE_NAME='PlanetLab-BootCD'
14     
15 SYSLINUX_SRC=sources/syslinux-2.11.tar.bz2
16
17 BOOTCD_YUM_GROUP=BootCD
18
19 CDRECORD_FLAGS="-v -dao"
20
21 CONF_FILES_DIR=conf_files/
22
23 # size of the ram disk in MB
24 RAMDISK_SIZE=64
25
26 # the bytes per inode ratio (the -i value in mkfs.ext2) for the ramdisk
27 INITRD_BYTES_PER_INODE=1024
28
29
30 function usage()
31 {
32     echo "Usage: build.sh <action> [<configuration>]"
33     echo "Action: build burn clean"
34     echo
35     echo "If configuration is missing, 'default' is loaded"
36     exit
37 }
38
39
40 function build_cdroot()
41 {
42     if [ -f $CD_ROOT/.built ]; then
43         echo "cd root already built, skipping"
44         return
45     fi
46
47     clean
48     
49     mkdir -p $CD_ROOT/dev/pts
50     mkdir -p $CD_ROOT/proc
51     mkdir -p $CD_ROOT/etc
52
53     echo "copy fstab and mtab"
54     cp -f $CONF_FILES_DIR/fstab $CD_ROOT/etc/
55     cp -f $CONF_FILES_DIR/mtab $CD_ROOT/etc/
56
57     echo "setup rpm to install only en_US locale and no docs"
58     mkdir -p $CD_ROOT/etc/rpm
59     cp -f $CONF_FILES_DIR/macros $CD_ROOT/etc/rpm
60
61     echo "initialize rpm db"
62     mkdir -p $CD_ROOT/var/lib/rpm
63     rpm --root $CD_ROOT --initdb
64
65     echo "install boot cd base rpms"
66     yum -c yum.conf --installroot=$CD_ROOT -y groupinstall $BOOTCD_YUM_GROUP
67
68     echo "checking to make sure rpms were installed"
69     packages=`cat yumgroups.xml | grep packagereq | sed 's#<[^<]*>##g'`
70     set +e
71     for package in $packages; do
72         echo "checking for package $package"
73         chroot $CD_ROOT /bin/rpm -qi $package > /dev/null
74         if [[ "$?" -ne 0 ]]; then
75             echo "package $package was not installed in the cd root."
76             echo "make sure it exists in the yum repository."
77             exit 1
78         fi
79     done
80     set -e
81     
82     echo "removing unneccessary build files"
83     (cd $CD_ROOT/lib/modules && \
84         find ./ -type d -name build -maxdepth 2 -exec rm -rf {} \;)
85
86     echo "setting up non-ssh authentication"
87     mkdir -p $CD_ROOT/etc/samba
88     chroot $CD_ROOT /usr/sbin/authconfig --nostart --kickstart \
89         --enablemd5 --enableshadow
90
91     echo "setting root password"
92     sed -i "s#root::#root:$ROOT_PASSWORD:#g" $CD_ROOT/etc/shadow
93
94     echo "relocate some large directories out of the root system"
95     # get /var/lib/rpm out, its 12mb. create in its place a 
96     # symbolic link to /usr/relocated/var/lib/rpm
97     mkdir -p $CD_ROOT/usr/relocated/var/lib/
98     mv $CD_ROOT/var/lib/rpm $CD_ROOT/usr/relocated/var/lib/
99     (cd $CD_ROOT/var/lib && ln -s ../../usr/relocated/var/lib/rpm rpm)
100
101     # get /lib/tls out
102     mkdir -p $CD_ROOT/usr/relocated/lib
103     mv $CD_ROOT/lib/tls $CD_ROOT/usr/relocated/lib/
104     (cd $CD_ROOT/lib && ln -s ../usr/relocated/lib/tls tls)
105
106     echo "extracting syslinux, copying isolinux files to cd"
107     mkdir -p $CD_ROOT/usr/isolinux/
108     mkdir -p $BUILD_DIR/syslinux
109     tar -C $BUILD_DIR/syslinux -xjvf $SYSLINUX_SRC
110     find $BUILD_DIR/syslinux -name isolinux.bin \
111         -exec cp -f {} $CD_ROOT/usr/isolinux/ \;
112
113     echo "moving kernel to isolinux directory"
114     KERNEL=$CD_ROOT/boot/vmlinuz-*
115     mv -f $KERNEL $CD_ROOT/usr/isolinux/kernel
116
117     echo "creating version files"
118     echo "$FULL_VERSION_STRING" > $CD_ROOT/usr/isolinux/pl_version
119     echo "$FULL_VERSION_STRING" > $CD_ROOT/pl_version
120
121     touch $CD_ROOT/.built
122 }
123
124 function build_initrd()
125 {
126     echo "building initrd"
127     rm -f $INITRD
128     rm -f $INITRD.gz
129
130     echo "copy fstab and mtab"
131     cp -f $CONF_FILES_DIR/fstab $CD_ROOT/etc/
132     cp -f $CONF_FILES_DIR/mtab $CD_ROOT/etc/
133
134     echo "installing generic modprobe.conf"
135     cp -f $CONF_FILES_DIR/modprobe.conf $CD_ROOT/etc/
136
137     echo "installing our own inittab and init scripts"
138     cp -f $CONF_FILES_DIR/inittab $CD_ROOT/etc
139     init_scripts="pl_sysinit pl_hwinit pl_netinit pl_validateconf pl_boot"
140     for script in $init_scripts; do
141         cp -f $CONF_FILES_DIR/$script $CD_ROOT/etc/init.d/
142         chmod +x $CD_ROOT/etc/init.d/$script
143     done
144
145     echo "setup basic networking files"
146     cp -f $CONF_FILES_DIR/hosts $CD_ROOT/etc/
147
148     echo "copying sysctl.conf (fix tcp window scaling and broken routers)"
149     cp -f $CONF_FILES_DIR/sysctl.conf $CD_ROOT/etc/
150
151     echo "setup default network conf file"
152     mkdir -p $CD_ROOT/usr/boot
153     cp -f $CONF_FILES_DIR/default-net.cnf $CD_ROOT/usr/boot/
154
155     echo "setup boot server configuration"
156     cp -f $CURRENT_CONFIG_DIR/$PRIMARY_SERVER_CERT $CD_ROOT/usr/boot/cacert.pem
157     cp -f $CURRENT_CONFIG_DIR/$PRIMARY_SERVER_GPG $CD_ROOT/usr/boot/pubring.gpg
158     echo "$PRIMARY_SERVER" > $CD_ROOT/usr/boot/boot_server
159     echo "$PRIMARY_SERVER_PORT" > $CD_ROOT/usr/boot/boot_server_port
160     echo "$PRIMARY_SERVER_PATH" > $CD_ROOT/usr/boot/boot_server_path
161
162     echo "setup backup boot server configuration"
163     mkdir -p $CD_ROOT/usr/boot/backup
164     cp -f $CURRENT_CONFIG_DIR/$BACKUP_SERVER_CERT \
165         $CD_ROOT/usr/boot/backup/cacert.pem
166     cp -f $CURRENT_CONFIG_DIR/$BACKUP_SERVER_GPG \
167         $CD_ROOT/usr/boot/backup/pubring.gpg
168     echo "$BACKUP_SERVER" > $CD_ROOT/usr/boot/backup/boot_server
169     echo "$BACKUP_SERVER_PORT" > $CD_ROOT/usr/boot/backup/boot_server_port
170     echo "$BACKUP_SERVER_PATH" > $CD_ROOT/usr/boot/backup/boot_server_path
171
172     echo "copying old boot cd directory bootme (TEMPORARY)"
173     cp -r bootme_old $CD_ROOT/usr/bootme
174     echo "$FULL_VERSION_STRING" > $CD_ROOT/usr/bootme/ID
175     echo "$PRIMARY_SERVER" > $CD_ROOT/usr/bootme/BOOTSERVER
176     echo "$PRIMARY_SERVER" > $CD_ROOT/usr/bootme/BOOTSERVER_IP
177     echo "$PRIMARY_SERVER_PORT" > $CD_ROOT/usr/bootme/BOOTPORT
178
179     echo "forcing lvm to make lvm1 partitions (TEMPORARY)"
180     cp -f $CONF_FILES_DIR/lvm.conf $CD_ROOT/etc/lvm/
181
182     echo "copying isolinux configuration files"
183     cp -f $CONF_FILES_DIR/isolinux.cfg $CD_ROOT/usr/isolinux/
184     echo "$FULL_VERSION_STRING" > $CD_ROOT/usr/isolinux/message.txt
185
186     echo "writing /etc/issue"
187     echo "$FULL_VERSION_STRING" > $CD_ROOT/etc/issue
188     echo "Kernel \r on an \m" >> $CD_ROOT/etc/issue
189     echo "" >> $CD_ROOT/etc/issue
190     echo "" >> $CD_ROOT/etc/issue
191
192     if [[ ! -z "$NODE_CONFIGURATION_FILE" ]]; then
193         echo "Copying node configuration file to cd"
194         cp -f $CURRENT_CONFIG_DIR/$NODE_CONFIGURATION_FILE \
195             $CD_ROOT/usr/boot/plnode.txt
196     fi
197
198     echo "making the isolinux initrd kernel command line match rd size"
199     let INITRD_SIZE_KB=$(($RAMDISK_SIZE * 1024))
200     sed -i "s#ramdisk_size=0#ramdisk_size=$INITRD_SIZE_KB#g" \
201         $CD_ROOT/usr/isolinux/isolinux.cfg
202
203     echo "building pcitable for hardware detection"
204     pci_map_file=`find $CD_ROOT/lib/modules/ -name modules.pcimap | head -1`
205     module_dep_file=`find $CD_ROOT/lib/modules/ -name modules.dep | head -1`
206     pci_table=$CD_ROOT/usr/share/hwdata/pcitable
207     ./scripts/rewrite-pcitable.py $module_dep_file $pci_map_file $pci_table \
208         $CD_ROOT/etc/pl_pcitable
209
210     dd if=/dev/zero of=$INITRD bs=1M count=$RAMDISK_SIZE
211     mkfs.ext2 -F -m 0 -i $INITRD_BYTES_PER_INODE $INITRD
212     mkdir -p $INITRD_MOUNT
213     mount -o loop,rw $INITRD $INITRD_MOUNT
214
215     echo "copy all files except usr to ramdisk"
216     pushd .
217     cd $CD_ROOT
218     find . -path ./usr -prune -o -print | cpio -p -d -u $INITRD_MOUNT
219     popd
220
221     umount $INITRD_MOUNT
222     rmdir $INITRD_MOUNT
223     
224     echo "compressing ramdisk"
225     gzip $INITRD
226 }
227
228 function build()
229 {
230     # build base image via yum
231     build_cdroot
232
233     # always build/rebuild initrd
234     build_initrd
235
236     rm -f $ISO
237     mkisofs -o $ISO -R -allow-leading-dots -J -r -b isolinux/isolinux.bin \
238         -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table \
239         $CD_ROOT/usr
240 }
241
242 function burn()
243 {
244     cdrecord $CDRECORD_FLAGS -data $ISO
245 }
246
247 function clean()
248 {
249     rm -rf $CD_ROOT
250     rm -rf $BUILD_DIR/syslinux
251     rm -rf $BUILD_DIR/$INITRD_MOUNT
252     rm -rf $BUILD_DIR
253     rm -f $ISO
254     rmdir --ignore-fail-on-non-empty build
255 }
256
257 if [[ "$1" == "clean" || "$1" == "burn" || "$1" == "build" ]]; then
258     action=$1
259     configuration=$2
260
261     if [[ -z "$configuration" ]]; then
262         configuration=default
263     fi
264
265     echo "Loading configuration $configuration"
266     CURRENT_CONFIG_DIR=$CONFIGURATIONS_DIR/$configuration
267     . $CURRENT_CONFIG_DIR/configuration
268
269     # setup vars for this configuration
270
271     # version string for this build
272     if [[ ! -z "$EXTRA_VERSION" ]]; then
273         FULL_VERSION_STRING="$FULL_VERSION_STRING $EXTRA_VERSION"
274     fi
275     FULL_VERSION_STRING="$FULL_VERSION_STRING $BOOTCD_VERSION"
276
277     # destination image
278     if [[ ! -z "$EXTRA_VERSION" ]]; then
279         OUTPUT_IMAGE_NAME="$OUTPUT_IMAGE_NAME-$EXTRA_VERSION"
280     fi
281     OUTPUT_IMAGE_NAME="$OUTPUT_IMAGE_NAME-$BOOTCD_VERSION"
282
283     # setup build directories
284     BUILD_DIR=build/$configuration
285     mkdir -p $BUILD_DIR
286     ISO=$BUILD_DIR/`echo $OUTPUT_IMAGE_NAME | sed -e "s/%version/$BOOTCD_VERSION/"`.iso
287
288     CD_ROOT=`pwd`/$BUILD_DIR/cdroot
289     mkdir -p $CD_ROOT
290
291     # location of the uncompressed ramdisk image
292     INITRD=$CD_ROOT/usr/isolinux/initrd
293
294     # temporary mount point for rd
295     INITRD_MOUNT=`pwd`/$BUILD_DIR/rd
296
297
298     case $action in 
299         build )
300             echo "Proceeding with building $DESCRIPTION"
301             build;;
302
303         clean )
304             echo "Removing built files for $DESCRIPTION"
305             clean;;
306
307         burn )
308             echo "Burning $DESCRIPTION"
309             burn;;
310     esac    
311 else
312     usage
313 fi
314