uses more neutral varnames - HOSTNAME likely to be set
[build.git] / vbuild-init-vserver.sh
1 #!/bin/bash
2 # -*-shell-*-
3
4 COMMAND=$(basename $0)
5 DIRNAME=$(dirname $0)
6
7 # lst parsing utilities
8 PATH=$(dirname $0):$PATH . build.common
9
10 DEFAULT_FCDISTRO=f7
11 DEFAULT_PLDISTRO=planetlab
12 DEFAULT_PERSONALITY=linux32
13
14 function failure () {
15     echo "$COMMAND : Bailing out"
16     exit 1
17 }
18
19 # overwrite vserver's internal yum config from what is in
20 # .distributions/<distrib>/yum/yum.conf and /yum.repos.d 
21
22 function configure_yum_in_vserver () {
23     set -x 
24     set -e 
25     trap failure ERR INT
26
27     vserver=$1; shift
28     fcdistro=$1; shift
29
30     cd /etc/vservers/.distributions/${fcdistro}
31     if [ -f yum/yum.conf ] ; then
32         echo "Initializing yum.conf in $vserver from $(pwd)/yum"
33         sed -e "s!@YUMETCDIR@!/etc!g;
34                 s!@YUMCACHEDIR@!/var/cache/yum!g;
35                 s!@YUMLOGDIR@!/var/log!g;
36                 s!@YUMLOCKDIR@!/var/lock!g;
37                " yum/yum.conf > /vservers/$vserver/etc/yum.conf
38
39         # post process the various @...@ variables from this yum.conf file.
40     else
41         echo "Using $fcdistro default for yum.conf"
42     fi
43
44     if [ -d yum.repos.d ] ; then
45         echo "Initializing yum.repos.d in $vserver from $(pwd)/yum.repos.d"
46         rm -rf /vservers/$vserver/etc/yum.repos.d
47         tar cf - yum.repos.d | tar -C /vservers/$vserver/etc -xvf -
48     else
49         echo "Cannot initialize yum.repos.d in $vserver"
50     fi
51
52     if [ -n "$MYPLC_MODE" ] ; then
53         if [ ! -d /vservers/$vserver/etc/yum.repos.d ] ; then
54             echo "WARNING : cannot create myplc repo"
55         else
56             # exclude kernel from fedora repos 
57             for i in /vservers/$vserver/etc/yum.repos.d/* ; do
58                 echo "exclude=kernel* ulogd iptables" >> $i
59             done
60             # the build repo is not signed at this stage
61             cat > /vservers/$vserver/etc/yum.repos.d/myplc.repo <<EOF
62 [myplc]
63 name= MyPLC
64 baseurl=$REPO_URL
65 enabled=1
66 gpgcheck=0
67 EOF
68         fi
69     fi
70     cd -
71 }    
72
73 function setup_vserver () {
74
75     set -x
76     set -e
77     trap failure ERR INT
78
79     vserver=$1; shift
80     fcdistro=$1; shift
81     personality=$1; shift
82
83     if [ -d /vservers/$vserver ] ; then
84         echo "$COMMAND : vserver $vserver seems to exist - bailing out"
85         exit 1
86     fi
87
88     # create it
89     options=""
90     [ -n "$V_IPADDR" ] && options="$options --interface $V_IPADDR"
91     [ -n "$V_HOSTNAME" ] && options="$options --hostname $V_HOSTNAME"
92     [ -n "$V_NET_DEV" ] && options="$options --netdev $V_NET_DEV"
93     $personality vserver $VERBOSE $vserver build $options -m yum -- -d $fcdistro
94
95     if [ ! -z "$personality" ] ; then
96         registered_personality=$(grep $personality /etc/vservers/$vserver/personality | wc -l)
97         if [ $registered_personality -eq 0 -a "$personality" != "linux64" ] ; then
98             echo $personality >> /etc/vservers/$vserver/personality
99         fi
100     fi
101
102     if [ -n "$VBUILD_MODE" ] ; then 
103     # set up appropriate vserver capabilities to mount, mknod and IPC_LOCK
104         BCAPFILE=/etc/vservers/$vserver/bcapabilities
105         touch $BCAPFILE
106         cap=$(grep ^CAP_SYS_ADMIN /etc/vservers/$vserver/bcapabilities | wc -l)
107         [ $cap -eq 0 ] && echo 'CAP_SYS_ADMIN' >> /etc/vservers/$vserver/bcapabilities
108         cap=$(grep ^CAP_MKNOD /etc/vservers/$vserver/bcapabilities | wc -l)
109         [ $cap -eq 0 ] && echo 'CAP_MKNOD' >> /etc/vservers/$vserver/bcapabilities
110         cap=$(grep ^CAP_IPC_LOCK /etc/vservers/$vserver/bcapabilities | wc -l)
111         [ $cap -eq 0 ] && echo 'CAP_IPC_LOCK' >> /etc/vservers/$vserver/bcapabilities
112     fi
113
114     $personality vyum $vserver -- -y install yum
115     $personality vserver $VERBOSE $vserver pkgmgmt internalize
116
117     # start the vserver so we can do the following operations
118     $personality vserver $VERBOSE $vserver start
119     $personality vserver $VERBOSE $vserver exec rm -f /var/lib/rpm/__db*
120     $personality vserver $VERBOSE $vserver exec rpm --rebuilddb
121
122     # minimal config in the vserver for yum to work
123     configure_yum_in_vserver $vserver $fcdistro 
124
125     # set up resolv.conf
126     cp /etc/resolv.conf /vservers/$vserver/etc/resolv.conf
127 }
128
129 function devel_tools () {
130
131     set -x 
132     set -e 
133     trap failure ERR INT
134
135     vserver=$1; shift
136     fcdistro=$1; shift
137     pldistro=$1; shift
138     personality=$1; shift
139
140     # check for .lst file based on pldistro
141     if [ -n "$VBUILD_MODE" ] ; then
142         lst=${pldistro}-devel.lst
143     else
144         lst=${pldistro}-shell.lst
145     fi
146     if [ -f $lst ] ; then
147         echo "$COMMAND: Using $lst"
148     elif [ -f $DIRNAME/$lst ] ; then
149         lst=$DIRNAME/$lst
150         echo "$COMMAND: Using $lst"
151     else
152         echo "$COMMAND : Cannot locate $lst - exiting"
153         usage
154     fi
155
156     # install individual packages, then groups
157     packages=$(pl_getPackages2 ${fcdistro} $lst)
158     groups=$(pl_getGroups2 ${fcdistro} $lst)
159
160     [ -n "$packages" ] && $personality vserver $vserver exec yum -y install $packages
161     [ -n "$groups" ] && $personality vserver $vserver exec yum -y groupinstall $groups
162     return 0
163 }
164
165 function post_install () {
166     if [ -n "$VBUILD_MODE" ] ; then
167         post_install_vbuild "$@" 
168     else
169         post_install_myplc "$@"
170     fi
171 }
172
173 function post_install_vbuild () {
174
175     set -x 
176     set -e 
177     trap failure ERR INT
178
179     vserver=$1; shift
180     personality=$1; shift
181
182 ### From myplc-devel-native.spec
183 # be careful to backslash $ in this, otherwise it's the root context that's going to do the evaluation
184     cat << EOF | $personality vserver $VERBOSE $vserver exec bash -x
185     # set up /dev/loop* in vserver
186     for i in \$(seq 0 255) ; do
187         mknod -m 640 /dev/loop\$i b 7 \$i
188     done
189     
190     # create symlink for /dev/fd
191     ln -fs /proc/self/fd /dev/fd
192
193     # modify /etc/rpm/macros to not use /sbin/new-kernel-pkg
194     sed -i 's,/sbin/new-kernel-pkg:,,' /etc/rpm/macros
195     if [ -h "/sbin/new-kernel-pkg" ] ; then
196         filename=\$(readlink -f /sbin/new-kernel-pkg)
197         if [ "\$filename" == "/sbin/true" ] ; then
198                 echo "WARNING: /sbin/new-kernel-pkg symlinked to /sbin/true"
199                 echo "\tmost likely /etc/rpm/macros has /sbin/new-kernel-pkg declared in _netsharedpath."
200                 echo "\tPlease remove /sbin/new-kernel-pkg from _netsharedpath and reintall mkinitrd."
201                 exit 1
202         fi
203     fi
204     
205     # customize root's prompt
206     cat << PROFILE > /root/.profile
207 export PS1="[$vserver] \\w # "
208 PROFILE
209
210     uid=2000
211     gid=2000
212     
213     # add a "build" user to the system
214     builduser=\$(grep "^build:" /etc/passwd | wc -l)
215     if [ \$builduser -eq 0 ] ; then
216         groupadd -o -g \$gid build;
217         useradd -o -c 'Automated Build' -u \$uid -g \$gid -n -M -s /bin/bash build;
218     fi
219
220 # Allow build user to build certain RPMs as root
221     if [ -f /etc/sudoers ] ; then
222         buildsudo=\$(grep "^build.*ALL=(ALL).*NOPASSWD:.*ALL"  /etc/sudoers | wc -l)
223         if [ \$buildsudo -eq 0 ] ; then
224             echo "build   ALL=(ALL)       NOPASSWD: ALL" >> /etc/sudoers
225         fi
226         sed -i 's,^Defaults.*requiretty,#Defaults requiretty,' /etc/sudoers
227     fi
228 #
229 EOF
230
231 }
232
233 function post_install_myplc  () {
234     set -x 
235     set -e 
236     trap failure ERR INT
237
238     vserver=$1; shift
239     personality=$1; shift
240
241 # be careful to backslash $ in this, otherwise it's the root context that's going to do the evaluation
242     cat << EOF | $personality vserver $VERBOSE $vserver exec bash -x
243
244     # customize root's prompt
245     cat << PROFILE > /root/.profile
246 export PS1="[$vserver] \\w # "
247 PROFILE
248
249 EOF
250 }
251
252 COMMAND_VBUILD="vbuild-init-vserver.sh"
253 COMMAND_MYPLC="myplc-init-vserver.sh"
254 function usage () {
255     set +x 
256     echo "Usage: $COMMAND_VBUILD [-v] vserver-name"
257     echo "Usage: $COMMAND_MYPLC [-v] vserver-name repo-url"
258     echo "Requirements: you need to have a vserver-compliant kernel,"
259     echo "  as well as the util-vserver RPM installed"
260     echo "Description:"
261     echo "  This command creates a fresh vserver instance, for building, or running, myplc"
262     echo "Supported options"
263     echo " -f fcdistro - for creating the root filesystem - defaults to $DEFAULT_FCDISTRO"
264     echo " -d pldistro - defaults to $DEFAULT_PLDISTRO"
265     echo " -p personality - defaults to $DEFAULT_PERSONALITY"
266     echo " -v : passes -v to calls to vserver"
267     echo "$COMMAND_MYPLC only:"
268     echo " -h hostname: passed as vserver build --hostname"
269     echo " -i ip-address: passed as vserver build --interface"
270     echo " -e dev: passed as vserver build --netdev"
271     exit 1
272 }
273
274 ### parse args and 
275 function main () {
276
277     set -e
278     trap failure ERR INT
279
280     case "$COMMAND" in
281         $COMMAND_VBUILD)
282             VBUILD_MODE=true ;;
283         $COMMAND_MYPLC)
284             MYPLC_MODE=true;;
285         *)
286             usage ;;
287     esac
288
289     VERBOSE=
290     while getopts "f:d:p:vu:h:i:e:" opt ; do
291         case $opt in
292             f) fcdistro=$OPTARG;;
293             d) pldistro=$OPTARG;;
294             p) personality=$OPTARG;;
295             i) [ -z "$MYPLC_MODE" ] && usage ; V_IPADDR=$OPTARG;;
296             h) [ -z "$MYPLC_MODE" ] && usage ; V_HOSTNAME=$OPTARG;;
297             e) [ -z "$MYPLC_MODE" ] && usage ; V_NET_DEV==$OPTARG;;
298             v) VERBOSE="-v" ;;
299             *) usage ;;
300         esac
301     done
302         
303     shift $(($OPTIND - 1))
304     [[ -z "$@" ]] && usage
305     vserver=$1 ; shift
306     if [ -n "$MYPLC_MODE" ] ; then
307         [[ -z "$@" ]] && usage
308         REPO_URL=$1 ; shift
309     fi
310     [[ -n "$@" ]] && usage
311
312     [ -z "$fcdistro" ] && fcdistro=$DEFAULT_FCDISTRO
313     [ -z "$pldistro" ] && pldistro=$DEFAULT_PLDISTRO
314     [ -z "$personality" ] && personality=$DEFAULT_PERSONALITY
315
316     setup_vserver $vserver $fcdistro $personality 
317     devel_tools $vserver $fcdistro $pldistro $personality
318     post_install $vserver $personality
319
320 }
321
322 main "$@"