Statistics
| Branch: | Tag: | Revision:

root / tools / vcluster-setup.in @ 6bf7dad4

History | View | Annotate | Download (7.6 kB)

1
#!/bin/bash
2
#
3

    
4
# Copyright (C) 2012 Google Inc.
5
#
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.
10
#
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.
15
#
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
19
# 02110-1301, USA.
20

    
21
set -e -u -o pipefail
22
shopt -s extglob
23

    
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
34

    
35
# IP address space:
36
# Cluster: .1
37
# Nodes: .10-.99
38
# Instances: .100-.254
39
readonly first_node_ipaddr_octet=10
40
readonly first_inst_ipaddr_octet=100
41

    
42
readonly max_node_count=$((first_inst_ipaddr_octet - first_node_ipaddr_octet))
43
readonly max_instance_count=$((255 - first_inst_ipaddr_octet))
44

    
45
usage() {
46
  echo "Usage: $0 [-E] [-N] [-c <number>] [-i <number>] [-p <prefix>]"\
47
       '[-n <netdev>] [-I <path>] <directory>'
48
  echo
49
  echo 'Options:'
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'\
54
       "$default_netdev)"
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'
58
}
59

    
60
# Variables for options
61
nodecount=$default_nodecount
62
instcount=$default_instcount
63
netprefix=$default_netprefix
64
netdev=$default_netdev
65
initscript=$default_initscript
66
etchosts=1
67
networking=1
68

    
69
# Parse options
70
while getopts :hENc:p:n:i:I: opt; do
71
  case "$opt" in
72
    h)
73
      usage
74
      exit 0
75
    ;;
76
    c)
77
      nodecount="$OPTARG"
78
      if [[ "$nodecount" != +([0-9]) ]]; then
79
        echo "Invalid node count number: $nodecount" >&2
80
        exit 1
81
      elif (( nodecount > max_node_count )); then
82
        echo "Node count must be $max_node_count or lower" >&2
83
        exit 1
84
      fi
85
    ;;
86
    i)
87
      instcount="$OPTARG"
88
      if [[ "$instcount" != +([0-9]) ]]; then
89
        echo "Invalid instance count number: $instcount" >&2
90
        exit 1
91
      elif (( instcount > max_instance_count )); then
92
        echo "Instance count must be $max_instance_count or lower" >&2
93
        exit 1
94
      fi
95
    ;;
96
    p)
97
      netprefix="$OPTARG"
98
      if [[ "$netprefix" != +([0-9]).+([0-9]).+([0-9]) ]]; then
99
        echo "Invalid network prefix: $netprefix" >&2
100
        exit 1
101
      fi
102
    ;;
103
    n)
104
      netdev="$OPTARG"
105
      if ! ip link show $netdev >/dev/null; then
106
        echo "Invalid network device: $netdev" >&2
107
        exit 1
108
      fi
109
    ;;
110
    I)
111
      initscript="$OPTARG"
112
      if [[ ! -x $initscript ]]; then
113
        echo "Init script '$initscript' is not executable" >&2
114
        exit 1
115
      fi
116
      ;;
117
    E)
118
      etchosts=
119
      ;;
120
    N)
121
      networking=
122
      ;;
123
    \?)
124
      echo "Invalid option: -$OPTARG" >&2
125
      usage >&2
126
      exit 1
127
      ;;
128
    :)
129
      echo "Option -$OPTARG requires an argument" >&2
130
      usage >&2
131
      exit 1
132
      ;;
133
  esac
134
done
135

    
136
shift $((OPTIND - 1))
137

    
138
if [[ "$#" != 1 ]]; then
139
  usage
140
  exit 1
141
fi
142

    
143
readonly rootdir=$1; shift
144

    
145
if [[ ! -d "$rootdir" ]]; then
146
  echo "Directory '$rootdir' does not exist!" >&2
147
  exit 1
148
fi
149

    
150
if (( $nodecount < 1 )); then
151
  echo "Must create at least one node, currently requested $nodecount" >&2
152
  exit 1
