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