Beginning of a setup filesystem preparation script that can be used to run
[build.git] / emsetup.sh
1 #!/bin/bash
2 #
3 # Copyright (c) 2005  The Trustees of Princeton University (Trustees).
4 # All Rights Reserved.
5 #
6 # Original from Mark Huang to setup uml
7 # Adapted by Marc Fiucznski to support qemu
8 #
9 # umsetup is used to create a filesystem image, kernel, and related
10 # files needed to run either UML or qemu.  It is intended to be used
11 # either by individuals for their own testing purposes, or as a
12 # nightly script on an build/qa system for automated testing.
13 #
14 # $Id:$
15
16 STEPS="Mkfs Install InstallKernel InstallVRef Config"
17
18 usage ()
19 {
20     echo "usage: $0 [-s $STEPS] [-t uml|qemu] [-y yum.conf] [kernelbuilddir] [installroot] [package ...]"
21     exit 1
22 }    
23
24 # default filesystem setup for uml
25 TYPE="qemu"
26
27 # defaults
28 YUMCONF=
29 UTS_RELEASE=
30
31 # Must be root for some tasks
32 if [ $UID -ne 0 ] ; then
33     echo "Must be root to run $0"
34     exit 1
35 fi
36
37 # Get options
38 while getopts 's:i:t:y:h' OPT ; do
39     case "$OPT" in
40         s)
41             STEPS=$OPTARG
42             ;;
43
44         t)
45             case "$OPTARG" in
46                 uml)
47                         TYPE="uml"
48                         ;;
49                 qemu)
50                         TYPE="qemu"
51                         ;;
52                 *)
53                         echo "expecting 'uml' or 'qemu', got $OPTARG"
54                         usage
55                         ;;
56             esac
57             ;;
58
59           y)
60                 YUMCONF=$OPTARG
61                 if [ ! -f "$YUMCONF" ]; then
62                         echo "yum configuration file $YUMCONF not found"
63                         usage
64                 fi
65                 ;;      
66
67           h)
68                 usage
69                 ;;
70     esac
71 done
72
73 # Get arguments
74 shift $(($OPTIND - 1))
75 KERNEL=$1
76 shift
77 INSTALLROOT=$1
78 PACKAGE="$@"
79
80
81 # setup the UTS_RELEASE
82 if [ -d "$KERNEL" -a -f "$KERNEL/include/linux/version.h" ] ; then
83     eval UTS_RELEASE=$(echo "#include <linux/version.h>" | cpp -I "$KERNEL/include" -dM - | awk '/UTS_RELEASE/ { print $3 }')
84 else
85     echo "$KERNEL is not a valid linux kernel directory"
86     exit 0
87 fi
88
89 # set installation mount point
90 if [ -z "$INSTALLROOT" ] ; then
91     INSTALLROOT=$(mktemp -d "/tmp/mountpoint.XXXXXX")
92 fi
93 # Convert to absolute path
94 INSTALLROOT=$(cd $INSTALLROOT && pwd)
95
96 # set packages
97 if [ -z "$PACKAGE" ] ; then
98     PACKAGE=PlanetLab
99 fi
100
101 # Bail on any simple error
102 set -e
103
104 # Be verbose
105 set -x
106
107 Unmount ()
108 {
109     # Unmount / image
110     if grep -q $INSTALLROOT /etc/mtab ; then
111         umount $INSTALLROOT
112         rmdir $INSTALLROOT
113     fi
114 }
115
116 Mount ()
117 {
118     # Mount / image
119     if ! grep -q $INSTALLROOT /etc/mtab ; then
120         mkdir -p $INSTALLROOT
121         modprobe loop
122         mount -o loop fs.img $INSTALLROOT
123     fi
124 }
125
126 Mkfs ()
127 {
128     # Make / image
129     if [ ! -f fs.img ] ; then
130         dd bs=1M count=2048 < /dev/zero > fs.img
131     fi
132     /sbin/mkfs.ext2 -F -j fs.img
133 }
134
135 MakeDevs () 
136 {
137     FAKEROOT=$1
138     if [ ! -z "$FAKEROOT" -a "$FAKEROOT" != "/" ] ; then
139         rm -rf $FAKEROOT/dev
140         mkdir -p $FAKEROOT/dev
141         mknod -m 666 $FAKEROOT/dev/null c 1 3
142         mknod -m 666 $FAKEROOT/dev/zero c 1 5
143         mknod -m 666 $FAKEROOT/dev/full c 1 7
144         mknod -m 644 $FAKEROOT/dev/random c 1 8
145         mknod -m 644 $FAKEROOT/dev/urandom c 1 9
146         mknod -m 666 $FAKEROOT/dev/tty c 5 0
147         mknod -m 666 $FAKEROOT/dev/ptmx c 5 2
148         mkdir -p $FAKEROOT/dev/pts
149         # well, /proc really is not in /dev
150         mkdir -p $FAKEROOT/proc
151     fi
152 }
153
154 Install ()
155 {
156     Mount
157
158     # Bootstrap RPM
159     mkdir -p $INSTALLROOT/var/lib/rpm
160     mkdir -p $INSTALLROOT/etc/rpm
161
162     # Only install English language locale files
163     cat > $INSTALLROOT/etc/rpm/macros <<EOF
164 %_install_langs en_US:en
165 EOF
166
167     # Initialize RPM database
168     rpm --root $INSTALLROOT --initdb
169
170     # Write TYPE specific fstab 
171     if [ "$TYPE" = "uml" ] ; then
172         # Mount home directory inside UML
173         mkdir -p $INSTALLROOT/$HOME
174
175         cat > $INSTALLROOT/etc/fstab <<EOF
176 /dev/ubd/0      /               ext3    defaults 0 0
177 /dev/ubd/1      /vservers       ext3    defaults 0 0
178 EOF
179     else
180         cat > $INSTALLROOT/etc/fstab <<EOF
181 /dev/hda        /               ext3    defaults 0 0
182 EOF
183     fi
184
185     # Write rest of fstab
186     cat >> $INSTALLROOT/etc/fstab <<EOF
187 none            /proc           proc    defaults 0 0
188 none            /dev/shm        tmpfs   defaults 0 0
189 none            /dev/pts        devpts  defaults 0 0
190 none            /rcfs           rcfs    defaults 0 0
191 EOF
192
193     TMP=$(mktemp "/tmp/yum.conf.XXXXXX")
194     if [ -z "$YUMCONF" ] ; then
195         cp yum.conf $TMP
196     else
197         cp $YUMCONF $TMP
198     fi
199         
200     MakeDevs $INSTALLROOT
201     # create mount points for /dev/pts and /proc
202     mount -t devpts none $INSTALLROOT/dev/pts
203     mount -t proc none $INSTALLROOT/proc
204
205     # Install
206     yum -c $TMP -y --installroot $INSTALLROOT install glibc yum
207     yum -c $TMP -y --installroot $INSTALLROOT groupinstall $PACKAGE
208     rm -f $TMP
209
210     umount $INSTALLROOT/dev/pts
211     umount $INSTALLROOT/proc
212
213     Unmount
214 }
215
216 InstallKernel () 
217 {
218     Mount
219
220     mkdir -p $INSTALLROOT/boot
221
222     if [ -f $KERNEL/System.map ] ; then
223         cp $KERNEL/System.map $INSTALLROOT/boot/System.map-$UTS_RELEASE
224     fi
225     if [ -f $KERNEL/init/kerntypes.o ] ; then
226         cp $KERNEL/init/kerntypes.o $INSTALLROOT/boot/Kerntypes-$UTS_RELEASE
227     fi
228     make -C $KERNEL modules_install INSTALL_MOD_PATH=$INSTALLROOT DEPMOD=/bin/true
229
230     rm -f ./initrd-$UTS_RELEASE.img ./bzImage-$UTS_RELEASE $INSTALLROOT/boot/initrd-$UTS_RELEASE.img
231     /usr/sbin/chroot $INSTALLROOT /sbin/depmod -ae -F /boot/System.map-$UTS_RELEASE $UTS_RELEASE
232     /usr/sbin/chroot $INSTALLROOT mkinitrd /boot/initrd-$UTS_RELEASE.img $UTS_RELEASE
233     cp $INSTALLROOT/boot/initrd-$UTS_RELEASE.img .
234
235     rm -f ./bzImage-$UTS_RELEASE ./vmlinux-$UTS_RELEASE
236     ln $KERNEL/arch/i386/boot/bzImage ./bzImage-$UTS_RELEASE
237     ln $KERNEL/vmlinux ./vmlinux-$UTS_RELEASE
238
239     ln -fs ./bzImage-$UTS_RELEASE ./bzImage
240     ln -fs ./initrd-$UTS_RELEASE.img ./initrd
241     ln -fs ./vmlinux-$UTS_RELEASE ./vmlinux
242
243     Unmount
244 }
245
246 InstallVRef ()
247 {
248     Mount
249     
250     # Based on vserver-reference
251
252     VROOTDIR=$INSTALLROOT/vservers
253
254     # Make /vservers
255     mkdir -p $VROOTDIR
256     chmod 000 $VROOTDIR
257     chattr +t $VROOTDIR
258     
259     # Build image in /vservers/.vtmp
260     mkdir -p $VROOTDIR/.vtmp
261     VROOT=$(mktemp -d $VROOTDIR/.vtmp/vserver-reference.XXXXXX)
262
263     # Make /vservers/.vtmp/vserver-reference.XXXXXX
264     mkdir -p $VROOT
265     chattr -t $VROOT
266     chmod 755 $VROOT
267
268     echo $"Building VServer reference: "
269
270     MakeDevs $VROOT
271     # create fake drive
272     touch $VROOT/dev/hdv1
273
274     # create mount points for /dev/pts and /proc
275     mount -t devpts none $VROOT/dev/pts
276     mount -t proc none $VROOT/proc
277
278     # Create a dummy /etc/fstab in reference image
279     mkdir -p $VROOT/etc
280
281     cat > $VROOT/etc/fstab <<EOF
282 # This fake fstab exists only to please df and linuxconf.
283 /dev/hdv1       /       ext2    defaults        1 1
284 EOF
285
286     cp $VROOT/etc/fstab $VROOT/etc/mtab
287
288     # Prevent all locales from being installed in reference image
289     mkdir -p $VROOT/etc/rpm
290     cat > $VROOT/etc/rpm/macros <<EOF
291 %_install_langs en_US:en
292 %_excludedocs 1
293 %__file_context_path /dev/null
294 EOF
295
296     # Initialize RPM database in reference image
297     mkdir -p $VROOT/var/lib/rpm
298     rpm --root $VROOT --initdb
299
300     # Install RPMs in reference image
301     TMP=$(mktemp "/tmp/yum.conf.XXXXXX")
302     if [ -z "$YUMCONF" ] ; then
303         cp yum.conf $TMP
304     else
305         cp $YUMCONF $TMP
306     fi
307
308     SSLCERTDIR=
309     yum $SSLCERTDIR -c $TMP --installroot=$VROOT -y groupinstall VServer
310     rm -f $TMP
311
312     # Clean up /dev in reference image
313     umount $VROOT/dev/pts
314
315     # Disable all services in reference image
316     chroot $VROOT /bin/sh -c "chkconfig --list | awk '{ print \$1 }' | xargs -i chkconfig {} off"
317
318     # Copy configuration files from host to reference image
319     for file in /etc/hosts /etc/resolv.conf /etc/yum.conf ; do
320         if [ -f $file ] ; then
321             echo $file | cpio -p -d -u $VROOT
322         fi
323     done
324
325     # Clean up
326     umount $VROOT/proc
327
328     # Swap them when complete
329     mv $VROOT $VROOTDIR
330     if [ -d $VROOTDIR/vserver-reference ] ; then
331         mv $VROOTDIR/vserver-reference $VROOT
332         rm -rf $VROOT
333     fi
334     mv $VROOTDIR/$(basename $VROOT) $VROOTDIR/vserver-reference
335
336     # turn off vserver-reference in host image
337     chkconfig --del vserver-reference
338
339
340     Unmount
341 }
342
343
344 Config ()
345 {
346     Mount
347
348     # Set local time to UTC
349     ln -sf /usr/share/zoneinfo/UTC $INSTALLROOT/etc/localtime
350
351     # Write network configuration
352     cat > $INSTALLROOT/etc/hosts <<EOF
353 127.0.0.1       localhost
354 EOF
355     cp /etc/resolv.conf $INSTALLROOT/etc/
356
357     # Disable unneeded services
358     SERVICES="netfs rawdevices cpuspeed smartd"
359     # i686 only
360     SERVICES="$SERVICES microcode_ctl"
361     # syslogd and sendmail broken for some reason
362     SERVICES="$SERVICES syslog sendmail"
363     # Not now
364     SERVICES="$SERVICES pl_conf pl_nm pl_spd PlanetLabID PlanetLabConf"
365     for service in $SERVICES ; do
366         /usr/sbin/chroot $INSTALLROOT chkconfig $service off || :
367     done
368
369     Unmount
370 }
371
372 trap "Unmount ; exit 255"
373
374 for step in $STEPS ; do
375     eval $step
376 done