153
fi
154

    
155
node_hostname() {
156
  local -r number="$1"
157

    
158
  echo "node$((number + 1))"
159
}
160

    
161
instance_hostname() {
162
  local -r number="$1"
163

    
164
  echo "instance$((number + 1))"
165
}
166

    
167
node_ipaddr() {
168
  local -r number="$1"
169

    
170
  echo "$netprefix.$((first_node_ipaddr_octet + number))"
171
}
172

    
173
instance_ipaddr() {
174
  local -r number="$1"
175

    
176
  echo "$netprefix.$((first_inst_ipaddr_octet + number))"
177
}
178

    
179
setup_node() {
180
  local -r number="$1"
181
  local -r nodedir=$rootdir/$(node_hostname $number)
182

    
183
  echo "Setting up node '$(node_hostname $number)' ..." >&2
184

    
185
  if [[ ! -d $nodedir ]]; then
186
    mkdir $nodedir
187
  fi
188

    
189
  mkdir -p \
190
    $nodedir@SYSCONFDIR@/{default,ganeti} \
191
    $nodedir@LOCALSTATEDIR@/lock\
192
    $nodedir@LOCALSTATEDIR@/{lib,log,run}/ganeti
193

    
194
  GANETI_HOSTNAME=$(node_hostname $number) \
195
  GANETI_ROOTDIR=$nodedir \
196
  $ensure_dirs
197

    
198
  local -r daemon_args="-b $(node_ipaddr $number)"
199

    
200
  cat > $nodedir/etc/default/ganeti <<EOF
201
# Default settings for virtual node $i
202
NODED_ARGS='--no-mlock $daemon_args'
203
MASTERD_ARGS=''
204
RAPI_ARGS='$daemon_args'
205
CONFD_ARGS='$daemon_args'
206

    
207
export GANETI_ROOTDIR='$nodedir'
208
export GANETI_HOSTNAME='$(node_hostname $number)'
209
EOF
210

    
211
  cat > $nodedir/cmd <<EOF
212
#!/bin/bash
213

    
214
export GANETI_ROOTDIR='$nodedir'
215
export GANETI_HOSTNAME='$(node_hostname $number)'
216

    
217
bash -c "\$*"
218
EOF
219
  chmod +x $nodedir/cmd
220
}
221

    
222
setup_all_nodes() {
223
  for ((i=0; i < nodecount; ++i)); do
224
    setup_node $i
225
  done
226
}
227

    
228
setup_etc_hosts() {
229
  echo "Configuring $etc_hosts_filename ..." >&2
230
  (
231
    set -e -u
232
    local -r tmpfile=$(mktemp $etc_hosts_filename.vcluster.XXXXX)
233
    trap "rm -f $tmpfile" EXIT
234
    {
235
      egrep -v "^$netprefix.[[:digit:]]+[[:space:]]" $etc_hosts_filename
236
      echo "$netprefix.1 $cluster_name"
237
      for ((i=0; i < nodecount; ++i)); do
238
        echo "$(node_ipaddr $i) $(node_hostname $i)"
239
      done
240
      for ((i=0; i < instcount; ++i)); do
241
        echo "$(instance_ipaddr $i) $(instance_hostname $i)"
242
      done
243
    } > $tmpfile && \
244
    chmod 0644 $tmpfile && \
245
    mv $tmpfile $etc_hosts_filename && \
246
    trap - EXIT
247
  )
248
}
249

    
250
setup_network_interfaces() {
251
  echo 'Configuring network ...' >&2
252
  for ((i=0; i < nodecount; ++i)); do
253
    local ipaddr="$(node_ipaddr $i)/32"
254
    ip addr del "$ipaddr" dev "$netdev" || :
255
    ip addr add "$ipaddr" dev "$netdev"
256
  done
257
}
258

    
259
setup_scripts() {
260
  echo 'Configuring helper scripts ...' >&2
261
  for action in "${action_shortcuts[@]}"; do
262
    {
263
      echo '#!/bin/bash'
264
      for ((i=0; i < nodecount; ++i)); do
265
        local name=$(node_hostname $i)
266
        if [[ $action = watcher ]]; then
267
          echo "echo 'Running watcher for virtual node \"$name\" ..."
268
          echo "$name/cmd ganeti-watcher \"\$@\""
269
        else
270
          echo "echo 'Action \"$action\" for virtual node \"$name\" ...'"
271
          echo "$name/cmd $initscript $action \"\$@\""
272
        fi
273
      done
274
    } > $rootdir/$action-all
275
    chmod +x $rootdir/$action-all
276
  done
277
}
278

    
279
show_info() {
280
  cat <<EOF
281
Virtual cluster setup is complete.
282

    
283
Root directory: $rootdir
284
Cluster name: $cluster_name
285
EOF
286

    
287
  echo 'Nodes:' $(for ((i=0; i < nodecount; ++i)); do node_hostname $i; done)
288

    
289
  cat <<EOF
290

    
291
Initialize cluster:
292
  cd $rootdir && node1/cmd gnt-cluster init --no-etc-hosts \\
293
    --no-ssh-init --no-lvm-storage --no-drbd-storage $cluster_name
294

    
295
Change cluster settings:
296
  cd $rootdir && node1/cmd gnt-cluster modify \\
297
    --enabled-hypervisors=fake --specs-nic-count=min=0 \\
298
    --specs-disk-size=min=0 --specs-disk-count=min=0
299

    
300
Add node:
301
  cd $rootdir && node1/cmd gnt-node add --no-ssh-key-check node2
302
EOF
303
}
304

    
305
setup_all_nodes
306
if [[ -n "$etchosts" ]]; then
307
  setup_etc_hosts
308
fi
309
if [[ -n "$networking" ]]; then
310
  setup_network_interfaces
311
fi
312
setup_scripts
313
show_info
314

    
315
exit 0
316

    
317
# vim: set sw=2 sts=2 et :