2 # main autocluster script
4 # Copyright (C) Andrew Tridgell 2008
5 # Copyright (C) Martin Schwenke 2008
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.
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.
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/>.
21 installdir="`dirname \"$0\"`"
23 autocluster=`which $0`
24 installdir="`dirname \"$autocluster\"`"
32 Usage: autocluster [OPTION] ... <COMMAND>
34 -c <file> specify config file (default is "config")
35 -x enable script debugging
36 --dump dump config settings and exit
38 configuration options:
49 create cluster CLUSTERNAME
52 create node CLUSTERNAME NODENUMBER
53 create one cluster node
55 create tsm CLUSTERNAME
56 create a TSM server node
59 mount a qemu disk on mnt/
62 unmount a qemu disk from mnt/
74 ###############################
75 # create a single node
79 NAME="$CLUSTER""n$NODENUMBER"
80 BASE="$VIRTBASE/$BASENAME.img"
81 DISK="$VIRTBASE/$CLUSTER/$NAME.qcow2"
84 # first node might need more memory for SoFS GUI
85 if [ $NODENUMBER = 1 -a $GUIMEM -gt $MEM ]; then
90 echo "Creating cluster node $NAME"
92 mkdir -p $VIRTBASE/$CLUSTER
94 echo "Creating the disk"
96 qemu-img create -b "$BASE" -f qcow2 "$DISK"
98 IPNUM=`expr $FIRSTIP + $NODENUMBER`
107 MAC1=`get_macaddr $CLUSTER $NODENUMBER 1`
108 MAC2=`get_macaddr $CLUSTER $NODENUMBER 2`
109 MAC3=`get_macaddr $CLUSTER $NODENUMBER 3`
112 echo "Creating $NAME.xml"
113 substitute_vars $NODE_TEMPLATE tmp/$NAME.xml
115 # install the XML file
116 $VIRSH undefine $NAME > /dev/null 2>&1 || true
117 $VIRSH define tmp/$NAME.xml
121 ###############################
126 BASE="$VIRTBASE/$BASENAME.img"
127 DISK="$VIRTBASE/$CLUSTER/$NAME.qcow2"
128 TSMDISK="$VIRTBASE/$CLUSTER/tsmstorage.qcow2"
130 echo "Creating TSM cluster node $NAME"
132 mkdir -p $VIRTBASE/$CLUSTER tmp
134 echo "Creating the disk"
136 qemu-img create -b "$BASE" -f qcow2 "$DISK"
138 echo "Creating tsm disk"
139 qemu-img create -f qcow2 "$TSMDISK" $TSMDISKSIZE
141 # TSM server is first IP in the cluster
150 MAC1=`get_macaddr $CLUSTER 0 0`
152 echo "Creating $NAME.xml"
153 substitute_vars $TSM_TEMPLATE tmp/$NAME.xml
155 # install the XML file
156 $VIRSH undefine $NAME > /dev/null 2>&1 || true
157 $VIRSH define tmp/$NAME.xml
161 ###############################
162 # create a whole cluster
166 mkdir -p $VIRTBASE/$CLUSTER tmp
169 echo "Creating 3 shared disks"
170 for i in `seq 1 3`; do
171 # setup a nice ID at the start of the disk
172 qemu-img create -f raw $VIRTBASE/$CLUSTER/shared$i $SHAREDDISKSIZE
173 echo "SOFS-`uuidgen`" > tmp/diskid
174 dd if=tmp/diskid of=$VIRTBASE/$CLUSTER/shared$i conv=notrunc bs=1 > /dev/null 2>&1
177 echo "Creating $NUMNODES base nodes"
178 for i in `seq 1 $NUMNODES`; do
179 create_node "$CLUSTER" $i
182 if [ $WITH_TSM_NODE -eq 1 ]; then
183 echo "Creating TSM server node"
184 create_tsm "$CLUSTER"
187 echo "# autocluster $CLUSTER" > hosts.$CLUSTER
188 [ $WITH_TSM_NODE -eq 1 ] && {
189 echo "$IPBASE.0.$FIRSTIP ${CLUSTER}tsm.$LOWDOMAIN ${CLUSTER}tsm" >> hosts.$CLUSTER
191 for i in `seq 1 $NUMNODES`; do
192 echo "$IPBASE.0.`expr $FIRSTIP + $i` ${CLUSTER}n$i.$LOWDOMAIN ${CLUSTER}n$i" >> hosts.$CLUSTER
194 echo >> hosts.$CLUSTER
196 echo "Cluster $CLUSTER created"
197 echo "You may want to add this to your /etc/hosts file:"
208 DISK="$VIRTBASE/$NAME.img"
212 echo "Creating the disk"
213 qemu-img create -f $BASE_FORMAT "$DISK" $DISKSIZE
216 mkdir -p mnt tmp tmp/ISO
221 echo "Creating kickstart file from template"
222 substitute_vars "$KICKSTART" "tmp/ks.cfg"
224 if [ $INSTALLKEY = "--skip" ]; then
226 --------------------------------------------------------------------------------------
227 WARNING: You have not entered an install key. Some RHEL packages will not be installed.
229 Please enter a valid RHEL install key in your config file like this:
231 INSTALLKEY="1234-5678-0123-4567"
233 The install will continue without an install key in 5 seconds
234 --------------------------------------------------------------------------------------
239 echo "Creating kickstart floppy"
240 dd if=/dev/zero of=tmp/floppy.img bs=1024 count=1440
241 mkdosfs tmp/floppy.img
242 mount -o loop -t msdos tmp/floppy.img mnt
244 mount -o loop,ro $ISO tmp/ISO
246 echo "Setting up bootloader"
247 cp tmp/ISO/isolinux/isolinux.bin tmp
248 cp tmp/ISO/isolinux/vmlinuz tmp
249 cp tmp/ISO/isolinux/initrd.img tmp
255 substitute_vars $INSTALL_TEMPLATE tmp/$NAME.xml
257 rm -f $KVMLOG/serial.$NAME
259 # boot the install CD
260 $VIRSH create tmp/$NAME.xml
262 echo "Waiting for install to start"
265 # wait for the install to finish
266 if ! waitfor $KVMLOG/serial.$NAME "you may safely reboot your system" 3600; then
268 echo "Failed to create base image $DISK"
277 Install finished, base image $DISK created
281 To ensure that this image does not change
283 Note that the root password has been set to $ROOTPASSWORD
290 ###############################
296 DISK="$VIRTBASE/$NAME.img"
310 echo "Creating $NAME.xml"
311 substitute_vars $BOOT_TEMPLATE tmp/$NAME.xml
313 # boot the base system
314 $VIRSH create tmp/$NAME.xml
317 ###############################
318 # test the proxy setup
320 export http_proxy=$WEBPROXY
321 wget -O /dev/null $INSTALL_SERVER
325 ######################################################################
327 . "$installdir/functions"
328 . "$installdir/config.default"
330 ############################
331 # parse command line options
332 long_opts=$(getopt_config_options)
333 getopt_output=$(getopt -n autocluster -o "c:xh" -l help,dump -l "$long_opts" -- "$@")
336 use_default_config=true
338 # We 2 passes of the options. The first time we just handle usageor the first pass
339 eval set -- "$getopt_output"
342 -c) shift 2 ; use_default_config=false ;;
345 -h|--help) usage ;; # Usage should be shown here for real defaults.
346 --*) shift 2 ;; # Assume other long opts are valid and take an arg.
347 *) usage ;; # shouldn't happen, so this is reasonable.
352 $use_default_config && [ -r "$config" ] && . "$config"
354 eval set -- "$getopt_output"
358 -c) . "`dirname $2`/$2" ; shift 2 ; conf_done=true ;;
360 --dump) dump_config ;;
362 -h|--help) usage ;; # Redundant.
364 # Putting --opt1|opt2|... into a variable and having case
365 # match against it as a pattern doesn't work. The | is
366 # part of shell syntax, so we need to do this. Look away
367 # now to stop your eyes from bleeding! :-)
368 x=",${long_opts}" # Now each option is surrounded by , and :
369 if [ "$x" != "${x#*,${1#--}:}" ] ; then
370 # Our option, $1, surrounded by , and : was in $x, so is legal.
371 setconf_longopt "$1" "$2"; shift 2
376 *) usage ;; # shouldn't happen, so this is reasonable.
384 echo ERROR: failed in function \"${FUNCNAME}\" at line ${LINENO} of ${BASH_SOURCE[0]} with code $es;
387 LOWDOMAIN=`echo $DOMAIN | tr A-Z a-z`
389 # check for needed programs
390 check_command nbd-client
392 check_command qemu-nbd
394 [ $# -lt 1 ] && usage
414 create_node "$1" "$2";