4 # Copyright (C) 2012 Google Inc.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 readonly self=$(readlink -f $0)
25 readonly ensure_dirs=@PKGLIBDIR@/ensure-dirs
26 readonly action_shortcuts=( start stop restart status watcher )
27 readonly default_nodecount=5
28 readonly default_instcount=10
29 readonly default_netprefix=192.0.2
30 readonly default_netdev=eth0
31 readonly default_initscript=@SYSCONFDIR@/init.d/ganeti
32 readonly cluster_name=cluster
33 readonly etc_hosts_filename=/etc/hosts
38 # Instances: .100-.254
39 readonly first_node_ipaddr_octet=10
40 readonly first_inst_ipaddr_octet=100
42 readonly max_node_count=$((first_inst_ipaddr_octet - first_node_ipaddr_octet))
43 readonly max_instance_count=$((255 - first_inst_ipaddr_octet))
46 echo "Usage: $0 [-E] [-N] [-c <number>] [-i <number>] [-p <prefix>]"\
47 '[-n <netdev>] [-I <path>] <directory>'
50 echo " -c Number of virtual nodes (defaults to $default_nodecount)"
51 echo " -i Number of instances (defaults to $default_instcount)"
52 echo " -p IPv4 network prefix (defaults to $default_netprefix)"
53 echo ' -n Network device for virtual IP addresses (defaults to'\
55 echo " -I Path to init script (defaults to $default_initscript)"
56 echo " -E Do not modify $etc_hosts_filename"
57 echo ' -N Do not configure networking'
60 # Variables for options
61 nodecount=$default_nodecount
62 instcount=$default_instcount
63 netprefix=$default_netprefix
64 netdev=$default_netdev
65 initscript=$default_initscript
70 while getopts :hENc:p:n:i:I: opt; do
78 if [[ "$nodecount" != +([0-9]) ]]; then
79 echo "Invalid node count number: $nodecount" >&2
81 elif (( nodecount > max_node_count )); then
82 echo "Node count must be $max_node_count or lower" >&2
88 if [[ "$instcount" != +([0-9]) ]]; then
89 echo "Invalid instance count number: $instcount" >&2
91 elif (( instcount > max_instance_count )); then
92 echo "Instance count must be $max_instance_count or lower" >&2
98 if [[ "$netprefix" != +([0-9]).+([0-9]).+([0-9]) ]]; then
99 echo "Invalid network prefix: $netprefix" >&2
105 if ! ip link show $netdev >/dev/null; then
106 echo "Invalid network device: $netdev" >&2
112 if [[ ! -x $initscript ]]; then
113 echo "Init script '$initscript' is not executable" >&2
124 echo "Invalid option: -$OPTARG" >&2
129 echo "Option -$OPTARG requires an argument" >&2
136 shift $((OPTIND - 1))
138 if [[ "$#" != 1 ]]; then
143 readonly rootdir=$1; shift
145 if [[ ! -d "$rootdir" ]]; then
146 echo "Directory '$rootdir' does not exist!" >&2
150 if (( $nodecount < 1 )); then
151 echo "Must create at least one node, currently requested $nodecount" >&2
158 echo "node$((number + 1))"
161 instance_hostname() {
164 echo "instance$((number + 1))"
170 echo "$netprefix.$((first_node_ipaddr_octet + number))"
176 echo "$netprefix.$((first_inst_ipaddr_octet + number))"
181 local -r nodedir=$rootdir/$(node_hostname $number)
183 echo "Setting up node '$(node_hostname $number)' ..." >&2
185 if [[ ! -d $nodedir ]]; then
190 $nodedir@SYSCONFDIR@/{default,ganeti} \
191 $nodedir@LOCALSTATEDIR@/lock\
192 $nodedir@LOCALSTATEDIR@/{lib,log,run}/ganeti
194 GANETI_HOSTNAME=$(node_hostname $number) \
195 GANETI_ROOTDIR=$nodedir \
198 local -r daemon_args="-b $(node_ipaddr $number)"
200 cat > $nodedir/etc/default/ganeti <<EOF
201 # Default settings for virtual node $i
202 NODED_ARGS='--no-mlock $daemon_args'
204 RAPI_ARGS='$daemon_args'
205 CONFD_ARGS='$daemon_args'
208 export GANETI_ROOTDIR='$nodedir'
209 export GANETI_HOSTNAME='$(node_hostname $number)'
212 cat > $nodedir/cmd <<EOF
215 export GANETI_ROOTDIR='$nodedir'
216 export GANETI_HOSTNAME='$(node_hostname $number)'
220 chmod +x $nodedir/cmd
224 for ((i=0; i < nodecount; ++i)); do
230 echo "Configuring $etc_hosts_filename ..." >&2
233 local -r tmpfile=$(mktemp $etc_hosts_filename.vcluster.XXXXX)
234 trap "rm -f $tmpfile" EXIT
236 egrep -v "^$netprefix.[[:digit:]]+[[:space:]]" $etc_hosts_filename
237 echo "$netprefix.1 $cluster_name"
238 for ((i=0; i < nodecount; ++i)); do
239 echo "$(node_ipaddr $i) $(node_hostname $i)"
241 for ((i=0; i < instcount; ++i)); do
242 echo "$(instance_ipaddr $i) $(instance_hostname $i)"
245 chmod 0644 $tmpfile && \
246 mv $tmpfile $etc_hosts_filename && \
251 setup_network_interfaces() {
252 echo 'Configuring network ...' >&2
253 for ((i=0; i < nodecount; ++i)); do
254 local ipaddr="$(node_ipaddr $i)/32"
255 ip addr del "$ipaddr" dev "$netdev" || :
256 ip addr add "$ipaddr" dev "$netdev"
259 route add -net $netprefix.0 netmask 255.255.255.0 dev $netdev || :
263 echo 'Configuring helper scripts ...' >&2
264 for action in "${action_shortcuts[@]}"; do
267 for ((i=0; i < nodecount; ++i)); do
268 local name=$(node_hostname $i)
269 if [[ $action = watcher ]]; then
270 echo "echo 'Running watcher for virtual node \"$name\" ..."
271 echo "$name/cmd ganeti-watcher \"\$@\""
273 echo "echo 'Action \"$action\" for virtual node \"$name\" ...'"
274 echo "$name/cmd $initscript $action \"\$@\""
277 } > $rootdir/$action-all
278 chmod +x $rootdir/$action-all
284 Virtual cluster setup is complete.
286 Root directory: $rootdir
287 Cluster name: $cluster_name
290 echo 'Nodes:' $(for ((i=0; i < nodecount; ++i)); do node_hostname $i; done)
295 cd $rootdir && node1/cmd gnt-cluster init --no-etc-hosts \\
296 --no-ssh-init --master-netdev=lo \\
297 --enabled-disk-templates=diskless --enabled-hypervisors=fake \\
298 --ipolicy-bounds-specs=min:disk-size=0,cpu-count=1,disk-count=0,memory-size=1,nic-count=0,spindle-use=0/max:disk-size=1048576,cpu-count=8,disk-count=16,memory-size=32768,nic-count=8,spindle-use=12 \\
302 cd $rootdir && node1/cmd gnt-node add --no-ssh-key-check node2
307 if [[ -n "$etchosts" ]]; then
310 if [[ -n "$networking" ]]; then
311 setup_network_interfaces
318 # vim: set sw=2 sts=2 et :