Statistics
| Branch: | Tag: | Revision:

root / tools / vcluster-setup.in @ a6d3644b

History | View | Annotate | Download (7.5 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

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

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

    
44
usage() {
45
  echo "Usage: $0 [-E] [-N] [-c <number>] [-i <number>] [-p <prefix>]"\
46
       '[-n <netdev>] [-I <path>] <directory>'
47
  echo
48
  echo 'Options:'
49
  echo "  -c  Number of virtual nodes (defaults to $default_nodecount)"
50
  echo "  -i  Number of instances (defaults to $default_instcount)"
51
  echo "  -p  IPv4 network prefix (defaults to $default_netprefix)"
52
  echo '  -n  Network device for virtual IP addresses (defaults to'\
53
       "$default_netdev)"
54
  echo "  -I  Path to init script (defaults to $default_initscript)"
55
  echo '  -E  Do not modify /etc/hosts'
56
  echo '  -N  Do not configure networking'
57
}
58

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

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

    
135
shift $((OPTIND - 1))
136

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

    
142
readonly rootdir=$1; shift
143

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
288
  cat <<EOF
289

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

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

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

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

    
314
exit 0
315

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