fixed install key
[tridge/autocluster.git] / autocluster
1 #!/bin/bash
2 # main autocluster script
3 #
4 # Copyright (C) Andrew Tridgell  2008
5 # Copyright (C) Martin Schwenke  2008
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #   
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #   
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, see <http://www.gnu.org/licenses/>.
19
20 if [ -f "$0" ]; then
21     installdir="`dirname \"$0\"`"
22 else
23     autocluster=`which $0`
24     installdir="`dirname \"$autocluster\"`"
25 fi
26
27 config="config"
28 set -e
29
30 ####################
31 # show program usage
32 usage ()
33 {
34     cat >&2 <<EOF
35 Usage: autocluster [OPTION] ... <COMMAND>
36   options:
37     -c <file>  specify config file (default is "config")
38     -x         enable script debugging
39
40   commands:
41      create base
42            create a base image
43
44      create cluster CLUSTERNAME
45            create a full cluster
46
47      create node CLUSTERNAME NODENUMBER
48            create one cluster node
49
50      create tsm CLUSTERNAME
51            create a TSM server node
52
53      mount DISK
54            mount a qemu disk on mnt/
55
56      unmount
57            unmount a qemu disk from mnt/
58
59      bootbase
60            boot the base image
61
62      testproxy
63            test your proxy setup
64 EOF
65     exit 1
66 }
67
68
69 ###############################
70 # create a single node
71 create_node() {
72     CLUSTER="$1"
73     NODENUMBER="$2"
74     NAME="$CLUSTER""n$NODENUMBER"
75     BASE="$VIRTBASE/$BASENAME.img"
76     DISK="$VIRTBASE/$CLUSTER/$NAME.qcow2"
77     NUMSHARED=3
78
79     # first node might need more memory for SoFS GUI
80     if [ $NODENUMBER = 1 -a $GUIMEM -gt $MEM ]; then
81         NODEMEM=$GUIMEM
82     else
83         NODEMEM=$MEM
84     fi
85     echo "Creating cluster node $NAME"
86
87     mkdir -p $VIRTBASE/$CLUSTER
88
89     echo "Creating the disk"
90     rm -f "$DISK"
91     qemu-img create -b "$BASE" -f qcow2 "$DISK"
92
93     IPNUM=`expr $FIRSTIP + $NODENUMBER`
94
95     mount_disk $DISK
96     setup_base
97     setup_network
98     unmount_disk
99
100     mkdir -p tmp
101
102     MAC1=`get_macaddr $CLUSTER $NODENUMBER 1`
103     MAC2=`get_macaddr $CLUSTER $NODENUMBER 2`
104     MAC3=`get_macaddr $CLUSTER $NODENUMBER 3`
105     UUID=`uuidgen`
106     
107     echo "Creating $NAME.xml"
108     substitute_vars $NODE_TEMPLATE tmp/$NAME.xml
109     
110     # install the XML file
111     $VIRSH undefine $NAME > /dev/null 2>&1 || true
112     $VIRSH define tmp/$NAME.xml
113 }
114
115
116 ###############################
117 # create a TSM node
118 create_tsm() {
119     CLUSTER="$1"
120     NAME="$CLUSTER""tsm"
121     BASE="$VIRTBASE/$BASENAME.img"
122     DISK="$VIRTBASE/$CLUSTER/$NAME.qcow2"
123     TSMDISK="$VIRTBASE/$CLUSTER/tsmstorage.qcow2"
124     
125     echo "Creating TSM cluster node $NAME"
126     
127     mkdir -p $VIRTBASE/$CLUSTER tmp
128     
129     echo "Creating the disk"
130     rm -f "$DISK"
131     qemu-img create -b "$BASE" -f qcow2 "$DISK"
132     
133     echo "Creating tsm disk"
134     qemu-img create -f qcow2 "$TSMDISK" $TSMDISKSIZE
135     
136     # TSM server is first IP in the cluster
137     IPNUM=$FIRSTIP
138
139     mount_disk $DISK
140     setup_base
141     setup_network
142     unmount_disk
143     
144     UUID=`uuidgen`
145     MAC1=`get_macaddr $CLUSTER 0 0`
146     
147     echo "Creating $NAME.xml"
148     substitute_vars $TSM_TEMPLATE tmp/$NAME.xml
149     
150     # install the XML file
151     $VIRSH undefine $NAME > /dev/null 2>&1 || true
152     $VIRSH define tmp/$NAME.xml
153 }
154
155
156 ###############################
157 # create a whole cluster
158 create_cluster() {
159     CLUSTER="$1"
160
161     mkdir -p $VIRTBASE/$CLUSTER tmp
162     mkdir -p $KVMLOG
163
164     echo "Creating 3 shared disks"
165     for i in `seq 1 3`; do
166         # setup a nice ID at the start of the disk
167         qemu-img create -f raw $VIRTBASE/$CLUSTER/shared$i $SHAREDDISKSIZE
168         echo "SOFS-`uuidgen`" > tmp/diskid
169         dd if=tmp/diskid of=$VIRTBASE/$CLUSTER/shared$i conv=notrunc bs=1 > /dev/null 2>&1
170     done
171
172     echo "Creating $NUMNODES base nodes"
173     for i in `seq 1 $NUMNODES`; do
174         create_node "$CLUSTER" $i
175     done
176
177     echo "Creating TSM server node"
178     create_tsm "$CLUSTER"
179
180     echo "# autocluster $CLUSTER" > hosts.$CLUSTER
181     echo "$IPBASE.0.$FIRSTIP ${CLUSTER}tsm.$LOWDOMAIN ${CLUSTER}tsm" >> hosts.$CLUSTER
182     for i in `seq 1 $NUMNODES`; do
183         echo "$IPBASE.0.`expr $FIRSTIP + $i` ${CLUSTER}n$i.$LOWDOMAIN ${CLUSTER}n$i" >> hosts.$CLUSTER
184     done
185     echo >> hosts.$CLUSTER
186
187     echo "Cluster $CLUSTER created"
188     echo "You may want to add this to your /etc/hosts file:"
189     cat hosts.$CLUSTER
190
191     echo
192 }
193
194 ###################
195 # create base image
196 create_base() {
197
198     NAME="$BASENAME"
199     DISK="$VIRTBASE/$NAME.img"
200
201     mkdir -p $KVMLOG
202
203     echo "Creating the disk"
204     qemu-img create -f $BASE_FORMAT "$DISK" $DISKSIZE
205
206     rm -rf tmp
207     mkdir -p mnt tmp tmp/ISO
208
209     setup_timezone
210     setup_repos
211
212     echo "Creating kickstart file from template"
213     substitute_vars "$KICKSTART" "tmp/ks.cfg"
214
215     if [ $INSTALLKEY = "--skip" ]; then
216         cat <<EOF
217 --------------------------------------------------------------------------------------
218 WARNING: You have not entered an install key. Some RHEL packages will not be installed.
219
220 Please enter a valid RHEL install key in your config file like this:
221
222   INSTALLKEY="1234-5678-0123-4567"
223
224 The install will continue without an install key in 5 seconds
225 --------------------------------------------------------------------------------------
226 EOF
227         sleep 5
228     fi
229     
230     echo "Creating kickstart floppy"
231     dd if=/dev/zero of=tmp/floppy.img bs=1024 count=1440
232     mkdosfs tmp/floppy.img
233     mount -o loop -t msdos tmp/floppy.img mnt
234     cp tmp/ks.cfg mnt
235     mount -o loop,ro $ISO tmp/ISO
236     
237     echo "Setting up bootloader"
238     cp tmp/ISO/isolinux/isolinux.bin tmp
239     cp tmp/ISO/isolinux/vmlinuz tmp
240     cp tmp/ISO/isolinux/initrd.img tmp
241     umount tmp/ISO
242     umount mnt
243
244     UUID=`uuidgen`
245
246     substitute_vars $INSTALL_TEMPLATE tmp/$NAME.xml
247
248     rm -f $KVMLOG/serial.$NAME
249
250     # boot the install CD
251     $VIRSH create tmp/$NAME.xml
252
253     echo "Waiting for install to start"
254     sleep 2
255     
256     # wait for the install to finish
257     cat <<EOF > tmp/wait.exp
258 spawn tail -f $KVMLOG/serial.$NAME
259 expect -timeout 3600 "you may safely reboot your system"
260 EOF
261
262     expect tmp/wait.exp
263     $VIRSH destroy $NAME
264     
265     if ! grep "you may safely reboot your system" $KVMLOG/serial.$NAME > /dev/null; then
266         echo "Failed to create base image $DISK"
267         exit 1
268     fi
269
270     ls -l $DISK
271     cat <<EOF
272
273 Install finished, base image $DISK created
274
275 You may wish to run
276    chattr +i $DISK
277 To ensure that this image does not change
278
279 EOF
280 }
281
282
283
284 ###############################
285 # boot the base disk
286 boot_base() {
287     CLUSTER="$1"
288
289     NAME="$BASENAME"
290     DISK="$VIRTBASE/$NAME.img"
291
292     rm -rf tmp
293     mkdir -p tmp
294
295     IPNUM=$FIRSTIP
296     CLUSTER="base"
297
298     mount_disk $DISK
299     setup_base
300     unmount_disk
301
302     UUID=`uuidgen`
303     
304     echo "Creating $NAME.xml"
305     substitute_vars $BOOT_TEMPLATE tmp/$NAME.xml
306     
307     # boot the base system
308     $VIRSH create tmp/$NAME.xml
309 }
310
311 ###############################
312 # test the proxy setup
313 test_proxy() {
314     export http_proxy=$WEBPROXY
315     wget -O /dev/null $INSTALL_SERVER
316     echo "Proxy OK"
317 }
318
319 ######################################################################
320
321
322 ############################
323 # parse command line options
324 temp=$(getopt -n "$prog" -o "c:xh" -l help -- "$@")
325
326 [ $? != 0 ] && usage
327
328 eval set -- "$temp"
329
330 while true ; do
331     case "$1" in
332         -c) config="$2" ; shift; shift ;;
333         -x) set -x; shift ;;
334         --) shift ; break ;;
335         -h|--help|*) usage ;; # Shouldn't happen, so this is reasonable.
336     esac
337 done
338
339 . "$installdir/config.default"
340 . "`dirname $config`/$config"
341 . "$installdir/functions"
342
343 LOWDOMAIN=`echo $DOMAIN | tr A-Z a-z`
344
345 # check for needed programs 
346 check_command nbd-client
347 check_command expect
348 check_command qemu-nbd
349
350 [ $# -lt 1 ] && usage
351
352 command="$1"
353 shift
354
355 case $command in
356     create)
357         type=$1
358         shift
359         case $type in
360             base)
361                 [ $# != 0 ] && usage
362                 create_base;
363                 ;;
364             cluster)
365                 [ $# != 1 ] && usage
366                 create_cluster "$1";
367                 ;;
368             node)
369                 [ $# != 2 ] && usage
370                 create_node "$1" "$2";
371                 ;;
372             tsm)
373                 [ $# != 1 ] && usage
374                 create_tsm "$1";
375                 ;;
376             *)
377                 usage;
378                 ;;
379         esac
380         ;;
381     mount)
382         [ $# != 1 ] && usage
383         mount_disk "$1"
384         ;;
385     unmount)
386         [ $# != 0 ] && usage
387         unmount_disk
388         ;;
389     bootbase)
390         boot_base;
391         ;;
392     testproxy)
393         test_proxy;
394         ;;
395     *)
396         usage;
397         ;;
398 esac
399
400