Statistics
| Branch: | Tag: | Revision:

root / tools / vcluster-setup.in @ 1266a29b

History | View | Annotate | Download (7 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 )
27
readonly default_nodecount=5
28
readonly default_instcount=10
29
readonly default_netprefix=192.0.2
30
readonly default_netdev=eth0
31
readonly cluster_name=cluster
32

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

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

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

    
57
# Variables for options
58
nodecount=$default_nodecount
59
instcount=$default_instcount
60
netprefix=$default_netprefix
61
netdev=$default_netdev
62
etchosts=1
63
networking=1
64

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

    
125
shift $((OPTIND - 1))
126

    
127
if [[ "$#" != 1 ]]; then
128
  usage
129
  exit 1
130
fi
131

    
132
readonly rootdir=$1; shift
133

    
134
if [[ ! -d "$rootdir" ]]; then
135
  echo "Directory '$rootdir' does not exist!" >&2
136
  exit 1
137
fi
138

    
139
if (( $nodecount < 1 )); then
140
  echo "Must create at least one node, currently requested $nodecount" >&2
141
  exit 1
142
fi
143

    
144
node_hostname() {
145
  local -r number="$1"
146

    
147
  echo "node$((number + 1))"
148
}
149

    
150
instance_hostname() {
151
  local -r number="$1"
152

    
153
  echo "instance$((number + 1))"
154
}
155

    
156
node_ipaddr() {
157
  local -r number="$1"
158

    
159
  echo "$netprefix.$((first_node_ipaddr_octet + number))"
160
}
161

    
162
instance_ipaddr() {
163
  local -r number="$1"
164

    
165
  echo "$netprefix.$((first_inst_ipaddr_octet + number))"
166
}
167

    
168
setup_node() {
169
  local -r number="$1"
170
  local -r nodedir=$rootdir/$(node_hostname $number)
171

    
172
  echo "Setting up node '$(node_hostname $number)' ..." >&2
173

    
174
  if [[ ! -d $nodedir ]]; then
175
    mkdir $nodedir
176
  fi
177

    
178
  mkdir -p \
179
    $nodedir@SYSCONFDIR@/default \
180
    $nodedir@LOCALSTATEDIR@/lock\
181
    $nodedir@LOCALSTATEDIR@/{lib,log,run}/ganeti
182

    
183
  GANETI_HOSTNAME=$(node_hostname $number) \
184
  GANETI_ROOTDIR=$nodedir \
185
  $ensure_dirs
186

    
187
  local -r daemon_args="-b $(node_ipaddr $number)"
188

    
189
  cat > $nodedir/etc/default/ganeti <<EOF
190
# Default settings for virtual node $i
191
NODED_ARGS='--no-mlock $daemon_args'
192
MASTERD_ARGS=''
193
RAPI_ARGS='$daemon_args'
194
CONFD_ARGS='$daemon_args'
195

    
196
export GANETI_ROOTDIR='$nodedir'
197
export GANETI_HOSTNAME='$(node_hostname $number)'
198
EOF
199

    
200
  cat > $nodedir/cmd <<EOF
201
#!/bin/bash
202

    
203
export GANETI_ROOTDIR='$nodedir'
204
export GANETI_HOSTNAME='$(node_hostname $number)'
205

    
206
bash -c "\$*"
207
EOF
208
  chmod +x $nodedir/cmd
209
}
210

    
211
setup_all_nodes() {
212
  for ((i=0; i < nodecount; ++i)); do
213
    setup_node $i
214
  done
215
}
216

    
217
setup_etc_hosts() {
218
  echo 'Configuring /etc/hosts ...' >&2
219
  (
220
    set -e -u
221
    local -r tmpfile=$(mktemp /etc/hosts.vcluster.XXXXX)
222
    trap "rm -f $tmpfile" EXIT
223
    {
224
      egrep -v "^$netprefix.[[:digit:]]+[[:space:]]" /etc/hosts
225
      echo "$netprefix.1 $cluster_name"
226
      for ((i=0; i < nodecount; ++i)); do
227
        echo "$(node_ipaddr $i) $(node_hostname $i)"
228
      done
229
      for ((i=0; i < instcount; ++i)); do
230
        echo "$(instance_ipaddr $i) $(instance_hostname $i)"
231
      done
232
    } > $tmpfile && \
233
    chmod 0644 $tmpfile && \
234
    mv $tmpfile /etc/hosts && \
235
    trap - EXIT
236
  )
237
}
238

    
239
setup_network_interfaces() {
240
  echo 'Configuring network ...' >&2
241
  for ((i=0; i < nodecount; ++i)); do
242
    local ipaddr="$(node_ipaddr $i)/32"
243
    ip addr del "$ipaddr" dev "$netdev" || :
244
    ip addr add "$ipaddr" dev "$netdev"
245
  done
246
}
247

    
248
setup_scripts() {
249
  echo 'Configuring helper scripts ...' >&2
250
  for action in "${action_shortcuts[@]}"; do
251
    {
252
      echo '#!/bin/bash'
253
      for ((i=0; i < nodecount; ++i)); do
254
        local name=$(node_hostname $i)
255
        echo "echo 'Action \"$action\" for virtual node \"$name\" ...'"
256
        echo "$name/cmd /etc/init.d/ganeti $action"
257
      done
258
    } > $rootdir/$action-all
259
    chmod +x $rootdir/$action-all
260
  done
261
}
262

    
263
show_info() {
264
  cat <<EOF
265
Virtual cluster setup is complete.
266

    
267
Root directory: $rootdir
268
Cluster name: $cluster_name
269
EOF
270

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

    
273
  cat <<EOF
274

    
275
Initialize cluster:
276
  cd $rootdir && node1/cmd gnt-cluster init --no-etc-hosts \\
277
    --no-ssh-init --no-lvm-storage --no-drbd-storage $cluster_name
278

    
279
Change cluster settings:
280
  cd $rootdir && node1/cmd gnt-cluster modify \\
281
    --enabled-hypervisors=fake --specs-nic-count=min=0 \\
282
    --specs-disk-size=min=0 --specs-disk-count=min=0
283

    
284
Add node:
285
  cd $rootdir && node1/cmd gnt-node add --no-ssh-key-check node2
286
EOF
287
}
288

    
289
setup_all_nodes
290
if [[ -n "$etchosts" ]]; then
291
  setup_etc_hosts
292
fi
293
if [[ -n "$networking" ]]; then
294
  setup_network_interfaces
295
fi
296
setup_scripts
297
show_info
298

    
299
exit 0
300

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